mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-30 01:41:43 +00:00
Merge branch 'main' of github.com:NousResearch/hermes-agent into feat/ink-refactor
This commit is contained in:
commit
f81dba0da2
128 changed files with 8357 additions and 842 deletions
|
|
@ -1372,7 +1372,7 @@ def select_provider_and_model(args=None):
|
|||
_model_flow_kimi(config, current_model)
|
||||
elif selected_provider == "bedrock":
|
||||
_model_flow_bedrock(config, current_model)
|
||||
elif selected_provider in ("gemini", "deepseek", "xai", "zai", "kimi-coding-cn", "minimax", "minimax-cn", "kilocode", "opencode-zen", "opencode-go", "ai-gateway", "alibaba", "huggingface", "xiaomi", "arcee"):
|
||||
elif selected_provider in ("gemini", "deepseek", "xai", "zai", "kimi-coding-cn", "minimax", "minimax-cn", "kilocode", "opencode-zen", "opencode-go", "ai-gateway", "alibaba", "huggingface", "xiaomi", "arcee", "ollama-cloud"):
|
||||
_model_flow_api_key_provider(config, selected_provider, current_model)
|
||||
|
||||
# ── Post-switch cleanup: clear stale OPENAI_BASE_URL ──────────────
|
||||
|
|
@ -1799,6 +1799,27 @@ def _model_flow_custom(config):
|
|||
|
||||
effective_key = api_key or current_key
|
||||
|
||||
# Hint: most local model servers (Ollama, vLLM, llama.cpp) require /v1
|
||||
# in the base URL for OpenAI-compatible chat completions. Prompt the
|
||||
# user if the URL looks like a local server without /v1.
|
||||
_url_lower = effective_url.rstrip("/").lower()
|
||||
_looks_local = any(h in _url_lower for h in ("localhost", "127.0.0.1", "0.0.0.0", ":11434", ":8080", ":5000"))
|
||||
if _looks_local and not _url_lower.endswith("/v1"):
|
||||
print()
|
||||
print(f" Hint: Did you mean to add /v1 at the end?")
|
||||
print(f" Most local model servers (Ollama, vLLM, llama.cpp) require it.")
|
||||
print(f" e.g. {effective_url.rstrip('/')}/v1")
|
||||
try:
|
||||
_add_v1 = input(" Add /v1? [Y/n]: ").strip().lower()
|
||||
except (KeyboardInterrupt, EOFError):
|
||||
_add_v1 = "n"
|
||||
if _add_v1 in ("", "y", "yes"):
|
||||
effective_url = effective_url.rstrip("/") + "/v1"
|
||||
if base_url:
|
||||
base_url = effective_url
|
||||
print(f" Updated URL: {effective_url}")
|
||||
print()
|
||||
|
||||
from hermes_cli.models import probe_api_models
|
||||
|
||||
probe = probe_api_models(effective_key, effective_url)
|
||||
|
|
@ -2965,34 +2986,43 @@ def _model_flow_api_key_provider(config, provider_id, current_model=""):
|
|||
# 1. models.dev registry (cached, filtered for agentic/tool-capable models)
|
||||
# 2. Curated static fallback list (offline insurance)
|
||||
# 3. Live /models endpoint probe (small providers without models.dev data)
|
||||
curated = _PROVIDER_MODELS.get(provider_id, [])
|
||||
|
||||
# Try models.dev first — returns tool-capable models, filtered for noise
|
||||
mdev_models: list = []
|
||||
try:
|
||||
from agent.models_dev import list_agentic_models
|
||||
mdev_models = list_agentic_models(provider_id)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if mdev_models:
|
||||
model_list = mdev_models
|
||||
print(f" Found {len(model_list)} model(s) from models.dev registry")
|
||||
elif curated and len(curated) >= 8:
|
||||
# Curated list is substantial — use it directly, skip live probe
|
||||
model_list = curated
|
||||
print(f" Showing {len(model_list)} curated models — use \"Enter custom model name\" for others.")
|
||||
else:
|
||||
#
|
||||
# Ollama Cloud: dedicated merged discovery (live API + models.dev + disk cache)
|
||||
if provider_id == "ollama-cloud":
|
||||
from hermes_cli.models import fetch_ollama_cloud_models
|
||||
api_key_for_probe = existing_key or (get_env_value(key_env) if key_env else "")
|
||||
live_models = fetch_api_models(api_key_for_probe, effective_base)
|
||||
if live_models and len(live_models) >= len(curated):
|
||||
model_list = live_models
|
||||
print(f" Found {len(model_list)} model(s) from {pconfig.name} API")
|
||||
else:
|
||||
model_list = fetch_ollama_cloud_models(api_key=api_key_for_probe, base_url=effective_base)
|
||||
if model_list:
|
||||
print(f" Found {len(model_list)} model(s) from Ollama Cloud")
|
||||
else:
|
||||
curated = _PROVIDER_MODELS.get(provider_id, [])
|
||||
|
||||
# Try models.dev first — returns tool-capable models, filtered for noise
|
||||
mdev_models: list = []
|
||||
try:
|
||||
from agent.models_dev import list_agentic_models
|
||||
mdev_models = list_agentic_models(provider_id)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if mdev_models:
|
||||
model_list = mdev_models
|
||||
print(f" Found {len(model_list)} model(s) from models.dev registry")
|
||||
elif curated and len(curated) >= 8:
|
||||
# Curated list is substantial — use it directly, skip live probe
|
||||
model_list = curated
|
||||
if model_list:
|
||||
print(f" Showing {len(model_list)} curated models — use \"Enter custom model name\" for others.")
|
||||
# else: no defaults either, will fall through to raw input
|
||||
print(f" Showing {len(model_list)} curated models — use \"Enter custom model name\" for others.")
|
||||
else:
|
||||
api_key_for_probe = existing_key or (get_env_value(key_env) if key_env else "")
|
||||
live_models = fetch_api_models(api_key_for_probe, effective_base)
|
||||
if live_models and len(live_models) >= len(curated):
|
||||
model_list = live_models
|
||||
print(f" Found {len(model_list)} model(s) from {pconfig.name} API")
|
||||
else:
|
||||
model_list = curated
|
||||
if model_list:
|
||||
print(f" Showing {len(model_list)} curated models — use \"Enter custom model name\" for others.")
|
||||
# else: no defaults either, will fall through to raw input
|
||||
|
||||
if provider_id in {"opencode-zen", "opencode-go"}:
|
||||
model_list = [normalize_opencode_model_id(provider_id, mid) for mid in model_list]
|
||||
|
|
@ -5130,7 +5160,7 @@ For more help on a command:
|
|||
)
|
||||
chat_parser.add_argument(
|
||||
"--provider",
|
||||
choices=["auto", "openrouter", "nous", "openai-codex", "copilot-acp", "copilot", "anthropic", "gemini", "huggingface", "zai", "kimi-coding", "kimi-coding-cn", "minimax", "minimax-cn", "kilocode", "xiaomi", "arcee"],
|
||||
choices=["auto", "openrouter", "nous", "openai-codex", "copilot-acp", "copilot", "anthropic", "gemini", "xai", "ollama-cloud", "huggingface", "zai", "kimi-coding", "kimi-coding-cn", "minimax", "minimax-cn", "kilocode", "xiaomi", "arcee"],
|
||||
default=None,
|
||||
help="Inference provider (default: auto)"
|
||||
)
|
||||
|
|
@ -6608,8 +6638,13 @@ Examples:
|
|||
sys.stderr = _io.StringIO()
|
||||
args = parser.parse_args(_processed_argv)
|
||||
sys.stderr = _saved_stderr
|
||||
except SystemExit:
|
||||
except SystemExit as exc:
|
||||
sys.stderr = _saved_stderr
|
||||
# Help/version flags (exit code 0) already printed output —
|
||||
# re-raise immediately to avoid a second parse_args printing
|
||||
# the same help text again (#10230).
|
||||
if exc.code == 0:
|
||||
raise
|
||||
# Subcommand name was consumed as a flag value (e.g. -c model).
|
||||
# Fall back to optional subparsers so argparse handles it normally.
|
||||
subparsers.required = False
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue