Download app/upstream/models.py from li2895/anuma2api: direct link, hf CLI and curl.
- Browser
- Download file 5.64 kB
-
https://huggingface.co/spaces/li2895/anuma2api/resolve/main/app/upstream/models.py
- Command line
-
hf download hf://spaces/li2895/anuma2api/app/upstream/models.py
-
curl -L -o models.py https://huggingface.co/spaces/li2895/anuma2api/resolve/main/app/upstream/models.py
5.64 kB
| """anuma.ai ModelRegistry:模型目录(探测自 GET portal.anuma.ai/api/v1/curated-models)。 | |
| 字段:id(catalog id,即上游 curated-models 的 id 如 ``kimi/kimi-k3``)/ | |
| name / owner(provider)/ upstream_id(Fireworks 格式 ``accounts/fireworks/models/<短名>``)。 | |
| ⚠️ 列表为 2026-08-01 探测快照;上游增删模型时用 scripts/probe_catalog.py 重新生成。 | |
| """ | |
| from __future__ import annotations | |
| import re | |
| from typing import Any | |
| from app.upstream.base import ModelRegistry | |
| __all__ = [ | |
| "DEFAULT_MODEL", "MODEL_CATALOG", "IMAGE_MODEL_CATALOG", | |
| "normalize_image_model", "DefaultModelRegistry", | |
| ] | |
| DEFAULT_MODEL = "openai/gpt-5.6-luna" # 上游未识别 model 时的回退模型(实测所见) | |
| # 生图模型(2026-08-08 从 chat.anuma.ai HAR 抓取):/v1/images 路由用。 | |
| # key = AnumaMediaMCP-anuma_create_image 工具 model 参数值;name = 对外展示名。 | |
| # 前缀 * 为 GPT-5.6 Luna 生图实测可用模型;tier alias(auto/anuma-*)由上游按订阅分层。 | |
| IMAGE_MODEL_CATALOG: list[dict[str, Any]] = [ | |
| {"id": "gpt-image-2", "name": "GPT Image 2"}, | |
| {"id": "flux-2-pro", "name": "Flux 2 Pro"}, | |
| {"id": "flux-2-klein-4b", "name": "Flux 2 Klein 4B"}, | |
| {"id": "grok-imagine", "name": "Grok Imagine"}, | |
| {"id": "nano-banana", "name": "Nano Banana"}, | |
| {"id": "nano-banana-pro", "name": "Nano Banana Pro"}, | |
| {"id": "nano-banana-2", "name": "Nano Banana 2"}, | |
| {"id": "anuma-flash", "name": "Anuma Flash (tier alias)"}, | |
| {"id": "anuma-pro", "name": "Anuma Pro (tier alias)"}, | |
| {"id": "anuma-flash-private", "name": "Anuma Flash Private (tier alias)"}, | |
| {"id": "anuma-pro-private", "name": "Anuma Pro Private (tier alias)"}, | |
| ] | |
| _IMAGE_BY_KEY: dict[str, dict[str, Any]] = {} | |
| for _im in IMAGE_MODEL_CATALOG: | |
| _IMAGE_BY_KEY[_im["id"]] = _im | |
| _IMAGE_BY_KEY[_im["name"].lower()] = _im | |
| def normalize_image_model(model: str | None) -> str | None: | |
| """客户端传入的 gen 图片模型 → 上游 tool 参数值;空/未知 → None(由客户端容错)。""" | |
| if not model: | |
| return None | |
| if model in _IMAGE_BY_KEY: | |
| return _IMAGE_BY_KEY[model]["id"] | |
| low = model.lower() | |
| if low in _IMAGE_BY_KEY: | |
| return _IMAGE_BY_KEY[low]["id"] | |
| norm = re.sub(r"[^a-z0-9]", "", low) | |
| for m in IMAGE_MODEL_CATALOG: | |
| if re.sub(r"[^a-z0-9]", "", m["id"]) == norm: | |
| return m["id"] | |
| return None | |
| # 探测自 /api/v1/curated-models(active=true 的 text/vision 模型为主) | |
| MODEL_CATALOG: list[dict[str, Any]] = [ | |
| {"id": "inclusionai/ling-2.6-flash", "name": "Ling 2.6 Flash", "owner": "InclusionAI", "upstream_id": "accounts/fireworks/models/ling-2.6-flash"}, | |
| {"id": "kimi/kimi-k3", "name": "Kimi K3", "owner": "Kimi", "upstream_id": "accounts/fireworks/models/kimi-k3"}, | |
| {"id": "kimi/kimi-k2.7-code", "name": "Kimi K2.7 Code", "owner": "Kimi", "upstream_id": "accounts/fireworks/models/kimi-k2.7-code"}, | |
| {"id": "kimi/kimi-k2.6", "name": "Kimi 2.6", "owner": "Kimi", "upstream_id": "accounts/fireworks/models/kimi-k2.6"}, | |
| {"id": "openai/gpt-5.6-sol", "name": "GPT 5.6 Sol", "owner": "OpenAI", "upstream_id": "accounts/fireworks/models/gpt-5.6-sol"}, | |
| {"id": "openai/gpt-5.6-terra", "name": "GPT 5.6 Terra", "owner": "OpenAI", "upstream_id": "accounts/fireworks/models/gpt-5.6-terra"}, | |
| {"id": "openai/gpt-5.6-luna", "name": "GPT 5.6 Luna", "owner": "OpenAI", "upstream_id": "accounts/fireworks/models/gpt-5.6-luna"}, | |
| {"id": "anthropic/claude-sonnet-5", "name": "Claude Sonnet 5", "owner": "Anthropic", "upstream_id": "accounts/fireworks/models/claude-sonnet-5"}, | |
| {"id": "anthropic/claude-opus-5", "name": "Claude Opus 5", "owner": "Anthropic", "upstream_id": "accounts/fireworks/models/claude-opus-5"}, | |
| {"id": "openai/gpt-5.5", "name": "GPT 5.5", "owner": "OpenAI", "upstream_id": "accounts/fireworks/models/gpt-5.5"}, | |
| {"id": "qwen/qwen-3.7-plus", "name": "Qwen 3.7 Plus", "owner": "Qwen", "upstream_id": "accounts/fireworks/models/qwen-3.7-plus"}, | |
| {"id": "qwen/qwen-3.6-plus", "name": "Qwen 3.6 Plus", "owner": "Qwen", "upstream_id": "accounts/fireworks/models/qwen-3.6-plus"}, | |
| {"id": "glm/glm-5.2", "name": "GLM 5.2", "owner": "Zhipu", "upstream_id": "accounts/fireworks/models/glm-5.2"}, | |
| {"id": "minimax/minimax-m3", "name": "MiniMax M3", "owner": "MiniMax", "upstream_id": "accounts/fireworks/models/minimax-m3"}, | |
| {"id": "minimax/minimax-m2.7", "name": "Minimax 2.7", "owner": "MiniMax", "upstream_id": "accounts/fireworks/models/minimax-m2.7"}, | |
| ] | |
| _BY_KEY: dict[str, dict[str, Any]] = {} | |
| for _m in MODEL_CATALOG: | |
| _BY_KEY[_m["id"]] = _m | |
| _BY_KEY[_m["name"].lower()] = _m | |
| class DefaultModelRegistry(ModelRegistry): | |
| def catalog(self) -> list[dict[str, Any]]: | |
| return list(MODEL_CATALOG) | |
| def normalize(self, model: str | None) -> str: | |
| """客户端传入的 model → catalog id;空或未知 → 默认。匹配:精确 id > 显示名(小写) > 模糊。""" | |
| if not model: | |
| return DEFAULT_MODEL | |
| if model in _BY_KEY: | |
| return _BY_KEY[model]["id"] | |
| low = model.lower() | |
| if low in _BY_KEY: | |
| return _BY_KEY[low]["id"] | |
| norm = re.sub(r"[^a-z0-9]", "", low) | |
| for m in MODEL_CATALOG: | |
| if (re.sub(r"[^a-z0-9]", "", m["id"]) == norm | |
| or re.sub(r"[^a-z0-9]", "", m["name"].lower()) == norm): | |
| return m["id"] | |
| return DEFAULT_MODEL | |
| def upstream_id_for(self, model_id: str) -> str | None: | |
| m = _BY_KEY.get(model_id) | |
| return m["upstream_id"] if m else None | |