Files

1 line
93 KiB
JSON

{"repo": "agentic-in/elephant-agent", "files": {"packages/models/model_metadata.py": {"b342fa5f7cceb2efc4945b50b54b6e8233452272": {"t": 1785595148.7759643, "n": 23169, "h": "8080afce24003935", "c": "\"\"\"Provider-aware model metadata fallback resolution.\"\"\"\n\nfrom __future__ import annotations\n\nfrom collections.abc import Mapping\nfrom dataclasses import dataclass\nimport ipaddress\nimport json\nimport os\nfrom pathlib import Path\nimport tempfile\nimport time\nfrom typing import Any\nfrom urllib import error, request\nfrom urllib.parse import urlparse\n\nfrom packages.runtime_layout import default_cli_state_dir\n\n\nMODELS_DEV_URL = \"https://models.dev/api.json\"\nOPENROUTER_MODELS_URL = \"https://openrouter.ai/api/v1/models\"\n_MODELS_DEV_CACHE_TTL_SECONDS = 3600\n_OPENROUTER_CACHE_TTL_SECONDS = 3600\n_ENDPOINT_CACHE_TTL_SECONDS = 300\n\n_LOCAL_HOSTS = frozenset({\"localhost\", \"127.0.0.1\", \"::1\", \"0.0.0.0\"})\n_CONTAINER_LOCAL_SUFFIXES = (\".docker.internal\", \".containers.internal\", \".lima.internal\")\n\n_CONTEXT_KEYS = (\n \"context_length\",\n \"context_window\",\n \"max_context_length\",\n \"max_position_embeddings\",\n \"max_model_len\",\n \"max_input_tokens\",\n \"max_sequence_length\",\n \"max_seq_len\",\n \"n_ctx\",\n \"n_ctx_train\",\n)\n_OUTPUT_KEYS = (\n \"max_completion_tokens\",\n \"max_output_tokens\",\n \"max_tokens\",\n)\n\n_PROVIDER_TO_MODELS_DEV: dict[str, str] = {\n \"alibaba\": \"alibaba\",\n \"anthropic\": \"anthropic\",\n \"baidu-qianfan\": \"baidu\",\n \"cerebras\": \"cerebras\",\n \"claude-code\": \"anthropic\",\n \"cohere\": \"cohere\",\n \"copilot\": \"github-copilot\",\n \"deepseek\": \"deepseek\",\n \"fireworks\": \"fireworks-ai\",\n \"google\": \"google\",\n \"groq\": \"groq\",\n \"huggingface\": \"huggingface\",\n \"kilocode\": \"kilo\",\n \"minimax\": \"minimax\",\n \"minimax-cn\": \"minimax-cn\",\n \"modelscope\": \"modelscope\",\n \"mistral\": \"mistral\",\n \"moonshot\": \"kimi-for-coding\",\n \"moonshot-cn\": \"kimi-for-coding\",\n \"nvidia\": \"nvidia\",\n \"openai\": \"openai\",\n \"openai-codex\": \"openai\",\n \"opencode-go\": \"opencode-go\",\n \"opencode-zen\": \"opencode\",\n \"openrouter\": \"openrouter\",\n \"perplexity\": \"perplexity\",\n \"qwen-oauth\": \"alibaba\",\n \"siliconflow\": \"siliconflow\",\n \"stepfun\": \"stepfun\",\n \"tencent-hunyuan\": \"tencent\",\n \"tencent-tokenhub\": \"tencent\",\n \"together\": \"togetherai\",\n \"volcengine\": \"volcengine\",\n \"xai\": \"xai\",\n \"xiaomi\": \"xiaomi\",\n \"zai\": \"zai\",\n}\n\n_URL_TO_PROVIDER: dict[str, str] = {\n \"api-inference.modelscope.cn\": \"modelscope\",\n \"api.anthropic.com\": \"anthropic\",\n \"api.cerebras.ai\": \"cerebras\",\n \"api.cohere.ai\": \"cohere\",\n \"api.deepseek.com\": \"deepseek\",\n \"api.githubcopilot.com\": \"copilot\",\n \"api.groq.com\": \"groq\",\n \"api.hunyuan.cloud.tencent.com\": \"tencent-hunyuan\",\n \"api.minimax\": \"minimax\",\n \"api.mistral.ai\": \"mistral\",\n \"api.moonshot.ai\": \"moonshot\",\n \"api.moonshot.cn\": \"moonshot-cn\",\n \"api.openai.com\": \"openai\",\n \"api.perplexity.ai\": \"perplexity\",\n \"api.siliconflow.cn\": \"siliconflow\",\n \"api.siliconflow.com\": \"siliconflow\",\n \"api.stepfun.ai\": \"stepfun\",\n \"api.stepfun.com\": \"stepfun\",\n \"api.together.ai\": \"together\",\n \"api.x.ai\": \"xai\",\n \"api.xiaomimimo.com\": \"xiaomi\",\n \"api.z.ai\": \"zai\",\n \"ark.cn-beijing.volces.com\": \"volcengine\",\n \"chatgpt.com\": \"openai-codex\",\n \"dashscope-intl.aliyuncs.com\": \"alibaba\",\n \"dashscope.aliyuncs.com\": \"alibaba\",\n \"generativelanguage.googleapis.com\": \"google\",\n \"integrate.api.nvidia.com\": \"nvidia\",\n \"models.github.ai\": \"copilot\",\n \"openrouter.ai\": \"openrouter\",\n \"opencode.ai\": \"opencode-go\",\n \"portal.qwen.ai\": \"qwen-oauth\",\n \"qianfan.baidubce.com\": \"baidu-qianfan\",\n \"tokenhub-intl.tencentcloudmaas.com\": \"tencent-tokenhub\",\n \"tokenhub-intl.tencentmaas.cn\": \"tencent-tokenhub\",\n \"tokenhub-intl.tencentmaas.com\": \"tencent-tokenhub\",\n \"tokenhub.tencentmaas.cn\": \"tencent-tokenhub\",\n \"tokenhub.tencentmaas.com\": \"tencent-tokenhub\",\n \"xiaomimimo.com\": \"xiaomi\",\n}\n\n_models_dev_cache: dict[str, Any] = {}\n_models_dev_cache_time = 0.0\n_openrouter_cache: dict[str, \"ResolvedModelMetadata\"] = {}\n_openrouter_cache_time = 0.0\n_endpoint_metadata_cache: dict[str, dict[str, \"ResolvedModelMetadata\"]] = {}\n_endpoint_metadata_cache_time: dict[str, float] = {}\n\n\n@dataclass(frozen=True, slots=True)\nclass ResolvedModelMetadata:\n context_window_tokens: int | None = None\n max_output_tokens: int | None = None\n source: str = \"unknown\"\n\n\ndef resolve_provider_model_metadata(\n *,\n provider_id: str,\n model_id: str,\n base_url: str | None = None,\n api_key: str | None = None,\n) -> ResolvedModelMetadata | None:\n \"\"\"Resolve metadata for one selected model from local, registry, or routed catalogs.\"\"\"\n\n normalized_model = str(model_id or \"\").strip()\n if not normalized_model:\n return None\n\n normalized_base_url = _normalize_base_url(base_url)\n cached_context = get_cached_context_length(normalized_model, normalized_base_url)\n if cached_context is not None:\n return ResolvedModelMetadata(\n context_window_tokens=cached_context,\n source=\"context-length-cache\",\n )\n\n if normalized_base_url and is_local_endpoint(normalized_base_url):\n local = query_local_endpoint_metadata(\n model_id=normalized_model,\n base_url=normalized_base_url,\n api_key=api_key,\n )\n if local is not None and local.context_window_tokens is not None:\n save_context_length(normalized_model, normalized_base_url, local.context_window_tokens)\n return local\n\n effective_provider = _effective_provider_id(provider_id=provider_id, base_url=normalized_base_url)\n models_dev = lookup_models_dev_metadata(effective_provider, normalized_model)\n if models_dev is not None and models_dev.context_window_tokens is not None:\n return models_dev\n\n openrouter = lookup_openrouter_metadata(normalized_model)\n if openrouter is not None and openrouter.context_window_tokens is not None:\n return openrouter\n\n return None\n\n\ndef lookup_models_dev_metadata(provider_id: str, model_id: str) -> ResolvedModelMetadata | None:\n models_dev_provider = _PROVIDER_TO_MODELS_DEV.get(provider_id.strip().lower())\n if not models_dev_provider:\n return None\n data = fetch_models_dev_registry()\n provider_data = data.get(models_dev_provider)\n if not isinstance(provider_data, Mapping):\n return None\n models = provider_data.get(\"models\")\n if not isinstance(models, Mapping):\n return None\n entry = _find_model_entry(models, model_id)\n if entry is None and \"/\" in model_id:\n entry = _find_model_entry(models, model_id.rsplit(\"/\", 1)[1])\n if entry is None:\n return None\n limit = entry.get(\"limit\")\n context = _coerce_reasonable_int(limit.get(\"context\") if isinstance(limit, Mapping) else None)\n output = _coerce_reasonable_int(limit.get(\"output\") if isinstance(limit, Mapping) else None)\n if context is None:\n context = _extract_nested_int(entry, _CONTEXT_KEYS)\n if output is None:\n output = _extract_nested_int(entry, _OUTPUT_KEYS)\n if context is None and output is None:\n return None\n return ResolvedModelMetadata(\n context_window_tokens=context,\n max_output_tokens=output,\n source=f\"models.dev:{models_dev_provider}\",\n )\n\n\ndef lookup_openrouter_metadata(model_id: str) -> ResolvedModelMetadata | None:\n metadata = fetch_openrouter_model_metadata()\n return _find_metadata_entry(metadata, model_id)\n\n\ndef get_cached_context_length(model_id: str, base_url: str | None) -> int | None:\n normalized_model = str(model_id or \"\").strip()\n normalized_base_url = _normalize_base_url(base_url)\n if not normalized_model or not normalized_base_url:\n return None\n return _load_context_length_cache().get(_context_length_cache_key(normalized_model, normalized_base_url))\n\n\ndef save_context_length(model_id: str, base_url: str | None, context_window_tokens: int) -> None:\n normalized_model = str(model_id or \"\").strip()\n normalized_base_url = _normalize_base_url(base_url)\n parsed = _coerce_reasonable_int(context_window_tokens)\n if not normalized_model or not normalized_base_url or parsed is None:\n return\n cache = _load_context_length_cache()\n key = _context_length_cache_key(normalized_model, normalized_base_url)\n if cache.get(key) == parsed:\n return\n cache[key] = parsed\n _save_context_length_cache(cache)\n\n\ndef query_local_endpoint_metadata(\n *,\n model_id: str,\n base_url: str,\n api_key: str | None = None,\n) -> ResolvedModelMetadata | None:\n normalized = _normalize_base_url(base_url)\n server_root = normalized[:-3] if normalized.endswith(\"/v1\") else normalized\n\n lm_studio = _request_json_object(f\"{server_root}/api/v1/models\", timeout_seconds=2.0)\n if lm_studio:\n for model in _model_items(lm_studio):\n candidate_id = str(model.get(\"key\") or model.get(\"id\") or \"\").strip()\n if not _model_id_matches(candidate_id, model_id):\n continue\n loaded_instances = model.get(\"loaded_instances\")\n if isinstance(loaded_instances, list):\n for instance in loaded_instances:\n if not isinstance(instance, Mapping):\n continue\n config = instance.get(\"config\")\n if not isinstance(config, Mapping):\n continue\n context = _coerce_reasonable_int(config.get(\"context_length\"))\n if context is not None:\n return ResolvedModelMetadata(context_window_tokens=context, source=\"local:lm-studio\")\n context = _extract_nested_int(model, _CONTEXT_KEYS)\n output = _extract_nested_int(model, _OUTPUT_KEYS)\n if context is not None or output is not None:\n return ResolvedModelMetadata(context, output, \"local:lm-studio\")\n\n detail = _request_json_object(\n f\"{server_root}/v1/models/{model_id}\",\n headers=_bearer_headers(api_key),\n timeout_seconds=2.0,\n )\n if detail:\n context = _extract_nested_int(detail, _CONTEXT_KEYS)\n output = _extract_nested_int(detail, _OUTPUT_KEYS)\n if context is not None or output is not None:\n return ResolvedModelMetadata(context, output, \"local:model-detail\")\n\n listed = fetch_endpoint_model_metadata(base_url=normalized, api_key=api_key)\n entry = _find_metadata_entry(listed, model_id)\n if entry is not None:\n return entry\n\n props = _request_json_object(f\"{server_root}/v1/props\", headers=_bearer_headers(api_key), timeout_seconds=2.0)\n if not props:\n props = _request_json_object(f\"{server_root}/props\", headers=_bearer_headers(api_key), timeout_seconds=2.0)\n if props:\n context = _extract_nested_int(props, _CONTEXT_KEYS)\n if context is not None:\n return ResolvedModelMetadata(context_window_tokens=context, source=\"local:llamacpp\")\n\n return None\n\n\ndef fetch_models_dev_registry(*, force_refresh: bool = False) -> Mapping[str, Any]:\n global _models_dev_cache, _models_dev_cache_time\n if (\n not force_refresh\n and _models_dev_cache\n and (time.time() - _models_dev_cache_time) < _MODELS_DEV_CACHE_TTL_SECONDS\n ):\n return _models_dev_cache\n\n try:\n payload = _request_json_object(MODELS_DEV_URL, timeout_seconds=10.0)\n if payload:\n _models_dev_cache = dict(payload)\n _models_dev_cache_time = time.time()\n _save_models_dev_disk_cache(_models_dev_cache)\n return _models_dev_cache\n except RuntimeError:\n pass\n\n if not _models_dev_cache:\n _models_dev_cache = _load_models_dev_disk_cache()\n if _models_dev_cache:\n _models_dev_cache_time = time.time() - _MODELS_DEV_CACHE_TTL_SECONDS + 300\n return _models_dev_cache\n\n\ndef fetch_openrouter_model_metadata(*, force_refresh: bool = False) -> Mapping[str, ResolvedModelMetadata]:\n global _openrouter_cache, _openrouter_cache_time\n if (\n not force_refresh\n and _openrouter_cache\n and (time.time() - _openrouter_cache_time) < _OPENROUTER_CACHE_TTL_SECONDS\n ):\n return _openrouter_cache\n\n try:\n payload = _request_json_object(OPENROUTER_MODELS_URL, timeout_seconds=10.0)\n except RuntimeError:\n return _openrouter_cache\n cache: dict[str, ResolvedModelMetadata] = {}\n for model in _model_items(payload):\n model_id = str(model.get(\"id\") or \"\").strip()\n if not model_id:\n continue\n top_provider = model.get(\"top_provider\")\n output = None\n if isinstance(top_provider, Mapping):\n output = _coerce_reasonable_int(top_provider.get(\"max_completion_tokens\"))\n entry = ResolvedModelMetadata(\n context_window_tokens=_extract_nested_int(model, _CONTEXT_KEYS),\n max_output_tokens=output or _extract_nested_int(model, _OUTPUT_KEYS),\n source=\"openrouter\",\n )\n _add_metadata_aliases(cache, model_id, entry)\n canonical_slug = str(model.get(\"canonical_slug\") or \"\").strip()\n if canonical_slug:\n _add_metadata_aliases(cache, canonical_slug, entry)\n _openrouter_cache = cache\n _openrouter_cache_time = time.time()\n return _openrouter_cache\n\n\ndef fetch_endpoint_model_metadata(\n *,\n base_url: str,\n api_key: str | None = None,\n force_refresh: bool = False,\n) -> Mapping[str, ResolvedModelMetadata]:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return {}\n if not force_refresh:\n cached = _endpoint_metadata_cache.get(normalized)\n cached_at = _endpoint_metadata_cache_time.get(normalized, 0)\n if cached is not None and (time.time() - cached_at) < _ENDPOINT_CACHE_TTL_SECONDS:\n return cached\n\n candidates = [normalized]\n alternate = normalized[:-3].rstrip(\"/\") if normalized.endswith(\"/v1\") else f\"{normalized}/v1\"\n if alternate and alternate not in candidates:\n candidates.append(alternate)\n\n for candidate in candidates:\n payload = _request_json_object(\n f\"{candidate.rstrip('/')}/models\",\n headers=_bearer_headers(api_key),\n timeout_seconds=5.0,\n )\n if not payload:\n continue\n cache: dict[str, ResolvedModelMetadata] = {}\n for model in _model_items(payload):\n model_id = str(model.get(\"id\") or model.get(\"key\") or \"\").strip()\n if not model_id:\n continue\n entry = ResolvedModelMetadata(\n context_window_tokens=_extract_nested_int(model, _CONTEXT_KEYS),\n max_output_tokens=_extract_nested_int(model, _OUTPUT_KEYS),\n source=\"endpoint:/models\",\n )\n _add_metadata_aliases(cache, model_id, entry)\n if cache:\n _endpoint_metadata_cache[normalized] = cache\n _endpoint_metadata_cache_time[normalized] = time.time()\n return cache\n\n _endpoint_metadata_cache[normalized] = {}\n _endpoint_metadata_cache_time[normalized] = time.time()\n return {}\n\n\ndef is_local_endpoint(base_url: str | None) -> bool:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return False\n try:\n parsed = urlparse(normalized if \"://\" in normalized else f\"http://{normalized}\")\n except ValueError:\n return False\n host = parsed.hostname or \"\"\n if host in _LOCAL_HOSTS or any(host.endswith(suffix) for suffix in _CONTAINER_LOCAL_SUFFIXES):\n return True\n try:\n address = ipaddress.ip_address(host)\n except ValueError:\n return False\n return address.is_private or address.is_loopback or address.is_link_local\n\n\ndef infer_provider_from_url(base_url: str | None) -> str | None:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return None\n parsed = urlparse(normalized if \"://\" in normalized else f\"https://{normalized}\")\n host = parsed.netloc.lower() or parsed.path.lower()\n for url_part, provider_id in _URL_TO_PROVIDER.items():\n if url_part in host:\n return provider_id\n return None\n\n\ndef _effective_provider_id(*, provider_id: str, base_url: str | None) -> str:\n normalized_provider = provider_id.strip().lower()\n if normalized_provider in {\"\", \"openai-compatible\"}:\n return infer_provider_from_url(base_url) or normalized_provider\n return normalized_provider\n\n\ndef _request_json_object(\n url: str,\n *,\n headers: Mapping[str, str] | None = None,\n timeout_seconds: float = 10.0,\n) -> Mapping[str, Any] | None:\n http_request = request.Request(url, headers=dict(headers or {}), method=\"GET\")\n try:\n with request.urlopen(http_request, timeout=timeout_seconds) as response:\n raw_body = response.read().decode(\"utf-8\")\n except (error.HTTPError, error.URLError, TimeoutError) as exc:\n return None\n try:\n payload = json.loads(raw_body) if raw_body else {}\n except json.JSONDecodeError:\n return None\n if isinstance(payload, list):\n return {\"data\": payload}\n if not isinstance(payload, Mapping):\n return None\n return payload\n\n\ndef _model_items(payload: Mapping[str, Any]) -> tuple[Mapping[str, Any], ...]:\n for key in (\"data\", \"models\"):\n value = payload.get(key)\n if isinstance(value, list):\n return tuple(item for item in value if isinstance(item, Mapping))\n return ()\n\n\ndef _iter_nested_mappings(value: Any):\n if isinstance(value, Mapping):\n yield value\n for nested in value.values():\n yield from _iter_nested_mappings(nested)\n elif isinstance(value, list):\n for item in value:\n yield from _iter_nested_mappings(item)\n\n\ndef _extract_nested_int(payload: Mapping[str, Any], keys: tuple[str, ...]) -> int | None:\n keyset = {key.casefold() for key in keys}\n for mapping in _iter_nested_mappings(payload):\n for key, value in mapping.items():\n if str(key).casefold() not in keyset:\n continue\n parsed = _coerce_reasonable_int(value)\n if parsed is not None:\n return parsed\n return None\n\n\ndef _coerce_reasonable_int(value: Any, *, minimum: int = 1024, maximum: int = 10_000_000) -> int | None:\n try:\n if isinstance(value, bool):\n return None\n if isinstance(value, str):\n value = value.strip().replace(\",\", \"\")\n parsed = int(value)\n except (TypeError, ValueError):\n return None\n if minimum <= parsed <= maximum:\n return parsed\n return None\n\n\ndef _find_model_entry(models: Mapping[str, Any], model_id: str) -> Mapping[str, Any] | None:\n entry = models.get(model_id)\n if isinstance(entry, Mapping):\n return entry\n model_lower = model_id.casefold()\n for candidate_id, candidate in models.items():\n if str(candidate_id).casefold() == model_lower and isinstance(candidate, Mapping):\n return candidate\n return None\n\n\ndef _find_metadata_entry(\n metadata: Mapping[str, ResolvedModelMetadata],\n model_id: str,\n) -> ResolvedModelMetadata | None:\n entry = metadata.get(model_id)\n if entry is not None:\n return entry\n if \"/\" not in model_id:\n for candidate_id, candidate in metadata.items():\n if candidate_id.rsplit(\"/\", 1)[-1] == model_id:\n return candidate\n model_lower = model_id.casefold()\n for candidate_id, candidate in metadata.items():\n if candidate_id.casefold() == model_lower:\n return candidate\n return None\n\n\ndef _add_metadata_aliases(\n cache: dict[str, ResolvedModelMetadata],\n model_id: str,\n entry: ResolvedModelMetadata,\n) -> None:\n cache[model_id] = entry\n if \"/\" in model_id:\n cache.setdefault(model_id.rsplit(\"/\", 1)[1], entry)\n\n\ndef _model_id_matches(candidate_id: str, lookup_model: str) -> bool:\n if candidate_id == lookup_model:\n return True\n return \"/\" in candidate_id and candidate_id.rsplit(\"/\", 1)[1] == lookup_model\n\n\ndef _bearer_headers(api_key: str | None) -> dict[str, str]:\n resolved = str(api_key or \"\").strip()\n return {\"Authorization\": f\"Bearer {resolved}\"} if resolved else {}\n\n\ndef _normalize_base_url(base_url: str | None) -> str:\n return str(base_url or \"\").strip().rstrip(\"/\")\n\n\ndef _models_dev_disk_cache_path() -> Path:\n override = os.environ.get(\"ELEPHANT_MODELS_DEV_CACHE_PATH\", \"\").strip()\n if override:\n return Path(override).expanduser()\n return default_cli_state_dir() / \"models-dev-cache.json\"\n\n\ndef _context_length_cache_path() -> Path:\n override = os.environ.get(\"ELEPHANT_CONTEXT_LENGTH_CACHE_PATH\", \"\").strip()\n if override:\n return Path(override).expanduser()\n return default_cli_state_dir() / \"context-length-cache.json\"\n\n\ndef _context_length_cache_key(model_id: str, base_url: str) -> str:\n return f\"{model_id}@{base_url}\"\n\n\ndef _load_context_length_cache() -> dict[str, int]:\n path = _context_length_cache_path()\n try:\n payload = json.loads(path.read_text(encoding=\"utf-8\"))\n except (OSError, json.JSONDecodeError):\n return {}\n raw_cache = payload.get(\"context_lengths\") if isinstance(payload, Mapping) else None\n if not isinstance(raw_cache, Mapping):\n return {}\n cache: dict[str, int] = {}\n for key, value in raw_cache.items():\n parsed = _coerce_reasonable_int(value)\n if parsed is not None:\n cache[str(key)] = parsed\n return cache\n\n\ndef _save_context_length_cache(cache: Mapping[str, int]) -> None:\n path = _context_length_cache_path()\n try:\n path.parent.mkdir(parents=True, exist_ok=True)\n with tempfile.NamedTemporaryFile(\"w\", encoding=\"utf-8\", dir=path.parent, delete=False) as handle:\n json.dump({\"context_lengths\": dict(cache)}, handle, separators=(\",\", \":\"))\n temp_name = handle.name\n Path(temp_name).replace(path)\n except OSError:\n return\n\n\ndef _load_models_dev_disk_cache() -> dict[str, Any]:\n path = _models_dev_disk_cache_path()\n try:\n payload = json.loads(path.read_text(encoding=\"utf-8\"))\n except (OSError, json.JSONDecodeError):\n return {}\n return dict(payload) if isinstance(payload, Mapping) else {}\n\n\ndef _save_models_dev_disk_cache(payload: Mapping[str, Any]) -> None:\n path = _models_dev_disk_cache_path()\n try:\n path.parent.mkdir(parents=True, exist_ok=True)\n with tempfile.NamedTemporaryFile(\"w\", encoding=\"utf-8\", dir=path.parent, delete=False) as handle:\n json.dump(dict(payload), handle, separators=(\",\", \":\"))\n temp_name = handle.name\n Path(temp_name).replace(path)\n except OSError:\n return\n\n\n__all__ = [\n \"ResolvedModelMetadata\",\n \"fetch_endpoint_model_metadata\",\n \"fetch_models_dev_registry\",\n \"fetch_openrouter_model_metadata\",\n \"get_cached_context_length\",\n \"infer_provider_from_url\",\n \"is_local_endpoint\",\n \"lookup_models_dev_metadata\",\n \"lookup_openrouter_metadata\",\n \"query_local_endpoint_metadata\",\n \"resolve_provider_model_metadata\",\n \"save_context_length\",\n]\n"}, "aa68047a34022a7a1e0ba91218bd90cb46204257": {"t": 1785758536.773551, "n": 23169, "h": "8080afce24003935", "c": "\"\"\"Provider-aware model metadata fallback resolution.\"\"\"\n\nfrom __future__ import annotations\n\nfrom collections.abc import Mapping\nfrom dataclasses import dataclass\nimport ipaddress\nimport json\nimport os\nfrom pathlib import Path\nimport tempfile\nimport time\nfrom typing import Any\nfrom urllib import error, request\nfrom urllib.parse import urlparse\n\nfrom packages.runtime_layout import default_cli_state_dir\n\n\nMODELS_DEV_URL = \"https://models.dev/api.json\"\nOPENROUTER_MODELS_URL = \"https://openrouter.ai/api/v1/models\"\n_MODELS_DEV_CACHE_TTL_SECONDS = 3600\n_OPENROUTER_CACHE_TTL_SECONDS = 3600\n_ENDPOINT_CACHE_TTL_SECONDS = 300\n\n_LOCAL_HOSTS = frozenset({\"localhost\", \"127.0.0.1\", \"::1\", \"0.0.0.0\"})\n_CONTAINER_LOCAL_SUFFIXES = (\".docker.internal\", \".containers.internal\", \".lima.internal\")\n\n_CONTEXT_KEYS = (\n \"context_length\",\n \"context_window\",\n \"max_context_length\",\n \"max_position_embeddings\",\n \"max_model_len\",\n \"max_input_tokens\",\n \"max_sequence_length\",\n \"max_seq_len\",\n \"n_ctx\",\n \"n_ctx_train\",\n)\n_OUTPUT_KEYS = (\n \"max_completion_tokens\",\n \"max_output_tokens\",\n \"max_tokens\",\n)\n\n_PROVIDER_TO_MODELS_DEV: dict[str, str] = {\n \"alibaba\": \"alibaba\",\n \"anthropic\": \"anthropic\",\n \"baidu-qianfan\": \"baidu\",\n \"cerebras\": \"cerebras\",\n \"claude-code\": \"anthropic\",\n \"cohere\": \"cohere\",\n \"copilot\": \"github-copilot\",\n \"deepseek\": \"deepseek\",\n \"fireworks\": \"fireworks-ai\",\n \"google\": \"google\",\n \"groq\": \"groq\",\n \"huggingface\": \"huggingface\",\n \"kilocode\": \"kilo\",\n \"minimax\": \"minimax\",\n \"minimax-cn\": \"minimax-cn\",\n \"modelscope\": \"modelscope\",\n \"mistral\": \"mistral\",\n \"moonshot\": \"kimi-for-coding\",\n \"moonshot-cn\": \"kimi-for-coding\",\n \"nvidia\": \"nvidia\",\n \"openai\": \"openai\",\n \"openai-codex\": \"openai\",\n \"opencode-go\": \"opencode-go\",\n \"opencode-zen\": \"opencode\",\n \"openrouter\": \"openrouter\",\n \"perplexity\": \"perplexity\",\n \"qwen-oauth\": \"alibaba\",\n \"siliconflow\": \"siliconflow\",\n \"stepfun\": \"stepfun\",\n \"tencent-hunyuan\": \"tencent\",\n \"tencent-tokenhub\": \"tencent\",\n \"together\": \"togetherai\",\n \"volcengine\": \"volcengine\",\n \"xai\": \"xai\",\n \"xiaomi\": \"xiaomi\",\n \"zai\": \"zai\",\n}\n\n_URL_TO_PROVIDER: dict[str, str] = {\n \"api-inference.modelscope.cn\": \"modelscope\",\n \"api.anthropic.com\": \"anthropic\",\n \"api.cerebras.ai\": \"cerebras\",\n \"api.cohere.ai\": \"cohere\",\n \"api.deepseek.com\": \"deepseek\",\n \"api.githubcopilot.com\": \"copilot\",\n \"api.groq.com\": \"groq\",\n \"api.hunyuan.cloud.tencent.com\": \"tencent-hunyuan\",\n \"api.minimax\": \"minimax\",\n \"api.mistral.ai\": \"mistral\",\n \"api.moonshot.ai\": \"moonshot\",\n \"api.moonshot.cn\": \"moonshot-cn\",\n \"api.openai.com\": \"openai\",\n \"api.perplexity.ai\": \"perplexity\",\n \"api.siliconflow.cn\": \"siliconflow\",\n \"api.siliconflow.com\": \"siliconflow\",\n \"api.stepfun.ai\": \"stepfun\",\n \"api.stepfun.com\": \"stepfun\",\n \"api.together.ai\": \"together\",\n \"api.x.ai\": \"xai\",\n \"api.xiaomimimo.com\": \"xiaomi\",\n \"api.z.ai\": \"zai\",\n \"ark.cn-beijing.volces.com\": \"volcengine\",\n \"chatgpt.com\": \"openai-codex\",\n \"dashscope-intl.aliyuncs.com\": \"alibaba\",\n \"dashscope.aliyuncs.com\": \"alibaba\",\n \"generativelanguage.googleapis.com\": \"google\",\n \"integrate.api.nvidia.com\": \"nvidia\",\n \"models.github.ai\": \"copilot\",\n \"openrouter.ai\": \"openrouter\",\n \"opencode.ai\": \"opencode-go\",\n \"portal.qwen.ai\": \"qwen-oauth\",\n \"qianfan.baidubce.com\": \"baidu-qianfan\",\n \"tokenhub-intl.tencentcloudmaas.com\": \"tencent-tokenhub\",\n \"tokenhub-intl.tencentmaas.cn\": \"tencent-tokenhub\",\n \"tokenhub-intl.tencentmaas.com\": \"tencent-tokenhub\",\n \"tokenhub.tencentmaas.cn\": \"tencent-tokenhub\",\n \"tokenhub.tencentmaas.com\": \"tencent-tokenhub\",\n \"xiaomimimo.com\": \"xiaomi\",\n}\n\n_models_dev_cache: dict[str, Any] = {}\n_models_dev_cache_time = 0.0\n_openrouter_cache: dict[str, \"ResolvedModelMetadata\"] = {}\n_openrouter_cache_time = 0.0\n_endpoint_metadata_cache: dict[str, dict[str, \"ResolvedModelMetadata\"]] = {}\n_endpoint_metadata_cache_time: dict[str, float] = {}\n\n\n@dataclass(frozen=True, slots=True)\nclass ResolvedModelMetadata:\n context_window_tokens: int | None = None\n max_output_tokens: int | None = None\n source: str = \"unknown\"\n\n\ndef resolve_provider_model_metadata(\n *,\n provider_id: str,\n model_id: str,\n base_url: str | None = None,\n api_key: str | None = None,\n) -> ResolvedModelMetadata | None:\n \"\"\"Resolve metadata for one selected model from local, registry, or routed catalogs.\"\"\"\n\n normalized_model = str(model_id or \"\").strip()\n if not normalized_model:\n return None\n\n normalized_base_url = _normalize_base_url(base_url)\n cached_context = get_cached_context_length(normalized_model, normalized_base_url)\n if cached_context is not None:\n return ResolvedModelMetadata(\n context_window_tokens=cached_context,\n source=\"context-length-cache\",\n )\n\n if normalized_base_url and is_local_endpoint(normalized_base_url):\n local = query_local_endpoint_metadata(\n model_id=normalized_model,\n base_url=normalized_base_url,\n api_key=api_key,\n )\n if local is not None and local.context_window_tokens is not None:\n save_context_length(normalized_model, normalized_base_url, local.context_window_tokens)\n return local\n\n effective_provider = _effective_provider_id(provider_id=provider_id, base_url=normalized_base_url)\n models_dev = lookup_models_dev_metadata(effective_provider, normalized_model)\n if models_dev is not None and models_dev.context_window_tokens is not None:\n return models_dev\n\n openrouter = lookup_openrouter_metadata(normalized_model)\n if openrouter is not None and openrouter.context_window_tokens is not None:\n return openrouter\n\n return None\n\n\ndef lookup_models_dev_metadata(provider_id: str, model_id: str) -> ResolvedModelMetadata | None:\n models_dev_provider = _PROVIDER_TO_MODELS_DEV.get(provider_id.strip().lower())\n if not models_dev_provider:\n return None\n data = fetch_models_dev_registry()\n provider_data = data.get(models_dev_provider)\n if not isinstance(provider_data, Mapping):\n return None\n models = provider_data.get(\"models\")\n if not isinstance(models, Mapping):\n return None\n entry = _find_model_entry(models, model_id)\n if entry is None and \"/\" in model_id:\n entry = _find_model_entry(models, model_id.rsplit(\"/\", 1)[1])\n if entry is None:\n return None\n limit = entry.get(\"limit\")\n context = _coerce_reasonable_int(limit.get(\"context\") if isinstance(limit, Mapping) else None)\n output = _coerce_reasonable_int(limit.get(\"output\") if isinstance(limit, Mapping) else None)\n if context is None:\n context = _extract_nested_int(entry, _CONTEXT_KEYS)\n if output is None:\n output = _extract_nested_int(entry, _OUTPUT_KEYS)\n if context is None and output is None:\n return None\n return ResolvedModelMetadata(\n context_window_tokens=context,\n max_output_tokens=output,\n source=f\"models.dev:{models_dev_provider}\",\n )\n\n\ndef lookup_openrouter_metadata(model_id: str) -> ResolvedModelMetadata | None:\n metadata = fetch_openrouter_model_metadata()\n return _find_metadata_entry(metadata, model_id)\n\n\ndef get_cached_context_length(model_id: str, base_url: str | None) -> int | None:\n normalized_model = str(model_id or \"\").strip()\n normalized_base_url = _normalize_base_url(base_url)\n if not normalized_model or not normalized_base_url:\n return None\n return _load_context_length_cache().get(_context_length_cache_key(normalized_model, normalized_base_url))\n\n\ndef save_context_length(model_id: str, base_url: str | None, context_window_tokens: int) -> None:\n normalized_model = str(model_id or \"\").strip()\n normalized_base_url = _normalize_base_url(base_url)\n parsed = _coerce_reasonable_int(context_window_tokens)\n if not normalized_model or not normalized_base_url or parsed is None:\n return\n cache = _load_context_length_cache()\n key = _context_length_cache_key(normalized_model, normalized_base_url)\n if cache.get(key) == parsed:\n return\n cache[key] = parsed\n _save_context_length_cache(cache)\n\n\ndef query_local_endpoint_metadata(\n *,\n model_id: str,\n base_url: str,\n api_key: str | None = None,\n) -> ResolvedModelMetadata | None:\n normalized = _normalize_base_url(base_url)\n server_root = normalized[:-3] if normalized.endswith(\"/v1\") else normalized\n\n lm_studio = _request_json_object(f\"{server_root}/api/v1/models\", timeout_seconds=2.0)\n if lm_studio:\n for model in _model_items(lm_studio):\n candidate_id = str(model.get(\"key\") or model.get(\"id\") or \"\").strip()\n if not _model_id_matches(candidate_id, model_id):\n continue\n loaded_instances = model.get(\"loaded_instances\")\n if isinstance(loaded_instances, list):\n for instance in loaded_instances:\n if not isinstance(instance, Mapping):\n continue\n config = instance.get(\"config\")\n if not isinstance(config, Mapping):\n continue\n context = _coerce_reasonable_int(config.get(\"context_length\"))\n if context is not None:\n return ResolvedModelMetadata(context_window_tokens=context, source=\"local:lm-studio\")\n context = _extract_nested_int(model, _CONTEXT_KEYS)\n output = _extract_nested_int(model, _OUTPUT_KEYS)\n if context is not None or output is not None:\n return ResolvedModelMetadata(context, output, \"local:lm-studio\")\n\n detail = _request_json_object(\n f\"{server_root}/v1/models/{model_id}\",\n headers=_bearer_headers(api_key),\n timeout_seconds=2.0,\n )\n if detail:\n context = _extract_nested_int(detail, _CONTEXT_KEYS)\n output = _extract_nested_int(detail, _OUTPUT_KEYS)\n if context is not None or output is not None:\n return ResolvedModelMetadata(context, output, \"local:model-detail\")\n\n listed = fetch_endpoint_model_metadata(base_url=normalized, api_key=api_key)\n entry = _find_metadata_entry(listed, model_id)\n if entry is not None:\n return entry\n\n props = _request_json_object(f\"{server_root}/v1/props\", headers=_bearer_headers(api_key), timeout_seconds=2.0)\n if not props:\n props = _request_json_object(f\"{server_root}/props\", headers=_bearer_headers(api_key), timeout_seconds=2.0)\n if props:\n context = _extract_nested_int(props, _CONTEXT_KEYS)\n if context is not None:\n return ResolvedModelMetadata(context_window_tokens=context, source=\"local:llamacpp\")\n\n return None\n\n\ndef fetch_models_dev_registry(*, force_refresh: bool = False) -> Mapping[str, Any]:\n global _models_dev_cache, _models_dev_cache_time\n if (\n not force_refresh\n and _models_dev_cache\n and (time.time() - _models_dev_cache_time) < _MODELS_DEV_CACHE_TTL_SECONDS\n ):\n return _models_dev_cache\n\n try:\n payload = _request_json_object(MODELS_DEV_URL, timeout_seconds=10.0)\n if payload:\n _models_dev_cache = dict(payload)\n _models_dev_cache_time = time.time()\n _save_models_dev_disk_cache(_models_dev_cache)\n return _models_dev_cache\n except RuntimeError:\n pass\n\n if not _models_dev_cache:\n _models_dev_cache = _load_models_dev_disk_cache()\n if _models_dev_cache:\n _models_dev_cache_time = time.time() - _MODELS_DEV_CACHE_TTL_SECONDS + 300\n return _models_dev_cache\n\n\ndef fetch_openrouter_model_metadata(*, force_refresh: bool = False) -> Mapping[str, ResolvedModelMetadata]:\n global _openrouter_cache, _openrouter_cache_time\n if (\n not force_refresh\n and _openrouter_cache\n and (time.time() - _openrouter_cache_time) < _OPENROUTER_CACHE_TTL_SECONDS\n ):\n return _openrouter_cache\n\n try:\n payload = _request_json_object(OPENROUTER_MODELS_URL, timeout_seconds=10.0)\n except RuntimeError:\n return _openrouter_cache\n cache: dict[str, ResolvedModelMetadata] = {}\n for model in _model_items(payload):\n model_id = str(model.get(\"id\") or \"\").strip()\n if not model_id:\n continue\n top_provider = model.get(\"top_provider\")\n output = None\n if isinstance(top_provider, Mapping):\n output = _coerce_reasonable_int(top_provider.get(\"max_completion_tokens\"))\n entry = ResolvedModelMetadata(\n context_window_tokens=_extract_nested_int(model, _CONTEXT_KEYS),\n max_output_tokens=output or _extract_nested_int(model, _OUTPUT_KEYS),\n source=\"openrouter\",\n )\n _add_metadata_aliases(cache, model_id, entry)\n canonical_slug = str(model.get(\"canonical_slug\") or \"\").strip()\n if canonical_slug:\n _add_metadata_aliases(cache, canonical_slug, entry)\n _openrouter_cache = cache\n _openrouter_cache_time = time.time()\n return _openrouter_cache\n\n\ndef fetch_endpoint_model_metadata(\n *,\n base_url: str,\n api_key: str | None = None,\n force_refresh: bool = False,\n) -> Mapping[str, ResolvedModelMetadata]:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return {}\n if not force_refresh:\n cached = _endpoint_metadata_cache.get(normalized)\n cached_at = _endpoint_metadata_cache_time.get(normalized, 0)\n if cached is not None and (time.time() - cached_at) < _ENDPOINT_CACHE_TTL_SECONDS:\n return cached\n\n candidates = [normalized]\n alternate = normalized[:-3].rstrip(\"/\") if normalized.endswith(\"/v1\") else f\"{normalized}/v1\"\n if alternate and alternate not in candidates:\n candidates.append(alternate)\n\n for candidate in candidates:\n payload = _request_json_object(\n f\"{candidate.rstrip('/')}/models\",\n headers=_bearer_headers(api_key),\n timeout_seconds=5.0,\n )\n if not payload:\n continue\n cache: dict[str, ResolvedModelMetadata] = {}\n for model in _model_items(payload):\n model_id = str(model.get(\"id\") or model.get(\"key\") or \"\").strip()\n if not model_id:\n continue\n entry = ResolvedModelMetadata(\n context_window_tokens=_extract_nested_int(model, _CONTEXT_KEYS),\n max_output_tokens=_extract_nested_int(model, _OUTPUT_KEYS),\n source=\"endpoint:/models\",\n )\n _add_metadata_aliases(cache, model_id, entry)\n if cache:\n _endpoint_metadata_cache[normalized] = cache\n _endpoint_metadata_cache_time[normalized] = time.time()\n return cache\n\n _endpoint_metadata_cache[normalized] = {}\n _endpoint_metadata_cache_time[normalized] = time.time()\n return {}\n\n\ndef is_local_endpoint(base_url: str | None) -> bool:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return False\n try:\n parsed = urlparse(normalized if \"://\" in normalized else f\"http://{normalized}\")\n except ValueError:\n return False\n host = parsed.hostname or \"\"\n if host in _LOCAL_HOSTS or any(host.endswith(suffix) for suffix in _CONTAINER_LOCAL_SUFFIXES):\n return True\n try:\n address = ipaddress.ip_address(host)\n except ValueError:\n return False\n return address.is_private or address.is_loopback or address.is_link_local\n\n\ndef infer_provider_from_url(base_url: str | None) -> str | None:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return None\n parsed = urlparse(normalized if \"://\" in normalized else f\"https://{normalized}\")\n host = parsed.netloc.lower() or parsed.path.lower()\n for url_part, provider_id in _URL_TO_PROVIDER.items():\n if url_part in host:\n return provider_id\n return None\n\n\ndef _effective_provider_id(*, provider_id: str, base_url: str | None) -> str:\n normalized_provider = provider_id.strip().lower()\n if normalized_provider in {\"\", \"openai-compatible\"}:\n return infer_provider_from_url(base_url) or normalized_provider\n return normalized_provider\n\n\ndef _request_json_object(\n url: str,\n *,\n headers: Mapping[str, str] | None = None,\n timeout_seconds: float = 10.0,\n) -> Mapping[str, Any] | None:\n http_request = request.Request(url, headers=dict(headers or {}), method=\"GET\")\n try:\n with request.urlopen(http_request, timeout=timeout_seconds) as response:\n raw_body = response.read().decode(\"utf-8\")\n except (error.HTTPError, error.URLError, TimeoutError) as exc:\n return None\n try:\n payload = json.loads(raw_body) if raw_body else {}\n except json.JSONDecodeError:\n return None\n if isinstance(payload, list):\n return {\"data\": payload}\n if not isinstance(payload, Mapping):\n return None\n return payload\n\n\ndef _model_items(payload: Mapping[str, Any]) -> tuple[Mapping[str, Any], ...]:\n for key in (\"data\", \"models\"):\n value = payload.get(key)\n if isinstance(value, list):\n return tuple(item for item in value if isinstance(item, Mapping))\n return ()\n\n\ndef _iter_nested_mappings(value: Any):\n if isinstance(value, Mapping):\n yield value\n for nested in value.values():\n yield from _iter_nested_mappings(nested)\n elif isinstance(value, list):\n for item in value:\n yield from _iter_nested_mappings(item)\n\n\ndef _extract_nested_int(payload: Mapping[str, Any], keys: tuple[str, ...]) -> int | None:\n keyset = {key.casefold() for key in keys}\n for mapping in _iter_nested_mappings(payload):\n for key, value in mapping.items():\n if str(key).casefold() not in keyset:\n continue\n parsed = _coerce_reasonable_int(value)\n if parsed is not None:\n return parsed\n return None\n\n\ndef _coerce_reasonable_int(value: Any, *, minimum: int = 1024, maximum: int = 10_000_000) -> int | None:\n try:\n if isinstance(value, bool):\n return None\n if isinstance(value, str):\n value = value.strip().replace(\",\", \"\")\n parsed = int(value)\n except (TypeError, ValueError):\n return None\n if minimum <= parsed <= maximum:\n return parsed\n return None\n\n\ndef _find_model_entry(models: Mapping[str, Any], model_id: str) -> Mapping[str, Any] | None:\n entry = models.get(model_id)\n if isinstance(entry, Mapping):\n return entry\n model_lower = model_id.casefold()\n for candidate_id, candidate in models.items():\n if str(candidate_id).casefold() == model_lower and isinstance(candidate, Mapping):\n return candidate\n return None\n\n\ndef _find_metadata_entry(\n metadata: Mapping[str, ResolvedModelMetadata],\n model_id: str,\n) -> ResolvedModelMetadata | None:\n entry = metadata.get(model_id)\n if entry is not None:\n return entry\n if \"/\" not in model_id:\n for candidate_id, candidate in metadata.items():\n if candidate_id.rsplit(\"/\", 1)[-1] == model_id:\n return candidate\n model_lower = model_id.casefold()\n for candidate_id, candidate in metadata.items():\n if candidate_id.casefold() == model_lower:\n return candidate\n return None\n\n\ndef _add_metadata_aliases(\n cache: dict[str, ResolvedModelMetadata],\n model_id: str,\n entry: ResolvedModelMetadata,\n) -> None:\n cache[model_id] = entry\n if \"/\" in model_id:\n cache.setdefault(model_id.rsplit(\"/\", 1)[1], entry)\n\n\ndef _model_id_matches(candidate_id: str, lookup_model: str) -> bool:\n if candidate_id == lookup_model:\n return True\n return \"/\" in candidate_id and candidate_id.rsplit(\"/\", 1)[1] == lookup_model\n\n\ndef _bearer_headers(api_key: str | None) -> dict[str, str]:\n resolved = str(api_key or \"\").strip()\n return {\"Authorization\": f\"Bearer {resolved}\"} if resolved else {}\n\n\ndef _normalize_base_url(base_url: str | None) -> str:\n return str(base_url or \"\").strip().rstrip(\"/\")\n\n\ndef _models_dev_disk_cache_path() -> Path:\n override = os.environ.get(\"ELEPHANT_MODELS_DEV_CACHE_PATH\", \"\").strip()\n if override:\n return Path(override).expanduser()\n return default_cli_state_dir() / \"models-dev-cache.json\"\n\n\ndef _context_length_cache_path() -> Path:\n override = os.environ.get(\"ELEPHANT_CONTEXT_LENGTH_CACHE_PATH\", \"\").strip()\n if override:\n return Path(override).expanduser()\n return default_cli_state_dir() / \"context-length-cache.json\"\n\n\ndef _context_length_cache_key(model_id: str, base_url: str) -> str:\n return f\"{model_id}@{base_url}\"\n\n\ndef _load_context_length_cache() -> dict[str, int]:\n path = _context_length_cache_path()\n try:\n payload = json.loads(path.read_text(encoding=\"utf-8\"))\n except (OSError, json.JSONDecodeError):\n return {}\n raw_cache = payload.get(\"context_lengths\") if isinstance(payload, Mapping) else None\n if not isinstance(raw_cache, Mapping):\n return {}\n cache: dict[str, int] = {}\n for key, value in raw_cache.items():\n parsed = _coerce_reasonable_int(value)\n if parsed is not None:\n cache[str(key)] = parsed\n return cache\n\n\ndef _save_context_length_cache(cache: Mapping[str, int]) -> None:\n path = _context_length_cache_path()\n try:\n path.parent.mkdir(parents=True, exist_ok=True)\n with tempfile.NamedTemporaryFile(\"w\", encoding=\"utf-8\", dir=path.parent, delete=False) as handle:\n json.dump({\"context_lengths\": dict(cache)}, handle, separators=(\",\", \":\"))\n temp_name = handle.name\n Path(temp_name).replace(path)\n except OSError:\n return\n\n\ndef _load_models_dev_disk_cache() -> dict[str, Any]:\n path = _models_dev_disk_cache_path()\n try:\n payload = json.loads(path.read_text(encoding=\"utf-8\"))\n except (OSError, json.JSONDecodeError):\n return {}\n return dict(payload) if isinstance(payload, Mapping) else {}\n\n\ndef _save_models_dev_disk_cache(payload: Mapping[str, Any]) -> None:\n path = _models_dev_disk_cache_path()\n try:\n path.parent.mkdir(parents=True, exist_ok=True)\n with tempfile.NamedTemporaryFile(\"w\", encoding=\"utf-8\", dir=path.parent, delete=False) as handle:\n json.dump(dict(payload), handle, separators=(\",\", \":\"))\n temp_name = handle.name\n Path(temp_name).replace(path)\n except OSError:\n return\n\n\n__all__ = [\n \"ResolvedModelMetadata\",\n \"fetch_endpoint_model_metadata\",\n \"fetch_models_dev_registry\",\n \"fetch_openrouter_model_metadata\",\n \"get_cached_context_length\",\n \"infer_provider_from_url\",\n \"is_local_endpoint\",\n \"lookup_models_dev_metadata\",\n \"lookup_openrouter_metadata\",\n \"query_local_endpoint_metadata\",\n \"resolve_provider_model_metadata\",\n \"save_context_length\",\n]\n"}, "80147155ed93065761d7d90b52b875505760d9b4": {"t": 1785758538.5653996, "n": 22066, "h": "eb2c81c8a4a135b4", "c": "\"\"\"Provider-aware model metadata fallback resolution.\"\"\"\n\nfrom __future__ import annotations\n\nfrom collections.abc import Mapping\nfrom dataclasses import dataclass\nimport ipaddress\nimport json\nimport os\nfrom pathlib import Path\nimport tempfile\nimport time\nfrom typing import Any\nfrom urllib import error, request\nfrom urllib.parse import urlparse\n\nfrom packages.runtime_layout import default_cli_state_dir\n\n\nMODELS_DEV_URL = \"https://models.dev/api.json\"\nOPENROUTER_MODELS_URL = \"https://openrouter.ai/api/v1/models\"\n_MODELS_DEV_CACHE_TTL_SECONDS = 3600\n_OPENROUTER_CACHE_TTL_SECONDS = 3600\n_ENDPOINT_CACHE_TTL_SECONDS = 300\n\n_LOCAL_HOSTS = frozenset({\"localhost\", \"127.0.0.1\", \"::1\", \"0.0.0.0\"})\n_CONTAINER_LOCAL_SUFFIXES = (\".docker.internal\", \".containers.internal\", \".lima.internal\")\n\n_CONTEXT_KEYS = (\n \"context_length\",\n \"context_window\",\n \"max_context_length\",\n \"max_position_embeddings\",\n \"max_model_len\",\n \"max_input_tokens\",\n \"max_sequence_length\",\n \"max_seq_len\",\n \"n_ctx\",\n \"n_ctx_train\",\n)\n_OUTPUT_KEYS = (\n \"max_completion_tokens\",\n \"max_output_tokens\",\n \"max_tokens\",\n)\n\n_PROVIDER_TO_MODELS_DEV: dict[str, str] = {\n \"alibaba\": \"alibaba\",\n \"anthropic\": \"anthropic\",\n \"claude-code\": \"anthropic\",\n \"copilot\": \"github-copilot\",\n \"deepseek\": \"deepseek\",\n \"fireworks\": \"fireworks-ai\",\n \"google\": \"google\",\n \"groq\": \"groq\",\n \"huggingface\": \"huggingface\",\n \"kilocode\": \"kilo\",\n \"minimax\": \"minimax\",\n \"minimax-cn\": \"minimax-cn\",\n \"mistral\": \"mistral\",\n \"moonshot\": \"kimi-for-coding\",\n \"moonshot-cn\": \"kimi-for-coding\",\n \"openai\": \"openai\",\n \"openai-codex\": \"openai\",\n \"opencode-go\": \"opencode-go\",\n \"opencode-zen\": \"opencode\",\n \"openrouter\": \"openrouter\",\n \"qwen-oauth\": \"alibaba\",\n \"together\": \"togetherai\",\n \"xai\": \"xai\",\n \"xiaomi\": \"xiaomi\",\n \"zai\": \"zai\",\n}\n\n_URL_TO_PROVIDER: dict[str, str] = {\n \"api.anthropic.com\": \"anthropic\",\n \"api.deepseek.com\": \"deepseek\",\n \"api.githubcopilot.com\": \"copilot\",\n \"api.groq.com\": \"groq\",\n \"api.minimax\": \"minimax\",\n \"api.mistral.ai\": \"mistral\",\n \"api.moonshot.ai\": \"moonshot\",\n \"api.moonshot.cn\": \"moonshot-cn\",\n \"api.openai.com\": \"openai\",\n \"api.together.ai\": \"together\",\n \"api.x.ai\": \"xai\",\n \"api.xiaomimimo.com\": \"xiaomi\",\n \"api.z.ai\": \"zai\",\n \"chatgpt.com\": \"openai-codex\",\n \"dashscope-intl.aliyuncs.com\": \"alibaba\",\n \"dashscope.aliyuncs.com\": \"alibaba\",\n \"generativelanguage.googleapis.com\": \"google\",\n \"models.github.ai\": \"copilot\",\n \"openrouter.ai\": \"openrouter\",\n \"opencode.ai\": \"opencode-go\",\n \"portal.qwen.ai\": \"qwen-oauth\",\n \"xiaomimimo.com\": \"xiaomi\",\n}\n\n_models_dev_cache: dict[str, Any] = {}\n_models_dev_cache_time = 0.0\n_openrouter_cache: dict[str, \"ResolvedModelMetadata\"] = {}\n_openrouter_cache_time = 0.0\n_endpoint_metadata_cache: dict[str, dict[str, \"ResolvedModelMetadata\"]] = {}\n_endpoint_metadata_cache_time: dict[str, float] = {}\n\n\n@dataclass(frozen=True, slots=True)\nclass ResolvedModelMetadata:\n context_window_tokens: int | None = None\n max_output_tokens: int | None = None\n source: str = \"unknown\"\n\n\ndef resolve_provider_model_metadata(\n *,\n provider_id: str,\n model_id: str,\n base_url: str | None = None,\n api_key: str | None = None,\n) -> ResolvedModelMetadata | None:\n \"\"\"Resolve metadata for one selected model from local, registry, or routed catalogs.\"\"\"\n\n normalized_model = str(model_id or \"\").strip()\n if not normalized_model:\n return None\n\n normalized_base_url = _normalize_base_url(base_url)\n cached_context = get_cached_context_length(normalized_model, normalized_base_url)\n if cached_context is not None:\n return ResolvedModelMetadata(\n context_window_tokens=cached_context,\n source=\"context-length-cache\",\n )\n\n if normalized_base_url and is_local_endpoint(normalized_base_url):\n local = query_local_endpoint_metadata(\n model_id=normalized_model,\n base_url=normalized_base_url,\n api_key=api_key,\n )\n if local is not None and local.context_window_tokens is not None:\n save_context_length(normalized_model, normalized_base_url, local.context_window_tokens)\n return local\n\n effective_provider = _effective_provider_id(provider_id=provider_id, base_url=normalized_base_url)\n models_dev = lookup_models_dev_metadata(effective_provider, normalized_model)\n if models_dev is not None and models_dev.context_window_tokens is not None:\n return models_dev\n\n openrouter = lookup_openrouter_metadata(normalized_model)\n if openrouter is not None and openrouter.context_window_tokens is not None:\n return openrouter\n\n return None\n\n\ndef lookup_models_dev_metadata(provider_id: str, model_id: str) -> ResolvedModelMetadata | None:\n models_dev_provider = _PROVIDER_TO_MODELS_DEV.get(provider_id.strip().lower())\n if not models_dev_provider:\n return None\n data = fetch_models_dev_registry()\n provider_data = data.get(models_dev_provider)\n if not isinstance(provider_data, Mapping):\n return None\n models = provider_data.get(\"models\")\n if not isinstance(models, Mapping):\n return None\n entry = _find_model_entry(models, model_id)\n if entry is None and \"/\" in model_id:\n entry = _find_model_entry(models, model_id.rsplit(\"/\", 1)[1])\n if entry is None:\n return None\n limit = entry.get(\"limit\")\n context = _coerce_reasonable_int(limit.get(\"context\") if isinstance(limit, Mapping) else None)\n output = _coerce_reasonable_int(limit.get(\"output\") if isinstance(limit, Mapping) else None)\n if context is None:\n context = _extract_nested_int(entry, _CONTEXT_KEYS)\n if output is None:\n output = _extract_nested_int(entry, _OUTPUT_KEYS)\n if context is None and output is None:\n return None\n return ResolvedModelMetadata(\n context_window_tokens=context,\n max_output_tokens=output,\n source=f\"models.dev:{models_dev_provider}\",\n )\n\n\ndef lookup_openrouter_metadata(model_id: str) -> ResolvedModelMetadata | None:\n metadata = fetch_openrouter_model_metadata()\n return _find_metadata_entry(metadata, model_id)\n\n\ndef get_cached_context_length(model_id: str, base_url: str | None) -> int | None:\n normalized_model = str(model_id or \"\").strip()\n normalized_base_url = _normalize_base_url(base_url)\n if not normalized_model or not normalized_base_url:\n return None\n return _load_context_length_cache().get(_context_length_cache_key(normalized_model, normalized_base_url))\n\n\ndef save_context_length(model_id: str, base_url: str | None, context_window_tokens: int) -> None:\n normalized_model = str(model_id or \"\").strip()\n normalized_base_url = _normalize_base_url(base_url)\n parsed = _coerce_reasonable_int(context_window_tokens)\n if not normalized_model or not normalized_base_url or parsed is None:\n return\n cache = _load_context_length_cache()\n key = _context_length_cache_key(normalized_model, normalized_base_url)\n if cache.get(key) == parsed:\n return\n cache[key] = parsed\n _save_context_length_cache(cache)\n\n\ndef query_local_endpoint_metadata(\n *,\n model_id: str,\n base_url: str,\n api_key: str | None = None,\n) -> ResolvedModelMetadata | None:\n normalized = _normalize_base_url(base_url)\n server_root = normalized[:-3] if normalized.endswith(\"/v1\") else normalized\n\n lm_studio = _request_json_object(f\"{server_root}/api/v1/models\", timeout_seconds=2.0)\n if lm_studio:\n for model in _model_items(lm_studio):\n candidate_id = str(model.get(\"key\") or model.get(\"id\") or \"\").strip()\n if not _model_id_matches(candidate_id, model_id):\n continue\n loaded_instances = model.get(\"loaded_instances\")\n if isinstance(loaded_instances, list):\n for instance in loaded_instances:\n if not isinstance(instance, Mapping):\n continue\n config = instance.get(\"config\")\n if not isinstance(config, Mapping):\n continue\n context = _coerce_reasonable_int(config.get(\"context_length\"))\n if context is not None:\n return ResolvedModelMetadata(context_window_tokens=context, source=\"local:lm-studio\")\n context = _extract_nested_int(model, _CONTEXT_KEYS)\n output = _extract_nested_int(model, _OUTPUT_KEYS)\n if context is not None or output is not None:\n return ResolvedModelMetadata(context, output, \"local:lm-studio\")\n\n detail = _request_json_object(\n f\"{server_root}/v1/models/{model_id}\",\n headers=_bearer_headers(api_key),\n timeout_seconds=2.0,\n )\n if detail:\n context = _extract_nested_int(detail, _CONTEXT_KEYS)\n output = _extract_nested_int(detail, _OUTPUT_KEYS)\n if context is not None or output is not None:\n return ResolvedModelMetadata(context, output, \"local:model-detail\")\n\n listed = fetch_endpoint_model_metadata(base_url=normalized, api_key=api_key)\n entry = _find_metadata_entry(listed, model_id)\n if entry is not None:\n return entry\n\n props = _request_json_object(f\"{server_root}/v1/props\", headers=_bearer_headers(api_key), timeout_seconds=2.0)\n if not props:\n props = _request_json_object(f\"{server_root}/props\", headers=_bearer_headers(api_key), timeout_seconds=2.0)\n if props:\n context = _extract_nested_int(props, _CONTEXT_KEYS)\n if context is not None:\n return ResolvedModelMetadata(context_window_tokens=context, source=\"local:llamacpp\")\n\n return None\n\n\ndef fetch_models_dev_registry(*, force_refresh: bool = False) -> Mapping[str, Any]:\n global _models_dev_cache, _models_dev_cache_time\n if (\n not force_refresh\n and _models_dev_cache\n and (time.time() - _models_dev_cache_time) < _MODELS_DEV_CACHE_TTL_SECONDS\n ):\n return _models_dev_cache\n\n try:\n payload = _request_json_object(MODELS_DEV_URL, timeout_seconds=10.0)\n if payload:\n _models_dev_cache = dict(payload)\n _models_dev_cache_time = time.time()\n _save_models_dev_disk_cache(_models_dev_cache)\n return _models_dev_cache\n except RuntimeError:\n pass\n\n if not _models_dev_cache:\n _models_dev_cache = _load_models_dev_disk_cache()\n if _models_dev_cache:\n _models_dev_cache_time = time.time() - _MODELS_DEV_CACHE_TTL_SECONDS + 300\n return _models_dev_cache\n\n\ndef fetch_openrouter_model_metadata(*, force_refresh: bool = False) -> Mapping[str, ResolvedModelMetadata]:\n global _openrouter_cache, _openrouter_cache_time\n if (\n not force_refresh\n and _openrouter_cache\n and (time.time() - _openrouter_cache_time) < _OPENROUTER_CACHE_TTL_SECONDS\n ):\n return _openrouter_cache\n\n try:\n payload = _request_json_object(OPENROUTER_MODELS_URL, timeout_seconds=10.0)\n except RuntimeError:\n return _openrouter_cache\n cache: dict[str, ResolvedModelMetadata] = {}\n for model in _model_items(payload):\n model_id = str(model.get(\"id\") or \"\").strip()\n if not model_id:\n continue\n top_provider = model.get(\"top_provider\")\n output = None\n if isinstance(top_provider, Mapping):\n output = _coerce_reasonable_int(top_provider.get(\"max_completion_tokens\"))\n entry = ResolvedModelMetadata(\n context_window_tokens=_extract_nested_int(model, _CONTEXT_KEYS),\n max_output_tokens=output or _extract_nested_int(model, _OUTPUT_KEYS),\n source=\"openrouter\",\n )\n _add_metadata_aliases(cache, model_id, entry)\n canonical_slug = str(model.get(\"canonical_slug\") or \"\").strip()\n if canonical_slug:\n _add_metadata_aliases(cache, canonical_slug, entry)\n _openrouter_cache = cache\n _openrouter_cache_time = time.time()\n return _openrouter_cache\n\n\ndef fetch_endpoint_model_metadata(\n *,\n base_url: str,\n api_key: str | None = None,\n force_refresh: bool = False,\n) -> Mapping[str, ResolvedModelMetadata]:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return {}\n if not force_refresh:\n cached = _endpoint_metadata_cache.get(normalized)\n cached_at = _endpoint_metadata_cache_time.get(normalized, 0)\n if cached is not None and (time.time() - cached_at) < _ENDPOINT_CACHE_TTL_SECONDS:\n return cached\n\n candidates = [normalized]\n alternate = normalized[:-3].rstrip(\"/\") if normalized.endswith(\"/v1\") else f\"{normalized}/v1\"\n if alternate and alternate not in candidates:\n candidates.append(alternate)\n\n for candidate in candidates:\n payload = _request_json_object(\n f\"{candidate.rstrip('/')}/models\",\n headers=_bearer_headers(api_key),\n timeout_seconds=5.0,\n )\n if not payload:\n continue\n cache: dict[str, ResolvedModelMetadata] = {}\n for model in _model_items(payload):\n model_id = str(model.get(\"id\") or model.get(\"key\") or \"\").strip()\n if not model_id:\n continue\n entry = ResolvedModelMetadata(\n context_window_tokens=_extract_nested_int(model, _CONTEXT_KEYS),\n max_output_tokens=_extract_nested_int(model, _OUTPUT_KEYS),\n source=\"endpoint:/models\",\n )\n _add_metadata_aliases(cache, model_id, entry)\n if cache:\n _endpoint_metadata_cache[normalized] = cache\n _endpoint_metadata_cache_time[normalized] = time.time()\n return cache\n\n _endpoint_metadata_cache[normalized] = {}\n _endpoint_metadata_cache_time[normalized] = time.time()\n return {}\n\n\ndef is_local_endpoint(base_url: str | None) -> bool:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return False\n try:\n parsed = urlparse(normalized if \"://\" in normalized else f\"http://{normalized}\")\n except ValueError:\n return False\n host = parsed.hostname or \"\"\n if host in _LOCAL_HOSTS or any(host.endswith(suffix) for suffix in _CONTAINER_LOCAL_SUFFIXES):\n return True\n try:\n address = ipaddress.ip_address(host)\n except ValueError:\n return False\n return address.is_private or address.is_loopback or address.is_link_local\n\n\ndef infer_provider_from_url(base_url: str | None) -> str | None:\n normalized = _normalize_base_url(base_url)\n if not normalized:\n return None\n parsed = urlparse(normalized if \"://\" in normalized else f\"https://{normalized}\")\n host = parsed.netloc.lower() or parsed.path.lower()\n for url_part, provider_id in _URL_TO_PROVIDER.items():\n if url_part in host:\n return provider_id\n return None\n\n\ndef _effective_provider_id(*, provider_id: str, base_url: str | None) -> str:\n normalized_provider = provider_id.strip().lower()\n if normalized_provider in {\"\", \"openai-compatible\"}:\n return infer_provider_from_url(base_url) or normalized_provider\n return normalized_provider\n\n\ndef _request_json_object(\n url: str,\n *,\n headers: Mapping[str, str] | None = None,\n timeout_seconds: float = 10.0,\n) -> Mapping[str, Any] | None:\n http_request = request.Request(url, headers=dict(headers or {}), method=\"GET\")\n try:\n with request.urlopen(http_request, timeout=timeout_seconds) as response:\n raw_body = response.read().decode(\"utf-8\")\n except (error.HTTPError, error.URLError, TimeoutError) as exc:\n return None\n try:\n payload = json.loads(raw_body) if raw_body else {}\n except json.JSONDecodeError:\n return None\n if isinstance(payload, list):\n return {\"data\": payload}\n if not isinstance(payload, Mapping):\n return None\n return payload\n\n\ndef _model_items(payload: Mapping[str, Any]) -> tuple[Mapping[str, Any], ...]:\n for key in (\"data\", \"models\"):\n value = payload.get(key)\n if isinstance(value, list):\n return tuple(item for item in value if isinstance(item, Mapping))\n return ()\n\n\ndef _iter_nested_mappings(value: Any):\n if isinstance(value, Mapping):\n yield value\n for nested in value.values():\n yield from _iter_nested_mappings(nested)\n elif isinstance(value, list):\n for item in value:\n yield from _iter_nested_mappings(item)\n\n\ndef _extract_nested_int(payload: Mapping[str, Any], keys: tuple[str, ...]) -> int | None:\n keyset = {key.casefold() for key in keys}\n for mapping in _iter_nested_mappings(payload):\n for key, value in mapping.items():\n if str(key).casefold() not in keyset:\n continue\n parsed = _coerce_reasonable_int(value)\n if parsed is not None:\n return parsed\n return None\n\n\ndef _coerce_reasonable_int(value: Any, *, minimum: int = 1024, maximum: int = 10_000_000) -> int | None:\n try:\n if isinstance(value, bool):\n return None\n if isinstance(value, str):\n value = value.strip().replace(\",\", \"\")\n parsed = int(value)\n except (TypeError, ValueError):\n return None\n if minimum <= parsed <= maximum:\n return parsed\n return None\n\n\ndef _find_model_entry(models: Mapping[str, Any], model_id: str) -> Mapping[str, Any] | None:\n entry = models.get(model_id)\n if isinstance(entry, Mapping):\n return entry\n model_lower = model_id.casefold()\n for candidate_id, candidate in models.items():\n if str(candidate_id).casefold() == model_lower and isinstance(candidate, Mapping):\n return candidate\n return None\n\n\ndef _find_metadata_entry(\n metadata: Mapping[str, ResolvedModelMetadata],\n model_id: str,\n) -> ResolvedModelMetadata | None:\n entry = metadata.get(model_id)\n if entry is not None:\n return entry\n if \"/\" not in model_id:\n for candidate_id, candidate in metadata.items():\n if candidate_id.rsplit(\"/\", 1)[-1] == model_id:\n return candidate\n model_lower = model_id.casefold()\n for candidate_id, candidate in metadata.items():\n if candidate_id.casefold() == model_lower:\n return candidate\n return None\n\n\ndef _add_metadata_aliases(\n cache: dict[str, ResolvedModelMetadata],\n model_id: str,\n entry: ResolvedModelMetadata,\n) -> None:\n cache[model_id] = entry\n if \"/\" in model_id:\n cache.setdefault(model_id.rsplit(\"/\", 1)[1], entry)\n\n\ndef _model_id_matches(candidate_id: str, lookup_model: str) -> bool:\n if candidate_id == lookup_model:\n return True\n return \"/\" in candidate_id and candidate_id.rsplit(\"/\", 1)[1] == lookup_model\n\n\ndef _bearer_headers(api_key: str | None) -> dict[str, str]:\n resolved = str(api_key or \"\").strip()\n return {\"Authorization\": f\"Bearer {resolved}\"} if resolved else {}\n\n\ndef _normalize_base_url(base_url: str | None) -> str:\n return str(base_url or \"\").strip().rstrip(\"/\")\n\n\ndef _models_dev_disk_cache_path() -> Path:\n override = os.environ.get(\"ELEPHANT_MODELS_DEV_CACHE_PATH\", \"\").strip()\n if override:\n return Path(override).expanduser()\n return default_cli_state_dir() / \"models-dev-cache.json\"\n\n\ndef _context_length_cache_path() -> Path:\n override = os.environ.get(\"ELEPHANT_CONTEXT_LENGTH_CACHE_PATH\", \"\").strip()\n if override:\n return Path(override).expanduser()\n return default_cli_state_dir() / \"context-length-cache.json\"\n\n\ndef _context_length_cache_key(model_id: str, base_url: str) -> str:\n return f\"{model_id}@{base_url}\"\n\n\ndef _load_context_length_cache() -> dict[str, int]:\n path = _context_length_cache_path()\n try:\n payload = json.loads(path.read_text(encoding=\"utf-8\"))\n except (OSError, json.JSONDecodeError):\n return {}\n raw_cache = payload.get(\"context_lengths\") if isinstance(payload, Mapping) else None\n if not isinstance(raw_cache, Mapping):\n return {}\n cache: dict[str, int] = {}\n for key, value in raw_cache.items():\n parsed = _coerce_reasonable_int(value)\n if parsed is not None:\n cache[str(key)] = parsed\n return cache\n\n\ndef _save_context_length_cache(cache: Mapping[str, int]) -> None:\n path = _context_length_cache_path()\n try:\n path.parent.mkdir(parents=True, exist_ok=True)\n with tempfile.NamedTemporaryFile(\"w\", encoding=\"utf-8\", dir=path.parent, delete=False) as handle:\n json.dump({\"context_lengths\": dict(cache)}, handle, separators=(\",\", \":\"))\n temp_name = handle.name\n Path(temp_name).replace(path)\n except OSError:\n return\n\n\ndef _load_models_dev_disk_cache() -> dict[str, Any]:\n path = _models_dev_disk_cache_path()\n try:\n payload = json.loads(path.read_text(encoding=\"utf-8\"))\n except (OSError, json.JSONDecodeError):\n return {}\n return dict(payload) if isinstance(payload, Mapping) else {}\n\n\ndef _save_models_dev_disk_cache(payload: Mapping[str, Any]) -> None:\n path = _models_dev_disk_cache_path()\n try:\n path.parent.mkdir(parents=True, exist_ok=True)\n with tempfile.NamedTemporaryFile(\"w\", encoding=\"utf-8\", dir=path.parent, delete=False) as handle:\n json.dump(dict(payload), handle, separators=(\",\", \":\"))\n temp_name = handle.name\n Path(temp_name).replace(path)\n except OSError:\n return\n\n\n__all__ = [\n \"ResolvedModelMetadata\",\n \"fetch_endpoint_model_metadata\",\n \"fetch_models_dev_registry\",\n \"fetch_openrouter_model_metadata\",\n \"get_cached_context_length\",\n \"infer_provider_from_url\",\n \"is_local_endpoint\",\n \"lookup_models_dev_metadata\",\n \"lookup_openrouter_metadata\",\n \"query_local_endpoint_metadata\",\n \"resolve_provider_model_metadata\",\n \"save_context_length\",\n]\n"}}, "packages/models/auth_headers.py": {"b342fa5f7cceb2efc4945b50b54b6e8233452272": {"t": 1785674430.8893015, "n": 6810, "h": "c7a32da98d3dc950", "c": "\"\"\"Auth-header strategies for provider transports.\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom typing import Mapping, Protocol, runtime_checkable\n\nANTHROPIC_OAUTH_BETA_HEADER = (\n \"interleaved-thinking-2025-05-14,\"\n \"fine-grained-tool-streaming-2025-05-14,\"\n \"claude-code-20250219,\"\n \"oauth-2025-04-20\"\n)\n\n\n@dataclass(frozen=True, slots=True)\nclass AuthHeaderContext:\n provider_id: str\n request_family: str\n api_key: str | None\n anthropic_version: str = \"2023-06-01\"\n metadata: Mapping[str, str] = field(default_factory=dict)\n\n\n@runtime_checkable\nclass AuthHeaderStrategy(Protocol):\n strategy_id: str\n\n def supports(self, context: AuthHeaderContext) -> bool:\n \"\"\"Return whether this strategy can build headers for the context.\"\"\"\n\n def build_headers(self, context: AuthHeaderContext) -> Mapping[str, str]:\n \"\"\"Build auth headers for the context.\"\"\"\n\n\nclass InMemoryAuthHeaderStrategyRegistry:\n def __init__(self, strategies: tuple[AuthHeaderStrategy, ...] = ()) -> None:\n self._strategies: dict[str, AuthHeaderStrategy] = {}\n for strategy in strategies:\n self.register(strategy)\n\n def register(self, strategy: AuthHeaderStrategy) -> None:\n self._strategies[strategy.strategy_id] = strategy\n\n def get(self, strategy_id: str) -> AuthHeaderStrategy | None:\n return self._strategies.get(strategy_id)\n\n def list(self) -> tuple[AuthHeaderStrategy, ...]:\n return tuple(self._strategies.values())\n\n def select(self, context: AuthHeaderContext) -> AuthHeaderStrategy:\n configured = str(context.metadata.get(\"auth_header_strategy\") or \"\").strip()\n if configured:\n strategy = self.get(configured)\n if strategy is None:\n raise LookupError(f\"no auth-header strategy registered for id: {configured}\")\n return strategy\n for strategy in self._strategies.values():\n if strategy.supports(context):\n return strategy\n raise LookupError(\n \"no auth-header strategy registered for \"\n f\"provider={context.provider_id} request_family={context.request_family}\"\n )\n\n @classmethod\n def default(cls) -> \"InMemoryAuthHeaderStrategyRegistry\":\n return cls(\n (\n _CopilotBearerStrategy(),\n _AnthropicOauthBearerStrategy(),\n _AnthropicApiKeyStrategy(),\n _BearerAuthHeaderStrategy(),\n )\n )\n\n\ndef _is_anthropic_oauth_token(api_key: str) -> bool:\n return (\n (api_key.startswith(\"sk-ant-\") and not api_key.startswith(\"sk-ant-api\"))\n or api_key.startswith(\"eyJ\")\n )\n\n\nclass _CopilotBearerStrategy:\n strategy_id = \"copilot-bearer\"\n\n def supports(self, context: AuthHeaderContext) -> bool:\n return bool(context.api_key) and context.provider_id.strip().lower() == \"copilot\"\n\n def build_headers(self, context: AuthHeaderContext) -> Mapping[str, str]:\n api_key = str(context.api_key or \"\").strip()\n if not api_key:\n return {}\n headers = {\"Authorization\": f\"Bearer {api_key}\"}\n if context.request_family.strip().lower() == \"messages\":\n headers[\"anthropic-version\"] = context.anthropic_version\n return headers\n\n\nclass _AnthropicOauthBearerStrategy:\n strategy_id = \"anthropic-oauth-bearer\"\n\n def supports(self, context: AuthHeaderContext) -> bool:\n api_key = str(context.api_key or \"\").strip()\n provider_id = context.provider_id.strip().lower()\n return bool(api_key) and (\n provider_id == \"claude-code\"\n or (provider_id == \"anthropic\" and _is_anthropic_oauth_token(api_key))\n )\n\n def build_headers(self, context: AuthHeaderContext) -> Mapping[str, str]:\n api_key = str(context.api_key or \"\").strip()\n if not api_key:\n return {}\n headers = {\n \"Authorization\": f\"Bearer {api_key}\",\n \"anthropic-beta\": ANTHROPIC_OAUTH_BETA_HEADER,\n \"user-agent\": \"claude-cli/2.1.74 (external, cli)\",\n \"x-app\": \"cli\",\n }\n if context.provider_id.strip().lower() == \"anthropic\":\n headers[\"anthropic-version\"] = context.anthropic_version\n return headers\n\n\nclass _AnthropicApiKeyStrategy:\n strategy_id = \"anthropic-x-api-key\"\n\n def supports(self, context: AuthHeaderContext) -> bool:\n api_key = str(context.api_key or \"\").strip()\n provider_id = context.provider_id.strip().lower()\n request_family = context.request_family.strip().lower()\n return bool(api_key) and (\n request_family == \"messages\" or provider_id == \"anthropic\"\n )\n\n def build_headers(self, context: AuthHeaderContext) -> Mapping[str, str]:\n api_key = str(context.api_key or \"\").strip()\n if not api_key:\n return {}\n return {\n \"anthropic-version\": context.anthropic_version,\n \"x-api-key\": api_key,\n }\n\n\nclass _BearerAuthHeaderStrategy:\n strategy_id = \"bearer\"\n\n def supports(self, context: AuthHeaderContext) -> bool:\n return bool(str(context.api_key or \"\").strip())\n\n def build_headers(self, context: AuthHeaderContext) -> Mapping[str, str]:\n api_key = str(context.api_key or \"\").strip()\n if not api_key:\n return {}\n return {\"Authorization\": f\"Bearer {api_key}\"}\n\n\n_DEFAULT_AUTH_HEADER_STRATEGY_REGISTRY: InMemoryAuthHeaderStrategyRegistry | None = None\n\n\ndef default_auth_header_strategy_registry() -> InMemoryAuthHeaderStrategyRegistry:\n global _DEFAULT_AUTH_HEADER_STRATEGY_REGISTRY\n if _DEFAULT_AUTH_HEADER_STRATEGY_REGISTRY is None:\n _DEFAULT_AUTH_HEADER_STRATEGY_REGISTRY = InMemoryAuthHeaderStrategyRegistry.default()\n return _DEFAULT_AUTH_HEADER_STRATEGY_REGISTRY\n\n\ndef build_provider_auth_headers(\n *,\n provider_id: str,\n request_family: str,\n api_key: str | None,\n anthropic_version: str = \"2023-06-01\",\n metadata: Mapping[str, str] | None = None,\n registry: InMemoryAuthHeaderStrategyRegistry | None = None,\n) -> dict[str, str]:\n context = AuthHeaderContext(\n provider_id=provider_id,\n request_family=request_family,\n api_key=api_key,\n anthropic_version=anthropic_version,\n metadata=dict(metadata or {}),\n )\n resolved_registry = registry or default_auth_header_strategy_registry()\n if not api_key:\n return {}\n return dict(resolved_registry.select(context).build_headers(context))\n\n\n__all__ = [\n \"ANTHROPIC_OAUTH_BETA_HEADER\",\n \"AuthHeaderContext\",\n \"AuthHeaderStrategy\",\n \"InMemoryAuthHeaderStrategyRegistry\",\n \"build_provider_auth_headers\",\n \"default_auth_header_strategy_registry\",\n]\n"}}, "packages/models/provider_catalog_extra.py": {"b342fa5f7cceb2efc4945b50b54b6e8233452272": {"t": 1785809847.1282167, "n": 14376, "h": "061296d1ab0fca7a", "c": "\"\"\"Additional popular provider catalog entries.\"\"\"\n\nfrom __future__ import annotations\n\nfrom .provider_catalog import ProviderDefinition\n\n\ndef extra_provider_definitions() -> tuple[ProviderDefinition, ...]:\n return (\n ProviderDefinition(\n provider_id=\"cohere\",\n display_name=\"Cohere\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use Cohere models through Cohere's OpenAI-compatible Compatibility API.\",\n onboarding_hint=\"Choose a Command model, attach a Cohere API key, and validate the Compatibility API route.\",\n default_base_url=\"https://api.cohere.ai/compatibility/v1\",\n default_model_id=\"command-a-03-2025\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\", \"embeddings\"),\n model_hints=(\"command-a-03-2025\", \"command-a-plus-05-2026\", \"command-r-plus-08-2024\"),\n supports_custom_base_url=False,\n listing_priority=56,\n docs_url=\"https://docs.cohere.com/docs/compatibility-api\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"COHERE_API_KEY\",),\n base_url_env_var=\"COHERE_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"reasoning\"},\n ),\n ProviderDefinition(\n provider_id=\"perplexity\",\n display_name=\"Perplexity Agent API\",\n transport_id=\"openai_responses\",\n catalog_summary=\"Use Perplexity's OpenAI-compatible Agent API for grounded model routing.\",\n onboarding_hint=\"Attach a Perplexity API key and use the Responses-compatible Agent API endpoint.\",\n default_base_url=\"https://api.perplexity.ai/v1\",\n default_model_id=\"openai/gpt-5-mini\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\",),\n model_hints=(\"openai/gpt-5.5\", \"openai/gpt-5-mini\", \"anthropic/claude-sonnet-4.6\"),\n supports_custom_base_url=False,\n listing_priority=57,\n docs_url=\"https://docs.perplexity.ai/docs/agent-api/openai-compatibility\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"PERPLEXITY_API_KEY\",),\n base_url_env_var=\"PERPLEXITY_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"embeddings\"},\n ),\n ProviderDefinition(\n provider_id=\"cerebras\",\n display_name=\"Cerebras\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use Cerebras Inference through its OpenAI-compatible high-speed endpoint.\",\n onboarding_hint=\"Attach a Cerebras API key and choose a production or preview Cerebras-served model.\",\n default_base_url=\"https://api.cerebras.ai/v1\",\n default_model_id=\"gpt-oss-120b\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\",),\n model_hints=(\"gpt-oss-120b\", \"zai-glm-4.7\", \"llama3.1-8b\"),\n supports_custom_base_url=False,\n listing_priority=58,\n docs_url=\"https://inference-docs.cerebras.ai/resources/openai\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"CEREBRAS_API_KEY\",),\n base_url_env_var=\"CEREBRAS_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"embeddings\"},\n ),\n ProviderDefinition(\n provider_id=\"nvidia\",\n display_name=\"NVIDIA NIM\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use NVIDIA API Catalog / NIM hosted models through the OpenAI-compatible endpoint.\",\n onboarding_hint=\"Attach an NVIDIA API key and choose a NIM-hosted model from the API catalog.\",\n default_base_url=\"https://integrate.api.nvidia.com/v1\",\n default_model_id=\"nvidia/llama-3.3-nemotron-super-49b-v1\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\",),\n model_hints=(\n \"nvidia/llama-3.3-nemotron-super-49b-v1\",\n \"nvidia/nemotron-3-super-120b-a12b\",\n \"nvidia/llama-3.1-nemotron-nano-vl-8b-v1\",\n ),\n supports_custom_base_url=False,\n listing_priority=59,\n docs_url=\"https://docs.api.nvidia.com/nim/reference/llm-apis\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"NVIDIA_API_KEY\", \"NVIDIA_NIM_API_KEY\"),\n base_url_env_var=\"NVIDIA_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"embeddings\"},\n ),\n ProviderDefinition(\n provider_id=\"siliconflow\",\n display_name=\"SiliconFlow\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use SiliconFlow's OpenAI-compatible model cloud for Chinese and open-source model families.\",\n onboarding_hint=\"Attach a SiliconFlow key and choose a Qwen, DeepSeek, Kimi, GLM, or other hosted model.\",\n default_base_url=\"https://api.siliconflow.cn/v1\",\n default_model_id=\"Qwen/Qwen3-32B\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\", \"embeddings\"),\n model_hints=(\n \"Qwen/Qwen3-32B\",\n \"Qwen/Qwen3-235B-A22B\",\n \"deepseek-ai/DeepSeek-V3.2\",\n \"moonshotai/Kimi-K2-Instruct\",\n ),\n supports_custom_base_url=False,\n listing_priority=63,\n docs_url=\"https://docs.siliconflow.com/cn/api-reference/chat-completions/chat-completions\",\n provider_kind=\"aggregator\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"SILICONFLOW_API_KEY\",),\n base_url_env_var=\"SILICONFLOW_BASE_URL\",\n metadata={\"surface\": \"aggregator\", \"unsupported_capabilities\": \"reasoning\"},\n ),\n ProviderDefinition(\n provider_id=\"volcengine\",\n display_name=\"Volcengine Ark / Doubao\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use Volcengine Ark and Doubao models through Ark's OpenAI-compatible endpoint.\",\n onboarding_hint=\"Attach an Ark API key, choose a Doubao model or endpoint id, and validate the China-region route.\",\n default_base_url=\"https://ark.cn-beijing.volces.com/api/v3\",\n default_model_id=\"doubao-1-5-pro-32k-250115\",\n endpoint_path_override=\"/chat/completions\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\",),\n model_hints=(\n \"doubao-1-5-pro-32k-250115\",\n \"doubao-1-5-pro-256k-250115\",\n \"doubao-seed-1-6-250615\",\n \"doubao-seed-1-6-thinking-250615\",\n ),\n supports_custom_base_url=False,\n listing_priority=64,\n docs_url=\"https://www.volcengine.com/docs/82379/1330626\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"ARK_API_KEY\", \"VOLCENGINE_API_KEY\"),\n base_url_env_var=\"VOLCENGINE_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"reasoning,embeddings\"},\n ),\n ProviderDefinition(\n provider_id=\"baidu-qianfan\",\n display_name=\"Baidu Qianfan / Wenxin\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use Baidu Qianfan ModelBuilder and Wenxin-compatible models through the v2 OpenAI-compatible API.\",\n onboarding_hint=\"Attach a Qianfan API key, select an ERNIE or DeepSeek model, and validate the v2 chat route.\",\n default_base_url=\"https://qianfan.baidubce.com/v2\",\n default_model_id=\"ernie-4.0-turbo-8k\",\n endpoint_path_override=\"/chat/completions\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\",),\n model_hints=(\"ernie-4.0-turbo-8k\", \"ernie-3.5-8k\", \"deepseek-v3.2\", \"deepseek-r1\"),\n supports_custom_base_url=False,\n listing_priority=67,\n docs_url=\"https://cloud.baidu.com/doc/qianfan-docs/s/Fm9l6ocai\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"QIANFAN_API_KEY\", \"BAIDU_QIANFAN_API_KEY\"),\n base_url_env_var=\"QIANFAN_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"reasoning,embeddings\"},\n ),\n ProviderDefinition(\n provider_id=\"tencent-hunyuan\",\n display_name=\"Tencent Hunyuan\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use Tencent Hunyuan through Tencent Cloud's OpenAI-compatible API.\",\n onboarding_hint=\"Attach a Hunyuan API key and choose a Tencent-hosted model such as Hunyuan Turbos.\",\n default_base_url=\"https://api.hunyuan.cloud.tencent.com/v1\",\n default_model_id=\"hunyuan-turbos-latest\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\", \"embeddings\"),\n model_hints=(\"hunyuan-turbos-latest\", \"hunyuan-t1-latest\", \"hunyuan-a13b-instruct\"),\n supports_custom_base_url=False,\n listing_priority=68,\n docs_url=\"https://cloud.tencent.com/document/product/1729/111007\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"HUNYUAN_API_KEY\", \"TENCENT_HUNYUAN_API_KEY\"),\n base_url_env_var=\"HUNYUAN_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"reasoning\"},\n ),\n ProviderDefinition(\n provider_id=\"tencent-tokenhub\",\n display_name=\"Tencent Cloud TokenHub\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use Tencent Cloud TokenHub as an OpenAI-compatible gateway for Hunyuan and third-party models.\",\n onboarding_hint=\"Attach a TokenHub API key and choose a TokenHub service ID such as hy3-preview or deepseek-v3.2.\",\n default_base_url=\"https://tokenhub.tencentmaas.com/v1\",\n default_model_id=\"hy3-preview\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\",),\n model_hints=(\n \"hy3-preview\",\n \"deepseek-v3.2\",\n \"deepseek-r1\",\n \"glm-5\",\n \"kimi-k2.5\",\n \"minimax-m2.5\",\n ),\n supports_custom_base_url=False,\n listing_priority=68,\n docs_url=\"https://cloud.tencent.com/document/product/1823/130079\",\n provider_kind=\"aggregator\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"TOKENHUB_API_KEY\", \"TENCENT_TOKENHUB_API_KEY\"),\n base_url_env_var=\"TOKENHUB_BASE_URL\",\n metadata={\"surface\": \"aggregator\", \"unsupported_capabilities\": \"reasoning,embeddings\"},\n ),\n ProviderDefinition(\n provider_id=\"stepfun\",\n display_name=\"StepFun\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use StepFun's Step models through the OpenAI-compatible chat endpoint.\",\n onboarding_hint=\"Attach a StepFun API key, select a Step model, and validate the compatible chat route.\",\n default_base_url=\"https://api.stepfun.com/v1\",\n default_model_id=\"step-3.5-flash\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\",),\n model_hints=(\"step-3.5-flash\", \"step-3.5\", \"step-2-16k\", \"step-1v-8k\"),\n supports_custom_base_url=False,\n listing_priority=69,\n docs_url=\"https://platform.stepfun.com/docs/guide/openai\",\n provider_kind=\"first_party\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"STEPFUN_API_KEY\", \"STEP_API_KEY\"),\n base_url_env_var=\"STEPFUN_BASE_URL\",\n metadata={\"surface\": \"first_party\", \"unsupported_capabilities\": \"reasoning,embeddings\"},\n ),\n ProviderDefinition(\n provider_id=\"modelscope\",\n display_name=\"ModelScope\",\n transport_id=\"openai_chat_compatible\",\n catalog_summary=\"Use ModelScope API Inference as an OpenAI-compatible route to popular open-source models.\",\n onboarding_hint=\"Attach a ModelScope access token and choose a hosted Qwen, GLM, DeepSeek, or Kimi model.\",\n default_base_url=\"https://api-inference.modelscope.cn/v1\",\n default_model_id=\"Qwen/Qwen3-235B-A22B-Instruct-2507\",\n required_secret_keys=(\"api_key\",),\n required_config_keys=(\"model_id\",),\n capability_flags=(\"chat\", \"embeddings\"),\n model_hints=(\n \"Qwen/Qwen3-235B-A22B-Instruct-2507\",\n \"Qwen/Qwen3-Coder-30B-A3B-Instruct\",\n \"ZhipuAI/GLM-4.6\",\n ),\n supports_custom_base_url=False,\n listing_priority=77,\n docs_url=\"https://www.modelscope.cn/docs/model-service/API-Inference/intro\",\n provider_kind=\"aggregator\",\n auth_method=\"api_key\",\n auth_type=\"api_key\",\n env_var_names=(\"MODELSCOPE_API_KEY\",),\n base_url_env_var=\"MODELSCOPE_BASE_URL\",\n metadata={\"surface\": \"aggregator\", \"unsupported_capabilities\": \"reasoning\"},\n ),\n )\n"}}}}