fix(model_tools): honor model.context_length to skip OpenRouter probe on banner

_cli's show_banner() calls _resolve_active_context_length() at every
startup. For non-OpenRouter providers (e.g. minimax-cn, kimi-coding,
custom endpoints) the resolver falls through to step 6 (OpenRouter
live /models fetch), which blocks ~2-3s per CLI launch and adds up
to 7+ minutes when openrouter.ai is unreachable through a proxy that
403s CONNECT (#46620).

Two complementary changes:

1. model_tools.py: read model.context_length from config.yaml and pass
   it as config_context_length to get_model_context_length. The
   step-0 config override short-circuits the entire resolution chain
   including the OpenRouter fetch. No network call is made when the
   user has set the value explicitly.

2. agent/model_metadata.py: replace flat timeout=10 with (5, 10)
   tuple at all five sites (fetch_model_metadata + four endpoint
   probes). urllib3 can otherwise block for 10s per retry stage
   through proxies that 403 CONNECT. The tuple bounds connect at 5s
   while still allowing slow reads.

Complements the in-flight PR #46685 (which adds HERMES_DISABLE_MODEL_METADATA
env var + same timeout tuple change for fetch_model_metadata). This PR
extends the timeout fix to the other four endpoint probes and adds the
config-override path that addresses the slow-but-reachable scenario
where env-var disable is too heavy-handed.

Refs #46620, PR #46685.

(cherry picked from commit e7faa34199)
This commit is contained in:
MiniMax-M3 2026-06-22 11:20:28 +08:00 committed by kshitij
parent 9a18a2de12
commit c454d32feb
2 changed files with 15 additions and 6 deletions

View file

@ -822,7 +822,10 @@ def fetch_model_metadata(force_refresh: bool = False) -> Dict[str, Dict[str, Any
return _model_metadata_cache
try:
response = requests.get(OPENROUTER_MODELS_URL, timeout=10, verify=_resolve_requests_verify())
# Tuple (connect, read) — flat timeout=10 means urllib3 can block 10s per
# retry stage through proxies that 403 CONNECT, ballooning to minutes
# (#46620). 5s connect / 10s read fails fast on unreachable hosts.
response = requests.get(OPENROUTER_MODELS_URL, timeout=(5, 10), verify=_resolve_requests_verify())
response.raise_for_status()
data = response.json()
@ -900,7 +903,7 @@ def fetch_endpoint_model_metadata(
response = requests.get(
server_url.rstrip("/") + "/api/v1/models",
headers=headers,
timeout=10,
timeout=(5, 10),
verify=_resolve_requests_verify(),
)
response.raise_for_status()
@ -948,7 +951,7 @@ def fetch_endpoint_model_metadata(
for candidate in candidates:
url = candidate.rstrip("/") + "/models"
try:
response = requests.get(url, headers=headers, timeout=10, verify=_resolve_requests_verify())
response = requests.get(url, headers=headers, timeout=(5, 10), verify=_resolve_requests_verify())
response.raise_for_status()
payload = response.json()
cache: Dict[str, Dict[str, Any]] = {}
@ -1715,7 +1718,7 @@ def _query_anthropic_context_length(model: str, base_url: str, api_key: str) ->
"x-api-key": api_key,
"anthropic-version": "2023-06-01",
}
resp = requests.get(url, headers=headers, timeout=10, verify=_resolve_requests_verify())
resp = requests.get(url, headers=headers, timeout=(5, 10), verify=_resolve_requests_verify())
if resp.status_code != 200:
return None
data = resp.json()
@ -1782,7 +1785,7 @@ def _fetch_codex_oauth_context_lengths(access_token: str) -> Dict[str, int]:
resp = requests.get(
"https://chatgpt.com/backend-api/codex/models?client_version=1.0.0",
headers={"Authorization": f"Bearer {access_token}"},
timeout=10,
timeout=(5, 10),
verify=_resolve_requests_verify(),
)
if resp.status_code != 200:

View file

@ -583,7 +583,13 @@ def _resolve_active_context_length() -> int:
if not model_id:
return 0
from agent.model_metadata import get_model_context_length
return int(get_model_context_length(model_id) or 0)
# Honor explicit `model.context_length` in config.yaml — short-circuits
# the OpenRouter /models probe at get_model_context_length step 0, so
# non-OpenRouter providers don't pay the ~2-3s OpenRouter fetch at every
# CLI startup. See issue #46620.
raw_ctx = model_cfg.get("context_length")
config_ctx = raw_ctx if isinstance(raw_ctx, int) and raw_ctx > 0 else None
return int(get_model_context_length(model_id, config_context_length=config_ctx) or 0)
except Exception as e:
logger.debug("Could not resolve active context length: %s", e)
return 0