merge: integrate origin/master (v0.5.50) into gitea/new_feature
- Resolve conflicts in chatCore handlers: keep apiKey/streamErrorPatterns from the details-filters feature, adopt origin's stripContinuityFields, customToolNames, cache-inclusive usage accounting, and Responses-API SSE→JSON conversion - Adopt origin's provider usage handlers (codebuddy-intl, qoder creds) and modality detection (audio/video inputs) - Keep requestDetails apiKey column (schema v2) + masked key persistence Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
@@ -279,7 +279,7 @@ export const PATTERN_CAPABILITIES = [
|
||||
{ pattern: "*minimax*", caps: { reasoning: true, thinkingFormat: "minimax", thinkingCanDisable: false, contextWindow: 200000, maxOutput: 131072 } },
|
||||
|
||||
// ── Xiaomi MiMo (vision, 1M / 262K ctx) ──────────────────────────
|
||||
{ pattern: "*mimo*v2.5*", caps: { vision: true, contextWindow: 1048576, maxOutput: 131072 } },
|
||||
{ pattern: "*mimo*v2.5*", caps: { vision: true, audioInput: true, videoInput: true, contextWindow: 1048576, maxOutput: 131072 } },
|
||||
{ pattern: "*mimo*omni*", caps: { vision: true, audioInput: true, contextWindow: 262144, maxOutput: 131072 } },
|
||||
{ pattern: "*mimo*", caps: { vision: true, contextWindow: 262144, maxOutput: 131072 } },
|
||||
|
||||
|
||||
@@ -141,6 +141,122 @@ export const PROVIDER_PRICING = {
|
||||
gh: {
|
||||
"gpt-5.3-codex": { input: 1.75, output: 14.00, cached: 0.175, reasoning: 14.00, cache_creation: 1.75 },
|
||||
},
|
||||
// TokenRouter — exact rates from https://api.tokenrouter.com/api/pricing ($1/1M tokens).
|
||||
// Ratio→USD: input = model_ratio×2, output = model_ratio×completion_ratio×2.
|
||||
// These override the canonical MODEL_PRICING/PATTERN_PRICING, whose rates often
|
||||
// differ from TokenRouter's reseller pricing.
|
||||
tokenrouter: {
|
||||
"MiniMax-M3": { input: 0.3, output: 1.2, cached: 0.06, reasoning: 1.2 },
|
||||
"anthropic/claude-fable-5": { input: 10, output: 50, cached: 1.0, cache_creation: 12.5, reasoning: 50 },
|
||||
"anthropic/claude-haiku-4.5": { input: 1.0, output: 5.0, cached: 0.1, cache_creation: 1.25, reasoning: 5.0 },
|
||||
"anthropic/claude-opus-4.5": { input: 5.0, output: 25.0, cached: 0.5, cache_creation: 6.25, reasoning: 25.0 },
|
||||
"anthropic/claude-opus-4.6": { input: 5.0, output: 25.0, cached: 0.5, cache_creation: 6.25, reasoning: 25.0 },
|
||||
"anthropic/claude-opus-4.7": { input: 5.0, output: 25.0, cached: 0.5, cache_creation: 6.25, reasoning: 25.0 },
|
||||
"anthropic/claude-opus-4.7-fast": { input: 30, output: 150, cached: 3.0, reasoning: 150 },
|
||||
"anthropic/claude-opus-4.8": { input: 5.0, output: 25.0, cached: 0.5, cache_creation: 6.25, reasoning: 25.0 },
|
||||
"anthropic/claude-opus-4.8-fast": { input: 10, output: 50, cached: 1.0, cache_creation: 12.5, reasoning: 50 },
|
||||
"anthropic/claude-opus-5": { input: 5.0, output: 25.0, cached: 0.5, cache_creation: 6.25, reasoning: 25.0 },
|
||||
"anthropic/claude-opus-5-fast": { input: 10, output: 50, cached: 1.0, cache_creation: 12.5, reasoning: 50 },
|
||||
"anthropic/claude-sonnet-4": { input: 3.0, output: 15.0, cached: 0.3, cache_creation: 3.75, reasoning: 15.0 },
|
||||
"anthropic/claude-sonnet-4.5": { input: 3.0, output: 15.0, cached: 0.3, cache_creation: 3.75, reasoning: 15.0 },
|
||||
"anthropic/claude-sonnet-4.6": { input: 3.0, output: 15.0, cached: 0.3, cache_creation: 3.75, reasoning: 15.0 },
|
||||
"anthropic/claude-sonnet-5": { input: 2, output: 10, cached: 0.2, reasoning: 10 },
|
||||
"claude-opus-4-8-m-aws": { input: 5.0, output: 25.0, cached: 0.5, cache_creation: 6.25, reasoning: 25.0 },
|
||||
"deepseek/deepseek-v3.2": { input: 0.26, output: 0.38, cached: 0.13, reasoning: 0.38 },
|
||||
"deepseek/deepseek-v4-flash": { input: 0.14, output: 0.28, cached: 0.0028, reasoning: 0.28 },
|
||||
"deepseek/deepseek-v4-flash-0731": { input: 0.14, output: 0.28, cached: 0.0028, reasoning: 0.28 },
|
||||
"deepseek/deepseek-v4-pro": { input: 0.435, output: 0.87, cached: 0.003625, reasoning: 0.87 },
|
||||
"ex/gpt-5.4": { input: 2.5, output: 15.0, cached: 0.25, reasoning: 15.0 },
|
||||
"google/gemini-2.5-flash-image": { input: 0.3, output: 2.5, reasoning: 2.5 },
|
||||
"google/gemini-3-flash-preview": { input: 0.5, output: 3.0, cached: 0.05, cache_creation: 0.08333, reasoning: 3.0 },
|
||||
"google/gemini-3-pro-image-preview": { input: 2, output: 12, reasoning: 12 },
|
||||
"google/gemini-3.1-flash-image-preview": { input: 0.5, output: 3.0, reasoning: 3.0 },
|
||||
"google/gemini-3.1-flash-lite-image": { input: 0.25, output: 1.5, reasoning: 1.5 },
|
||||
"google/gemini-3.1-pro-preview": { input: 2, output: 12, cached: 0.2, cache_creation: 0.375, reasoning: 12 },
|
||||
"google/gemini-3.5-flash": { input: 1.5, output: 9.0, cached: 0.15, cache_creation: 0.08333, reasoning: 9.0 },
|
||||
"google/gemini-3.5-flash-lite": { input: 0.3, output: 2.5, cached: 0.03, cache_creation: 0.08333, reasoning: 2.5 },
|
||||
"google/gemini-3.6-flash": { input: 1.5, output: 7.5, cached: 0.15, cache_creation: 0.08333, reasoning: 7.5 },
|
||||
"google/gemini-embedding-2": { input: 1.0, output: 6.0, cached: 0.1, reasoning: 6.0 },
|
||||
"google/gemma-4-26b-a4b-it": { input: 0.06, output: 0.33, reasoning: 0.33 },
|
||||
"kling-3.0-turbo": { input: 2.1, output: 2.1, reasoning: 2.1 },
|
||||
"microsoft/mai-image-2.5": { input: 5.0, output: 47.0, reasoning: 47.0 },
|
||||
"minimax/minimax-m2-her": { input: 0.3, output: 1.2, cached: 0.03, reasoning: 1.2 },
|
||||
"minimax/minimax-m2.1": { input: 0.3, output: 1.2, cached: 0.03, reasoning: 1.2 },
|
||||
"minimax/minimax-m2.1-highspeed": { input: 0.6, output: 2.4, cached: 0.06, reasoning: 2.4 },
|
||||
"minimax/minimax-m2.5": { input: 0.3, output: 1.2, cached: 0.03, reasoning: 1.2 },
|
||||
"minimax/minimax-m2.7": { input: 0.3, output: 1.2, cached: 0.06, reasoning: 1.2 },
|
||||
"minimax/minimax-m2.7-highspeed": { input: 0.6, output: 2.4, cached: 0.06, reasoning: 2.4 },
|
||||
"miromind/mirothinker-1-7-deepresearch": { input: 4, output: 25.0, reasoning: 25.0 },
|
||||
"miromind/mirothinker-1-7-deepresearch-mini": { input: 1.25, output: 10.0, reasoning: 10.0 },
|
||||
"mistralai/devstral-2512": { input: 0.4, output: 2.0, cached: 0.04, reasoning: 2.0 },
|
||||
"mistralai/mistral-medium-3-5": { input: 1.5, output: 7.5, reasoning: 7.5 },
|
||||
"mistralai/mistral-small-2603": { input: 0.15, output: 0.6, cached: 0.015, reasoning: 0.6 },
|
||||
"mistralai/voxtral-small-24b-2507": { input: 0.1, output: 0.3, cached: 0.01, reasoning: 0.3 },
|
||||
"moonshotai/kimi-k2.5": { input: 0.6, output: 3.0, cached: 0.1, reasoning: 3.0 },
|
||||
"moonshotai/kimi-k2.6": { input: 0.95, output: 4.0, cached: 0.16, reasoning: 4.0 },
|
||||
"moonshotai/kimi-k2.7-code": { input: 0.9286, output: 3.8571, cached: 0.1857, reasoning: 3.8571 },
|
||||
"moonshotai/kimi-k3": { input: 3.0, output: 15.0, cached: 0.3, reasoning: 15.0 },
|
||||
"nvidia/nemotron-3-super-120b-a12b": { input: 0.3, output: 0.9, cached: 0.1, reasoning: 0.9 },
|
||||
"openai/gpt-4o-mini": { input: 0.15, output: 0.6, cached: 0.075, reasoning: 0.6 },
|
||||
"openai/gpt-5": { input: 1.25, output: 10.0, cached: 0.125, reasoning: 10.0 },
|
||||
"openai/gpt-5-image": { input: 10, output: 40, cached: 2.5, reasoning: 40 },
|
||||
"openai/gpt-5-image-mini": { input: 2.5, output: 8.0, cached: 0.25, reasoning: 8.0 },
|
||||
"openai/gpt-5-mini": { input: 0.25, output: 2.0, cached: 0.025, reasoning: 2.0 },
|
||||
"openai/gpt-5.2": { input: 1.75, output: 14.0, cached: 0.175, reasoning: 14.0 },
|
||||
"openai/gpt-5.3-codex": { input: 1.75, output: 14.0, cached: 0.175, reasoning: 14.0 },
|
||||
"openai/gpt-5.4": { input: 2.5, output: 15.0, cached: 0.25, reasoning: 15.0 },
|
||||
"openai/gpt-5.4-image-2": { input: 8, output: 30.0, cached: 2.0, reasoning: 30.0 },
|
||||
"openai/gpt-5.4-mini": { input: 0.75, output: 4.5, cached: 0.075, reasoning: 4.5 },
|
||||
"openai/gpt-5.4-nano": { input: 0.2, output: 1.25, cached: 0.02, reasoning: 1.25 },
|
||||
"openai/gpt-5.4-pro": { input: 30, output: 180, reasoning: 180 },
|
||||
"openai/gpt-5.5": { input: 5.0, output: 30.0, cached: 0.5, reasoning: 30.0 },
|
||||
"openai/gpt-5.5-pro": { input: 30, output: 180, reasoning: 180 },
|
||||
"openai/gpt-5.6-luna": { input: 0.2, output: 1.2, cached: 0.02, cache_creation: 0.25, reasoning: 1.2 },
|
||||
"openai/gpt-5.6-sol": { input: 5.0, output: 30.0, cached: 0.5, cache_creation: 6.25, reasoning: 30.0 },
|
||||
"openai/gpt-5.6-terra": { input: 2, output: 12, cached: 0.2, cache_creation: 2.5, reasoning: 12 },
|
||||
"openai/gpt-audio": { input: 2.5, output: 10.0, reasoning: 10.0 },
|
||||
"openai/gpt-audio-mini": { input: 0.6, output: 2.4, reasoning: 2.4 },
|
||||
"openai/gpt-oss-120b": { input: 0.039, output: 0.18, reasoning: 0.18 },
|
||||
"qwen/qwen3-coder-next": { input: 0.12, output: 0.75, cached: 0.06, reasoning: 0.75 },
|
||||
"qwen/qwen3.5-122b-a10b": { input: 0.26, output: 2.08, reasoning: 2.08 },
|
||||
"qwen/qwen3.5-35b-a3b": { input: 0.1625, output: 1.3, reasoning: 1.3 },
|
||||
"qwen/qwen3.5-397b-a17b": { input: 0.39, output: 2.34, reasoning: 2.34 },
|
||||
"qwen/qwen3.5-9b": { input: 0.1, output: 0.15, reasoning: 0.15 },
|
||||
"qwen/qwen3.5-flash": { input: 0.1048, output: 0.4194, reasoning: 0.4194 },
|
||||
"qwen/qwen3.5-plus-02-15": { input: 0.26, output: 1.56, reasoning: 1.56 },
|
||||
"qwen/qwen3.6-plus": { input: 0.54, output: 3.21, reasoning: 3.21 },
|
||||
"qwen/qwen3.7-max": { input: 1.25, output: 3.75, cached: 0.25, reasoning: 3.75 },
|
||||
"qwen/qwen3.7-plus": { input: 0.4, output: 1.6, cached: 0.08, reasoning: 1.6 },
|
||||
"qwen/qwen3.8-max": { input: 2, output: 6, cached: 0.25, cache_creation: 2.5, reasoning: 6 },
|
||||
"qwen3.5-omni-plus": { input: 1.0, output: 5.7143, reasoning: 5.7143 },
|
||||
"qwen3.6-flash": { input: 0.171, output: 1.029, cached: 0.017, cache_creation: 0.214, reasoning: 1.029 },
|
||||
"sakana/fugu-ultra": { input: 5.0, output: 30.0, cached: 0.5, reasoning: 30.0 },
|
||||
"seed-2-0-code-preview-260328": { input: 1.0, output: 6.0, cached: 0.2, cache_creation: 0.008333, reasoning: 6.0 },
|
||||
"seed-2-0-lite-260428": { input: 0.5, output: 4.0, cached: 0.1, cache_creation: 0.008333, reasoning: 4.0 },
|
||||
"seed-2-0-mini-260428": { input: 0.2, output: 0.8, cached: 0.04, cache_creation: 0.00833, reasoning: 0.8 },
|
||||
"seed-2-0-pro-260328": { input: 1.0, output: 6.0, cached: 0.2, cache_creation: 0.008333, reasoning: 6.0 },
|
||||
"stepfun/step-3.5-flash": { input: 0.1, output: 0.3, cached: 0.02, reasoning: 0.3 },
|
||||
"stepfun/step-3.7-flash": { input: 0.2, output: 1.15, cached: 0.04, reasoning: 1.15 },
|
||||
"tencent/hy3-preview": { input: 0.066, output: 0.26, cached: 0.029, reasoning: 0.26 },
|
||||
"x-ai/grok-4.1-fast": { input: 0.2, output: 0.5, cached: 0.05, reasoning: 0.5 },
|
||||
"x-ai/grok-4.20-beta": { input: 2, output: 6, cached: 0.2, reasoning: 6 },
|
||||
"x-ai/grok-4.3": { input: 1.25, output: 2.5, cached: 0.2, reasoning: 2.5 },
|
||||
"x-ai/grok-4.5": { input: 2, output: 6, cached: 0.5, reasoning: 6 },
|
||||
"x-ai/grok-build-0.1": { input: 1.0, output: 2.0, cached: 0.2, reasoning: 2.0 },
|
||||
"xiaomi/mimo-v2-flash": { input: 0.1, output: 0.3, cached: 0.01, reasoning: 0.3 },
|
||||
"xiaomi/mimo-v2-omni": { input: 0.4, output: 2.0, cached: 0.08, reasoning: 2.0 },
|
||||
"xiaomi/mimo-v2-pro": { input: 1.0, output: 3.0, cached: 0.2, reasoning: 3.0 },
|
||||
"xiaomi/mimo-v2.5": { input: 0.4, output: 2.0, cached: 0.08, reasoning: 2.0 },
|
||||
"xiaomi/mimo-v2.5-pro": { input: 1.0, output: 3.0, cached: 0.2, reasoning: 3.0 },
|
||||
"z-ai/glm-4.5-air": { input: 0.13, output: 0.85, cached: 0.025, reasoning: 0.85 },
|
||||
"z-ai/glm-4.6": { input: 0.6, output: 2.2, cached: 0.11, reasoning: 2.2 },
|
||||
"z-ai/glm-4.6v": { input: 0.3, output: 0.9, reasoning: 0.9 },
|
||||
"z-ai/glm-4.7": { input: 0.6, output: 2.2, cached: 0.11, reasoning: 2.2 },
|
||||
"z-ai/glm-5": { input: 1.0, output: 3.2, cached: 0.2, reasoning: 3.2 },
|
||||
"z-ai/glm-5-turbo": { input: 1.2, output: 4.0, cached: 0.24, reasoning: 4.0 },
|
||||
"z-ai/glm-5.1": { input: 1.05, output: 3.5, cached: 0.525, reasoning: 3.5 },
|
||||
"z-ai/glm-5.2": { input: 1.4, output: 4.4, cached: 0.26, reasoning: 4.4 },
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,8 +76,7 @@ export default {
|
||||
apiVersion: "v1internal",
|
||||
loadCodeAssistEndpoint: "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist",
|
||||
onboardUserEndpoint: "https://cloudcode-pa.googleapis.com/v1internal:onboardUser",
|
||||
loadCodeAssistUserAgent: "google-api-nodejs-client/9.15.1",
|
||||
loadCodeAssistApiClient: "google-cloud-sdk vscode_cloudshelleditor/0.1",
|
||||
loadCodeAssistUserAgent: ANTIGRAVITY_IDE_USER_AGENT,
|
||||
refreshLeadMs: 300000,
|
||||
},
|
||||
features: {
|
||||
|
||||
@@ -49,9 +49,6 @@ export default {
|
||||
header: "Authorization",
|
||||
scheme: "bearer",
|
||||
},
|
||||
hooks: [
|
||||
"claudeOverlay",
|
||||
],
|
||||
},
|
||||
usage: {
|
||||
oauthUrl: "https://api.anthropic.com/api/oauth/usage",
|
||||
|
||||
@@ -19,6 +19,8 @@ export default {
|
||||
},
|
||||
},
|
||||
category: "freeTier",
|
||||
authType: "apikey",
|
||||
authModes: ["apikey"],
|
||||
hasProviderSpecificData: true,
|
||||
transport: {
|
||||
baseUrl: "https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1/chat/completions",
|
||||
|
||||
@@ -38,6 +38,10 @@ export default {
|
||||
header: "Authorization",
|
||||
scheme: "bearer",
|
||||
},
|
||||
// Intl billing endpoint mirrors CN shape (data.Response.Data.Accounts[]).
|
||||
usage: {
|
||||
url: "https://www.codebuddy.ai/v2/billing/meter/get-user-resource",
|
||||
},
|
||||
},
|
||||
// Same model lineup exposed by the CN gateway — intl backend is the same catalog.
|
||||
models: [
|
||||
|
||||
@@ -75,7 +75,6 @@ import p72 from "./perplexity.js";
|
||||
import p73 from "./perplexity-agent.js";
|
||||
import p74 from "./playht.js";
|
||||
import p75 from "./qoder.js";
|
||||
import p76 from "./qwen.js";
|
||||
import p77 from "./recraft.js";
|
||||
import p78 from "./runwayml.js";
|
||||
import p79 from "./sdwebui.js";
|
||||
@@ -116,6 +115,10 @@ import p113 from "./morph.js";
|
||||
// import p114 from "./devin-cli.js";
|
||||
// import p104 from "./windsurf.js";
|
||||
import p115 from "./poolside.js";
|
||||
import p116 from "./tokenrouter.js";
|
||||
import p117 from "./selfhosted-stt.js";
|
||||
import p118 from "./selfhosted-tts.js";
|
||||
import p119 from "./selfhosted-embedding.js";
|
||||
|
||||
export default [
|
||||
p0,
|
||||
@@ -194,7 +197,6 @@ export default [
|
||||
p73,
|
||||
p74,
|
||||
p75,
|
||||
p76,
|
||||
p77,
|
||||
p78,
|
||||
p79,
|
||||
@@ -233,4 +235,8 @@ export default [
|
||||
// p114, // devin-cli — hidden, spawns local agent with shell/fs access
|
||||
// p104, // windsurf — hidden, no tool calling
|
||||
p115,
|
||||
p116,
|
||||
p117,
|
||||
p118,
|
||||
p119,
|
||||
];
|
||||
|
||||
@@ -15,6 +15,8 @@ export default {
|
||||
},
|
||||
},
|
||||
category: "freeTier",
|
||||
authType: "apikey",
|
||||
authModes: ["apikey"],
|
||||
transport: {
|
||||
baseUrl: "https://ollama.com/api/chat",
|
||||
validateUrl: "https://ollama.com/api/tags",
|
||||
@@ -32,5 +34,6 @@ export default {
|
||||
serviceKinds: ["llm"],
|
||||
features: {
|
||||
usage: true,
|
||||
usageApikey: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -52,5 +52,7 @@ export default {
|
||||
},
|
||||
features: {
|
||||
usage: true,
|
||||
// PAT (apikey) connections also carry quota usage (via job-token exchange).
|
||||
usageApikey: true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
export default {
|
||||
id: "qwen",
|
||||
hidden: true,
|
||||
priority: 130,
|
||||
alias: "qw",
|
||||
display: {
|
||||
name: "Qwen Code",
|
||||
icon: "psychology",
|
||||
color: "#10B981",
|
||||
website: "https://chat.qwen.ai",
|
||||
notice: {
|
||||
signupUrl: "https://chat.qwen.ai",
|
||||
},
|
||||
},
|
||||
category: "oauth",
|
||||
transport: {
|
||||
baseUrl: "https://portal.qwen.ai/v1/chat/completions",
|
||||
},
|
||||
models: [
|
||||
{ id: "qwen3-coder-plus", name: "Qwen3 Coder Plus" },
|
||||
{ id: "qwen3-coder-flash", name: "Qwen3 Coder Flash" },
|
||||
{ id: "vision-model", name: "Qwen3 Vision Model" },
|
||||
{ id: "coder-model", name: "Qwen3.6 Coder Model" },
|
||||
],
|
||||
oauth: {
|
||||
clientId: "f0304373b74a44d2b584a3fb70ca9e56",
|
||||
deviceCodeUrl: "https://chat.qwen.ai/api/v1/oauth2/device/code",
|
||||
tokenUrl: "https://chat.qwen.ai/api/v1/oauth2/token",
|
||||
scope: "openid profile email model.completion",
|
||||
codeChallengeMethod: "S256",
|
||||
refreshLeadMs: 1200000,
|
||||
},
|
||||
};
|
||||
73
open-sse/providers/registry/selfhosted-embedding.js
Normal file
73
open-sse/providers/registry/selfhosted-embedding.js
Normal file
@@ -0,0 +1,73 @@
|
||||
// Self-hosted, OpenAI-compatible embeddings (llama.cpp / llama-server, vLLM,
|
||||
// Infinity, text-embeddings-inference, ...) — the embeddings counterpart of
|
||||
// selfhosted-stt and selfhosted-tts.
|
||||
//
|
||||
// Routing a self-hosted embeddings server already WORKS today, via a custom
|
||||
// provider node: getEmbeddingAdapter() matches `openai-compatible-*` and
|
||||
// `custom-embedding-*` and returns openaiCompatNode, whose buildUrl reads
|
||||
// creds.providerSpecificData.baseUrl. What is missing is a first-class provider,
|
||||
// and the gap is visible rather than functional:
|
||||
//
|
||||
// /v1/embeddings on such a node -> 200, correct vectors
|
||||
// the Embedding page in the dashboard -> the node is not listed at all
|
||||
//
|
||||
// The page renders getProvidersByKind("embedding") plus provider nodes filtered
|
||||
// to `type === "custom-embedding"`. A node created as `openai-compatible` — the
|
||||
// natural choice when ONE endpoint serves chat and embeddings behind the same
|
||||
// front door — satisfies neither, so a working self-hosted embeddings endpoint is
|
||||
// invisible on the page whose job is to show embeddings providers. Diagnosed on a
|
||||
// deployment serving Qwen3-Embedding-8B at 4096 dimensions through exactly that
|
||||
// shape (2026-08-04).
|
||||
//
|
||||
// Declaring it as a provider with serviceKinds: ["embedding"] puts it on the page
|
||||
// beside Voyage, Jina and the rest, and keeps the per-connection baseUrl that
|
||||
// makes self-hosting possible at all.
|
||||
//
|
||||
// authType is "apikey" rather than "none" for the same reason as the STT and TTS
|
||||
// entries: it is what gives the connection a credentials record, and
|
||||
// providerSpecificData.baseUrl lives there. Local servers ignore the key itself;
|
||||
// any non-empty value works.
|
||||
export default {
|
||||
id: "selfhosted-embedding",
|
||||
priority: 50,
|
||||
hasFree: true,
|
||||
alias: "selfhosted-embedding",
|
||||
display: {
|
||||
name: "Self-hosted Embedding",
|
||||
icon: "cloud",
|
||||
color: "#ffffffff",
|
||||
textIcon: "SE",
|
||||
website: "https://github.com/ggml-org/llama.cpp",
|
||||
},
|
||||
category: "apikey",
|
||||
auth: {
|
||||
apiKey: {
|
||||
// Note the /v1: the adapter appends "/embeddings" to whatever it is given,
|
||||
// so a bare http://host:8080 resolves to http://host:8080/embeddings and
|
||||
// misses the OpenAI route entirely. Give it the OpenAI base, the same value
|
||||
// an OpenAI client would use. A trailing /embeddings is tolerated.
|
||||
text: "Set providerSpecificData.baseUrl to the OpenAI base URL, e.g. http://host:8080/v1 — /embeddings is appended. The API key is not checked by local servers; any value works.",
|
||||
},
|
||||
},
|
||||
// A self-hosted server serves whatever model it was started with, so the id
|
||||
// here is a placeholder for the UI: the request passes `model` straight
|
||||
// through, and llama-server ignores an unknown value rather than rejecting it.
|
||||
// Dimensions are deliberately NOT declared — they are a property of the loaded
|
||||
// weights, and asserting a number here would be a guess that silently
|
||||
// contradicts the server.
|
||||
models: [
|
||||
{ id: "embedding", name: "Self-hosted embedding model", kind: "embedding" },
|
||||
],
|
||||
serviceKinds: ["embedding"],
|
||||
embeddingConfig: {
|
||||
// Declared for shape-consistency with the other embedding providers, and
|
||||
// read by the UI — but NOT by the request path. openaiCompatNode resolves the
|
||||
// URL purely from creds.providerSpecificData.baseUrl (falling back to
|
||||
// api.openai.com), so unlike a fixed cloud provider this baseUrl never
|
||||
// reaches the wire. Stated plainly because a reader would otherwise
|
||||
// reasonably assume it is the default endpoint.
|
||||
baseUrl: "http://localhost:8080/v1/embeddings",
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
},
|
||||
};
|
||||
48
open-sse/providers/registry/selfhosted-stt.js
Normal file
48
open-sse/providers/registry/selfhosted-stt.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// Self-hosted, OpenAI-compatible speech-to-text (whisper.cpp, faster-whisper,
|
||||
// Speaches, vLLM-served Whisper, ...).
|
||||
//
|
||||
// Every other STT provider here is a named cloud service with a fixed endpoint.
|
||||
// This one exists so a locally-served /v1/audio/transcriptions can be used at
|
||||
// all: set the connection's providerSpecificData.baseUrl to the full URL of the
|
||||
// endpoint, exactly as the custom embedding providers already work.
|
||||
//
|
||||
// sttCore dispatches on `format`; anything that is not one of the five named
|
||||
// cloud shapes falls through to transcribeOpenAICompatible, which POSTs the
|
||||
// standard multipart body (file, model, and optional language / prompt /
|
||||
// response_format / temperature). That is precisely what whisper.cpp's OpenAI
|
||||
// endpoint accepts.
|
||||
//
|
||||
// authType is "apikey" rather than "none" so the connection carries a
|
||||
// credentials record — which is where providerSpecificData.baseUrl lives. Local
|
||||
// servers ignore the key itself; any non-empty value works.
|
||||
export default {
|
||||
id: "selfhosted-stt",
|
||||
priority: 50,
|
||||
hasFree: true,
|
||||
alias: "selfhosted-stt",
|
||||
display: {
|
||||
name: "Self-hosted STT",
|
||||
icon: "cloud",
|
||||
color: "#ffffffff",
|
||||
textIcon: "ST",
|
||||
website: "https://github.com/ggml-org/whisper.cpp",
|
||||
},
|
||||
category: "apikey",
|
||||
auth: {
|
||||
apiKey: {
|
||||
text: "Set providerSpecificData.baseUrl to the full transcriptions URL, e.g. http://host:8080/v1/audio/transcriptions. The API key is not checked by local servers; any value works.",
|
||||
},
|
||||
},
|
||||
models: [
|
||||
{ id: "whisper-1", name: "Whisper (self-hosted)", params: ["language", "response_format", "temperature", "prompt"], kind: "stt" },
|
||||
],
|
||||
serviceKinds: ["stt"],
|
||||
sttConfig: {
|
||||
// Overridden per connection by providerSpecificData.baseUrl; this default
|
||||
// only makes the provider usable out of the box on a same-host deployment.
|
||||
baseUrl: "http://localhost:8080/v1/audio/transcriptions",
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
format: "openai",
|
||||
},
|
||||
};
|
||||
44
open-sse/providers/registry/selfhosted-tts.js
Normal file
44
open-sse/providers/registry/selfhosted-tts.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// Self-hosted, OpenAI-compatible text-to-speech (Kokoro-FastAPI, openedai-speech,
|
||||
// vLLM-served TTS, ...) — the TTS counterpart of selfhosted-stt.
|
||||
//
|
||||
// Every other self-hostable TTS provider here (coqui, tortoise) carries a FIXED
|
||||
// localhost baseUrl in its registry entry and `authType: "none"`, and the generic
|
||||
// dispatcher reads `ttsConfig.baseUrl` from that entry rather than from the
|
||||
// connection. So there was no way to point TTS at a server on another host.
|
||||
//
|
||||
// `authType: "apikey"` is what makes the override possible at all: it gives the
|
||||
// connection a credentials record, which is where providerSpecificData.baseUrl
|
||||
// lives. Local servers ignore the key; any non-empty value works.
|
||||
export default {
|
||||
id: "selfhosted-tts",
|
||||
priority: 50,
|
||||
hasFree: true,
|
||||
alias: "selfhosted-tts",
|
||||
display: {
|
||||
name: "Self-hosted TTS",
|
||||
icon: "cloud",
|
||||
color: "#ffffffff",
|
||||
textIcon: "TT",
|
||||
website: "https://github.com/remsky/Kokoro-FastAPI",
|
||||
},
|
||||
category: "apikey",
|
||||
auth: {
|
||||
apiKey: {
|
||||
text: "Set providerSpecificData.baseUrl to the server root, e.g. http://host:8080 — /v1/audio/speech is appended. The API key is not checked by local servers; any value works.",
|
||||
},
|
||||
},
|
||||
// Voice is selected as "<model>/<voice>", the same convention the OpenAI TTS
|
||||
// adapter uses, so existing clients need no special casing.
|
||||
models: [
|
||||
{ id: "kokoro", name: "Kokoro (self-hosted)", params: ["voice", "response_format", "speed"], kind: "tts" },
|
||||
],
|
||||
serviceKinds: ["tts"],
|
||||
ttsConfig: {
|
||||
// Overridden per connection by providerSpecificData.baseUrl; this default
|
||||
// only makes the provider usable on a same-host deployment.
|
||||
baseUrl: "http://localhost:8880",
|
||||
defaultModel: "kokoro",
|
||||
authType: "apikey",
|
||||
format: "openai-speech",
|
||||
},
|
||||
};
|
||||
162
open-sse/providers/registry/tokenrouter.js
Normal file
162
open-sse/providers/registry/tokenrouter.js
Normal file
@@ -0,0 +1,162 @@
|
||||
export default {
|
||||
id: "tokenrouter",
|
||||
alias: "tokenrouter",
|
||||
aliases: ["tr"],
|
||||
uiAlias: "tokenrouter",
|
||||
display: {
|
||||
name: "TokenRouter",
|
||||
icon: "hub",
|
||||
color: "#0EA5E9",
|
||||
textIcon: "TR",
|
||||
website: "https://www.tokenrouter.com",
|
||||
notice: {
|
||||
text: "OpenAI-compatible gateway. 300+ models (OpenAI, Claude, Gemini, Qwen, DeepSeek, Kimi, GLM, dsb).",
|
||||
apiKeyUrl: "https://www.tokenrouter.com",
|
||||
},
|
||||
},
|
||||
category: "apikey",
|
||||
thinkingConfig: {
|
||||
options: ["low", "medium", "high", "xhigh", "max"],
|
||||
defaultMode: "high",
|
||||
},
|
||||
transport: {
|
||||
baseUrl: "https://api.tokenrouter.com/v1/chat/completions",
|
||||
validateUrl: "https://api.tokenrouter.com/v1/models",
|
||||
thinkingFormat: "tokenrouter",
|
||||
},
|
||||
// Seed snapshot from live /v1/models (120 entries). Latest catalogue is
|
||||
// fetched via modelsFetcher; other ids still accepted via passthroughModels.
|
||||
models: [
|
||||
{ id: "MiniMax-Hailuo-2.3", name: "Minimax Hailuo 2.3", kind: "video" },
|
||||
{ id: "MiniMax-M3", name: "Minimax M3" },
|
||||
{ id: "anthropic/claude-fable-5", name: "Claude Fable 5" },
|
||||
{ id: "anthropic/claude-haiku-4.5", name: "Claude Haiku 4.5" },
|
||||
{ id: "anthropic/claude-opus-4.5", name: "Claude Opus 4.5" },
|
||||
{ id: "anthropic/claude-opus-4.6", name: "Claude Opus 4.6" },
|
||||
{ id: "anthropic/claude-opus-4.7", name: "Claude Opus 4.7" },
|
||||
{ id: "anthropic/claude-opus-4.7-fast", name: "Claude Opus 4.7 Fast" },
|
||||
{ id: "anthropic/claude-opus-4.8", name: "Claude Opus 4.8" },
|
||||
{ id: "anthropic/claude-opus-4.8-fast", name: "Claude Opus 4.8 Fast" },
|
||||
{ id: "anthropic/claude-opus-5", name: "Claude Opus 5" },
|
||||
{ id: "anthropic/claude-opus-5-fast", name: "Claude Opus 5 Fast" },
|
||||
{ id: "anthropic/claude-sonnet-4", name: "Claude Sonnet 4" },
|
||||
{ id: "anthropic/claude-sonnet-4.5", name: "Claude Sonnet 4.5" },
|
||||
{ id: "anthropic/claude-sonnet-4.6", name: "Claude Sonnet 4.6" },
|
||||
{ id: "anthropic/claude-sonnet-5", name: "Claude Sonnet 5" },
|
||||
{ id: "bytedance-seed/seedream-4.5", name: "Seedream 4.5", kind: "image" },
|
||||
{ id: "bytedance-seed/seedream-5.0-lite", name: "Seedream 5.0 Lite", kind: "image" },
|
||||
{ id: "bytedance-seed/seedream-5.0-pro", name: "Seedream 5.0 Pro", kind: "image" },
|
||||
{ id: "claude-haiku-4-5", name: "Claude Haiku 4 5" },
|
||||
{ id: "claude-opus-4-8-m-aws", name: "Claude Opus 4 8 M Aws" },
|
||||
{ id: "deepseek/deepseek-v3.2", name: "Deepseek V3.2" },
|
||||
{ id: "deepseek/deepseek-v4-flash", name: "Deepseek V4 Flash" },
|
||||
{ id: "deepseek/deepseek-v4-flash-0731", name: "Deepseek V4 Flash 0731" },
|
||||
{ id: "deepseek/deepseek-v4-pro", name: "Deepseek V4 Pro" },
|
||||
{ id: "ex/gpt-5.4", name: "Gpt 5.4" },
|
||||
{ id: "google/gemini-2.5-flash-image", name: "Gemini 2.5 Flash Image" },
|
||||
{ id: "google/gemini-3-flash-preview", name: "Gemini 3 Flash Preview" },
|
||||
{ id: "google/gemini-3-pro-image-preview", name: "Gemini 3 Pro Image Preview" },
|
||||
{ id: "google/gemini-3.1-flash-image-preview", name: "Gemini 3.1 Flash Image Preview" },
|
||||
{ id: "google/gemini-3.1-flash-lite-image", name: "Gemini 3.1 Flash Lite Image" },
|
||||
{ id: "google/gemini-3.1-pro-preview", name: "Gemini 3.1 Pro Preview" },
|
||||
{ id: "google/gemini-3.5-flash", name: "Gemini 3.5 Flash" },
|
||||
{ id: "google/gemini-3.5-flash-lite", name: "Gemini 3.5 Flash Lite" },
|
||||
{ id: "google/gemini-3.6-flash", name: "Gemini 3.6 Flash" },
|
||||
{ id: "google/gemini-embedding-2", name: "Gemini Embedding 2" },
|
||||
{ id: "google/gemma-4-26b-a4b-it", name: "Gemma 4 26B A4B It" },
|
||||
{ id: "happyhorse-1.0-t2v", name: "Happyhorse 1.0 T2V", kind: "video" },
|
||||
{ id: "kling-3.0-turbo", name: "Kling 3.0 Turbo", kind: "video" },
|
||||
{ id: "kling-v2-6", name: "Kling V2 6", kind: "video" },
|
||||
{ id: "kling-v3", name: "Kling V3", kind: "video" },
|
||||
{ id: "kling-v3-omni", name: "Kling V3 Omni", kind: "video" },
|
||||
{ id: "microsoft/mai-image-2.5", name: "Mai Image 2.5" },
|
||||
{ id: "minimax/minimax-m2-her", name: "Minimax M2 Her" },
|
||||
{ id: "minimax/minimax-m2.1", name: "Minimax M2.1" },
|
||||
{ id: "minimax/minimax-m2.1-highspeed", name: "Minimax M2.1 Highspeed" },
|
||||
{ id: "minimax/minimax-m2.5", name: "Minimax M2.5" },
|
||||
{ id: "minimax/minimax-m2.7", name: "Minimax M2.7" },
|
||||
{ id: "minimax/minimax-m2.7-highspeed", name: "Minimax M2.7 Highspeed" },
|
||||
{ id: "miromind/mirothinker-1-7-deepresearch", name: "Mirothinker 1 7 Deepresearch" },
|
||||
{ id: "miromind/mirothinker-1-7-deepresearch-mini", name: "Mirothinker 1 7 Deepresearch Mini" },
|
||||
{ id: "mistralai/devstral-2512", name: "Devstral 2512" },
|
||||
{ id: "mistralai/mistral-medium-3-5", name: "Mistral Medium 3 5" },
|
||||
{ id: "mistralai/mistral-small-2603", name: "Mistral Small 2603" },
|
||||
{ id: "mistralai/voxtral-small-24b-2507", name: "Voxtral Small 24B 2507" },
|
||||
{ id: "moonshotai/kimi-k2.5", name: "Kimi K2.5" },
|
||||
{ id: "moonshotai/kimi-k2.6", name: "Kimi K2.6" },
|
||||
{ id: "moonshotai/kimi-k2.7-code", name: "Kimi K2.7 Code" },
|
||||
{ id: "moonshotai/kimi-k3", name: "Kimi K3" },
|
||||
{ id: "moonshotai/kimi-k3-free", name: "Kimi K3 Free" },
|
||||
{ id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free", name: "Nemotron 3 Nano Omni 30B A3B Reasoning:Free" },
|
||||
{ id: "nvidia/nemotron-3-super-120b-a12b", name: "Nemotron 3 Super 120B A12B" },
|
||||
{ id: "openai/gpt-4o-mini", name: "Gpt 4O Mini" },
|
||||
{ id: "openai/gpt-5", name: "Gpt 5" },
|
||||
{ id: "openai/gpt-5-image", name: "Gpt 5 Image" },
|
||||
{ id: "openai/gpt-5-image-mini", name: "Gpt 5 Image Mini" },
|
||||
{ id: "openai/gpt-5-mini", name: "Gpt 5 Mini" },
|
||||
{ id: "openai/gpt-5.2", name: "Gpt 5.2" },
|
||||
{ id: "openai/gpt-5.4", name: "Gpt 5.4" },
|
||||
{ id: "openai/gpt-5.4-image-2", name: "Gpt 5.4 Image 2", kind: "image" },
|
||||
{ id: "openai/gpt-5.4-mini", name: "Gpt 5.4 Mini" },
|
||||
{ id: "openai/gpt-5.4-nano", name: "Gpt 5.4 Nano" },
|
||||
{ id: "openai/gpt-5.4-pro", name: "Gpt 5.4 Pro" },
|
||||
{ id: "openai/gpt-5.5", name: "Gpt 5.5" },
|
||||
{ id: "openai/gpt-5.5-pro", name: "Gpt 5.5 Pro" },
|
||||
{ id: "openai/gpt-5.6-luna", name: "Gpt 5.6 Luna" },
|
||||
{ id: "openai/gpt-5.6-sol", name: "Gpt 5.6 Sol" },
|
||||
{ id: "openai/gpt-5.6-terra", name: "Gpt 5.6 Terra" },
|
||||
{ id: "openai/gpt-audio", name: "Gpt Audio", kind: "audio" },
|
||||
{ id: "openai/gpt-audio-mini", name: "Gpt Audio Mini", kind: "audio" },
|
||||
{ id: "openai/gpt-oss-120b", name: "Gpt Oss 120B" },
|
||||
{ id: "qwen/qwen3-coder-next", name: "Qwen3 Coder Next" },
|
||||
{ id: "qwen/qwen3.5-122b-a10b", name: "Qwen3.5 122B A10B" },
|
||||
{ id: "qwen/qwen3.5-35b-a3b", name: "Qwen3.5 35B A3B" },
|
||||
{ id: "qwen/qwen3.5-397b-a17b", name: "Qwen3.5 397B A17B" },
|
||||
{ id: "qwen/qwen3.5-9b", name: "Qwen3.5 9B" },
|
||||
{ id: "qwen/qwen3.5-flash", name: "Qwen3.5 Flash" },
|
||||
{ id: "qwen/qwen3.5-plus-02-15", name: "Qwen3.5 Plus 02 15" },
|
||||
{ id: "qwen/qwen3.6-plus", name: "Qwen3.6 Plus" },
|
||||
{ id: "qwen/qwen3.7-max", name: "Qwen3.7 Max" },
|
||||
{ id: "qwen/qwen3.7-plus", name: "Qwen3.7 Plus" },
|
||||
{ id: "qwen/qwen3.8-max", name: "Qwen3.8 Max" },
|
||||
{ id: "qwen3.5-omni-plus", name: "Qwen3.5 Omni Plus" },
|
||||
{ id: "qwen3.6-flash", name: "Qwen3.6 Flash" },
|
||||
{ id: "sakana/fugu-ultra", name: "Fugu Ultra" },
|
||||
{ id: "seed-2-0-code-preview-260328", name: "Seed 2 0 Code Preview 260328" },
|
||||
{ id: "seed-2-0-lite-260428", name: "Seed 2 0 Lite 260428" },
|
||||
{ id: "seed-2-0-mini-260428", name: "Seed 2 0 Mini 260428" },
|
||||
{ id: "seed-2-0-pro-260328", name: "Seed 2 0 Pro 260328" },
|
||||
{ id: "stepfun/step-3.5-flash", name: "Step 3.5 Flash" },
|
||||
{ id: "stepfun/step-3.7-flash", name: "Step 3.7 Flash" },
|
||||
{ id: "tencent/hy3-preview", name: "Hy3 Preview" },
|
||||
{ id: "x-ai/grok-4.1-fast", name: "Grok 4.1 Fast" },
|
||||
{ id: "x-ai/grok-4.20-beta", name: "Grok 4.20 Beta" },
|
||||
{ id: "x-ai/grok-4.3", name: "Grok 4.3" },
|
||||
{ id: "x-ai/grok-4.5", name: "Grok 4.5" },
|
||||
{ id: "x-ai/grok-build-0.1", name: "Grok Build 0.1" },
|
||||
{ id: "xiaomi/mimo-v2-flash", name: "Mimo V2 Flash" },
|
||||
{ id: "xiaomi/mimo-v2-omni", name: "Mimo V2 Omni" },
|
||||
{ id: "xiaomi/mimo-v2-pro", name: "Mimo V2 Pro" },
|
||||
{ id: "xiaomi/mimo-v2.5", name: "Mimo V2.5" },
|
||||
{ id: "xiaomi/mimo-v2.5-pro", name: "Mimo V2.5 Pro" },
|
||||
{ id: "z-ai/glm-4.5-air", name: "Glm 4.5 Air" },
|
||||
{ id: "z-ai/glm-4.6", name: "Glm 4.6" },
|
||||
{ id: "z-ai/glm-4.6v", name: "Glm 4.6V" },
|
||||
{ id: "z-ai/glm-4.7", name: "Glm 4.7" },
|
||||
{ id: "z-ai/glm-5", name: "Glm 5" },
|
||||
{ id: "z-ai/glm-5-turbo", name: "Glm 5 Turbo" },
|
||||
{ id: "z-ai/glm-5.1", name: "Glm 5.1" },
|
||||
{ id: "z-ai/glm-5.2", name: "Glm 5.2" },
|
||||
],
|
||||
serviceKinds: ["llm", "embedding", "image"],
|
||||
embeddingConfig: {
|
||||
baseUrl: "https://api.tokenrouter.com/v1/embeddings",
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
},
|
||||
imageConfig: {
|
||||
baseUrl: "https://api.tokenrouter.com/v1/images/generations",
|
||||
},
|
||||
modelsFetcher: { url: "https://api.tokenrouter.com/v1/models", type: "openai" },
|
||||
passthroughModels: true,
|
||||
};
|
||||
@@ -15,10 +15,11 @@ export default {
|
||||
textIcon: "XM",
|
||||
website: "https://xiaomimimo.com",
|
||||
notice: {
|
||||
apiKeyUrl: "https://xiaomimimo.com",
|
||||
apiKeyUrl: "https://platform.xiaomimimo.com/console/api-keys",
|
||||
},
|
||||
},
|
||||
category: "apikey",
|
||||
serviceKinds: ["llm", "tts"],
|
||||
transport: {
|
||||
baseUrl: "https://api.xiaomimimo.com/v1/chat/completions",
|
||||
validateUrl: "https://api.xiaomimimo.com/v1/models",
|
||||
@@ -42,5 +43,12 @@ export default {
|
||||
{ id: "mimo-v2.5", name: "MiMo V2.5" },
|
||||
{ id: "mimo-v2-omni", name: "MiMo V2 Omni" },
|
||||
{ id: "mimo-v2-flash", name: "MiMo V2 Flash" },
|
||||
{ id: "mimo-v2.5-tts", name: "MiMo V2.5 TTS", kind: "tts" },
|
||||
],
|
||||
ttsConfig: {
|
||||
baseUrl: "https://api.xiaomimimo.com/v1/chat/completions",
|
||||
authType: "apikey",
|
||||
authHeader: "bearer",
|
||||
format: "xiaomi-mimo-tts",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -47,6 +47,26 @@ export const CLAUDE_CLI_SPOOF_HEADERS = {
|
||||
"X-Stainless-Timeout": "600"
|
||||
};
|
||||
|
||||
const ANTHROPIC_BETA_BASE = [
|
||||
"claude-code-20250219",
|
||||
"oauth-2025-04-20",
|
||||
"interleaved-thinking-2025-05-14",
|
||||
"context-management-2025-06-27",
|
||||
"prompt-caching-scope-2026-01-05",
|
||||
"structured-outputs-2025-12-15",
|
||||
"fast-mode-2026-02-01",
|
||||
"redact-thinking-2026-02-12",
|
||||
"token-efficient-tools-2026-03-28",
|
||||
];
|
||||
const ANTHROPIC_BETA_HEAVY_AGENT = ["advanced-tool-use-2025-11-20", "effort-2025-11-24"];
|
||||
|
||||
// Heavy-agent beta flags are gated to opus/sonnet — cheaper models don't need them.
|
||||
export function selectAnthropicBeta(model = "") {
|
||||
const flags = [...ANTHROPIC_BETA_BASE];
|
||||
if (/^claude-(opus|sonnet)/.test(model)) flags.push(...ANTHROPIC_BETA_HEAVY_AGENT);
|
||||
return flags.join(",");
|
||||
}
|
||||
|
||||
// Shared baseUrls
|
||||
export const KIMI_CODING_BASE_URL = "https://api.kimi.com/coding/v1/messages";
|
||||
|
||||
|
||||
@@ -31,10 +31,13 @@ const FORMAT_LEVELS = {
|
||||
step: L.base,
|
||||
};
|
||||
|
||||
const CODEX_GPT_5_6_LEVELS = ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
||||
|
||||
// Model-name pattern overrides (glob, first match wins) — more precise than format default.
|
||||
const PATTERN_THINKING = [
|
||||
// gpt-5.6-sol accepts max (maps to xhigh on wire); live probe rejected ultra.
|
||||
{ pattern: "*gpt-5.6-sol*", levels: ["none", "minimal", "low", "medium", "high", "xhigh", "max"] },
|
||||
{ provider: "codex", pattern: "*gpt-5.6-sol*", levels: [...CODEX_GPT_5_6_LEVELS, "ultra"] },
|
||||
{ provider: "codex", pattern: "*gpt-5.6-terra*", levels: [...CODEX_GPT_5_6_LEVELS, "ultra"] },
|
||||
{ provider: "codex", pattern: "*gpt-5.6-luna*", levels: CODEX_GPT_5_6_LEVELS },
|
||||
{ pattern: "*codex*", levels: ["low", "medium", "high", "xhigh"] }, // codex cannot disable thinking
|
||||
];
|
||||
|
||||
@@ -43,7 +46,9 @@ export function getThinkingLevels(provider, model) {
|
||||
if (provider === "kiro" && resolveKiroEffortPath(model) === null) return null;
|
||||
const caps = getCapabilitiesForModel(provider, model);
|
||||
if (!caps.reasoning) return null;
|
||||
const hit = PATTERN_THINKING.find((p) => matchPattern(p.pattern, model));
|
||||
const hit = PATTERN_THINKING.find((entry) =>
|
||||
(!entry.provider || entry.provider === provider) && matchPattern(entry.pattern, model)
|
||||
);
|
||||
let levels = hit?.levels || FORMAT_LEVELS[caps.thinkingFormat] || L.base;
|
||||
if (caps.thinkingCanDisable === false) levels = levels.filter((l) => l !== "none");
|
||||
return levels;
|
||||
|
||||
Reference in New Issue
Block a user