From 5c717f12afe414bdc23f01294db67b6de5fa4783 Mon Sep 17 00:00:00 2001 From: HUANG Cheng Date: Mon, 7 Sep 2026 11:41:05 +0800 Subject: [PATCH 1/3] feat(providers): add Volcano Engine Agent Plan site Expose the /api/plan/v3 Agent Plan endpoint as a third Volcano Engine site (with UI label), injecting the preset when harness-agent has not shipped the template row yet. --- CHANGELOG.md | 4 + .../src/pages/Settings/Models/presetUtils.ts | 1 + src/octop/infra/agents/providers/presets.py | 115 ++++++++++++++++++ tests/unit/test_provider_preset_expansion.py | 13 ++ 4 files changed, 133 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2256785..eda28b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ## [Unreleased] +### 新增 + +- 火山引擎模型站点增加 Agent Plan(`/api/plan/v3`)及对应预设模型列表 + ## [0.9.32] - 2026-09-06 ### 新增 diff --git a/dashboard/src/pages/Settings/Models/presetUtils.ts b/dashboard/src/pages/Settings/Models/presetUtils.ts index fdf7ca48..210d8eeb 100644 --- a/dashboard/src/pages/Settings/Models/presetUtils.ts +++ b/dashboard/src/pages/Settings/Models/presetUtils.ts @@ -41,6 +41,7 @@ const VARIANT_LABELS: Record = { coding_plan: "Coding Plan", coding_plan_cn: "Coding (CN)", coding_plan_intl: "Coding (Intl)", + agent_plan: "Agent Plan", token_plan: "Token Plan", token_plan_enterprise_cn: "Token Enterprise (CN)", token_plan_intl: "Token (Intl)", diff --git a/src/octop/infra/agents/providers/presets.py b/src/octop/infra/agents/providers/presets.py index 039bf3a6..fdcdd5b3 100644 --- a/src/octop/infra/agents/providers/presets.py +++ b/src/octop/infra/agents/providers/presets.py @@ -269,6 +269,121 @@ def load_provider_presets() -> list[dict[str, Any]]: len(out), ) out.insert(insert_at, onnx_preset) + # Prefer harness-bundled Agent Plan when present; otherwise inject so Octop + # can ship the site before orcakit-harness-agent publishes the template row. + if not any(p.get("id") == "volcengine-cn-agentplan" for p in out): + agent_plan = { + "id": "volcengine-cn-agentplan", + "name": "Volcano Engine Agent Plan", + "base_url": "https://ark.cn-beijing.volces.com/api/plan/v3", + "protocol": "openai", + "api_key_prefix": "", + "models": [ + { + "id": "ark-code-latest", + "name": "Ark Code Latest (Auto)", + "max_input_tokens": 256000, + "max_output_tokens": 32000, + "input": ["text", "image"], + }, + { + "id": "doubao-seed-2.1-turbo", + "name": "Doubao Seed 2.1 Turbo", + "max_input_tokens": 256000, + "max_output_tokens": 65536, + "input": ["text", "image"], + }, + { + "id": "doubao-seed-evolving", + "name": "Doubao Seed Evolving", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text", "image"], + }, + { + "id": "glm-5.3", + "name": "GLM 5.3", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text"], + }, + { + "id": "glm-5.3-flash", + "name": "GLM 5.3 Flash", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text", "image"], + }, + { + "id": "glm-latest", + "name": "GLM Latest", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text"], + }, + { + "id": "deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text"], + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text"], + }, + { + "id": "doubao-seed-2.0-lite", + "name": "Doubao Seed 2.0 Lite", + "max_input_tokens": 256000, + "max_output_tokens": 65536, + "input": ["text", "image"], + }, + { + "id": "doubao-seed-2.0-mini", + "name": "Doubao Seed 2.0 Mini", + "max_input_tokens": 256000, + "max_output_tokens": 65536, + "input": ["text", "image"], + }, + { + "id": "minimax-m3", + "name": "MiniMax M3", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text", "image"], + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "max_input_tokens": 256000, + "max_output_tokens": 32000, + "input": ["text", "image"], + }, + { + "id": "kimi-k3", + "name": "Kimi K3", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": ["text", "image"], + }, + ], + "logo_id": "volces", + "vendor": "volcengine", + "vendor_name": "Volcano Engine", + "provider_group": "volcengine", + "provider_group_name": "Volcano Engine", + "variant": "agent_plan", + "provider_variant": "agent_plan", + } + insert_at = next( + (i + 1 for i, p in enumerate(out) if p.get("id") == "volcengine-cn-codingplan"), + len(out), + ) + out.insert(insert_at, agent_plan) for preset in out: provider_id = str(preset.get("id") or "") for model in preset.get("models") or []: diff --git a/tests/unit/test_provider_preset_expansion.py b/tests/unit/test_provider_preset_expansion.py index 7ad08e16..4f720128 100644 --- a/tests/unit/test_provider_preset_expansion.py +++ b/tests/unit/test_provider_preset_expansion.py @@ -81,6 +81,19 @@ def test_load_provider_presets_integration() -> None: assert "DeepSeek-V4-Flash" in coding_ids assert "kimi-k2.6" in coding_ids + agent_plan = next(p for p in presets if p["id"] == "volcengine-cn-agentplan") + assert agent_plan["base_url"] == "https://ark.cn-beijing.volces.com/api/plan/v3" + assert agent_plan.get("provider_group") == "volcengine" + assert agent_plan.get("provider_variant") == "agent_plan" + agent_ids = {m["id"] for m in agent_plan["models"]} + assert { + "ark-code-latest", + "doubao-seed-2.1-turbo", + "glm-5.3", + "deepseek-v4-flash", + "kimi-k3", + } <= agent_ids + opencode_ids = { "opencode-zen-openai", "opencode-zen-anthropic", From 02fdddd3a593d5e8cf01e175cb9280ee808810ab Mon Sep 17 00:00:00 2001 From: HUANG Cheng Date: Mon, 7 Sep 2026 12:01:33 +0800 Subject: [PATCH 2/3] docs(examples): attach provider_template with Volcano Agent Plan Add the full catalog JSON (Agent Plan inserted after Coding Plan) so reviewers can sync harness-agent without relying on a private template. --- docs/examples/provider_template.json | 2225 ++++++++++++++++++++++++++ 1 file changed, 2225 insertions(+) create mode 100644 docs/examples/provider_template.json diff --git a/docs/examples/provider_template.json b/docs/examples/provider_template.json new file mode 100644 index 00000000..951be4fe --- /dev/null +++ b/docs/examples/provider_template.json @@ -0,0 +1,2225 @@ +[ + { + "id": "tencent-coding-plan", + "name": "Tencent Cloud Coding Plan", + "base_url": "https://api.lkeap.cloud.tencent.com/coding/v3", + "protocol": "openai", + "api_key_env": "TENCENT_CODING_PLAN_API_KEY", + "api_key_prefix": "", + "logo": "tencent-coding-plan.png", + "models": [ + { + "id": "tc-code-latest", + "name": "Auto", + "max_input_tokens": 196608, + "input": [ + "text" + ] + }, + { + "id": "minimax-m2.5", + "name": "MiniMax-M2.5", + "max_input_tokens": 196608, + "input": [ + "text" + ] + }, + { + "id": "kimi-k2.5", + "name": "Kimi-K2.5", + "max_input_tokens": 262144, + "input": [ + "text" + ] + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 202752, + "input": [ + "text" + ] + } + ], + "vendor": "tencent", + "vendor_name": "Tencent Cloud", + "variant": "coding_plan" + }, + { + "id": "tencent-token-plan", + "name": "Tencent Cloud Token Plan", + "base_url": "https://api.lkeap.cloud.tencent.com/plan/v3", + "protocol": "openai", + "api_key_env": "TENCENT_TOKEN_PLAN_API_KEY", + "api_key_prefix": "sk-tp-", + "logo": "tencent-token-plan.png", + "models": [ + { + "id": "tc-code-latest", + "name": "Auto", + "max_input_tokens": 196608, + "input": [ + "text" + ] + }, + { + "id": "minimax-m2.7", + "name": "MiniMax-M2.7", + "max_input_tokens": 204800, + "reasoning": true, + "input": [ + "text" + ] + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 202752, + "reasoning": true, + "input": [ + "text" + ] + }, + { + "id": "glm-5.1", + "name": "GLM-5.1", + "max_input_tokens": 202752, + "max_output_tokens": 131072, + "reasoning": true, + "input": [ + "text" + ] + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072, + "reasoning": true, + "input": [ + "text" + ] + }, + { + "id": "deepseek-v4-flash-202605", + "name": "DeepSeek-V4-Flash Direct", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true, + "input": [ + "text" + ] + }, + { + "id": "deepseek-v4-pro-202606", + "name": "DeepSeek-V4-Pro Direct", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true, + "input": [ + "text" + ] + } + ], + "vendor": "tencent", + "vendor_name": "Tencent Cloud", + "variant": "token_plan" + }, + { + "id": "tencent-token-plan-enterprise-cn", + "name": "Tencent Cloud Token Plan Enterprise", + "base_url": "https://tokenhub.tencentmaas.com/plan/v3", + "protocol": "openai", + "api_key_env": "TENCENT_TOKEN_PLAN_ENTERPRISE_API_KEY", + "api_key_prefix": "sk-tp-", + "logo": "tencent-token-plan.png", + "models": [ + { + "id": "auto", + "name": "Auto", + "max_input_tokens": 196608, + "input": [ + "text" + ] + }, + { + "id": "deepseek-v4-flash", + "name": "DeepSeek-V4-Flash", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true + }, + { + "id": "deepseek-v4-flash-0731", + "name": "DeepSeek-V4-Flash 0731", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true + }, + { + "id": "deepseek-v4-flash-202605", + "name": "DeepSeek-V4-Flash Direct", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek-V4-Pro", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true + }, + { + "id": "deepseek-v4-pro-0813", + "name": "DeepSeek-V4-Pro 0813", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true + }, + { + "id": "deepseek-v4-pro-202606", + "name": "DeepSeek-V4-Pro Direct", + "max_input_tokens": 1000000, + "max_output_tokens": 384000, + "reasoning": true + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 202752, + "reasoning": true + }, + { + "id": "glm-5-turbo", + "name": "GLM-5 Turbo", + "max_input_tokens": 200000, + "max_output_tokens": 131072, + "reasoning": true + }, + { + "id": "glm-5.1", + "name": "GLM-5.1", + "max_input_tokens": 202752, + "max_output_tokens": 131072, + "reasoning": true + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072, + "reasoning": true + }, + { + "id": "glm-5.3", + "name": "GLM-5.3", + "max_input_tokens": 1000000, + "max_output_tokens": 131072, + "reasoning": true + }, + { + "id": "kimi-k2.5", + "name": "Kimi-K2.5", + "max_input_tokens": 262144, + "reasoning": true, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k2.6", + "name": "Kimi-K2.6", + "max_input_tokens": 262144, + "max_output_tokens": 65536, + "reasoning": true, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "max_input_tokens": 262144, + "reasoning": true + }, + { + "id": "kimi-k2.7-code-highspeed", + "name": "Kimi K2.7 Code HighSpeed", + "max_input_tokens": 262144, + "reasoning": true + }, + { + "id": "minimax-m2.5", + "name": "MiniMax-M2.5", + "max_input_tokens": 196608, + "reasoning": true + }, + { + "id": "minimax-m2.7", + "name": "MiniMax-M2.7", + "max_input_tokens": 204800, + "reasoning": true + }, + { + "id": "minimax-m3", + "name": "MiniMax-M3", + "max_input_tokens": 1000000, + "reasoning": true + } + ], + "vendor": "tencent", + "vendor_name": "Tencent Cloud", + "variant": "token_plan_enterprise_cn" + }, + { + "id": "tencent-hy-token-plan", + "name": "Tencent Cloud Hy Token Plan", + "base_url": "https://api.lkeap.cloud.tencent.com/plan/v3", + "protocol": "openai", + "api_key_env": "TENCENT_HY_TOKEN_PLAN_API_KEY", + "api_key_prefix": "sk-tp-", + "logo": "tencent-token-plan.png", + "models": [ + { + "id": "hy3", + "name": "Hy3", + "max_input_tokens": 256000, + "max_output_tokens": 64000, + "reasoning": true + }, + { + "id": "hy3-preview", + "name": "Hy3 Preview", + "max_input_tokens": 256000, + "max_output_tokens": 64000, + "reasoning": true + } + ], + "vendor": "tencent", + "vendor_name": "Tencent Cloud", + "variant": "hy_token_plan" + }, + { + "id": "tencent-hai", + "name": "Tencent Cloud HAI", + "base_url": "https://api.model.haihub.cn/v1", + "protocol": "openai", + "api_key_env": "TENCENT_HAI_API_KEY", + "api_key_prefix": "", + "logo": "tencent-hai.png", + "models": [ + { + "id": "MiniMax-M2.7", + "name": "MiniMax M2.7", + "max_input_tokens": 204800 + }, + { + "id": "Qwen3.5-397B-A17B-FP8", + "name": "Qwen3.5 397B A17B FP8", + "max_input_tokens": 262144, + "input": [ + "text", + "image" + ] + }, + { + "id": "Qwen3-32B-FP8", + "name": "Qwen3 32B FP8", + "max_input_tokens": 40960, + "max_output_tokens": 32768 + }, + { + "id": "Qwen3-VL-32B-Instruct-FP8", + "name": "Qwen3 VL 32B Instruct FP8", + "max_input_tokens": 262144, + "max_output_tokens": 32768, + "input": [ + "text", + "image" + ] + }, + { + "id": "Qwen2.5-VL-32B-Instruct", + "name": "Qwen2.5 VL 32B Instruct", + "max_input_tokens": 32768, + "input": [ + "text", + "image" + ] + }, + { + "id": "Qwen3-VL-2B-Instruct", + "name": "Qwen3 VL 2B Instruct", + "max_input_tokens": 262144, + "input": [ + "text", + "image" + ] + }, + { + "id": "Kimi-K2.5", + "name": "Kimi K2.5", + "max_input_tokens": 262144, + "input": [ + "text", + "image" + ] + }, + { + "id": "DeepSeek-V4-Pro", + "name": "DeepSeek V4 Pro", + "max_input_tokens": 128000 + }, + { + "id": "DeepSeek-V4-Flash", + "name": "DeepSeek V4 Flash", + "max_input_tokens": 128000 + }, + { + "id": "GLM-5.1-FP8", + "name": "GLM 5.1 FP8", + "max_input_tokens": 200000 + }, + { + "id": "DeepSeek-V3.1-Terminus-W4AFP8", + "name": "DeepSeek V3.1 Terminus W4AFP8", + "max_input_tokens": 128000 + } + ], + "vendor": "tencent", + "vendor_name": "Tencent Cloud", + "variant": "hai" + }, + { + "id": "deepseek", + "name": "DeepSeek", + "base_url": "https://api.deepseek.com/v1", + "protocol": "openai", + "api_key_env": "DEEPSEEK_API_KEY", + "api_key_prefix": "sk-", + "logo": "deepseek.png", + "models": [ + { + "id": "deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "max_input_tokens": 1000000, + "max_output_tokens": 384000 + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "max_input_tokens": 1000000, + "max_output_tokens": 384000 + } + ] + }, + { + "id": "mimo", + "name": "Xiaomi MiMo", + "base_url": "https://api.xiaomimimo.com/v1", + "protocol": "openai", + "api_key_env": "MIMO_API_KEY", + "api_key_prefix": "", + "logo": "mimo.svg", + "models": [ + { + "id": "mimo-v2.5", + "name": "MiMo V2.5", + "max_input_tokens": 1048576, + "max_output_tokens": 131072 + }, + { + "id": "mimo-v2.5-pro", + "name": "MiMo V2.5 Pro", + "max_input_tokens": 1048576, + "max_output_tokens": 131072 + }, + { + "id": "mimo-v2-flash", + "name": "MiMo V2 Flash", + "max_input_tokens": 262144 + }, + { + "id": "mimo-v2-pro", + "name": "MiMo V2 Pro", + "max_input_tokens": 262144 + } + ] + }, + { + "id": "modelscope", + "name": "ModelScope", + "base_url": "https://api-inference.modelscope.cn/v1", + "protocol": "openai", + "api_key_env": "MODELSCOPE_API_KEY", + "api_key_prefix": "", + "logo": "modelscope.png", + "models": [ + { + "id": "Qwen/Qwen3.5-122B-A10B", + "name": "Qwen3.5-122B-A10B", + "max_input_tokens": 131072 + }, + { + "id": "ZhipuAI/GLM-5", + "name": "GLM-5", + "max_input_tokens": 131072 + } + ] + }, + { + "id": "openai", + "name": "OpenAI", + "base_url": "https://api.openai.com/v1", + "protocol": "openai", + "api_key_env": "OPENAI_API_KEY", + "api_key_prefix": "sk-", + "logo": "openai.png", + "models": [ + { + "id": "gpt-5.2", + "name": "GPT-5.2", + "max_input_tokens": 256000, + "input": [ + "text", + "image" + ] + }, + { + "id": "gpt-5", + "name": "GPT-5", + "max_input_tokens": 256000, + "input": [ + "text", + "image" + ] + }, + { + "id": "gpt-5-mini", + "name": "GPT-5 Mini", + "max_input_tokens": 256000, + "input": [ + "text", + "image" + ] + }, + { + "id": "gpt-5-nano", + "name": "GPT-5 Nano", + "max_input_tokens": 256000 + }, + { + "id": "gpt-4.1", + "name": "GPT-4.1", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gpt-4.1-mini", + "name": "GPT-4.1 Mini", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gpt-4.1-nano", + "name": "GPT-4.1 Nano", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "o3", + "name": "o3", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ], + "reasoning": true + }, + { + "id": "o4-mini", + "name": "o4-mini", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ], + "reasoning": true + }, + { + "id": "gpt-4o", + "name": "GPT-4o", + "max_input_tokens": 128000, + "input": [ + "text", + "image" + ] + }, + { + "id": "gpt-4o-mini", + "name": "GPT-4o Mini", + "max_input_tokens": 128000, + "input": [ + "text", + "image" + ] + } + ] + }, + { + "id": "anthropic", + "name": "Anthropic", + "base_url": "https://api.anthropic.com/v1", + "protocol": "anthropic", + "api_key_env": "ANTHROPIC_API_KEY", + "api_key_prefix": "sk-ant-", + "logo": "anthropic.png", + "models": [ + { + "id": "claude-sonnet-4-20250514", + "name": "Claude Sonnet 4", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + }, + { + "id": "claude-opus-4-20250514", + "name": "Claude Opus 4", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + }, + { + "id": "claude-3-5-sonnet-20241022", + "name": "Claude 3.5 Sonnet", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + }, + { + "id": "claude-3-5-haiku-20241022", + "name": "Claude 3.5 Haiku", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + } + ] + }, + { + "id": "gemini", + "name": "Google Gemini", + "base_url": "https://generativelanguage.googleapis.com/v1beta/openai", + "protocol": "openai", + "api_key_env": "GEMINI_API_KEY", + "api_key_prefix": "", + "logo": "gemini.png", + "models": [ + { + "id": "gemini-3.1-pro-preview", + "name": "Gemini 3.1 Pro Preview", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gemini-3-flash-preview", + "name": "Gemini 3 Flash Preview", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gemini-3.1-flash-lite-preview", + "name": "Gemini 3.1 Flash Lite Preview", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gemini-2.5-pro", + "name": "Gemini 2.5 Pro", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gemini-2.5-flash", + "name": "Gemini 2.5 Flash", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gemini-2.5-flash-lite", + "name": "Gemini 2.5 Flash Lite", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "gemini-2.0-flash", + "name": "Gemini 2.0 Flash", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + } + ] + }, + { + "id": "groq", + "name": "Groq", + "base_url": "https://api.groq.com/openai/v1", + "protocol": "openai", + "api_key_env": "GROQ_API_KEY", + "api_key_prefix": "gsk_", + "logo": "groq.png", + "models": [ + { + "id": "llama-3.3-70b-versatile", + "name": "Llama 3.3 70B", + "max_input_tokens": 131072 + }, + { + "id": "llama-3.1-8b-instant", + "name": "Llama 3.1 8B", + "max_input_tokens": 131072 + }, + { + "id": "openai/gpt-oss-120b", + "name": "GPT-OSS 120B", + "max_input_tokens": 131072 + }, + { + "id": "openai/gpt-oss-20b", + "name": "GPT-OSS 20B", + "max_input_tokens": 131072 + } + ] + }, + { + "id": "openrouter", + "name": "OpenRouter", + "base_url": "https://openrouter.ai/api/v1", + "protocol": "openai", + "api_key_env": "OPENROUTER_API_KEY", + "api_key_prefix": "sk-or-", + "logo": "openrouter.png", + "models": [ + { + "id": "anthropic/claude-sonnet-4", + "name": "Claude Sonnet 4", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + }, + { + "id": "google/gemini-2.5-flash-preview", + "name": "Gemini 2.5 Flash", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + }, + { + "id": "deepseek/deepseek-chat-v3-0324", + "name": "DeepSeek Chat V3", + "max_input_tokens": 65536 + }, + { + "id": "openai/gpt-4.1", + "name": "GPT-4.1", + "max_input_tokens": 1048576, + "input": [ + "text", + "image" + ] + } + ] + }, + { + "id": "ollama", + "name": "Ollama (Local)", + "base_url": "http://localhost:11434/v1", + "protocol": "openai", + "api_key_env": "", + "api_key_prefix": "", + "logo": "ollama.png", + "models": [ + { + "id": "llama3", + "name": "llama3", + "max_input_tokens": 8192 + }, + { + "id": "mistral", + "name": "mistral", + "max_input_tokens": 32768 + } + ] + }, + { + "id": "kimi-cn", + "name": "Kimi (China)", + "base_url": "https://api.moonshot.cn/v1", + "protocol": "openai", + "api_key_env": "MOONSHOT_API_KEY", + "api_key_prefix": "sk-", + "logo": "moonshot.webp", + "models": [ + { + "id": "kimi-k3", + "name": "Kimi K3", + "max_input_tokens": 1000000 + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "max_input_tokens": 262144, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "max_input_tokens": 262144, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k2-0905-preview", + "name": "Kimi K2 0905 Preview", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2-0711-preview", + "name": "Kimi K2 0711 Preview", + "max_input_tokens": 131072 + }, + { + "id": "kimi-k2-turbo-preview", + "name": "Kimi K2 Turbo Preview", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2-thinking", + "name": "Kimi K2 Thinking", + "max_input_tokens": 262144, + "reasoning": true + }, + { + "id": "kimi-k2-thinking-turbo", + "name": "Kimi K2 Thinking Turbo", + "max_input_tokens": 262144, + "reasoning": true + } + ], + "vendor": "kimi", + "vendor_name": "Kimi", + "variant": "open_platform_cn" + }, + { + "id": "kimi-intl", + "name": "Kimi (International)", + "base_url": "https://api.moonshot.ai/v1", + "protocol": "openai", + "api_key_env": "MOONSHOT_API_KEY", + "api_key_prefix": "sk-", + "logo": "moonshot.webp", + "models": [ + { + "id": "kimi-k3", + "name": "Kimi K3", + "max_input_tokens": 1000000 + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "max_input_tokens": 262144, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "max_input_tokens": 262144, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k2-0905-preview", + "name": "Kimi K2 0905 Preview", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2-0711-preview", + "name": "Kimi K2 0711 Preview", + "max_input_tokens": 131072 + }, + { + "id": "kimi-k2-turbo-preview", + "name": "Kimi K2 Turbo Preview", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2-thinking", + "name": "Kimi K2 Thinking", + "max_input_tokens": 262144, + "reasoning": true + }, + { + "id": "kimi-k2-thinking-turbo", + "name": "Kimi K2 Thinking Turbo", + "max_input_tokens": 262144, + "reasoning": true + } + ], + "vendor": "kimi", + "vendor_name": "Kimi", + "variant": "open_platform_intl" + }, + { + "id": "kimi-codingplan", + "name": "Kimi Coding Plan", + "base_url": "https://api.kimi.com/coding/v1", + "protocol": "openai", + "api_key_env": "MOONSHOT_API_KEY", + "api_key_prefix": "sk-kimi-", + "logo": "moonshot.webp", + "models": [ + { + "id": "kimi-for-coding", + "name": "Kimi for Coding", + "max_input_tokens": 262144 + }, + { + "id": "kimi-for-coding-highspeed", + "name": "Kimi for Coding Highspeed", + "max_input_tokens": 262144 + }, + { + "id": "k3", + "name": "Kimi K3", + "max_input_tokens": 262144 + }, + { + "id": "k3-256k", + "name": "Kimi K3 256K", + "max_input_tokens": 262144 + } + ], + "vendor": "kimi", + "vendor_name": "Kimi", + "variant": "coding_plan" + }, + { + "id": "minimax-cn", + "name": "MiniMax (China)", + "base_url": "https://api.minimaxi.com/v1", + "protocol": "openai", + "api_key_env": "MINIMAX_API_KEY", + "api_key_prefix": "", + "logo": "minimax.png", + "models": [ + { + "id": "MiniMax-M2.5", + "name": "MiniMax M2.5", + "max_input_tokens": 204800 + }, + { + "id": "MiniMax-M2.5-highspeed", + "name": "MiniMax M2.5 Highspeed", + "max_input_tokens": 204800 + }, + { + "id": "MiniMax-M2.7", + "name": "MiniMax M2.7", + "max_input_tokens": 204800 + }, + { + "id": "MiniMax-M2.7-highspeed", + "name": "MiniMax M2.7 Highspeed", + "max_input_tokens": 204800 + } + ], + "vendor": "minimax", + "vendor_name": "MiniMax", + "variant": "open_platform_cn" + }, + { + "id": "minimax-intl", + "name": "MiniMax (International)", + "base_url": "https://api.minimax.io/v1", + "protocol": "openai", + "api_key_env": "MINIMAX_API_KEY", + "api_key_prefix": "", + "logo": "minimax.png", + "models": [ + { + "id": "MiniMax-M2.5", + "name": "MiniMax M2.5", + "max_input_tokens": 204800 + }, + { + "id": "MiniMax-M2.5-highspeed", + "name": "MiniMax M2.5 Highspeed", + "max_input_tokens": 204800 + }, + { + "id": "MiniMax-M2.7", + "name": "MiniMax M2.7", + "max_input_tokens": 204800 + }, + { + "id": "MiniMax-M2.7-highspeed", + "name": "MiniMax M2.7 Highspeed", + "max_input_tokens": 204800 + } + ], + "vendor": "minimax", + "vendor_name": "MiniMax", + "variant": "open_platform_intl" + }, + { + "id": "zhipu-cn", + "name": "Zhipu (BigModel)", + "base_url": "https://open.bigmodel.cn/api/paas/v4", + "protocol": "openai", + "api_key_env": "ZHIPU_API_KEY", + "api_key_prefix": "", + "logo": "zhipu.png", + "models": [ + { + "id": "glm-4.7-flash", + "name": "GLM-4.7-Flash", + "max_input_tokens": 200000 + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 200000 + }, + { + "id": "glm-5.1", + "name": "GLM-5.1", + "max_input_tokens": 200000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5-turbo", + "name": "GLM-5 Turbo", + "max_input_tokens": 200000 + }, + { + "id": "glm-5v-turbo", + "name": "GLM-5V Turbo", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + } + ], + "vendor": "zhipu", + "vendor_name": "Zhipu", + "variant": "open_platform_cn" + }, + { + "id": "zhipu-intl", + "name": "Zhipu (Z.AI)", + "base_url": "https://api.z.ai/api/paas/v4", + "protocol": "openai", + "api_key_env": "ZHIPU_API_KEY", + "api_key_prefix": "", + "logo": "zhipu.png", + "models": [ + { + "id": "glm-4.7-flash", + "name": "GLM-4.7-Flash", + "max_input_tokens": 200000 + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 200000 + }, + { + "id": "glm-5.1", + "name": "GLM-5.1", + "max_input_tokens": 200000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5-turbo", + "name": "GLM-5 Turbo", + "max_input_tokens": 200000 + }, + { + "id": "glm-5v-turbo", + "name": "GLM-5V Turbo", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + } + ], + "vendor": "zhipu", + "vendor_name": "Zhipu", + "variant": "open_platform_intl" + }, + { + "id": "zhipu-cn-codingplan", + "name": "Zhipu Coding Plan (BigModel)", + "base_url": "https://open.bigmodel.cn/api/coding/paas/v4", + "protocol": "openai", + "api_key_env": "ZHIPU_API_KEY", + "api_key_prefix": "", + "logo": "zhipu.png", + "models": [ + { + "id": "glm-4.7-flash", + "name": "GLM-4.7-Flash", + "max_input_tokens": 200000 + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 200000 + }, + { + "id": "glm-5.1", + "name": "GLM-5.1", + "max_input_tokens": 200000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5-turbo", + "name": "GLM-5 Turbo", + "max_input_tokens": 200000 + }, + { + "id": "glm-5v-turbo", + "name": "GLM-5V Turbo", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + } + ], + "vendor": "zhipu", + "vendor_name": "Zhipu", + "variant": "coding_plan_cn" + }, + { + "id": "zhipu-intl-codingplan", + "name": "Zhipu Coding Plan (Z.AI)", + "base_url": "https://api.z.ai/api/coding/paas/v4", + "protocol": "openai", + "api_key_env": "ZHIPU_API_KEY", + "api_key_prefix": "", + "logo": "zhipu.png", + "models": [ + { + "id": "glm-4.7-flash", + "name": "GLM-4.7-Flash", + "max_input_tokens": 200000 + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 200000 + }, + { + "id": "glm-5.1", + "name": "GLM-5.1", + "max_input_tokens": 200000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5.2", + "name": "GLM-5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5-turbo", + "name": "GLM-5 Turbo", + "max_input_tokens": 200000 + }, + { + "id": "glm-5v-turbo", + "name": "GLM-5V Turbo", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + } + ], + "vendor": "zhipu", + "vendor_name": "Zhipu", + "variant": "coding_plan_intl" + }, + { + "id": "dashscope", + "name": "DashScope (China)", + "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1", + "protocol": "openai", + "api_key_env": "DASHSCOPE_API_KEY", + "api_key_prefix": "sk-", + "logo": "dashscope.png", + "models": [ + { + "id": "qwen3.7-plus", + "name": "Qwen3.7 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3-max", + "name": "Qwen3 Max", + "max_input_tokens": 262144 + }, + { + "id": "qwen3-235b-a22b-thinking-2507", + "name": "Qwen3 235B Thinking", + "max_input_tokens": 131072, + "reasoning": true + }, + { + "id": "deepseek-v3.2", + "name": "DeepSeek V3.2", + "max_input_tokens": 65536 + } + ], + "vendor": "aliyun", + "vendor_name": "Aliyun", + "variant": "dashscope" + }, + { + "id": "dashscope-intl", + "name": "DashScope (Singapore)", + "base_url": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1", + "protocol": "openai", + "api_key_env": "DASHSCOPE_API_KEY", + "api_key_prefix": "sk-", + "logo": "dashscope.png", + "models": [ + { + "id": "qwen3-max", + "name": "Qwen3 Max", + "max_input_tokens": 131072 + }, + { + "id": "qwen3-235b-a22b-thinking-2507", + "name": "Qwen3 235B Thinking", + "max_input_tokens": 131072, + "reasoning": true + }, + { + "id": "deepseek-v3.2", + "name": "DeepSeek V3.2", + "max_input_tokens": 65536 + } + ], + "vendor": "aliyun", + "vendor_name": "Aliyun", + "variant": "dashscope_intl" + }, + { + "id": "dashscope-us", + "name": "DashScope (US)", + "base_url": "https://dashscope-us.aliyuncs.com/compatible-mode/v1", + "protocol": "openai", + "api_key_env": "DASHSCOPE_API_KEY", + "api_key_prefix": "sk-", + "logo": "dashscope.png", + "models": [ + { + "id": "qwen3-max", + "name": "Qwen3 Max", + "max_input_tokens": 131072 + }, + { + "id": "qwen3-235b-a22b-thinking-2507", + "name": "Qwen3 235B Thinking", + "max_input_tokens": 131072, + "reasoning": true + }, + { + "id": "deepseek-v3.2", + "name": "DeepSeek V3.2", + "max_input_tokens": 65536 + } + ], + "vendor": "aliyun", + "vendor_name": "Aliyun", + "variant": "dashscope_us" + }, + { + "id": "aliyun-codingplan-cn", + "name": "Aliyun Coding Plan (China)", + "base_url": "https://coding.dashscope.aliyuncs.com/v1", + "protocol": "openai", + "api_key_env": "DASHSCOPE_API_KEY", + "api_key_prefix": "sk-sp", + "logo": "dashscope.png", + "models": [ + { + "id": "qwen3.7-plus", + "name": "Qwen3.7 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.6-plus", + "name": "Qwen3.6 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.5-plus", + "name": "Qwen3.5 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 202752 + }, + { + "id": "glm-4.7", + "name": "GLM-4.7", + "max_input_tokens": 202752 + }, + { + "id": "MiniMax-M2.5", + "name": "MiniMax M2.5", + "max_input_tokens": 196608 + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "max_input_tokens": 262144 + }, + { + "id": "qwen3-max-2026-01-23", + "name": "Qwen3 Max 2026-01-23", + "max_input_tokens": 262144 + }, + { + "id": "qwen3-coder-next", + "name": "Qwen3 Coder Next", + "max_input_tokens": 262144 + }, + { + "id": "qwen3-coder-plus", + "name": "Qwen3 Coder Plus", + "max_input_tokens": 1000000 + } + ], + "vendor": "aliyun", + "vendor_name": "Aliyun", + "variant": "coding_plan_cn" + }, + { + "id": "aliyun-codingplan-intl", + "name": "Aliyun Coding Plan (International)", + "base_url": "https://coding-intl.dashscope.aliyuncs.com/v1", + "protocol": "openai", + "api_key_env": "DASHSCOPE_API_KEY", + "api_key_prefix": "sk-sp", + "logo": "dashscope.png", + "models": [ + { + "id": "qwen3.7-plus", + "name": "Qwen3.7 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.6-plus", + "name": "Qwen3.6 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.5-plus", + "name": "Qwen3.5 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 202752 + }, + { + "id": "glm-4.7", + "name": "GLM-4.7", + "max_input_tokens": 202752 + }, + { + "id": "MiniMax-M2.5", + "name": "MiniMax M2.5", + "max_input_tokens": 196608 + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "max_input_tokens": 262144 + }, + { + "id": "qwen3-max-2026-01-23", + "name": "Qwen3 Max 2026-01-23", + "max_input_tokens": 262144 + }, + { + "id": "qwen3-coder-next", + "name": "Qwen3 Coder Next", + "max_input_tokens": 262144 + }, + { + "id": "qwen3-coder-plus", + "name": "Qwen3 Coder Plus", + "max_input_tokens": 1000000 + } + ], + "vendor": "aliyun", + "vendor_name": "Aliyun", + "variant": "coding_plan_intl" + }, + { + "id": "aliyun-tokenplan", + "name": "Aliyun Token Plan", + "base_url": "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1", + "protocol": "openai", + "api_key_env": "DASHSCOPE_API_KEY", + "api_key_prefix": "sk-sp", + "logo": "dashscope.png", + "models": [ + { + "id": "qwen3.6-plus", + "name": "Qwen3.6 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 202752 + }, + { + "id": "MiniMax-M2.5", + "name": "MiniMax M2.5", + "max_input_tokens": 196608 + }, + { + "id": "deepseek-v3.2", + "name": "DeepSeek V3.2", + "max_input_tokens": 128000 + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "max_input_tokens": 262144 + } + ], + "vendor": "aliyun", + "vendor_name": "Aliyun", + "variant": "token_plan" + }, + { + "id": "aliyun-tokenplan-intl", + "name": "Aliyun Token Plan (International)", + "base_url": "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1", + "protocol": "openai", + "api_key_env": "DASHSCOPE_API_KEY", + "api_key_prefix": "sk-sp", + "logo": "dashscope.png", + "models": [ + { + "id": "qwen3.6-plus", + "name": "Qwen3.6 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "glm-5", + "name": "GLM-5", + "max_input_tokens": 202752 + }, + { + "id": "MiniMax-M2.5", + "name": "MiniMax M2.5", + "max_input_tokens": 196608 + }, + { + "id": "deepseek-v3.2", + "name": "DeepSeek V3.2", + "max_input_tokens": 128000 + }, + { + "id": "kimi-k2.5", + "name": "Kimi K2.5", + "max_input_tokens": 262144 + } + ], + "vendor": "aliyun", + "vendor_name": "Aliyun", + "variant": "token_plan_intl" + }, + { + "id": "volcengine-cn", + "name": "Volcano Engine", + "base_url": "https://ark.cn-beijing.volces.com/api/v3", + "protocol": "openai", + "api_key_env": "VOLCES_API_KEY", + "api_key_prefix": "", + "logo": "volces.svg", + "models": [ + { + "id": "doubao-seed-2-0-code-preview-260215", + "name": "Doubao-Seed-2.0-Code", + "max_input_tokens": 131072 + }, + { + "id": "doubao-seed-2-0-pro-260215", + "name": "Doubao-Seed-2.0-pro", + "max_input_tokens": 131072, + "input": [ + "text", + "image" + ] + }, + { + "id": "doubao-seed-2-0-lite-260428", + "name": "Doubao-Seed-2.0-lite", + "max_input_tokens": 131072 + }, + { + "id": "doubao-seed-code-preview-251028", + "name": "Doubao-Seed-Code", + "max_input_tokens": 131072 + }, + { + "id": "glm-4-7-251222", + "name": "GLM-4.7", + "max_input_tokens": 131072 + }, + { + "id": "deepseek-v3-2-251201", + "name": "DeepSeek-V3.2", + "max_input_tokens": 65536 + }, + { + "id": "doubao-seed-1-8-251228", + "name": "Doubao-Seed-1.8", + "max_input_tokens": 131072 + }, + { + "id": "doubao-seed-2-0-mini-260428", + "name": "Doubao-Seed-2.0-mini", + "max_input_tokens": 131072 + }, + { + "id": "doubao-seed-character-251128", + "name": "Doubao-Seed-Character", + "max_input_tokens": 131072 + } + ], + "vendor": "volcengine", + "vendor_name": "Volcano Engine", + "variant": "open_platform" + }, + { + "id": "volcengine-cn-codingplan", + "name": "Volcano Engine Coding Plan", + "base_url": "https://ark.cn-beijing.volces.com/api/coding/v3", + "protocol": "openai", + "api_key_env": "VOLCES_API_KEY", + "api_key_prefix": "", + "logo": "volces.svg", + "models": [ + { + "id": "ark-code-latest", + "name": "Ark Code Latest (Auto)" + }, + { + "id": "doubao-seed-2.1-turbo", + "name": "Doubao Seed 2.1 Turbo", + "max_input_tokens": 262144, + "context_window": 262144, + "max_output_tokens": 262144, + "input": [ + "text", + "image", + "video" + ], + "reasoning": true + }, + { + "id": "glm-5.2", + "name": "GLM 5.2", + "max_input_tokens": 1048576, + "context_window": 1048576, + "max_output_tokens": 131072, + "reasoning": true + }, + { + "id": "minimax-m3", + "name": "MiniMax M3", + "max_input_tokens": 1000000, + "context_window": 1000000, + "reasoning": true + }, + { + "id": "minimax-m2.7", + "name": "MiniMax M2.7", + "max_input_tokens": 204800, + "context_window": 204800, + "reasoning": true + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "max_input_tokens": 262144, + "context_window": 262144, + "input": [ + "text", + "image" + ], + "reasoning": true + }, + { + "id": "DeepSeek-V4-Flash", + "name": "DeepSeek V4 Flash", + "max_input_tokens": 1048576, + "context_window": 1048576, + "max_output_tokens": 393216, + "reasoning": true + }, + { + "id": "DeepSeek-V4-Pro", + "name": "DeepSeek V4 Pro", + "max_input_tokens": 1048576, + "context_window": 1048576, + "max_output_tokens": 393216, + "reasoning": true + }, + { + "id": "doubao-seed-2-0-code-preview-260215", + "name": "Doubao Seed 2.0 Code", + "max_input_tokens": 262144, + "context_window": 262144, + "max_output_tokens": 131072, + "input": [ + "text", + "image", + "video" + ], + "reasoning": true + }, + { + "id": "doubao-seed-2-0-pro-260215", + "name": "Doubao Seed 2.0 Pro", + "max_input_tokens": 262144, + "context_window": 262144, + "max_output_tokens": 131072, + "input": [ + "text", + "image", + "video" + ], + "reasoning": true + }, + { + "id": "doubao-seed-2-0-lite-260428", + "name": "Doubao Seed 2.0 Lite", + "max_input_tokens": 229376, + "context_window": 262144, + "max_output_tokens": 131072, + "input": [ + "text", + "image", + "video", + "audio" + ], + "reasoning": true + }, + { + "id": "doubao-seed-code-preview-251028", + "name": "Doubao Seed Code", + "max_input_tokens": 229376, + "context_window": 262144, + "max_output_tokens": 32768, + "input": [ + "text", + "image", + "video" + ], + "reasoning": true + } + ], + "vendor": "volcengine", + "vendor_name": "Volcano Engine", + "variant": "coding_plan" + }, + { + "id": "volcengine-cn-agentplan", + "name": "Volcano Engine Agent Plan", + "base_url": "https://ark.cn-beijing.volces.com/api/plan/v3", + "protocol": "openai", + "api_key_env": "VOLCES_API_KEY", + "api_key_prefix": "", + "logo": "volces.svg", + "models": [ + { + "id": "ark-code-latest", + "name": "Ark Code Latest (Auto)", + "max_input_tokens": 256000, + "max_output_tokens": 32000, + "input": [ + "text", + "image" + ] + }, + { + "id": "doubao-seed-2.1-turbo", + "name": "Doubao Seed 2.1 Turbo", + "max_input_tokens": 256000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "doubao-seed-evolving", + "name": "Doubao Seed Evolving", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "glm-5.3", + "name": "GLM 5.3", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text" + ] + }, + { + "id": "glm-5.3-flash", + "name": "GLM 5.3 Flash", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "glm-latest", + "name": "GLM Latest", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text" + ] + }, + { + "id": "deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text" + ] + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text" + ] + }, + { + "id": "doubao-seed-2.0-lite", + "name": "Doubao Seed 2.0 Lite", + "max_input_tokens": 256000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "doubao-seed-2.0-mini", + "name": "Doubao Seed 2.0 Mini", + "max_input_tokens": 256000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "minimax-m3", + "name": "MiniMax M3", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "max_input_tokens": 256000, + "max_output_tokens": 32000, + "input": [ + "text", + "image" + ] + }, + { + "id": "kimi-k3", + "name": "Kimi K3", + "max_input_tokens": 1024000, + "max_output_tokens": 65536, + "input": [ + "text", + "image" + ] + } + ], + "vendor": "volcengine", + "vendor_name": "Volcano Engine", + "variant": "agent_plan" + }, + { + "id": "siliconflow-cn", + "name": "SiliconFlow (China)", + "base_url": "https://api.siliconflow.cn/v1", + "protocol": "openai", + "api_key_env": "SILICON_API_KEY", + "api_key_prefix": "sk-", + "logo": "silicon.png", + "models": [ + { + "id": "deepseek-ai/DeepSeek-V3.2", + "name": "DeepSeek V3.2", + "max_input_tokens": 65536 + }, + { + "id": "deepseek-ai/DeepSeek-R1", + "name": "DeepSeek R1", + "max_input_tokens": 65536, + "reasoning": true + }, + { + "id": "Qwen/Qwen3-235B-A22B-Instruct-2507", + "name": "Qwen3 235B", + "max_input_tokens": 131072 + }, + { + "id": "moonshotai/Kimi-K2-Instruct", + "name": "Kimi K2", + "max_input_tokens": 131072 + }, + { + "id": "Pro/zai-org/GLM-4.7", + "name": "GLM-4.7", + "max_input_tokens": 131072 + } + ], + "vendor": "siliconflow", + "vendor_name": "SiliconFlow", + "variant": "china" + }, + { + "id": "siliconflow-intl", + "name": "SiliconFlow (International)", + "base_url": "https://api.siliconflow.com/v1", + "protocol": "openai", + "api_key_env": "SILICON_API_KEY", + "api_key_prefix": "sk-", + "logo": "silicon.png", + "models": [ + { + "id": "deepseek-ai/DeepSeek-V3.2", + "name": "DeepSeek V3.2", + "max_input_tokens": 65536 + }, + { + "id": "deepseek-ai/DeepSeek-R1", + "name": "DeepSeek R1", + "max_input_tokens": 65536, + "reasoning": true + }, + { + "id": "Qwen/Qwen3-235B-A22B-Instruct-2507", + "name": "Qwen3 235B", + "max_input_tokens": 131072 + }, + { + "id": "moonshotai/Kimi-K2-Instruct", + "name": "Kimi K2", + "max_input_tokens": 131072 + }, + { + "id": "Pro/zai-org/GLM-4.7", + "name": "GLM-4.7", + "max_input_tokens": 131072 + } + ], + "vendor": "siliconflow", + "vendor_name": "SiliconFlow", + "variant": "international" + }, + { + "id": "opencode-zen-openai", + "name": "OpenCode Zen (Compatible)", + "base_url": "https://opencode.ai/zen/v1", + "protocol": "openai", + "api_key_env": "OPENCODE_API_KEY", + "api_key_prefix": "sk-", + "logo": "opencode.svg", + "models": [ + { + "id": "grok-4.5", + "name": "Grok 4.5" + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "max_input_tokens": 1000000, + "max_output_tokens": 384000 + }, + { + "id": "deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "max_input_tokens": 1000000, + "max_output_tokens": 384000 + }, + { + "id": "kimi-k3", + "name": "Kimi K3", + "max_input_tokens": 1000000 + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "max_input_tokens": 262144 + }, + { + "id": "glm-5.2", + "name": "GLM 5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5.1", + "name": "GLM 5.1", + "max_input_tokens": 200000, + "max_output_tokens": 131072 + }, + { + "id": "minimax-m3", + "name": "MiniMax M3" + }, + { + "id": "minimax-m2.7", + "name": "MiniMax M2.7", + "max_input_tokens": 204800 + }, + { + "id": "big-pickle", + "name": "Big Pickle" + }, + { + "id": "deepseek-v4-flash-free", + "name": "DeepSeek V4 Flash Free", + "max_input_tokens": 1000000, + "max_output_tokens": 384000 + } + ], + "vendor": "opencode", + "vendor_name": "OpenCode", + "variant": "zen_compatible" + }, + { + "id": "opencode-zen-anthropic", + "name": "OpenCode Zen (Anthropic)", + "base_url": "https://opencode.ai/zen", + "protocol": "anthropic", + "api_key_env": "OPENCODE_API_KEY", + "api_key_prefix": "sk-", + "logo": "opencode.svg", + "models": [ + { + "id": "claude-opus-4-6", + "name": "Claude Opus 4.6", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + }, + { + "id": "claude-sonnet-4-6", + "name": "Claude Sonnet 4.6", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + }, + { + "id": "claude-haiku-4-5", + "name": "Claude Haiku 4.5", + "max_input_tokens": 200000, + "input": [ + "text", + "image" + ] + }, + { + "id": "qwen3.7-max", + "name": "Qwen3.7 Max", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.7-plus", + "name": "Qwen3.7 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.6-plus", + "name": "Qwen3.6 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + } + ], + "vendor": "opencode", + "vendor_name": "OpenCode", + "variant": "zen_anthropic" + }, + { + "id": "opencode-go-openai", + "name": "OpenCode Go (Compatible)", + "base_url": "https://opencode.ai/zen/go/v1", + "protocol": "openai", + "api_key_env": "OPENCODE_API_KEY", + "api_key_prefix": "sk-", + "logo": "opencode.svg", + "models": [ + { + "id": "grok-4.5", + "name": "Grok 4.5" + }, + { + "id": "glm-5.2", + "name": "GLM 5.2", + "max_input_tokens": 1000000, + "max_output_tokens": 131072 + }, + { + "id": "glm-5.1", + "name": "GLM 5.1", + "max_input_tokens": 200000, + "max_output_tokens": 131072 + }, + { + "id": "kimi-k3", + "name": "Kimi K3", + "max_input_tokens": 1000000 + }, + { + "id": "kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "max_input_tokens": 262144 + }, + { + "id": "kimi-k2.6", + "name": "Kimi K2.6", + "max_input_tokens": 262144 + }, + { + "id": "deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "max_input_tokens": 1000000, + "max_output_tokens": 384000 + }, + { + "id": "deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "max_input_tokens": 1000000, + "max_output_tokens": 384000 + }, + { + "id": "mimo-v2.5", + "name": "MiMo V2.5", + "max_input_tokens": 1048576, + "max_output_tokens": 131072 + }, + { + "id": "mimo-v2.5-pro", + "name": "MiMo V2.5 Pro", + "max_input_tokens": 1048576, + "max_output_tokens": 131072 + }, + { + "id": "hy3", + "name": "Hy3" + } + ], + "vendor": "opencode", + "vendor_name": "OpenCode", + "variant": "go_compatible" + }, + { + "id": "opencode-go-anthropic", + "name": "OpenCode Go (Anthropic)", + "base_url": "https://opencode.ai/zen/go", + "protocol": "anthropic", + "api_key_env": "OPENCODE_API_KEY", + "api_key_prefix": "sk-", + "logo": "opencode.svg", + "models": [ + { + "id": "minimax-m3", + "name": "MiniMax M3" + }, + { + "id": "minimax-m2.7", + "name": "MiniMax M2.7", + "max_input_tokens": 204800 + }, + { + "id": "minimax-m2.5", + "name": "MiniMax M2.5", + "max_input_tokens": 204800 + }, + { + "id": "qwen3.7-max", + "name": "Qwen3.7 Max", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.7-plus", + "name": "Qwen3.7 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + }, + { + "id": "qwen3.6-plus", + "name": "Qwen3.6 Plus", + "max_input_tokens": 1000000, + "max_output_tokens": 65536 + } + ], + "vendor": "opencode", + "vendor_name": "OpenCode", + "variant": "go_anthropic" + } +] From 81a5e80e74be14d087b7be9b94c60ebf07c8132e Mon Sep 17 00:00:00 2001 From: HUANG Cheng Date: Mon, 7 Sep 2026 17:05:24 +0800 Subject: [PATCH 3/3] refactor(providers): use bundled template as general harness fallback Move provider_template.json into the providers package and merge any missing harness ids from it, so new sites like Agent Plan are data-driven instead of hardcoded in presets.py. --- CHANGELOG.md | 1 + src/octop/infra/agents/providers/presets.py | 167 ++++++------------ .../agents/providers}/provider_template.json | 0 tests/unit/test_provider_preset_expansion.py | 11 ++ 4 files changed, 63 insertions(+), 116 deletions(-) rename {docs/examples => src/octop/infra/agents/providers}/provider_template.json (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index eda28b47..c8afed22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### 新增 - 火山引擎模型站点增加 Agent Plan(`/api/plan/v3`)及对应预设模型列表 +- 新增 Octop 内置 `provider_template.json` 作为 harness 目录兜底:harness 缺少的 provider id 从此补齐(同 id 仍以 harness 为准) ## [0.9.32] - 2026-09-06 diff --git a/src/octop/infra/agents/providers/presets.py b/src/octop/infra/agents/providers/presets.py index fdcdd5b3..82e365af 100644 --- a/src/octop/infra/agents/providers/presets.py +++ b/src/octop/infra/agents/providers/presets.py @@ -211,14 +211,64 @@ def _reasoning_profile(provider_id: str, model_id: str) -> dict[str, Any] | None return None +def _octop_provider_template_path() -> object: + """Path to Octop's bundled provider catalog fallback.""" + from importlib import resources + + return resources.files(__package__).joinpath("provider_template.json") + + +def _load_octop_provider_presets() -> list[dict[str, Any]]: + """Serialize Octop's bundled ``provider_template.json``.""" + from harness_agent.providers import load_provider_templates, serialize_provider_preset + + path = _octop_provider_template_path() + return [serialize_provider_preset(p) for p in load_provider_templates(str(path))] + + +def _provider_group_key(preset: dict[str, Any]) -> str: + return str(preset.get("provider_group") or preset.get("vendor") or "") + + +def _merge_octop_template_fallback(out: list[dict[str, Any]]) -> None: + """Fill gaps from Octop's catalog without overriding harness rows. + + For each preset id present in Octop's ``provider_template.json`` but missing + from ``out``, insert the Octop row after the last existing sibling of the + same vendor/group (so Agent Plan lands with other Volcano sites). Otherwise + append. Shared ids keep the harness definition. + """ + have = {str(p.get("id") or "") for p in out} + for row in _load_octop_provider_presets(): + pid = str(row.get("id") or "") + if not pid or pid in have: + continue + group = _provider_group_key(row) + insert_at = len(out) + if group: + for i, existing in enumerate(out): + if _provider_group_key(existing) == group: + insert_at = i + 1 + out.insert(insert_at, row) + have.add(pid) + + def load_provider_presets() -> list[dict[str, Any]]: - """Serialize harness-agent provider templates for API / CLI.""" + """Serialize provider templates for API / CLI. + + Source order: + + 1. harness-agent bundled ``provider_template.json`` + 2. Octop ``provider_template.json`` rows whose ids are still missing (fallback) + 3. Octop-only overlays (``openai-codex``, ``onnx``) when absent + """ from importlib import resources from harness_agent.providers import load_provider_templates, serialize_provider_preset bundled = resources.files("harness_agent.providers").joinpath("provider_template.json") out = [serialize_provider_preset(p) for p in load_provider_templates(str(bundled))] + _merge_octop_template_fallback(out) if not any(p.get("id") == "openai-codex" for p in out): out.insert( 0, @@ -269,121 +319,6 @@ def load_provider_presets() -> list[dict[str, Any]]: len(out), ) out.insert(insert_at, onnx_preset) - # Prefer harness-bundled Agent Plan when present; otherwise inject so Octop - # can ship the site before orcakit-harness-agent publishes the template row. - if not any(p.get("id") == "volcengine-cn-agentplan" for p in out): - agent_plan = { - "id": "volcengine-cn-agentplan", - "name": "Volcano Engine Agent Plan", - "base_url": "https://ark.cn-beijing.volces.com/api/plan/v3", - "protocol": "openai", - "api_key_prefix": "", - "models": [ - { - "id": "ark-code-latest", - "name": "Ark Code Latest (Auto)", - "max_input_tokens": 256000, - "max_output_tokens": 32000, - "input": ["text", "image"], - }, - { - "id": "doubao-seed-2.1-turbo", - "name": "Doubao Seed 2.1 Turbo", - "max_input_tokens": 256000, - "max_output_tokens": 65536, - "input": ["text", "image"], - }, - { - "id": "doubao-seed-evolving", - "name": "Doubao Seed Evolving", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text", "image"], - }, - { - "id": "glm-5.3", - "name": "GLM 5.3", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text"], - }, - { - "id": "glm-5.3-flash", - "name": "GLM 5.3 Flash", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text", "image"], - }, - { - "id": "glm-latest", - "name": "GLM Latest", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text"], - }, - { - "id": "deepseek-v4-flash", - "name": "DeepSeek V4 Flash", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text"], - }, - { - "id": "deepseek-v4-pro", - "name": "DeepSeek V4 Pro", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text"], - }, - { - "id": "doubao-seed-2.0-lite", - "name": "Doubao Seed 2.0 Lite", - "max_input_tokens": 256000, - "max_output_tokens": 65536, - "input": ["text", "image"], - }, - { - "id": "doubao-seed-2.0-mini", - "name": "Doubao Seed 2.0 Mini", - "max_input_tokens": 256000, - "max_output_tokens": 65536, - "input": ["text", "image"], - }, - { - "id": "minimax-m3", - "name": "MiniMax M3", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text", "image"], - }, - { - "id": "kimi-k2.7-code", - "name": "Kimi K2.7 Code", - "max_input_tokens": 256000, - "max_output_tokens": 32000, - "input": ["text", "image"], - }, - { - "id": "kimi-k3", - "name": "Kimi K3", - "max_input_tokens": 1024000, - "max_output_tokens": 65536, - "input": ["text", "image"], - }, - ], - "logo_id": "volces", - "vendor": "volcengine", - "vendor_name": "Volcano Engine", - "provider_group": "volcengine", - "provider_group_name": "Volcano Engine", - "variant": "agent_plan", - "provider_variant": "agent_plan", - } - insert_at = next( - (i + 1 for i, p in enumerate(out) if p.get("id") == "volcengine-cn-codingplan"), - len(out), - ) - out.insert(insert_at, agent_plan) for preset in out: provider_id = str(preset.get("id") or "") for model in preset.get("models") or []: diff --git a/docs/examples/provider_template.json b/src/octop/infra/agents/providers/provider_template.json similarity index 100% rename from docs/examples/provider_template.json rename to src/octop/infra/agents/providers/provider_template.json diff --git a/tests/unit/test_provider_preset_expansion.py b/tests/unit/test_provider_preset_expansion.py index 4f720128..155ed2fe 100644 --- a/tests/unit/test_provider_preset_expansion.py +++ b/tests/unit/test_provider_preset_expansion.py @@ -93,6 +93,17 @@ def test_load_provider_presets_integration() -> None: "deepseek-v4-flash", "kimi-k3", } <= agent_ids + # Fallback keeps Agent Plan adjacent to other Volcano Engine sites. + volc_ids = [p["id"] for p in presets if p.get("provider_group") == "volcengine"] + assert "volcengine-cn-agentplan" in volc_ids + assert volc_ids.index("volcengine-cn-codingplan") < volc_ids.index("volcengine-cn-agentplan") + + from octop.infra.agents.providers.presets import _load_octop_provider_presets + + octop_ids = {p["id"] for p in _load_octop_provider_presets()} + assert "volcengine-cn-agentplan" in octop_ids + # Shared ids stay on the harness definition (fallback must not duplicate). + assert len([p for p in presets if p["id"] == "volcengine-cn"]) == 1 opencode_ids = { "opencode-zen-openai",