mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
Merge branch 'main' of github.com:NousResearch/hermes-agent into feat/ink-refactor
This commit is contained in:
commit
7e4dd6ea02
220 changed files with 23482 additions and 1959 deletions
|
|
@ -12,7 +12,7 @@ import os
|
|||
import urllib.request
|
||||
import urllib.error
|
||||
from difflib import get_close_matches
|
||||
from typing import Any, Optional
|
||||
from typing import Any, NamedTuple, Optional
|
||||
|
||||
COPILOT_BASE_URL = "https://api.githubcopilot.com"
|
||||
COPILOT_MODELS_URL = f"{COPILOT_BASE_URL}/models"
|
||||
|
|
@ -70,13 +70,13 @@ def _codex_curated_models() -> list[str]:
|
|||
|
||||
_PROVIDER_MODELS: dict[str, list[str]] = {
|
||||
"nous": [
|
||||
"xiaomi/mimo-v2-pro",
|
||||
"anthropic/claude-opus-4.6",
|
||||
"anthropic/claude-sonnet-4.6",
|
||||
"anthropic/claude-sonnet-4.5",
|
||||
"anthropic/claude-haiku-4.5",
|
||||
"openai/gpt-5.4",
|
||||
"openai/gpt-5.4-mini",
|
||||
"xiaomi/mimo-v2-pro",
|
||||
"openai/gpt-5.3-codex",
|
||||
"google/gemini-3-pro-preview",
|
||||
"google/gemini-3-flash-preview",
|
||||
|
|
@ -130,6 +130,7 @@ _PROVIDER_MODELS: dict[str, list[str]] = {
|
|||
"gemma-4-26b-it",
|
||||
],
|
||||
"zai": [
|
||||
"glm-5.1",
|
||||
"glm-5",
|
||||
"glm-5-turbo",
|
||||
"glm-4.7",
|
||||
|
|
@ -157,6 +158,12 @@ _PROVIDER_MODELS: dict[str, list[str]] = {
|
|||
"kimi-k2-turbo-preview",
|
||||
"kimi-k2-0905-preview",
|
||||
],
|
||||
"kimi-coding-cn": [
|
||||
"kimi-k2.5",
|
||||
"kimi-k2-thinking",
|
||||
"kimi-k2-turbo-preview",
|
||||
"kimi-k2-0905-preview",
|
||||
],
|
||||
"moonshot": [
|
||||
"kimi-k2.5",
|
||||
"kimi-k2-thinking",
|
||||
|
|
@ -478,29 +485,55 @@ def check_nous_free_tier() -> bool:
|
|||
return False # default to paid on error — don't block users
|
||||
|
||||
|
||||
_PROVIDER_LABELS = {
|
||||
"openrouter": "OpenRouter",
|
||||
"openai-codex": "OpenAI Codex",
|
||||
"copilot-acp": "GitHub Copilot ACP",
|
||||
"nous": "Nous Portal",
|
||||
"copilot": "GitHub Copilot",
|
||||
"gemini": "Google AI Studio",
|
||||
"zai": "Z.AI / GLM",
|
||||
"kimi-coding": "Kimi / Moonshot",
|
||||
"minimax": "MiniMax",
|
||||
"minimax-cn": "MiniMax (China)",
|
||||
"anthropic": "Anthropic",
|
||||
"deepseek": "DeepSeek",
|
||||
"opencode-zen": "OpenCode Zen",
|
||||
"opencode-go": "OpenCode Go",
|
||||
"ai-gateway": "AI Gateway",
|
||||
"kilocode": "Kilo Code",
|
||||
"alibaba": "Alibaba Cloud (DashScope)",
|
||||
"qwen-oauth": "Qwen OAuth (Portal)",
|
||||
"huggingface": "Hugging Face",
|
||||
"xiaomi": "Xiaomi MiMo",
|
||||
"custom": "Custom endpoint",
|
||||
}
|
||||
# ---------------------------------------------------------------------------
|
||||
# Canonical provider list — single source of truth for provider identity.
|
||||
# Every code path that lists, displays, or iterates providers derives from
|
||||
# this list: hermes model, /model, /provider, list_authenticated_providers.
|
||||
#
|
||||
# Fields:
|
||||
# slug — internal provider ID (used in config.yaml, --provider flag)
|
||||
# label — short display name
|
||||
# tier — "top" (shown first) or "extended" (behind "More...")
|
||||
# tui_desc — longer description for the `hermes model` interactive picker
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class ProviderEntry(NamedTuple):
|
||||
slug: str
|
||||
label: str
|
||||
tier: str # "top" or "extended"
|
||||
tui_desc: str # detailed description for `hermes model` TUI
|
||||
|
||||
|
||||
CANONICAL_PROVIDERS: list[ProviderEntry] = [
|
||||
# -- Top tier (shown by default) --
|
||||
ProviderEntry("nous", "Nous Portal", "top", "Nous Portal (Nous Research subscription)"),
|
||||
ProviderEntry("openrouter", "OpenRouter", "top", "OpenRouter (100+ models, pay-per-use)"),
|
||||
ProviderEntry("anthropic", "Anthropic", "top", "Anthropic (Claude models — API key or Claude Code)"),
|
||||
ProviderEntry("openai-codex", "OpenAI Codex", "top", "OpenAI Codex"),
|
||||
ProviderEntry("qwen-oauth", "Qwen OAuth (Portal)", "top", "Qwen OAuth (reuses local Qwen CLI login)"),
|
||||
ProviderEntry("copilot", "GitHub Copilot", "top", "GitHub Copilot (uses GITHUB_TOKEN or gh auth token)"),
|
||||
ProviderEntry("huggingface", "Hugging Face", "top", "Hugging Face Inference Providers (20+ open models)"),
|
||||
# -- Extended tier (behind "More..." in hermes model) --
|
||||
ProviderEntry("copilot-acp", "GitHub Copilot ACP", "extended", "GitHub Copilot ACP (spawns `copilot --acp --stdio`)"),
|
||||
ProviderEntry("gemini", "Google AI Studio", "extended", "Google AI Studio (Gemini models — OpenAI-compatible endpoint)"),
|
||||
ProviderEntry("deepseek", "DeepSeek", "extended", "DeepSeek (DeepSeek-V3, R1, coder — direct API)"),
|
||||
ProviderEntry("xai", "xAI", "extended", "xAI (Grok models — direct API)"),
|
||||
ProviderEntry("zai", "Z.AI / GLM", "extended", "Z.AI / GLM (Zhipu AI direct API)"),
|
||||
ProviderEntry("kimi-coding", "Kimi / Moonshot", "extended", "Kimi / Moonshot (Moonshot AI direct API)"),
|
||||
ProviderEntry("kimi-coding-cn", "Kimi / Moonshot (China)", "extended", "Kimi / Moonshot China (Moonshot CN direct API)"),
|
||||
ProviderEntry("minimax", "MiniMax", "extended", "MiniMax (global direct API)"),
|
||||
ProviderEntry("minimax-cn", "MiniMax (China)", "extended", "MiniMax China (domestic direct API)"),
|
||||
ProviderEntry("kilocode", "Kilo Code", "extended", "Kilo Code (Kilo Gateway API)"),
|
||||
ProviderEntry("opencode-zen", "OpenCode Zen", "extended", "OpenCode Zen (35+ curated models, pay-as-you-go)"),
|
||||
ProviderEntry("opencode-go", "OpenCode Go", "extended", "OpenCode Go (open models, $10/month subscription)"),
|
||||
ProviderEntry("ai-gateway", "AI Gateway", "extended", "AI Gateway (Vercel — 200+ models, pay-per-use)"),
|
||||
ProviderEntry("alibaba", "Alibaba Cloud (DashScope)","extended", "Alibaba Cloud / DashScope Coding (Qwen + multi-provider)"),
|
||||
ProviderEntry("xiaomi", "Xiaomi MiMo", "extended", "Xiaomi MiMo (MiMo-V2 models — pro, omni, flash)"),
|
||||
]
|
||||
|
||||
# Derived dicts — used throughout the codebase
|
||||
_PROVIDER_LABELS = {p.slug: p.label for p in CANONICAL_PROVIDERS}
|
||||
_PROVIDER_LABELS["custom"] = "Custom endpoint" # special case: not a named provider
|
||||
|
||||
_PROVIDER_ALIASES = {
|
||||
"glm": "zai",
|
||||
|
|
@ -518,6 +551,8 @@ _PROVIDER_ALIASES = {
|
|||
"google-ai-studio": "gemini",
|
||||
"kimi": "kimi-coding",
|
||||
"moonshot": "kimi-coding",
|
||||
"kimi-cn": "kimi-coding-cn",
|
||||
"moonshot-cn": "kimi-coding-cn",
|
||||
"minimax-china": "minimax-cn",
|
||||
"minimax_cn": "minimax-cn",
|
||||
"claude": "anthropic",
|
||||
|
|
@ -543,6 +578,9 @@ _PROVIDER_ALIASES = {
|
|||
"huggingface-hub": "huggingface",
|
||||
"mimo": "xiaomi",
|
||||
"xiaomi-mimo": "xiaomi",
|
||||
"grok": "xai",
|
||||
"x-ai": "xai",
|
||||
"x.ai": "xai",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -835,23 +873,20 @@ def list_available_providers() -> list[dict[str, str]]:
|
|||
|
||||
Each dict has ``id``, ``label``, and ``aliases``.
|
||||
Checks which providers have valid credentials configured.
|
||||
|
||||
Derives the provider list from :data:`CANONICAL_PROVIDERS` (single
|
||||
source of truth shared with ``hermes model``, ``/model``, etc.).
|
||||
"""
|
||||
# Canonical providers in display order
|
||||
_PROVIDER_ORDER = [
|
||||
"openrouter", "nous", "openai-codex", "copilot", "copilot-acp",
|
||||
"gemini", "huggingface",
|
||||
"zai", "kimi-coding", "minimax", "minimax-cn", "kilocode", "anthropic", "alibaba",
|
||||
"qwen-oauth", "xiaomi",
|
||||
"opencode-zen", "opencode-go",
|
||||
"ai-gateway", "deepseek", "custom",
|
||||
]
|
||||
# Derive display order from canonical list + custom
|
||||
provider_order = [p.slug for p in CANONICAL_PROVIDERS] + ["custom"]
|
||||
|
||||
# Build reverse alias map
|
||||
aliases_for: dict[str, list[str]] = {}
|
||||
for alias, canonical in _PROVIDER_ALIASES.items():
|
||||
aliases_for.setdefault(canonical, []).append(alias)
|
||||
|
||||
result = []
|
||||
for pid in _PROVIDER_ORDER:
|
||||
for pid in provider_order:
|
||||
label = _PROVIDER_LABELS.get(pid, pid)
|
||||
alias_list = aliases_for.get(pid, [])
|
||||
# Check if this provider has credentials available
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue