diff --git a/open-sse/config/providers/registry/adapta-web/index.ts b/open-sse/config/providers/registry/adapta-web/index.ts index 8bd195cc10..0b13f6a4b7 100644 --- a/open-sse/config/providers/registry/adapta-web/index.ts +++ b/open-sse/config/providers/registry/adapta-web/index.ts @@ -9,12 +9,12 @@ export const adapta_webProvider: RegistryEntry = { authType: "apikey", authHeader: "bearer", models: [ - { id: "adapta-one", name: "Adapta ONE (Auto)" }, - { id: "adapta-gpt", name: "GPT-5 (via Adapta)" }, - { id: "adapta-claude", name: "Claude Sonnet 4.6 (via Adapta)" }, - { id: "adapta-gemini", name: "Gemini 2.5 Pro (via Adapta)" }, - { id: "adapta-grok", name: "Grok 4 (via Adapta)" }, - { id: "adapta-deepseek", name: "DeepSeek R2 (via Adapta)" }, - { id: "adapta-llama", name: "Llama 4 (via Adapta)" }, + { id: "adapta-one", name: "Adapta ONE (Auto)", toolCalling: false }, + { id: "adapta-gpt", name: "GPT-5 (via Adapta)", toolCalling: false }, + { id: "adapta-claude", name: "Claude Sonnet 4.6 (via Adapta)", toolCalling: false }, + { id: "adapta-gemini", name: "Gemini 2.5 Pro (via Adapta)", toolCalling: false }, + { id: "adapta-grok", name: "Grok 4 (via Adapta)", toolCalling: false }, + { id: "adapta-deepseek", name: "DeepSeek R2 (via Adapta)", toolCalling: false }, + { id: "adapta-llama", name: "Llama 4 (via Adapta)", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/blackbox/web/index.ts b/open-sse/config/providers/registry/blackbox/web/index.ts index 61b7ddd87f..4a8eef4547 100644 --- a/open-sse/config/providers/registry/blackbox/web/index.ts +++ b/open-sse/config/providers/registry/blackbox/web/index.ts @@ -9,11 +9,11 @@ export const blackbox_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "gpt-4-turbo", name: "GPT-4 Turbo" }, - { id: "gpt-4", name: "GPT-4" }, - { id: "gpt-3.5-turbo", name: "GPT-3.5 Turbo" }, - { id: "claude-3-opus", name: "Claude 3 Opus" }, - { id: "claude-3-sonnet", name: "Claude 3 Sonnet" }, - { id: "gemini-pro", name: "Gemini Pro" }, + { id: "gpt-4-turbo", name: "GPT-4 Turbo", toolCalling: false }, + { id: "gpt-4", name: "GPT-4", toolCalling: false }, + { id: "gpt-3.5-turbo", name: "GPT-3.5 Turbo", toolCalling: false }, + { id: "claude-3-opus", name: "Claude 3 Opus", toolCalling: false }, + { id: "claude-3-sonnet", name: "Claude 3 Sonnet", toolCalling: false }, + { id: "gemini-pro", name: "Gemini Pro", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/chatgpt-web/index.ts b/open-sse/config/providers/registry/chatgpt-web/index.ts index 6bdaeed9fc..bb57c7f31c 100644 --- a/open-sse/config/providers/registry/chatgpt-web/index.ts +++ b/open-sse/config/providers/registry/chatgpt-web/index.ts @@ -9,12 +9,12 @@ export const chatgpt_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "gpt-5.6-pro", name: "GPT-5.6 Pro" }, // pro tier only, standard effort - { id: "gpt-5.6-thinking", name: "GPT-5.6 Thinking" }, // plus, pro tier - { id: "gpt-5.5-pro-extended", name: "GPT-5.5 Pro Extended" }, // pro tier only, extended effort - { id: "gpt-5.5-pro", name: "GPT-5.5 Pro" }, // pro tier only, standard effort - { id: "gpt-5.5-thinking", name: "GPT-5.5 Thinking" }, // plus, pro tier - { id: "gpt-5.5", name: "GPT-5.5 Instant" }, // free, plus, pro tier - { id: "o3", name: "o3" }, // plus ~ tier + { id: "gpt-5.6-pro", name: "GPT-5.6 Pro", toolCalling: false }, // pro tier only, standard effort + { id: "gpt-5.6-thinking", name: "GPT-5.6 Thinking", toolCalling: false }, // plus, pro tier + { id: "gpt-5.5-pro-extended", name: "GPT-5.5 Pro Extended", toolCalling: false }, // pro tier only, extended effort + { id: "gpt-5.5-pro", name: "GPT-5.5 Pro", toolCalling: false }, // pro tier only, standard effort + { id: "gpt-5.5-thinking", name: "GPT-5.5 Thinking", toolCalling: false }, // plus, pro tier + { id: "gpt-5.5", name: "GPT-5.5 Instant", toolCalling: false }, // free, plus, pro tier + { id: "o3", name: "o3", toolCalling: false }, // plus ~ tier ], }; diff --git a/open-sse/config/providers/registry/claude/web/index.ts b/open-sse/config/providers/registry/claude/web/index.ts index 952b4f39fe..cf5bdb16b2 100644 --- a/open-sse/config/providers/registry/claude/web/index.ts +++ b/open-sse/config/providers/registry/claude/web/index.ts @@ -9,8 +9,8 @@ export const claude_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "claude-sonnet-5", name: "Claude 5 Sonnet (web)" }, - { id: "claude-sonnet-4-6", name: "Claude 4.6 Sonnet (web)" }, - { id: "claude-haiku-4-5", name: "Claude 4.5 Haiku (web)" }, + { id: "claude-sonnet-5", name: "Claude 5 Sonnet (web)", toolCalling: false }, + { id: "claude-sonnet-4-6", name: "Claude 4.6 Sonnet (web)", toolCalling: false }, + { id: "claude-haiku-4-5", name: "Claude 4.5 Haiku (web)", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/copilot-m365-web/index.ts b/open-sse/config/providers/registry/copilot-m365-web/index.ts index 7429153222..98a288fa4b 100644 --- a/open-sse/config/providers/registry/copilot-m365-web/index.ts +++ b/open-sse/config/providers/registry/copilot-m365-web/index.ts @@ -8,5 +8,5 @@ export const copilot_m365_webProvider: RegistryEntry = { baseUrl: "wss://substrate.office.com/m365Copilot/Chathub", authType: "apikey", authHeader: "cookie", - models: [{ id: "copilot-m365", name: "Microsoft 365 Copilot (BizChat)" }], + models: [{ id: "copilot-m365", name: "Microsoft 365 Copilot (BizChat)", toolCalling: false }], }; diff --git a/open-sse/config/providers/registry/copilot-web/index.ts b/open-sse/config/providers/registry/copilot-web/index.ts index d4611008ec..c09342d58b 100644 --- a/open-sse/config/providers/registry/copilot-web/index.ts +++ b/open-sse/config/providers/registry/copilot-web/index.ts @@ -9,8 +9,8 @@ export const copilot_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "copilot-pro", name: "Copilot Pro (web)" }, - { id: "gpt-4-turbo", name: "GPT-4 Turbo (via Copilot)" }, - { id: "gpt-4", name: "GPT-4 (via Copilot)" }, + { id: "copilot-pro", name: "Copilot Pro (web)", toolCalling: false }, + { id: "gpt-4-turbo", name: "GPT-4 Turbo (via Copilot)", toolCalling: false }, + { id: "gpt-4", name: "GPT-4 (via Copilot)", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/deepseek/web/index.ts b/open-sse/config/providers/registry/deepseek/web/index.ts index 331c2c739e..ba20e12e0d 100644 --- a/open-sse/config/providers/registry/deepseek/web/index.ts +++ b/open-sse/config/providers/registry/deepseek/web/index.ts @@ -9,27 +9,27 @@ export const deepseek_webProvider: RegistryEntry = { authType: "apikey", authHeader: "bearer", models: [ - { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro" }, + { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", toolCalling: false }, { id: "deepseek-v4-pro-think", name: "DeepSeek V4 Pro Think", supportsReasoning: true }, - { id: "deepseek-v4-pro-search", name: "DeepSeek V4 Pro Search" }, + { id: "deepseek-v4-pro-search", name: "DeepSeek V4 Pro Search", toolCalling: false }, { id: "deepseek-v4-pro-think-search", name: "DeepSeek V4 Pro Think+Search", supportsReasoning: true, }, - { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash" }, + { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", toolCalling: false }, { id: "deepseek-v4-flash-think", name: "DeepSeek V4 Flash Think", supportsReasoning: true }, - { id: "deepseek-v4-flash-search", name: "DeepSeek V4 Flash Search" }, + { id: "deepseek-v4-flash-search", name: "DeepSeek V4 Flash Search", toolCalling: false }, { id: "deepseek-v4-flash-think-search", name: "DeepSeek V4 Flash Think+Search", supportsReasoning: true, }, - { id: "deepseek-chat", name: "DeepSeek Chat" }, + { id: "deepseek-chat", name: "DeepSeek Chat", toolCalling: false }, { id: "deepseek-reasoner", name: "DeepSeek Reasoner", supportsReasoning: true }, { id: "DeepSeek-R1", name: "DeepSeek R1", supportsReasoning: true }, { id: "DeepSeek-R1-Search", name: "DeepSeek R1 Search", supportsReasoning: true }, - { id: "DeepSeek-V3.2", name: "DeepSeek V3.2" }, - { id: "DeepSeek-Search", name: "DeepSeek Search" }, + { id: "DeepSeek-V3.2", name: "DeepSeek V3.2", toolCalling: false }, + { id: "DeepSeek-Search", name: "DeepSeek Search", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/doubao/web/index.ts b/open-sse/config/providers/registry/doubao/web/index.ts index 025d4b7e82..e66ff3f45c 100644 --- a/open-sse/config/providers/registry/doubao/web/index.ts +++ b/open-sse/config/providers/registry/doubao/web/index.ts @@ -9,7 +9,7 @@ export const doubao_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "dola-speed", name: "Dola Speed" }, - { id: "dola-pro", name: "Dola Pro" }, + { id: "dola-speed", name: "Dola Speed", toolCalling: false }, + { id: "dola-pro", name: "Dola Pro", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/duckduckgo-web/index.ts b/open-sse/config/providers/registry/duckduckgo-web/index.ts index 888d56f7be..3fbab5688c 100644 --- a/open-sse/config/providers/registry/duckduckgo-web/index.ts +++ b/open-sse/config/providers/registry/duckduckgo-web/index.ts @@ -9,11 +9,11 @@ export const duckduckgo_webProvider: RegistryEntry = { authType: "none", authHeader: "none", models: [ - { id: "gpt-4o-mini", name: "GPT-4o Mini" }, - { id: "gpt-5-mini", name: "GPT-5 Mini" }, - { id: "claude-3-5-haiku-20241022", name: "Claude 3.5 Haiku" }, - { id: "llama-4-scout", name: "Llama 4 Scout" }, - { id: "mistral-small-2501", name: "Mistral Small" }, - { id: "o3-mini", name: "O3 Mini" }, + { id: "gpt-4o-mini", name: "GPT-4o Mini", toolCalling: false }, + { id: "gpt-5-mini", name: "GPT-5 Mini", toolCalling: false }, + { id: "claude-3-5-haiku-20241022", name: "Claude 3.5 Haiku", toolCalling: false }, + { id: "llama-4-scout", name: "Llama 4 Scout", toolCalling: false }, + { id: "mistral-small-2501", name: "Mistral Small", toolCalling: false }, + { id: "o3-mini", name: "O3 Mini", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/felo-web/index.ts b/open-sse/config/providers/registry/felo-web/index.ts index 4cf8fcae25..58f1605d1d 100644 --- a/open-sse/config/providers/registry/felo-web/index.ts +++ b/open-sse/config/providers/registry/felo-web/index.ts @@ -9,10 +9,10 @@ export const felo_webProvider: RegistryEntry = { authType: "none", authHeader: "none", models: [ - { id: "felo-chat", name: "Felo Chat" }, - { id: "felo-search", name: "Felo Search" }, - { id: "felo-scholar", name: "Felo Scholar" }, - { id: "felo-social", name: "Felo Social" }, - { id: "felo-document", name: "Felo Document" }, + { id: "felo-chat", name: "Felo Chat", toolCalling: false }, + { id: "felo-search", name: "Felo Search", toolCalling: false }, + { id: "felo-scholar", name: "Felo Scholar", toolCalling: false }, + { id: "felo-social", name: "Felo Social", toolCalling: false }, + { id: "felo-document", name: "Felo Document", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/gemini/web/index.ts b/open-sse/config/providers/registry/gemini/web/index.ts index de4f818918..6843ae86a8 100644 --- a/open-sse/config/providers/registry/gemini/web/index.ts +++ b/open-sse/config/providers/registry/gemini/web/index.ts @@ -9,8 +9,8 @@ export const gemini_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "gemini-3.1-pro", name: "Gemini 3.1 Pro" }, - { id: "gemini-3.5-flash", name: "Gemini 3.5 Flash" }, - { id: "gemini-3.1-flash-lite", name: "Gemini 3.1 Flash-Lite" }, + { id: "gemini-3.1-pro", name: "Gemini 3.1 Pro", toolCalling: false }, + { id: "gemini-3.5-flash", name: "Gemini 3.5 Flash", toolCalling: false }, + { id: "gemini-3.1-flash-lite", name: "Gemini 3.1 Flash-Lite", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/muse-spark-web/index.ts b/open-sse/config/providers/registry/muse-spark-web/index.ts index 7ddcd9f1fe..03021bdfff 100644 --- a/open-sse/config/providers/registry/muse-spark-web/index.ts +++ b/open-sse/config/providers/registry/muse-spark-web/index.ts @@ -9,7 +9,7 @@ export const muse_spark_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "muse-spark", name: "Muse Spark" }, + { id: "muse-spark", name: "Muse Spark", toolCalling: false }, { id: "muse-spark-thinking", name: "Muse Spark Thinking", diff --git a/open-sse/config/providers/registry/nvidia/index.ts b/open-sse/config/providers/registry/nvidia/index.ts index 64871e95ba..fb36561e07 100644 --- a/open-sse/config/providers/registry/nvidia/index.ts +++ b/open-sse/config/providers/registry/nvidia/index.ts @@ -49,21 +49,21 @@ export const nvidiaProvider: RegistryEntry = { { id: "abacusai/dracarys-llama-3.1-70b-instruct", name: "Dracarys Llama 3.1 70B Instruct" }, { id: "google/gemma-2-2b-it", name: "Gemma 2 2B IT" }, { id: "google/gemma-3n-e2b-it", name: "Gemma 3n E2B IT" }, - { id: "meta/llama-3.1-8b-instruct", name: "Llama 3.1 8B Instruct" }, + { id: "meta/llama-3.1-8b-instruct", name: "Llama 3.1 8B Instruct", toolCalling: false }, { id: "meta/llama-3.2-11b-vision-instruct", name: "Llama 3.2 11B Vision Instruct", supportsVision: true, }, { id: "meta/llama-3.2-1b-instruct", name: "Llama 3.2 1B Instruct" }, - { id: "meta/llama-3.2-3b-instruct", name: "Llama 3.2 3B Instruct" }, + { id: "meta/llama-3.2-3b-instruct", name: "Llama 3.2 3B Instruct", toolCalling: false }, { id: "meta/llama-3.2-90b-vision-instruct", name: "Llama 3.2 90B Vision Instruct", supportsVision: true, }, { id: "meta/llama-4-maverick-17b-128e-instruct", name: "Llama 4 Maverick 17B 128E Instruct" }, - { id: "meta/llama-guard-4-12b", name: "Llama Guard 4 12B" }, + { id: "meta/llama-guard-4-12b", name: "Llama Guard 4 12B", toolCalling: false }, { id: "mistralai/ministral-14b-instruct-2512", name: "Ministral 14B Instruct 2512" }, { id: "mistralai/mistral-medium-3.5-128b", name: "Mistral Medium 3.5 128B" }, { id: "mistralai/mistral-nemotron", name: "Mistral Nemotron" }, diff --git a/open-sse/config/providers/registry/perplexity/web/index.ts b/open-sse/config/providers/registry/perplexity/web/index.ts index 5eb8261350..71ca1d4fd8 100644 --- a/open-sse/config/providers/registry/perplexity/web/index.ts +++ b/open-sse/config/providers/registry/perplexity/web/index.ts @@ -9,16 +9,16 @@ export const perplexity_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "pplx-auto", name: "Perplexity Best" }, - { id: "pplx-sonar", name: "Sonar 2 (via Perplexity)" }, - { id: "pplx-gpt-5.6-terra", name: "GPT-5.6 Terra (via Perplexity)" }, - { id: "pplx-gpt-5.6-sol", name: "GPT-5.6 Sol (via Perplexity)" }, - { id: "pplx-gemini", name: "Gemini 3.1 Pro (via Perplexity)" }, - { id: "pplx-sonnet", name: "Claude Sonnet 5.0 (via Perplexity)" }, - { id: "pplx-opus", name: "Claude Opus 4.8 (via Perplexity)" }, - { id: "pplx-glm", name: "GLM-5.2 (via Perplexity)" }, - { id: "pplx-kimi", name: "Kimi K2.6 (via Perplexity)" }, - { id: "pplx-grok-4.5", name: "Grok 4.5 (via Perplexity)" }, - { id: "pplx-nemotron", name: "Nemotron 3 Ultra (via Perplexity)" }, + { id: "pplx-auto", name: "Perplexity Best", toolCalling: false }, + { id: "pplx-sonar", name: "Sonar 2 (via Perplexity)", toolCalling: false }, + { id: "pplx-gpt-5.6-terra", name: "GPT-5.6 Terra (via Perplexity)", toolCalling: false }, + { id: "pplx-gpt-5.6-sol", name: "GPT-5.6 Sol (via Perplexity)", toolCalling: false }, + { id: "pplx-gemini", name: "Gemini 3.1 Pro (via Perplexity)", toolCalling: false }, + { id: "pplx-sonnet", name: "Claude Sonnet 5.0 (via Perplexity)", toolCalling: false }, + { id: "pplx-opus", name: "Claude Opus 4.8 (via Perplexity)", toolCalling: false }, + { id: "pplx-glm", name: "GLM-5.2 (via Perplexity)", toolCalling: false }, + { id: "pplx-kimi", name: "Kimi K2.6 (via Perplexity)", toolCalling: false }, + { id: "pplx-grok-4.5", name: "Grok 4.5 (via Perplexity)", toolCalling: false }, + { id: "pplx-nemotron", name: "Nemotron 3 Ultra (via Perplexity)", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/t3-web/index.ts b/open-sse/config/providers/registry/t3-web/index.ts index 40b3e62c17..7b9339365d 100644 --- a/open-sse/config/providers/registry/t3-web/index.ts +++ b/open-sse/config/providers/registry/t3-web/index.ts @@ -10,36 +10,36 @@ export const t3_webProvider: RegistryEntry = { authHeader: "cookie", models: [ // Claude - { id: "claude-opus-4", name: "Claude Opus 4 (via t3.chat)" }, - { id: "claude-sonnet-4", name: "Claude Sonnet 4 (via t3.chat)" }, - { id: "claude-haiku-4", name: "Claude Haiku 4 (via t3.chat)" }, - { id: "claude-3.7", name: "Claude 3.7 Sonnet (via t3.chat)" }, + { id: "claude-opus-4", name: "Claude Opus 4 (via t3.chat)", toolCalling: false }, + { id: "claude-sonnet-4", name: "Claude Sonnet 4 (via t3.chat)", toolCalling: false }, + { id: "claude-haiku-4", name: "Claude Haiku 4 (via t3.chat)", toolCalling: false }, + { id: "claude-3.7", name: "Claude 3.7 Sonnet (via t3.chat)", toolCalling: false }, // GPT / OpenAI - { id: "gpt-5", name: "GPT-5 (via t3.chat)" }, - { id: "gpt-4o", name: "GPT-4o (via t3.chat)" }, - { id: "gpt-4.1", name: "GPT-4.1 (via t3.chat)" }, - { id: "o3", name: "o3 (via t3.chat)" }, - { id: "o4-mini", name: "o4-mini (via t3.chat)" }, + { id: "gpt-5", name: "GPT-5 (via t3.chat)", toolCalling: false }, + { id: "gpt-4o", name: "GPT-4o (via t3.chat)", toolCalling: false }, + { id: "gpt-4.1", name: "GPT-4.1 (via t3.chat)", toolCalling: false }, + { id: "o3", name: "o3 (via t3.chat)", toolCalling: false }, + { id: "o4-mini", name: "o4-mini (via t3.chat)", toolCalling: false }, // Gemini - { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro (via t3.chat)" }, - { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash (via t3.chat)" }, + { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro (via t3.chat)", toolCalling: false }, + { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash (via t3.chat)", toolCalling: false }, // DeepSeek { id: "deepseek-r1", name: "DeepSeek R1 (via t3.chat)", supportsReasoning: true }, - { id: "deepseek-v3", name: "DeepSeek V3 (via t3.chat)" }, + { id: "deepseek-v3", name: "DeepSeek V3 (via t3.chat)", toolCalling: false }, // Grok - { id: "grok-3", name: "Grok 3 (via t3.chat)" }, - { id: "grok-3-mini", name: "Grok 3 Mini (via t3.chat)" }, + { id: "grok-3", name: "Grok 3 (via t3.chat)", toolCalling: false }, + { id: "grok-3-mini", name: "Grok 3 Mini (via t3.chat)", toolCalling: false }, // Llama / Meta - { id: "llama-4-maverick", name: "Llama 4 Maverick (via t3.chat)" }, - { id: "llama-4-scout", name: "Llama 4 Scout (via t3.chat)" }, - { id: "llama-3.3-70b", name: "Llama 3.3 70B (via t3.chat)" }, + { id: "llama-4-maverick", name: "Llama 4 Maverick (via t3.chat)", toolCalling: false }, + { id: "llama-4-scout", name: "Llama 4 Scout (via t3.chat)", toolCalling: false }, + { id: "llama-3.3-70b", name: "Llama 3.3 70B (via t3.chat)", toolCalling: false }, // Mistral - { id: "devstral", name: "Devstral (via t3.chat)" }, - { id: "mistral-large", name: "Mistral Large (via t3.chat)" }, + { id: "devstral", name: "Devstral (via t3.chat)", toolCalling: false }, + { id: "mistral-large", name: "Mistral Large (via t3.chat)", toolCalling: false }, // Qwen { id: "qwen3-235b", name: "Qwen3 235B (via t3.chat)", supportsReasoning: true }, { id: "qwen3-32b", name: "Qwen3 32B (via t3.chat)", supportsReasoning: true }, // Kimi - { id: "kimi-k2", name: "Kimi K2 (via t3.chat)" }, + { id: "kimi-k2", name: "Kimi K2 (via t3.chat)", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/veoaifree-web/index.ts b/open-sse/config/providers/registry/veoaifree-web/index.ts index 2c5144c2e5..961aedec0e 100644 --- a/open-sse/config/providers/registry/veoaifree-web/index.ts +++ b/open-sse/config/providers/registry/veoaifree-web/index.ts @@ -9,7 +9,7 @@ export const veoaifree_webProvider: RegistryEntry = { authType: "none", authHeader: "none", models: [ - { id: "veo", name: "VEO 3.1" }, - { id: "seedance", name: "Seedance" }, + { id: "veo", name: "VEO 3.1", toolCalling: false }, + { id: "seedance", name: "Seedance", toolCalling: false }, ], }; diff --git a/open-sse/config/providers/registry/yuanbao-web/index.ts b/open-sse/config/providers/registry/yuanbao-web/index.ts index c3dc4b1565..b4e70a7fca 100644 --- a/open-sse/config/providers/registry/yuanbao-web/index.ts +++ b/open-sse/config/providers/registry/yuanbao-web/index.ts @@ -15,19 +15,19 @@ export const yuanbao_webProvider: RegistryEntry = { name: "DeepSeek R1 (via Yuanbao)", supportsReasoning: true, }, - { id: "hunyuan", name: "Hunyuan (via Yuanbao)" }, + { id: "hunyuan", name: "Hunyuan (via Yuanbao)", toolCalling: false }, { id: "hunyuan-t1", name: "Hunyuan T1 (via Yuanbao)", supportsReasoning: true, }, - { id: "deepseek-v3-search", name: "DeepSeek V3 + Web Search (via Yuanbao)" }, + { id: "deepseek-v3-search", name: "DeepSeek V3 + Web Search (via Yuanbao)", toolCalling: false }, { id: "deepseek-r1-search", name: "DeepSeek R1 + Web Search (via Yuanbao)", supportsReasoning: true, }, - { id: "hunyuan-search", name: "Hunyuan + Web Search (via Yuanbao)" }, + { id: "hunyuan-search", name: "Hunyuan + Web Search (via Yuanbao)", toolCalling: false }, { id: "hunyuan-t1-search", name: "Hunyuan T1 + Web Search (via Yuanbao)", diff --git a/open-sse/config/providers/registry/zai-web/index.ts b/open-sse/config/providers/registry/zai-web/index.ts index 47ad4d5b2f..ab40af01ef 100644 --- a/open-sse/config/providers/registry/zai-web/index.ts +++ b/open-sse/config/providers/registry/zai-web/index.ts @@ -12,8 +12,8 @@ export const zai_webProvider: RegistryEntry = { authType: "apikey", authHeader: "cookie", models: [ - { id: "glm-4.6", name: "GLM-4.6" }, - { id: "glm-4.5", name: "GLM-4.5" }, - { id: "glm-4.5v", name: "GLM-4.5V (Vision)" }, + { id: "glm-4.6", name: "GLM-4.6", toolCalling: false }, + { id: "glm-4.5", name: "GLM-4.5", toolCalling: false }, + { id: "glm-4.5v", name: "GLM-4.5V (Vision)", toolCalling: false }, ], }; diff --git a/open-sse/translator/response/gemini-to-claude.ts b/open-sse/translator/response/gemini-to-claude.ts index f2c96bf137..2307edd61e 100644 --- a/open-sse/translator/response/gemini-to-claude.ts +++ b/open-sse/translator/response/gemini-to-claude.ts @@ -1,6 +1,11 @@ import { register } from "../registry.ts"; import { FORMATS } from "../formats.ts"; import { isAbortFinishReason } from "../../utils/finishReason.ts"; +import { REVERSE_MAP } from "../../services/claudeCodeToolRemapper.ts"; + +function normalizeToolName(name: string): string { + return REVERSE_MAP[name] ?? name; +} /** * Direct Gemini → Claude response translator. @@ -82,7 +87,7 @@ export function geminiToClaudeResponse(chunk, state) { } const fc = part.functionCall; const rawToolName = fc.name; - const restoredToolName = state.toolNameMap?.get(rawToolName) || rawToolName; + const restoredToolName = normalizeToolName(state.toolNameMap?.get(rawToolName) || rawToolName); const idx = state.contentBlockIndex++; const toolId = fc.id || `toolu_${Date.now()}_${idx}`; diff --git a/open-sse/translator/response/openai-to-claude.ts b/open-sse/translator/response/openai-to-claude.ts index c7c9cac3b9..de34ddc139 100644 --- a/open-sse/translator/response/openai-to-claude.ts +++ b/open-sse/translator/response/openai-to-claude.ts @@ -5,6 +5,83 @@ import { hasToolCallShim, applyToolCallShimToBuffer } from "../helpers/toolCallS import { appendToolCallArgumentDelta } from "../../utils/toolCallArguments.ts"; import { isAbortFinishReason } from "../../utils/finishReason.ts"; import { isInternalReasoningPlaceholder } from "../../utils/reasoningPlaceholder.ts"; +import { REVERSE_MAP } from "../../services/claudeCodeToolRemapper.ts"; + +function normalizeToolName(name: string): string { + return REVERSE_MAP[name] ?? name; +} + +interface XmlToolCall { + id: string; + name: string; + args: Record; +} + +/** + * Extract complete XML blocks from text content. + * Some models (e.g. nvidia/abacusai/dracarys) emit tool calls as + * XML blocks instead of JSON tool_calls. This function detects + * value + * blocks, converts them to tool calls, and returns the cleaned text. + * Incomplete XML is buffered in state for the next chunk. + */ +function extractXmlInvokeBlocks( + text: string, + state +): { cleaned: string; toolCalls: XmlToolCall[] } { + const toolCalls: XmlToolCall[] = []; + + // Prepend any incomplete content from previous chunk + const combined = (state._xmlInvokeBuffer || "") + text; + state._xmlInvokeBuffer = ""; + + let remaining = combined; + let cleaned = ""; + + while (true) { + const startMatch = remaining.match(//); + if (!startMatch) { + cleaned += remaining; + break; + } + + // Text before the block + cleaned += remaining.slice(0, startMatch.index); + + const blockStart = startMatch.index; + const restAfterStart = remaining.slice(blockStart); + const endMatch = restAfterStart.match(/<\/invoke>/); + + if (!endMatch) { + // Incomplete block — buffer for next chunk + state._xmlInvokeBuffer = restAfterStart; + break; + } + + // Complete block found + const innerXml = restAfterStart.slice(startMatch[0].length, endMatch.index); + const fullBlock = restAfterStart.slice(0, endMatch.index + endMatch[0].length); + + // Parse value + const args: Record = {}; + const paramRegex = /]*>([\s\S]*?)<\/parameter>/g; + let pm; + while ((pm = paramRegex.exec(innerXml)) !== null) { + args[pm[1]] = pm[2].trim(); + } + + toolCalls.push({ + id: `toolu_xml_${Date.now()}_${toolCalls.length}`, + name: startMatch[1], + args, + }); + + // Continue scanning after the block + remaining = remaining.slice(blockStart + fullBlock.length); + } + + return { cleaned, toolCalls }; +} // Helper: stop thinking block if started function stopThinkingBlock(state, results) { @@ -81,6 +158,8 @@ export function openaiToClaudeResponse(chunk, state) { } state.model = chunk.model || "unknown"; state.nextBlockIndex = 0; + state._pendingXmlToolCalls = []; + state._xmlInvokeBuffer = ""; results.push({ type: "message_start", message: { @@ -133,22 +212,55 @@ export function openaiToClaudeResponse(chunk, state) { if (delta?.content) { stopThinkingBlock(state, results); - if (!state.textBlockStarted) { - state.textBlockIndex = state.nextBlockIndex++; - state.textBlockStarted = true; - state.textBlockClosed = false; - results.push({ - type: "content_block_start", - index: state.textBlockIndex, - content_block: { type: "text", text: "" }, - }); + // Check for XML blocks that some models emit instead of JSON tool_calls + const { cleaned, toolCalls: xmlToolCalls } = extractXmlInvokeBlocks(delta.content, state); + + // Accumulate extracted tool calls for emission at finish + if (xmlToolCalls.length > 0) { + // Close any ongoing text block before tool calls + stopTextBlock(state, results); + state._pendingXmlToolCalls.push(...xmlToolCalls); } - results.push({ - type: "content_block_delta", - index: state.textBlockIndex, - delta: { type: "text_delta", text: delta.content }, - }); + // Emit remaining non-XML text content + if (!cleaned) { + // All content was XML invoke blocks — skip text block entirely + // (tool calls will be emitted at finish) + } else if (xmlToolCalls.length > 0) { + // Text before/between/after XML blocks — (re)start a text block + if (!state.textBlockStarted) { + state.textBlockIndex = state.nextBlockIndex++; + state.textBlockStarted = true; + state.textBlockClosed = false; + results.push({ + type: "content_block_start", + index: state.textBlockIndex, + content_block: { type: "text", text: "" }, + }); + } + results.push({ + type: "content_block_delta", + index: state.textBlockIndex, + delta: { type: "text_delta", text: cleaned }, + }); + } else { + // No XML — emit as regular text (original behaviour) + if (!state.textBlockStarted) { + state.textBlockIndex = state.nextBlockIndex++; + state.textBlockStarted = true; + state.textBlockClosed = false; + results.push({ + type: "content_block_start", + index: state.textBlockIndex, + content_block: { type: "text", text: "" }, + }); + } + results.push({ + type: "content_block_delta", + index: state.textBlockIndex, + delta: { type: "text_delta", text: cleaned }, + }); + } } // Tool calls @@ -289,14 +401,38 @@ export function openaiToClaudeResponse(chunk, state) { }); } + // Emit any XML-extracted tool calls (from models like Dracarys that + // emit blocks in content instead of JSON tool_calls in delta) + const xmlToolCalls = state._pendingXmlToolCalls || []; + for (const tc of xmlToolCalls) { + const blockIndex = state.nextBlockIndex++; + results.push({ + type: "content_block_start", + index: blockIndex, + content_block: { + type: "tool_use", + id: tc.id, + name: normalizeToolName(tc.name), + input: tc.args, + }, + }); + results.push({ + type: "content_block_stop", + index: blockIndex, + }); + } + + // Override finish_reason to tool_use if XML tool calls were found + const overrideFinishReason = xmlToolCalls.length > 0 ? "tool_calls" : choice.finish_reason; + // Mark finish for later usage injection in stream.js - state.finishReason = choice.finish_reason; + state.finishReason = overrideFinishReason; // Use tracked usage (will be estimated in stream.js if not valid) const finalUsage = state.usage || { input_tokens: 0, output_tokens: 0 }; results.push({ type: "message_delta", - delta: { stop_reason: convertFinishReason(choice.finish_reason) }, + delta: { stop_reason: convertFinishReason(overrideFinishReason) }, usage: finalUsage, }); results.push({ type: "message_stop" }); diff --git a/package-lock.json b/package-lock.json index b591dbc113..e92a77f207 100644 --- a/package-lock.json +++ b/package-lock.json @@ -346,9 +346,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -363,9 +360,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -380,9 +374,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -397,9 +388,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "SEE LICENSE IN LICENSE.md", "optional": true, "os": [ @@ -5223,9 +5211,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5243,9 +5228,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5263,9 +5245,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5283,9 +5262,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5303,9 +5279,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5413,9 +5386,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5432,9 +5402,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5451,9 +5418,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -5470,9 +5434,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -9587,9 +9548,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -10434,9 +10392,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10453,9 +10408,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10472,9 +10424,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10491,9 +10440,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10510,9 +10456,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -10529,9 +10472,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0 AND MIT", "optional": true, "os": [ @@ -31007,9 +30947,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31027,9 +30964,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31047,9 +30981,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31067,9 +30998,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31087,9 +31015,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31107,9 +31032,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31127,9 +31049,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31147,9 +31066,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -31167,9 +31083,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -31193,9 +31106,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -31219,9 +31129,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -31245,9 +31152,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -31271,9 +31175,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -31297,9 +31198,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -31323,9 +31221,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -31349,9 +31244,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ diff --git a/tests/unit/translator-resp-openai-to-claude.test.ts b/tests/unit/translator-resp-openai-to-claude.test.ts index 04f4c4fd62..1d831a05f5 100644 --- a/tests/unit/translator-resp-openai-to-claude.test.ts +++ b/tests/unit/translator-resp-openai-to-claude.test.ts @@ -10,6 +10,8 @@ const { FORMATS } = await import("../../open-sse/translator/formats.ts"); function createState() { return { toolCalls: new Map(), + _pendingXmlToolCalls: [], + _xmlInvokeBuffer: "", }; } @@ -282,6 +284,190 @@ test("OpenAI non-stream: chat completion becomes Claude message with thinking an }); }); +test("OpenAI stream: XML block in content becomes tool_use at finish", () => { + const state = createState(); + const chunk1 = openaiToClaudeResponse( + { + id: "chatcmpl-xml1", + model: "dracarys", + choices: [ + { + index: 0, + delta: { + content: + 'ls -la', + }, + finish_reason: null, + }, + ], + }, + state + ); + const chunk2 = openaiToClaudeResponse( + { + id: "chatcmpl-xml1", + model: "dracarys", + choices: [{ index: 0, delta: {}, finish_reason: "stop" }], + usage: { prompt_tokens: 3, completion_tokens: 5, total_tokens: 8 }, + }, + state + ); + const result = flatten([chunk1, chunk2]); + + // message_start → (no text block since all content was XML) + assert.equal(result[0].type, "message_start"); + // At finish: tool_use content_block_start + const toolStart = result.find((e) => e.type === "content_block_start" && e.content_block?.type === "tool_use"); + assert.ok(toolStart, "expected tool_use content_block_start"); + assert.equal(toolStart.content_block.name, "bash"); // normalized via REVERSE_MAP + assert.deepEqual(toolStart.content_block.input, { command: "ls -la" }); + // tool_use content_block_stop + const toolStop = result.find((e) => e.type === "content_block_stop"); + assert.ok(toolStop, "expected content_block_stop after tool_use"); + // message_delta with tool_use stop_reason + const delta = result.find((e) => e.type === "message_delta"); + assert.ok(delta, "expected message_delta"); + assert.equal(delta.delta.stop_reason, "tool_use"); +}); + +test("OpenAI stream: XML invoke block across two streaming chunks", () => { + const state = createState(); + // Chunk 1: partial XML + const chunk1 = openaiToClaudeResponse( + { + id: "chatcmpl-xml2", + model: "dracarys", + choices: [ + { + index: 0, + delta: { content: '/etc/' }, + finish_reason: null, + }, + ], + }, + state + ); + // Chunk 2: completes the XML + const chunk2 = openaiToClaudeResponse( + { + id: "chatcmpl-xml2", + model: "dracarys", + choices: [ + { + index: 0, + delta: { content: 'hosts' }, + finish_reason: null, + }, + ], + }, + state + ); + // Chunk 3: finish + const chunk3 = openaiToClaudeResponse( + { + id: "chatcmpl-xml2", + model: "dracarys", + choices: [{ index: 0, delta: {}, finish_reason: "stop" }], + usage: { prompt_tokens: 3, completion_tokens: 5, total_tokens: 8 }, + }, + state + ); + const result = flatten([chunk1, chunk2, chunk3]); + + // Buffer should be cleared after chunk2 + assert.equal(state._xmlInvokeBuffer, "", "buffer cleared after complete block"); + + const toolStart = result.find((e) => e.type === "content_block_start" && e.content_block?.type === "tool_use"); + assert.ok(toolStart, "expected tool_use content_block_start"); + assert.equal(toolStart.content_block.name, "read"); + assert.deepEqual(toolStart.content_block.input, { file_path: "/etc/hosts" }); +}); + +test("OpenAI stream: text before XML block is emitted as text content", () => { + const state = createState(); + const chunk1 = openaiToClaudeResponse( + { + id: "chatcmpl-xml3", + model: "dracarys", + choices: [ + { + index: 0, + delta: { + content: + 'Checking...date', + }, + finish_reason: null, + }, + ], + }, + state + ); + const chunk2 = openaiToClaudeResponse( + { + id: "chatcmpl-xml3", + model: "dracarys", + choices: [ + { + index: 0, + delta: { content: " Done." }, + finish_reason: null, + }, + ], + }, + state + ); + const chunk3 = openaiToClaudeResponse( + { + id: "chatcmpl-xml3", + model: "dracarys", + choices: [{ index: 0, delta: {}, finish_reason: "stop" }], + usage: { prompt_tokens: 3, completion_tokens: 8, total_tokens: 11 }, + }, + state + ); + const result = flatten([chunk1, chunk2, chunk3]); + + // "Checking..." should be emitted as text + const textDeltas = result.filter((e) => e.type === "content_block_delta" && e.delta?.type === "text_delta"); + assert.ok(textDeltas.length > 0, "expected at least one text delta"); + assert.ok(textDeltas.some((d) => d.delta.text.includes("Checking...")), "text before XML preserved"); + assert.ok(textDeltas.some((d) => d.delta.text.includes("Done.")), "text after XML preserved"); + + // Tool call should still be emitted + const toolStart = result.find((e) => e.type === "content_block_start" && e.content_block?.type === "tool_use"); + assert.ok(toolStart, "expected tool_use content_block_start"); + assert.equal(toolStart.content_block.name, "bash"); + assert.deepEqual(toolStart.content_block.input, { command: "date" }); +}); + +test("OpenAI stream: no XML in content behaves normally", () => { + const state = createState(); + const chunk1 = openaiToClaudeResponse( + { + id: "chatcmpl-normal", + model: "gpt-4.1", + choices: [{ index: 0, delta: { content: "Hello world" }, finish_reason: null }], + }, + state + ); + const chunk2 = openaiToClaudeResponse( + { + id: "chatcmpl-normal", + model: "gpt-4.1", + choices: [{ index: 0, delta: {}, finish_reason: "stop" }], + usage: { prompt_tokens: 3, completion_tokens: 2, total_tokens: 5 }, + }, + state + ); + const result = flatten([chunk1, chunk2]); + + assert.equal(result[1].type, "content_block_start"); + assert.equal(result[2].delta.text, "Hello world"); + assert.equal(result[3].type, "content_block_stop"); + assert.equal(result[4].type, "message_delta"); + assert.equal(result[4].delta.stop_reason, "end_turn"); +}); + test("OpenAI stream: null chunk is ignored", () => { assert.equal(openaiToClaudeResponse(null, createState()), null); });