import test from "node:test"; import assert from "node:assert/strict"; import { applyConfiguredUserAgent, BaseExecutor, getCustomUserAgent, mergeAbortSignals, mergeUpstreamExtraHeaders, setUserAgentHeader, } from "../../open-sse/executors/base.ts"; import { DefaultExecutor } from "../../open-sse/executors/default.ts"; import { PROVIDERS } from "../../open-sse/config/constants.ts"; import { CLAUDE_CODE_COMPATIBLE_ANTHROPIC_VERSION, CLAUDE_CODE_COMPATIBLE_DEFAULT_CHAT_PATH, CLAUDE_CODE_COMPATIBLE_REDACT_THINKING_BETA, CONTEXT_1M_BETA_HEADER, } from "../../open-sse/services/claudeCodeCompatible.ts"; import { runWithCapture } from "../../open-sse/utils/providerRequestLogging.ts"; class TestExecutor extends BaseExecutor { constructor(config = {}) { super("test-provider", { baseUrls: [ "https://primary.example/v1/chat/completions", "https://fallback.example/v1/chat/completions", ], headers: { "X-Test-Header": "base" }, ...config, }); } async transformRequest(model, body, stream) { return { ...body, transformed: true, model, stream }; } } test("BaseExecutor: openai-compatible buildUrl sanitizes custom chat paths", () => { const executor = new BaseExecutor("openai-compatible-test", {}); const valid = executor.buildUrl("gpt-4.1", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/", chatPath: "/custom/chat/completions", }, }); const invalid = executor.buildUrl("gpt-4.1", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/", chatPath: "../evil", }, }); const invalidNullByte = executor.buildUrl("gpt-4.1", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/", chatPath: "/ok\0evil", }, }); assert.equal(valid, "https://proxy.example/v1/custom/chat/completions"); assert.equal(invalid, "https://proxy.example/v1/chat/completions"); assert.equal(invalidNullByte, "https://proxy.example/v1/chat/completions"); }); test("BaseExecutor: legacy openai-compatible providers honor providerSpecificData.apiType", () => { const executor = new BaseExecutor("openai-compatible-sp-openai", {}); const url = executor.buildUrl("gpt-5.4", true, 0, { providerSpecificData: { apiType: "responses", baseUrl: "https://proxy.example/v1/", }, }); assert.equal(url, "https://proxy.example/v1/responses"); }); test("DefaultExecutor.buildUrl handles Gemini, Claude and Qwen variants", () => { const gemini = new DefaultExecutor("gemini"); const claude = new DefaultExecutor("claude"); const qwen = new DefaultExecutor("qwen"); assert.equal( gemini.buildUrl("gemini-2.5-flash", false), "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" ); assert.equal( gemini.buildUrl("gemini-2.5-flash", true), "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse" ); assert.equal(claude.buildUrl("claude-sonnet-4", true), `${PROVIDERS.claude.baseUrl}?beta=true`); assert.equal(qwen.buildUrl("qwen3-coder", true), "https://portal.qwen.ai/v1/chat/completions"); assert.equal( qwen.buildUrl("qwen3-coder", true, 0, { providerSpecificData: { resourceUrl: "custom.qwen.ai" }, }), "https://custom.qwen.ai/v1/chat/completions" ); }); test("DefaultExecutor.buildUrl uses full chat endpoints for hosted OpenAI-compatible providers", () => { const bazaarlink = new DefaultExecutor("bazaarlink"); const crof = new DefaultExecutor("crof"); assert.equal( bazaarlink.buildUrl("auto:free", true), "https://bazaarlink.ai/api/v1/chat/completions" ); assert.equal(crof.buildUrl("gpt-4.1", true), "https://crof.ai/v1/chat/completions"); }); test("DefaultExecutor.buildUrl honors a custom providerSpecificData.baseUrl for the built-in openai provider", () => { const openai = new DefaultExecutor("openai"); // No override → hardcoded OpenAI endpoint (unchanged behavior). assert.equal(openai.buildUrl("gpt-4o", true), "https://api.openai.com/v1/chat/completions"); // Custom base URL (e.g. a proxy/gateway) must be used instead of api.openai.com. assert.equal( openai.buildUrl("gpt-4o", true, 0, { providerSpecificData: { baseUrl: "https://api.contactboxtools.me/v1" }, }), "https://api.contactboxtools.me/v1/chat/completions" ); // Trailing slash is normalized. assert.equal( openai.buildUrl("gpt-4o", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/" }, }), "https://proxy.example/v1/chat/completions" ); // A base URL already pointing at the chat endpoint is kept as-is. assert.equal( openai.buildUrl("gpt-4o", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/chat/completions" }, }), "https://proxy.example/v1/chat/completions" ); }); test("DefaultExecutor.buildUrl handles openai-compatible and anthropic-compatible providers", () => { const openAICompat = new DefaultExecutor("openai-compatible-test"); const openAIResponsesCompat = new DefaultExecutor("openai-compatible-responses-test"); const openAILegacyResponsesCompat = new DefaultExecutor("openai-compatible-sp-openai"); const anthropicCompat = new DefaultExecutor("anthropic-compatible-test"); const anthropicCcCompat = new DefaultExecutor("anthropic-compatible-cc-test"); assert.equal( openAICompat.buildUrl("gpt-4.1", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/" }, }), "https://proxy.example/v1/chat/completions" ); assert.equal( openAICompat.buildUrl("gpt-4.1", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/", chatPath: "/custom/chat", }, }), "https://proxy.example/v1/custom/chat" ); assert.equal( openAIResponsesCompat.buildUrl("gpt-4.1", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/" }, }), "https://proxy.example/v1/responses" ); assert.equal( openAICompat.buildUrl("gpt-4.1", true, 0, { providerSpecificData: { baseUrl: "https://proxy.example/v1/", _omnirouteForceResponsesUpstream: true, }, }), "https://proxy.example/v1/responses" ); assert.equal( openAILegacyResponsesCompat.buildUrl("gpt-5.4", true, 0, { providerSpecificData: { apiType: "responses", baseUrl: "https://proxy.example/v1/", }, }), "https://proxy.example/v1/responses" ); assert.equal( anthropicCompat.buildUrl("claude-sonnet-4", true, 0, { providerSpecificData: { baseUrl: "https://anthropic.example/v1/" }, }), "https://anthropic.example/v1/messages" ); assert.equal( anthropicCompat.buildUrl("claude-sonnet-4", true, 0, { providerSpecificData: { baseUrl: "https://anthropic.example/v1/", chatPath: "/custom/messages", }, }), "https://anthropic.example/v1/custom/messages" ); assert.equal( anthropicCcCompat.buildUrl("claude-sonnet-4", true, 0, { providerSpecificData: { baseUrl: "https://cc.example/v1/messages", }, }), `https://cc.example${CLAUDE_CODE_COMPATIBLE_DEFAULT_CHAT_PATH}` ); }); test("DefaultExecutor.buildUrl normalizes configurable chat-openai-compat base URLs", () => { const bailian = new DefaultExecutor("bailian-coding-plan"); const heroku = new DefaultExecutor("heroku"); const databricks = new DefaultExecutor("databricks"); const azureAi = new DefaultExecutor("azure-ai"); const watsonx = new DefaultExecutor("watsonx"); const oci = new DefaultExecutor("oci"); const sap = new DefaultExecutor("sap"); const modal = new DefaultExecutor("modal"); const reka = new DefaultExecutor("reka"); const maritalk = new DefaultExecutor("maritalk"); const snowflake = new DefaultExecutor("snowflake"); const gigachat = new DefaultExecutor("gigachat"); const siliconflow = new DefaultExecutor("siliconflow"); assert.equal( bailian.buildUrl("qwen3-coder-plus", true, 0, { providerSpecificData: { baseUrl: "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1", }, }), "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1/messages" ); assert.equal( heroku.buildUrl("claude-4-sonnet", true, 0, { providerSpecificData: { baseUrl: "https://us.inference.heroku.com" }, }), "https://us.inference.heroku.com/v1/chat/completions" ); assert.equal( databricks.buildUrl("databricks-gpt-5", true, 0, { providerSpecificData: { baseUrl: "https://adb-1234567890123456.7.azuredatabricks.net/serving-endpoints", }, }), "https://adb-1234567890123456.7.azuredatabricks.net/serving-endpoints/chat/completions" ); assert.equal( azureAi.buildUrl("DeepSeek-V3.1", true, 0, { providerSpecificData: { baseUrl: "https://my-foundry.services.ai.azure.com" }, }), "https://my-foundry.services.ai.azure.com/openai/v1/chat/completions" ); assert.equal( watsonx.buildUrl("ibm/granite-3-3-8b-instruct", true, 0, { providerSpecificData: { baseUrl: "https://ca-tor.ml.cloud.ibm.com" }, }), "https://ca-tor.ml.cloud.ibm.com/ml/gateway/v1/chat/completions" ); assert.equal( oci.buildUrl("openai.gpt-oss-20b", true, 0, { providerSpecificData: { baseUrl: "https://inference.generativeai.us-ashburn-1.oci.oraclecloud.com", }, }), "https://inference.generativeai.us-ashburn-1.oci.oraclecloud.com/openai/v1/chat/completions" ); assert.equal( sap.buildUrl("gpt-4o", true, 0, { providerSpecificData: { baseUrl: "https://sap.example.com/v2/lm/deployments/demo-deployment", }, }), "https://sap.example.com/v2/lm/deployments/demo-deployment/chat/completions" ); assert.equal( modal.buildUrl("Qwen/Qwen3-4B-Thinking-2507-FP8", true, 0, { providerSpecificData: { baseUrl: "https://alice--demo.modal.run/v1", }, }), "https://alice--demo.modal.run/v1/chat/completions" ); assert.equal( reka.buildUrl("reka-core", true, 0, { providerSpecificData: { baseUrl: "https://api.reka.ai/v1", }, }), "https://api.reka.ai/v1/chat/completions" ); assert.equal( maritalk.buildUrl("sabia-4", true, 0, { providerSpecificData: { baseUrl: "https://chat.maritaca.ai/api/chat/inference", }, }), "https://chat.maritaca.ai/api/chat/completions" ); assert.equal( snowflake.buildUrl("llama3.3-70b", true, 0, { providerSpecificData: { baseUrl: "https://account.snowflakecomputing.com" }, }), "https://account.snowflakecomputing.com/api/v2/cortex/inference:complete" ); assert.equal( gigachat.buildUrl("GigaChat-2-Pro", true, 0, { providerSpecificData: { baseUrl: "https://gigachat.devices.sberbank.ru/api/v1" }, }), "https://gigachat.devices.sberbank.ru/api/v1/chat/completions" ); assert.equal( siliconflow.buildUrl("deepseek-ai/DeepSeek-V3.2", true), "https://api.siliconflow.com/v1/chat/completions" ); assert.equal( siliconflow.buildUrl("deepseek-ai/DeepSeek-V3.2", true, 0, { providerSpecificData: { baseUrl: "https://api.siliconflow.cn/v1" }, }), "https://api.siliconflow.cn/v1/chat/completions" ); }); test("DefaultExecutor.buildUrl falls back to OpenAI config for unknown providers", () => { const executor = new DefaultExecutor("unknown-provider"); assert.equal(executor.config.baseUrl, PROVIDERS.openai.baseUrl); assert.equal(executor.buildUrl("gpt-4.1", true), PROVIDERS.openai.baseUrl); }); test("DefaultExecutor.buildUrl applies urlSuffix for zai and glm-coding-apikey", () => { const zai = new DefaultExecutor("zai"); const glmCodingApikey = new DefaultExecutor("glm-coding-apikey"); assert.equal( zai.buildUrl("glm-5", true, 0, { providerSpecificData: { baseUrl: "https://api.z.ai/api/anthropic/v1/messages" }, }), "https://api.z.ai/api/anthropic/v1/messages?beta=true" ); assert.equal( glmCodingApikey.buildUrl("glm-4.7", true, 0, { providerSpecificData: { baseUrl: "https://api.z.ai/api/anthropic/v1/messages" }, }), "https://api.z.ai/api/anthropic/v1/messages?beta=true" ); assert.equal(zai.buildUrl("glm-5", true), "https://api.z.ai/api/anthropic/v1/messages?beta=true"); }); test("DefaultExecutor.buildUrl applies urlSuffix from registry for unknown providers with suffix", () => { const executor = new DefaultExecutor("unknown-provider"); assert.equal(executor.buildUrl("gpt-4.1", true), PROVIDERS.openai.baseUrl); }); test("DefaultExecutor.buildHeaders uses x-api-key for zai and glm-coding-apikey", () => { const zai = new DefaultExecutor("zai"); const glmCodingApikey = new DefaultExecutor("glm-coding-apikey"); const zaiHeaders = zai.buildHeaders({ apiKey: "zai-key" }, true); const glmHeaders = glmCodingApikey.buildHeaders({ apiKey: "glm-key" }, true); assert.equal(zaiHeaders["x-api-key"], "zai-key"); assert.equal(glmHeaders["x-api-key"], "glm-key"); assert.equal(zaiHeaders["Authorization"], undefined); assert.equal(glmHeaders["Authorization"], undefined); }); test("DefaultExecutor.buildHeaders handles Gemini and Claude auth modes", () => { const gemini = new DefaultExecutor("gemini"); const claude = new DefaultExecutor("claude"); const azureAi = new DefaultExecutor("azure-ai"); const oci = new DefaultExecutor("oci"); const sap = new DefaultExecutor("sap"); const modal = new DefaultExecutor("modal"); const maritalk = new DefaultExecutor("maritalk"); const geminiApiKeyHeaders = gemini.buildHeaders({ apiKey: "gem-key" }, true); const geminiOAuthHeaders = gemini.buildHeaders({ accessToken: "gem-token" }, false); const claudeApiKeyHeaders = claude.buildHeaders({ apiKey: "claude-key" }, true); const claudeOAuthHeaders = claude.buildHeaders({ accessToken: "claude-token" }, false); const azureAiHeaders = azureAi.buildHeaders({ apiKey: "azure-ai-key" }, true); const ociHeaders = oci.buildHeaders( { apiKey: "oci-key", projectId: "ocid1.generativeaiproject.oc1.us-chicago-1.example", }, true ); const sapHeaders = sap.buildHeaders( { apiKey: "sap-key", providerSpecificData: { resourceGroup: "shared", }, }, true ); const modalHeaders = modal.buildHeaders( { apiKey: "modal-key", }, true ); const maritalkHeaders = maritalk.buildHeaders({ apiKey: "maritalk-key" }, true); assert.equal(geminiApiKeyHeaders["x-goog-api-key"], "gem-key"); assert.equal(geminiApiKeyHeaders.Accept, "text/event-stream"); assert.equal(geminiApiKeyHeaders.Authorization, undefined); assert.equal(geminiOAuthHeaders.Authorization, "Bearer gem-token"); assert.equal(claudeApiKeyHeaders["x-api-key"], "claude-key"); assert.equal(claudeApiKeyHeaders.Accept, "text/event-stream"); assert.equal(claudeOAuthHeaders.Authorization, "Bearer claude-token"); assert.equal(claudeOAuthHeaders["x-api-key"], undefined); assert.equal(azureAiHeaders["api-key"], "azure-ai-key"); assert.equal(azureAiHeaders.Authorization, undefined); assert.equal(ociHeaders.Authorization, "Bearer oci-key"); assert.equal(ociHeaders["OpenAI-Project"], "ocid1.generativeaiproject.oc1.us-chicago-1.example"); assert.equal(sapHeaders.Authorization, "Bearer sap-key"); assert.equal(sapHeaders["AI-Resource-Group"], "shared"); assert.equal(modalHeaders.Authorization, "Bearer modal-key"); assert.equal(maritalkHeaders.Authorization, "Key maritalk-key"); }); test("DefaultExecutor.buildHeaders handles GLM, default auth and anthropic-compatible headers", () => { const glm = new DefaultExecutor("glm"); const glmt = new DefaultExecutor("glmt"); const openai = new DefaultExecutor("openai"); const anthropicCompat = new DefaultExecutor("anthropic-compatible-test"); const glmHeaders = glm.buildHeaders({ accessToken: "glm-token" }, false); const glmtHeaders = glmt.buildHeaders({ apiKey: "glmt-key" }, false); const openaiHeaders = openai.buildHeaders({ apiKey: "sk-openai" }, true); const anthropicHeaders = anthropicCompat.buildHeaders({ apiKey: "anth-key" }, true); assert.equal(glmHeaders["x-api-key"], "glm-token"); assert.equal(glmtHeaders["x-api-key"], "glmt-key"); assert.equal(openaiHeaders.Authorization, "Bearer sk-openai"); assert.equal(openaiHeaders.Accept, "text/event-stream"); assert.equal(anthropicHeaders["x-api-key"], "anth-key"); assert.equal(anthropicHeaders["anthropic-version"], "2023-06-01"); assert.equal(anthropicHeaders.Accept, "text/event-stream"); }); test("DefaultExecutor.buildHeaders keeps a caller-supplied Anthropic-Version (case-insensitive guard) for anthropic-compatible providers", () => { // An operator may configure a Title-Case "Anthropic-Version" via the provider // config headers. The default-guard at the anthropic-compatible-* branch must // detect it case-insensitively and NOT add a second lowercase // "anthropic-version" key, which undici would otherwise combine into // "2025-01-01, 2023-06-01" and break the upstream request. const anthropicCompat = new DefaultExecutor("anthropic-compatible-test"); // `config` is shared across instances via the provider registry, so snapshot // and restore `config.headers` to avoid leaking the Title-Case override into // other tests. const originalConfigHeaders = anthropicCompat.config.headers; anthropicCompat.config.headers = { ...originalConfigHeaders, "Anthropic-Version": "2025-01-01", }; try { const headers = anthropicCompat.buildHeaders({ apiKey: "anth-key" }, true); const versionKeys = Object.keys(headers).filter( (key) => key.toLowerCase() === "anthropic-version" ); assert.equal(versionKeys.length, 1, "Duplicate anthropic-version header keys found"); assert.equal(headers["Anthropic-Version"], "2025-01-01"); assert.equal(headers["anthropic-version"], undefined); assert.equal(headers["x-api-key"], "anth-key"); } finally { anthropicCompat.config.headers = originalConfigHeaders; } }); test("DefaultExecutor.buildHeaders still defaults anthropic-version when no variant is present", () => { const anthropicCompat = new DefaultExecutor("anthropic-compatible-test"); const headers = anthropicCompat.buildHeaders({ apiKey: "anth-key" }, true); assert.equal(headers["anthropic-version"], "2023-06-01"); }); test("DefaultExecutor local OpenAI-style providers honor custom base URLs and skip empty bearer headers", () => { const lmStudio = new DefaultExecutor("lm-studio"); const vllm = new DefaultExecutor("vllm"); const lmStudioUrl = lmStudio.buildUrl("local-model", true, 0, { providerSpecificData: { baseUrl: "http://127.0.0.1:4321/v1" }, }); const vllmHeaders = vllm.buildHeaders({}, false); assert.equal(lmStudioUrl, "http://127.0.0.1:4321/v1/chat/completions"); assert.equal(vllmHeaders.Authorization, undefined); assert.equal(vllmHeaders.Accept, "application/json"); }); test("DefaultExecutor local providers append /v1/chat/completions for bare hostname base URLs", () => { const llamaCpp = new DefaultExecutor("llama-cpp"); const lmStudio = new DefaultExecutor("lm-studio"); const vllm = new DefaultExecutor("vllm"); const bareHost = llamaCpp.buildUrl("gemma-4", true, 0, { providerSpecificData: { baseUrl: "https://foo.llama.example.com" }, }); const customPath = lmStudio.buildUrl("gemma-4", true, 0, { providerSpecificData: { baseUrl: "https://bar.llama.ai/foo" }, }); const alreadyComplete = vllm.buildUrl("gemma-4", true, 0, { providerSpecificData: { baseUrl: "https://baz.llama.ai/v1/chat/completions" }, }); assert.equal(bareHost, "https://foo.llama.example.com/v1/chat/completions"); assert.equal(customPath, "https://bar.llama.ai/foo/v1/chat/completions"); assert.equal(alreadyComplete, "https://baz.llama.ai/v1/chat/completions"); }); test("DefaultExecutor.buildHeaders handles Snowflake PATs and GigaChat access tokens", () => { const snowflake = new DefaultExecutor("snowflake"); const gigachat = new DefaultExecutor("gigachat"); const snowflakePatHeaders = snowflake.buildHeaders({ apiKey: "pat/test-token" }, false); const snowflakeJwtHeaders = snowflake.buildHeaders({ apiKey: "jwt-token" }, false); const gigachatHeaders = gigachat.buildHeaders({ accessToken: "gigachat-token" }, false); assert.equal(snowflakePatHeaders.Authorization, "Bearer test-token"); assert.equal( snowflakePatHeaders["X-Snowflake-Authorization-Token-Type"], "PROGRAMMATIC_ACCESS_TOKEN" ); assert.equal(snowflakeJwtHeaders.Authorization, "Bearer jwt-token"); assert.equal(snowflakeJwtHeaders["X-Snowflake-Authorization-Token-Type"], "KEYPAIR_JWT"); assert.equal(gigachatHeaders.Authorization, "Bearer gigachat-token"); }); test("DefaultExecutor.buildHeaders strips DashScope headers for Qwen API keys and preserves them for OAuth", () => { const executor = new DefaultExecutor("qwen"); const apiKeyHeaders = executor.buildHeaders({ apiKey: "dash-key" }, true); const oauthHeaders = executor.buildHeaders({ accessToken: "oauth-token" }, true); assert.equal(apiKeyHeaders.Authorization, "Bearer dash-key"); assert.equal( Object.keys(apiKeyHeaders).some((key) => key.toLowerCase().startsWith("x-dashscope-")), false ); assert.equal(oauthHeaders.Authorization, "Bearer oauth-token"); assert.equal(oauthHeaders["X-Dashscope-AuthType"], "qwen-oauth"); assert.equal(oauthHeaders["X-Dashscope-CacheControl"], "enable"); }); test("DefaultExecutor.buildHeaders rotates extra API keys and builds Claude Code compatible headers", () => { const openai = new DefaultExecutor("openai"); const cc = new DefaultExecutor("anthropic-compatible-cc-test"); const first = openai.buildHeaders( { apiKey: "primary", connectionId: "conn-rotation", providerSpecificData: { extraApiKeys: ["extra-1", "extra-2"] }, }, false ); const second = openai.buildHeaders( { apiKey: "primary", connectionId: "conn-rotation", providerSpecificData: { extraApiKeys: ["extra-1", "extra-2"] }, }, false ); const ccHeaders = cc.buildHeaders( { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1" }, }, true ); const ccJsonHeaders = cc.buildHeaders( { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1" }, }, false ); assert.equal(first.Authorization, "Bearer primary"); assert.equal(second.Authorization, "Bearer extra-1"); assert.equal(ccHeaders.Authorization, "Bearer cc-key"); assert.equal(ccHeaders["x-api-key"], undefined); assert.equal(ccHeaders["anthropic-version"], CLAUDE_CODE_COMPATIBLE_ANTHROPIC_VERSION); assert.equal(ccHeaders["X-Claude-Code-Session-Id"], "session-1"); assert.equal(ccHeaders.Accept, "text/event-stream"); assert.equal(ccJsonHeaders.Accept, "application/json"); }); test("DefaultExecutor.execute uses CC-compatible connection defaults to append 1M beta", async () => { const originalFetch = globalThis.fetch; const calls = []; const toPlainHeaders = (headers) => headers instanceof Headers ? Object.fromEntries(headers.entries()) : Object.fromEntries( Object.entries(headers || {}).map(([key, value]) => [ key, value == null ? "" : String(value), ]) ); globalThis.fetch = async (_url, init = {}) => { calls.push({ headers: toPlainHeaders(init.headers) }); return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { const cc = new DefaultExecutor("anthropic-compatible-cc-test"); await cc.execute({ model: "claude-sonnet-4-6", body: { model: "claude-sonnet-4-6", messages: [{ role: "user", content: "hi" }], max_tokens: 1, }, stream: false, credentials: { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1", }, }, clientHeaders: { "x-app": "cli", "user-agent": "claude-cli/2.1.116 (external, cli)", }, extendedContext: false, }); await cc.execute({ model: "claude-sonnet-4-6", body: { model: "claude-sonnet-4-6", messages: [{ role: "user", content: "hi" }], max_tokens: 1, }, stream: false, credentials: { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1", requestDefaults: { context1m: true, redactThinking: true }, }, }, extendedContext: false, }); const anthropicCompat = new DefaultExecutor("anthropic-compatible-test"); await anthropicCompat.execute({ model: "claude-sonnet-4-6", body: { model: "claude-sonnet-4-6", messages: [{ role: "user", content: "hi" }], max_tokens: 1, }, stream: false, credentials: { apiKey: "anth-key", providerSpecificData: { baseUrl: "https://anthropic.example.com/v1", }, }, extendedContext: true, }); } finally { globalThis.fetch = originalFetch; } assert.equal(calls[0].headers["anthropic-beta"].includes(CONTEXT_1M_BETA_HEADER), false); assert.equal( calls[0].headers["anthropic-beta"].includes(CLAUDE_CODE_COMPATIBLE_REDACT_THINKING_BETA), false ); assert.equal(calls[1].headers["anthropic-beta"].includes(CONTEXT_1M_BETA_HEADER), true); assert.equal( calls[1].headers["anthropic-beta"].includes(CLAUDE_CODE_COMPATIBLE_REDACT_THINKING_BETA), true ); assert.equal(calls[2].headers["anthropic-beta"], undefined); }); test("DefaultExecutor.execute reports the exact serialized provider request before fetch", async () => { const originalFetch = globalThis.fetch; let fetchStarted = false; let fetchBody: any = null; let prepared: any = null; let preparedBeforeFetch = false; globalThis.fetch = async (_url, init = {}) => { fetchStarted = true; fetchBody = JSON.parse(String(init.body || "{}")); return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { const cc = new DefaultExecutor("anthropic-compatible-cc-test"); const requestCapture = { capture(request) { preparedBeforeFetch = !fetchStarted; prepared = request; }, body(fallback) { return prepared?.body ?? fallback; }, latest() { return prepared; }, }; const result = await runWithCapture(requestCapture, () => cc.execute({ model: "claude-sonnet-4-6", body: { model: "claude-sonnet-4-6", system: [ { type: "text", text: "x-anthropic-billing-header: cc_version=1.0.0; cc_entrypoint=sdk-cli; cch=00000;", }, ], messages: [{ role: "user", content: "hi" }], max_tokens: 1, reasoning_effort: "xhigh", }, stream: false, credentials: { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1", }, }, }) ); assert.ok(prepared, "prepared request hook should fire before fetch"); assert.equal(preparedBeforeFetch, true); assert.deepEqual(prepared.body, fetchBody); assert.deepEqual(result.transformedBody, fetchBody); assert.equal(prepared.body.reasoning_effort, "high"); assert.equal(fetchBody.reasoning_effort, "high"); assert.match(JSON.stringify(fetchBody), /\bcch=(?!00000)[0-9a-f]{5};/); } finally { globalThis.fetch = originalFetch; } }); test("DefaultExecutor.execute only injects adaptive thinking defaults for Claude models that support x-high effort", async () => { const originalFetch = globalThis.fetch; const requestBodies = []; globalThis.fetch = async (_url, init = {}) => { requestBodies.push(JSON.parse(String(init.body))); return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { const claude = new DefaultExecutor("claude"); await claude.execute({ model: "claude-opus-4-7", body: { model: "claude-opus-4-7", messages: [{ role: "user", content: "hi" }], max_tokens: 1, }, stream: false, credentials: { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1", }, }, clientHeaders: { "x-app": "cli", "user-agent": "claude-cli/2.1.116 (external, cli)", }, extendedContext: false, }); await claude.execute({ model: "claude-haiku-4-5-20251001", body: { model: "claude-haiku-4-5-20251001", messages: [{ role: "user", content: "hi" }], max_tokens: 1, }, stream: false, credentials: { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1", }, }, clientHeaders: { "x-app": "cli", "user-agent": "claude-cli/2.1.116 (external, cli)", }, extendedContext: false, }); await claude.execute({ model: "claude-sonnet-4-6", body: { model: "claude-sonnet-4-6", messages: [{ role: "user", content: "hi" }], max_tokens: 1, thinking: { type: "disabled" }, }, stream: false, credentials: { apiKey: "cc-key", providerSpecificData: { ccSessionId: "session-1", }, }, clientHeaders: { "x-app": "cli", "user-agent": "claude-cli/2.1.116 (external, cli)", }, extendedContext: false, }); } finally { globalThis.fetch = originalFetch; } assert.deepEqual((requestBodies[0] as any).thinking, { type: "adaptive" }); assert.deepEqual((requestBodies[0] as any).context_management, { edits: [{ type: "clear_thinking_20251015", keep: "all" }], }); assert.deepEqual((requestBodies[0] as any).output_config, { effort: "high" }); assert.equal((requestBodies[1] as any).thinking, undefined); assert.equal((requestBodies[1] as any).context_management, undefined); assert.equal((requestBodies[1] as any).output_config, undefined); assert.deepEqual((requestBodies[2] as any).thinking, { type: "disabled" }); assert.equal((requestBodies[2] as any).context_management, undefined); }); test("DefaultExecutor.transformRequest injects OpenAI stream usage and preserves model ids with slashes", () => { const executor = new DefaultExecutor("openai"); const body = { model: "zai-org/GLM-5-FP8", messages: [{ role: "user", content: "hi" }] }; const result = executor.transformRequest("zai-org/GLM-5-FP8", body, true, {}); assert.notEqual(result, body); assert.equal(result.model, "zai-org/GLM-5-FP8"); assert.deepEqual((result as any).stream_options, { include_usage: true }); assert.equal((body as any).stream_options, undefined); }); test("DefaultExecutor.transformRequest only injects stream usage for OpenAI chat targets", () => { const openAICompat = new DefaultExecutor("openai-compatible-test"); const openAIResponsesCompat = new DefaultExecutor("openai-compatible-responses-test"); const chatBody = { model: "gpt-4.1", messages: [{ role: "user", content: "hi" }] }; const responsesBody = { model: "gpt-4.1", input: "hi" }; const chatResult = openAICompat.transformRequest("gpt-4.1", chatBody, true, { providerSpecificData: { baseUrl: "https://proxy.example/v1" }, }); const responsesResult = openAIResponsesCompat.transformRequest("gpt-4.1", responsesBody, true, { providerSpecificData: { baseUrl: "https://proxy.example/v1" }, }); assert.deepEqual((chatResult as any).stream_options, { include_usage: true }); assert.equal((responsesResult as any).stream_options, undefined); }); test("DefaultExecutor.execute routes Responses-shaped MCP requests to /responses for OpenAI-compatible providers", async () => { const originalFetch = globalThis.fetch; const calls: Array<{ url: string; body: any }> = []; globalThis.fetch = async (url, init = {}) => { calls.push({ url: String(url), body: JSON.parse(String(init.body)), }); return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { const executor = new DefaultExecutor("openai-compatible-test"); await executor.execute({ model: "gpt-4.1", body: { model: "gpt-4.1", input: "find tools", tools: [{ type: "tool_search" }], }, stream: false, credentials: { apiKey: "test-key", providerSpecificData: { baseUrl: "https://proxy.example/v1/" }, }, }); } finally { globalThis.fetch = originalFetch; } assert.equal(calls.length, 1); assert.equal(calls[0].url, "https://proxy.example/v1/responses"); assert.equal(calls[0].body.stream_options, undefined); assert.deepEqual(calls[0].body.tools, [{ type: "tool_search" }]); }); test("DefaultExecutor.transformRequest respects disableStreamOptions for OpenAI chat targets", () => { const openAICompat = new DefaultExecutor("openai-compatible-test"); const chatBody = { model: "gpt-4.1", messages: [{ role: "user", content: "hi" }] }; const chatResultDisabled = openAICompat.transformRequest("gpt-4.1", chatBody, true, { providerSpecificData: { baseUrl: "https://proxy.example/v1", disableStreamOptions: true }, }); const chatResultEnabled = openAICompat.transformRequest("gpt-4.1", chatBody, true, { providerSpecificData: { baseUrl: "https://proxy.example/v1", disableStreamOptions: false }, }); assert.equal((chatResultDisabled as any).stream_options, undefined); assert.deepEqual((chatResultEnabled as any).stream_options, { include_usage: true }); }); test("DefaultExecutor.transformRequest injects OpenRouter connection preset", () => { const executor = new DefaultExecutor("openrouter"); const body = { model: "openai/gpt-4", messages: [{ role: "user", content: "hi" }] }; const result = executor.transformRequest("openai/gpt-4", body, true, { providerSpecificData: { preset: " email-copywriter " }, }); assert.equal((result as any).preset, "email-copywriter"); assert.deepEqual((result as any).stream_options, { include_usage: true }); assert.equal((body as any).preset, undefined); const explicit = executor.transformRequest( "openai/gpt-4", { ...body, preset: "client-preset" }, true, { providerSpecificData: { preset: "connection-preset" } } ); assert.equal((explicit as any).preset, "client-preset"); const explicitNull = executor.transformRequest("openai/gpt-4", { ...body, preset: null }, true, { providerSpecificData: { preset: "connection-preset" }, }); assert.equal((explicitNull as any).preset, null); const explicitEmpty = executor.transformRequest("openai/gpt-4", { ...body, preset: "" }, true, { providerSpecificData: { preset: "connection-preset" }, }); assert.equal((explicitEmpty as any).preset, ""); const blank = executor.transformRequest("openai/gpt-4", body, true, { providerSpecificData: { preset: " " }, }); assert.equal((blank as any).preset, undefined); }); test("DefaultExecutor.transformRequest strips stream_options from Anthropic-compatible targets", () => { const anthropicCompat = new DefaultExecutor("anthropic-compatible-test"); const anthropicCcCompat = new DefaultExecutor("anthropic-compatible-cc-test"); const anthropicBody = { model: "claude-sonnet-4-6", messages: [{ role: "user", content: "hi" }], max_tokens: 1, stream_options: { include_usage: true }, }; const ccBody = { model: "claude-sonnet-4-6", messages: [{ role: "user", content: "hi" }], max_tokens: 1, }; const anthropicResult = anthropicCompat.transformRequest( "claude-sonnet-4-6", anthropicBody, true, {} ); const ccResult = anthropicCcCompat.transformRequest("claude-sonnet-4-6", ccBody, true, {}); assert.notEqual(anthropicResult, anthropicBody); assert.equal((anthropicResult as any).stream_options, undefined); assert.equal((ccResult as any).stream_options, undefined); }); test("DefaultExecutor.transformRequest neutralizes incompatible tool_choice for Qwen thinking", () => { const executor = new DefaultExecutor("qwen"); const body = { messages: [{ role: "user", content: "hi" }], thinking: { type: "enabled" }, tool_choice: { type: "function", function: { name: "pwd" } }, }; const result = executor.transformRequest("qwen3-coder-plus", body, true, {}); assert.notEqual(result, body); assert.equal((result as any).tool_choice, "auto"); }); // Port of decolua/9router#1343: openai-compatible-* providers (DeepSeek / Ollama / // local OpenAI-compatible models) often lack native Structured Output, so a // `json_schema` response_format is downgraded to `json_object` with the schema // injected into the system prompt instead. test("DefaultExecutor.transformRequest downgrades json_schema to json_object for openai-compatible providers and injects the schema into a fresh system prompt", () => { const executor = new DefaultExecutor("openai-compatible-deepseek"); const schema = { type: "object", properties: { answer: { type: "string" } }, required: ["answer"], }; const body = { model: "deepseek-chat", messages: [{ role: "user", content: "give me JSON" }], response_format: { type: "json_schema", json_schema: { name: "answer_schema", schema }, }, }; const result = executor.transformRequest("deepseek-chat", body, true, { providerSpecificData: { baseUrl: "https://proxy.example/v1" }, }) as any; // response_format is downgraded to json_object. assert.deepEqual(result.response_format, { type: "json_object" }); // A system message carrying the schema is injected at the front. assert.equal(result.messages[0].role, "system"); assert.match(result.messages[0].content, /strictly follows this JSON schema/); assert.ok(result.messages[0].content.includes('"answer"')); // The original user message is preserved. assert.equal(result.messages[1].role, "user"); assert.equal(result.messages[1].content, "give me JSON"); // Original body is not mutated. assert.equal((body as any).response_format.type, "json_schema"); assert.equal(body.messages.length, 1); }); test("DefaultExecutor.transformRequest appends the json_schema prompt to an existing system message", () => { const executor = new DefaultExecutor("openai-compatible-ollama"); const body = { model: "llama3.1", messages: [ { role: "system", content: "You are concise." }, { role: "user", content: "give me JSON" }, ], response_format: { type: "json_schema", json_schema: { name: "s", schema: { type: "object" } }, }, }; const result = executor.transformRequest("llama3.1", body, true, { providerSpecificData: { baseUrl: "https://proxy.example/v1" }, }) as any; assert.deepEqual(result.response_format, { type: "json_object" }); assert.equal(result.messages[0].role, "system"); assert.match(result.messages[0].content, /^You are concise\./); assert.match(result.messages[0].content, /strictly follows this JSON schema/); // Existing system message object is not mutated in place. assert.equal(body.messages[0].content, "You are concise."); }); test("DefaultExecutor.transformRequest leaves json_schema response_format untouched for native providers", () => { const executor = new DefaultExecutor("openai"); const responseFormat = { type: "json_schema", json_schema: { name: "s", schema: { type: "object" } }, }; const body = { model: "gpt-4.1", messages: [{ role: "user", content: "give me JSON" }], response_format: responseFormat, }; const result = executor.transformRequest("gpt-4.1", body, true, {}) as any; // Native OpenAI keeps the json_schema response_format; no system prompt injected. assert.deepEqual(result.response_format, responseFormat); assert.equal(result.messages.length, 1); assert.equal(result.messages[0].role, "user"); }); test("DefaultExecutor.transformRequest ignores non-json_schema response_format for openai-compatible providers", () => { const executor = new DefaultExecutor("openai-compatible-deepseek"); const body = { model: "deepseek-chat", messages: [{ role: "user", content: "hi" }], response_format: { type: "json_object" }, }; const result = executor.transformRequest("deepseek-chat", body, true, { providerSpecificData: { baseUrl: "https://proxy.example/v1" }, }) as any; assert.deepEqual(result.response_format, { type: "json_object" }); assert.equal(result.messages.length, 1); assert.equal(result.messages[0].role, "user"); }); test("DefaultExecutor.transformRequest applies GLMT preset defaults without overriding explicit values", () => { const executor = new DefaultExecutor("glmt"); const autoBody = { messages: [{ role: "user", content: "hi" }], }; const autoResult = executor.transformRequest("glm-5.1", autoBody, true, {}); assert.notEqual(autoResult, autoBody); assert.equal((autoResult as any).max_tokens, 65536); (assert as any).equal((autoResult as any).temperature, 0.2); (assert as any).deepEqual((autoResult as any).thinking, { type: "enabled", budget_tokens: 24576, }); const explicitBody = { messages: [{ role: "user", content: "hi" }], max_tokens: 4096, temperature: 0.7, thinking: { type: "enabled" }, }; const explicitResult = executor.transformRequest("glm-5.1", explicitBody, true, {}); assert.notEqual(explicitResult, explicitBody); assert.equal((explicitResult as any).max_tokens, 4096); assert.equal((explicitResult as any).temperature, 0.7); assert.deepEqual((explicitResult as any).thinking, { type: "enabled", budget_tokens: 4095, }); }); test("BaseExecutor helpers manage custom user agents and upstream extra headers", () => { const headers = { "user-agent": "old", Authorization: "Bearer old" }; assert.equal(getCustomUserAgent({ customUserAgent: " MyAgent/1.0 " }), "MyAgent/1.0"); assert.equal(getCustomUserAgent({ customUserAgent: " " }), null); setUserAgentHeader(headers, "MyAgent/2.0"); assert.equal(headers["User-Agent"], "MyAgent/2.0"); assert.equal(headers["user-agent"], "MyAgent/2.0"); applyConfiguredUserAgent(headers, { customUserAgent: "MyAgent/3.0" }); assert.equal(headers["User-Agent"], "MyAgent/3.0"); mergeUpstreamExtraHeaders(headers, { Authorization: "Bearer override", "user-agent": "Merged/4.0", "X-Upstream": "1", }); assert.equal(headers.Authorization, "Bearer override"); assert.equal(headers["User-Agent"], "Merged/4.0"); assert.equal(headers["user-agent"], "Merged/4.0"); assert.equal(headers["X-Upstream"], "1"); }); test("BaseExecutor.mergeAbortSignals aborts when either source signal aborts", () => { const primary = new AbortController(); const secondary = new AbortController(); const merged = mergeAbortSignals(primary.signal, secondary.signal); assert.equal(merged.aborted, false); const primaryReason = new Error("primary timeout"); primaryReason.name = "TimeoutError"; primary.abort(primaryReason); assert.equal(merged.aborted, true); assert.equal(merged.reason, primaryReason); const otherPrimary = new AbortController(); const otherSecondary = new AbortController(); const merged2 = mergeAbortSignals(otherPrimary.signal, otherSecondary.signal); const secondaryReason = new Error("client closed"); otherSecondary.abort(secondaryReason); assert.equal(merged2.aborted, true); assert.equal(merged2.reason, secondaryReason); }); test("BaseExecutor.needsRefresh returns true only when expiry is near", () => { const executor = new TestExecutor(); const soon = new Date(Date.now() + 60_000).toISOString(); const later = new Date(Date.now() + 60 * 60 * 1000).toISOString(); assert.equal(executor.needsRefresh({ expiresAt: soon }), true); assert.equal(executor.needsRefresh({ expiresAt: later }), false); assert.equal(executor.needsRefresh({}), false); }); test("DefaultExecutor.refreshCredentials returns null without refresh token", async () => { const executor = new DefaultExecutor("gemini"); const result = await executor.refreshCredentials({}, null); assert.equal(result, null); }); test("DefaultExecutor.needsRefresh requests a proactive token for GigaChat", () => { const executor = new DefaultExecutor("gigachat"); assert.equal(executor.needsRefresh({ apiKey: "base64-basic-credentials" }), true); assert.equal( executor.needsRefresh({ apiKey: "base64-basic-credentials", accessToken: "existing-token", expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(), }), false ); }); test("DefaultExecutor.refreshCredentials delegates to OAuth refresh and returns new tokens", async () => { const executor = new DefaultExecutor("gemini"); const originalFetch = globalThis.fetch; globalThis.fetch = async (url, options) => { assert.match(String(url), /oauth2\.googleapis\.com/); assert.equal(options.method, "POST"); return new Response( JSON.stringify({ access_token: "new-access-token", refresh_token: "new-refresh-token", expires_in: 3600, }), { status: 200, headers: { "Content-Type": "application/json" }, } ); }; try { const result = await executor.refreshCredentials({ refreshToken: "refresh-me" }, null); assert.deepEqual(result, { accessToken: "new-access-token", refreshToken: "new-refresh-token", expiresIn: 3600, }); } finally { globalThis.fetch = originalFetch; } }); test("DefaultExecutor.refreshCredentials swallows refresh errors and logs them", async () => { const executor = new DefaultExecutor("gemini"); const originalFetch = globalThis.fetch; const messages = []; globalThis.fetch = async () => { throw new Error("network down"); }; try { const result = await executor.refreshCredentials( { refreshToken: "refresh-me" }, { error: (tag, message) => messages.push({ tag, message }) } ); assert.equal(result, null); assert.equal(messages.length, 1); assert.match(messages[0].message, /refresh error: network down/); } finally { globalThis.fetch = originalFetch; } }); test("BaseExecutor.execute returns response metadata and merges headers", async () => { const executor = new TestExecutor(); const originalFetch = globalThis.fetch; let captured; globalThis.fetch = async (url, options) => { captured = { url, options }; return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { const result = await executor.execute({ model: "gpt-4.1", body: { messages: [{ role: "user", content: "hi" }] }, stream: true, credentials: { apiKey: "base-key", providerSpecificData: { customUserAgent: "CredsAgent/1.0" }, }, upstreamExtraHeaders: { Authorization: "Bearer override", "user-agent": "UpstreamAgent/2.0", "X-Trace-Id": "trace-1", }, }); assert.equal(result.url, "https://primary.example/v1/chat/completions"); assert.equal(result.response.status, 200); (assert as any).equal((result.transformedBody as any).transformed, true); assert.equal((result.transformedBody as any).model, "gpt-4.1"); assert.equal(result.headers.Authorization, "Bearer override"); assert.equal(result.headers["User-Agent"], "UpstreamAgent/2.0"); assert.equal(result.headers["user-agent"], undefined); assert.equal(result.headers["X-Trace-Id"], "trace-1"); assert.equal(result.headers.Accept, "text/event-stream"); assert.equal(captured.options.body.includes('"transformed":true'), true); } finally { globalThis.fetch = originalFetch; } }); test("BaseExecutor.execute refreshes credentials before the request when needed", async () => { class RefreshingExecutor extends BaseExecutor { constructor() { super("refreshing-provider", { baseUrl: "https://refresh.example/v1/chat/completions", }); } needsRefresh() { return true; } async refreshCredentials() { return { accessToken: "fresh-token", expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(), }; } } const executor = new RefreshingExecutor(); const originalFetch = globalThis.fetch; let capturedHeaders; globalThis.fetch = async (url, options) => { assert.equal(String(url), "https://refresh.example/v1/chat/completions"); capturedHeaders = options.headers; return new Response(JSON.stringify({ ok: true }), { status: 200 }); }; try { await executor.execute({ model: "gpt-4.1", body: {}, stream: false, credentials: { apiKey: "stale-token" }, }); assert.equal(capturedHeaders.Authorization, "Bearer fresh-token"); } finally { globalThis.fetch = originalFetch; } }); test("BaseExecutor.execute falls back to the next base URL after a transport error", async () => { const executor = new TestExecutor(); const originalFetch = globalThis.fetch; const calls = []; globalThis.fetch = async (url) => { calls.push(String(url)); if (calls.length === 1) { throw new Error("first node down"); } return new Response("ok", { status: 200 }); }; try { const result = await executor.execute({ model: "gpt-4.1", body: { hello: "world" }, stream: false, credentials: {}, }); assert.deepEqual(calls, [ "https://primary.example/v1/chat/completions", "https://fallback.example/v1/chat/completions", ]); assert.equal(result.url, "https://fallback.example/v1/chat/completions"); } finally { globalThis.fetch = originalFetch; } }); test("BaseExecutor.execute throws the last error when all URLs fail", async () => { const executor = new TestExecutor(); const originalFetch = globalThis.fetch; globalThis.fetch = async () => { throw new Error("still down"); }; try { await assert.rejects( executor.execute({ model: "gpt-4.1", body: {}, stream: false, credentials: {}, }), /still down/ ); } finally { globalThis.fetch = originalFetch; } }); test("BaseExecutor.execute propagates aborted requests through the merged signal", async () => { const executor = new TestExecutor({ baseUrls: ["https://single.example/v1/chat/completions"] }); const controller = new AbortController(); controller.abort(); const originalFetch = globalThis.fetch; globalThis.fetch = async (url, options) => { assert.equal(options.signal.aborted, true); const error = new Error(`aborted ${url}`); error.name = "AbortError"; throw error; }; try { await assert.rejects( executor.execute({ model: "gpt-4.1", body: {}, stream: false, credentials: {}, signal: controller.signal, }), /aborted/ ); } finally { globalThis.fetch = originalFetch; } }); test("BaseExecutor.execute clears the startup timeout after headers arrive", async () => { const executor = new TestExecutor({ baseUrls: ["https://single.example/v1/chat/completions"] }); const originalFetch = globalThis.fetch; const originalFetchStartTimeoutMs = BaseExecutor.FETCH_START_TIMEOUT_MS; let capturedSignal; BaseExecutor.FETCH_START_TIMEOUT_MS = 20; globalThis.fetch = async (_url, options) => { capturedSignal = options.signal; return new Response("ok", { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { await executor.execute({ model: "gpt-4.1", body: {}, stream: true, credentials: {}, }); assert.equal(capturedSignal?.aborted, false); await new Promise((resolve) => setTimeout(resolve, 40)); assert.equal(capturedSignal?.aborted, false); } finally { BaseExecutor.FETCH_START_TIMEOUT_MS = originalFetchStartTimeoutMs; globalThis.fetch = originalFetch; } }); // Regression test for issue #1454: duplicate anthropic-version header when // Claude Code CLI headers are detected on the native `claude` provider. // The provider config seeds headers with Title-Case "Anthropic-Version" while // the Claude-Code patch injects lowercase "anthropic-version". Before the fix, // both keys coexisted in the JS object and undici combined their values into // "2023-06-01, 2023-06-01", causing a 400 from Anthropic. test("DefaultExecutor.execute does not produce duplicate anthropic-version header when Claude Code CLI headers are present", async () => { const executor = new DefaultExecutor("claude"); const originalFetch = globalThis.fetch; let capturedHeaders: Record = {}; globalThis.fetch = async (_url, init = {}) => { // Capture raw headers without normalisation so case-variant duplicate keys are visible. capturedHeaders = (init.headers as Record) || {}; return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { "Content-Type": "application/json" }, }); }; try { await executor.execute({ model: "claude-sonnet-4-6", body: { model: "claude-sonnet-4-6", messages: [{ role: "user", content: "hi" }], max_tokens: 1, }, stream: false, credentials: { accessToken: "oauth-token" }, clientHeaders: { "x-app": "cli", "user-agent": "claude-cli/2.1.116 (external, cli)", "anthropic-beta": "oauth-2025-04-20", }, }); } finally { globalThis.fetch = originalFetch; } // Must be exactly one key — not multiple case variants that undici would combine const versionKeys = Object.keys(capturedHeaders).filter( (k) => k.toLowerCase() === "anthropic-version" ); assert.equal(versionKeys.length, 1, "Duplicate anthropic-version header keys found"); assert.equal(capturedHeaders[versionKeys[0]], "2023-06-01"); });