From 368b5f33da33db570722e191e079ecad08384a02 Mon Sep 17 00:00:00 2001 From: jatmn Date: Thu, 30 Jul 2026 11:59:55 -0700 Subject: [PATCH] test(openai-shim): remove migrated executor duplicates --- src/services/api/openaiShim.test.ts | 5641 --------------------------- 1 file changed, 5641 deletions(-) diff --git a/src/services/api/openaiShim.test.ts b/src/services/api/openaiShim.test.ts index e53292180..27718f87b 100644 --- a/src/services/api/openaiShim.test.ts +++ b/src/services/api/openaiShim.test.ts @@ -586,115 +586,6 @@ afterEach(() => { releaseSharedMutationLock() } }) - -// openaiShim test extraction seam 001 start: strips canonical Anthropic headers from direct shim defaultHeaders - -// openaiShim test extraction seam 001 end - - -// openaiShim test extraction seam 002 start: uses OpenAI-compatible responses endpoint when OPENAI_API_FORMAT=responses -test('uses OpenAI-compatible responses endpoint when OPENAI_API_FORMAT=responses', async () => { - process.env.OPENAI_API_FORMAT = 'responses' - let capturedUrl = '' - let capturedBody: Record | undefined - - globalThis.fetch = (async (input, init) => { - capturedUrl = String(input) - capturedBody = JSON.parse(String(init?.body)) as Record - - return new Response( - JSON.stringify({ - id: 'resp-1', - model: 'gpt-5.4', - output: [ - { - type: 'message', - role: 'assistant', - content: [{ type: 'output_text', text: 'ok' }], - }, - ], - usage: { - input_tokens: 8, - output_tokens: 3, - total_tokens: 11, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-5.4', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedUrl).toBe('http://example.test/v1/responses') - expect(capturedBody?.model).toBe('gpt-5.4') - expect(capturedBody?.instructions).toBe('test system') - expect(capturedBody?.max_output_tokens).toBe(64) - expect(capturedBody?.store).toBe(false) - expect(capturedBody?.input).toEqual([ - { - type: 'message', - role: 'user', - content: [{ type: 'input_text', text: 'hello' }], - }, - ]) -}) -// openaiShim test extraction seam 002 end - - -// openaiShim test extraction seam 003 start: nests reasoning effort for OpenAI-compatible responses endpoint -test('nests reasoning effort for OpenAI-compatible responses endpoint', async () => { - process.env.OPENAI_API_FORMAT = 'responses' - let capturedBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - capturedBody = JSON.parse(String(init?.body)) as Record - - return new Response( - JSON.stringify({ - id: 'resp-1', - model: 'gpt-5.4', - output: [ - { - type: 'message', - role: 'assistant', - content: [{ type: 'output_text', text: 'ok' }], - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ reasoningEffort: 'high' }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-5.4', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedBody?.reasoning).toEqual({ effort: 'high', summary: 'auto' }) - expect(capturedBody?.include).toEqual(['reasoning.encrypted_content']) - expect(capturedBody).not.toHaveProperty('reasoning_effort') - expect(capturedBody).not.toHaveProperty('reasoning_summary') -}) // openaiShim test extraction seam 003 end test('auto-routes gpt-5.6 to /responses on api.openai.com with tools and nested reasoning', async () => { @@ -1262,65 +1153,6 @@ test('auto-routed gpt-5.6 on an Azure base nests reasoning.effort and the encryp expect(capturedBody?.reasoning).toEqual({ effort: 'high', summary: 'auto' }) expect(capturedBody?.include).toEqual(['reasoning.encrypted_content']) }) - -// openaiShim test extraction seam 004 start: uses OpenAI-compatible responses endpoint with text chunk types when OPENAI_API_FORMAT=responses_compat -test('uses OpenAI-compatible responses endpoint with text chunk types when OPENAI_API_FORMAT=responses_compat', async () => { - process.env.OPENAI_API_FORMAT = 'responses_compat' - let capturedUrl = '' - let capturedBody: Record | undefined - - globalThis.fetch = (async (input, init) => { - capturedUrl = String(input) - capturedBody = JSON.parse(String(init?.body)) as Record - - return new Response( - JSON.stringify({ - id: 'resp-1', - model: 'gpt-5.4', - output: [ - { - type: 'message', - role: 'assistant', - content: [{ type: 'output_text', text: 'ok' }], - }, - ], - usage: { - input_tokens: 8, - output_tokens: 3, - total_tokens: 11, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-5.4', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedUrl).toBe('http://example.test/v1/responses') - expect(capturedBody?.model).toBe('gpt-5.4') - expect(capturedBody?.instructions).toBe('test system') - expect(capturedBody?.max_output_tokens).toBe(64) - expect(capturedBody?.store).toBe(false) - expect(capturedBody?.input).toEqual([ - { - type: 'message', - role: 'user', - content: [{ type: 'text', text: 'hello' }], - }, - ]) -}) // openaiShim test extraction seam 004 end @@ -1369,636 +1201,6 @@ test('uses correct empty input fallback schema for standard responses and respon }, ]) }) - -// openaiShim test extraction seam 005 end - - -// openaiShim test extraction seam 006 start: strips store from strict OpenAI-compatible responses providers -test('strips store from strict OpenAI-compatible responses providers', async () => { - process.env.OPENAI_BASE_URL = 'https://api.moonshot.ai/v1' - process.env.OPENAI_API_FORMAT = 'responses' - let capturedUrl = '' - let capturedBody: Record | undefined - - globalThis.fetch = (async (input, init) => { - capturedUrl = String(input) - capturedBody = JSON.parse(String(init?.body)) as Record - - return new Response( - JSON.stringify({ - id: 'resp-1', - model: 'kimi-k2.5', - output: [ - { - type: 'message', - role: 'assistant', - content: [{ type: 'output_text', text: 'ok' }], - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'kimi-k2.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedUrl).toBe('https://api.moonshot.ai/v1/responses') - expect(capturedBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 006 end - - -// openaiShim test extraction seam 007 start: strips store when providerOverride routes chat_completions to the Gemini host -test('strips store when providerOverride routes chat_completions to the Gemini host', async () => { - let capturedBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - capturedBody = JSON.parse(String(init?.body)) as Record - return new Response( - JSON.stringify({ - id: 'chatcmpl-gemini', - choices: [{ message: { role: 'assistant', content: 'ok' } }], - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - defaultHeaders: {}, - providerOverride: { - model: 'gemini-3.1-pro', - baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai', - apiKey: 'gemini-key', - }, - }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gemini-3.1-pro', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 007 end - - -// openaiShim test extraction seam 008 start: strips store when providerOverride routes responses API to the Gemini host -test('strips store when providerOverride routes responses API to the Gemini host', async () => { - process.env.OPENAI_API_FORMAT = 'responses' - let capturedBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - capturedBody = JSON.parse(String(init?.body)) as Record - return new Response( - JSON.stringify({ - id: 'resp-gemini', - output: [ - { - type: 'message', - role: 'assistant', - content: [{ type: 'output_text', text: 'ok' }], - }, - ], - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - defaultHeaders: {}, - providerOverride: { - model: 'gemini-3.1-pro', - baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai', - apiKey: 'gemini-key', - }, - }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gemini-3.1-pro', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 008 end - - -// openaiShim test extraction seam 009 start: uses custom OpenAI-compatible auth header value when configured -test('uses custom OpenAI-compatible auth header value when configured', async () => { - process.env.OPENAI_API_KEY = 'generic-key' - process.env.OPENAI_AUTH_HEADER = 'api-key' - process.env.OPENAI_AUTH_HEADER_VALUE = 'hicap-header-value' - let capturedHeaders: Headers | undefined - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers as HeadersInit) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - choices: [{ message: { role: 'assistant', content: 'ok' } }], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-4o', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedHeaders?.get('api-key')).toBe('hicap-header-value') - expect(capturedHeaders?.get('authorization')).toBeNull() -}) -// openaiShim test extraction seam 009 end - - -// openaiShim test extraction seam 010 start: uses Hicap api-key auth header for the Hicap route -test('uses Hicap api-key auth header for the Hicap route', async () => { - process.env.OPENAI_API_KEY = 'hicap-live-key' - process.env.OPENAI_BASE_URL = 'https://api.hicap.ai/v1' - let capturedHeaders: Headers | undefined - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers as HeadersInit) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - choices: [{ message: { role: 'assistant', content: 'ok' } }], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'claude-opus-4.8', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedHeaders?.get('api-key')).toBe('hicap-live-key') - expect(capturedHeaders?.get('authorization')).toBeNull() -}) -// openaiShim test extraction seam 010 end - - -// openaiShim test extraction seam 011 start: defaults Authorization custom auth header to bearer scheme -test('defaults Authorization custom auth header to bearer scheme', async () => { - process.env.OPENAI_API_KEY = 'authorization-key' - process.env.OPENAI_AUTH_HEADER = 'Authorization' - let capturedHeaders: Headers | undefined - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers as HeadersInit) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - choices: [{ message: { role: 'assistant', content: 'ok' } }], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-4o', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedHeaders?.get('authorization')).toBe('Bearer authorization-key') -}) -// openaiShim test extraction seam 011 end - - -// openaiShim test extraction seam 012 start: honors bearer scheme for custom OpenAI-compatible auth headers -test('honors bearer scheme for custom OpenAI-compatible auth headers', async () => { - process.env.OPENAI_API_KEY = 'custom-key' - process.env.OPENAI_AUTH_HEADER = 'X-Custom-Authorization' - process.env.OPENAI_AUTH_SCHEME = 'bearer' - let capturedHeaders: Headers | undefined - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers as HeadersInit) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - choices: [{ message: { role: 'assistant', content: 'ok' } }], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-4o', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedHeaders?.get('x-custom-authorization')).toBe('Bearer custom-key') - expect(capturedHeaders?.get('authorization')).toBeNull() -}) -// openaiShim test extraction seam 012 end - - -// openaiShim test extraction seam 013 start: ignores custom auth header value when no custom header is configured -test('ignores custom auth header value when no custom header is configured', async () => { - delete process.env.OPENAI_API_KEY - process.env.OPENAI_AUTH_HEADER_VALUE = 'gateway-header-value' - let capturedHeaders: Headers | undefined - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers as HeadersInit) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - choices: [{ message: { role: 'assistant', content: 'ok' } }], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ defaultHeaders: {} }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-4o', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedHeaders?.get('authorization')).toBeNull() -}) -// openaiShim test extraction seam 013 end - - -// openaiShim test extraction seam 014 start: strips canonical Anthropic headers from per-request shim headers too - -// openaiShim test extraction seam 014 end - - -// openaiShim test extraction seam 015 start: applies descriptor static headers before client and request headers -test('applies descriptor static headers before client and request headers', async () => { - let capturedHeaders: Headers | undefined - - registerGateway({ - id: 'shim-header-test', - label: 'Shim Header Test', - category: 'hosted', - defaultBaseUrl: 'https://shim-header-test.example/v1', - defaultModel: 'shim-test-model', - setup: { - requiresAuth: true, - authMode: 'api-key', - credentialEnvVars: ['OPENAI_API_KEY'], - }, - transportConfig: { - kind: 'openai-compatible', - openaiShim: { - headers: { - 'x-static-header': 'from-descriptor', - 'x-override-header': 'from-descriptor', - }, - }, - }, - }) - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://shim-header-test.example/v1' - process.env.OPENAI_MODEL = 'shim-test-model' - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'shim-test-model', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 8, - completion_tokens: 3, - total_tokens: 11, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - defaultHeaders: { - 'x-override-header': 'from-client', - }, - }) as OpenAIShimClient - - await client.beta.messages.create( - { - model: 'shim-test-model', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }, - { - headers: { - 'x-override-header': 'from-request', - }, - }, - ) - - expect(capturedHeaders?.get('x-static-header')).toBe('from-descriptor') - expect(capturedHeaders?.get('x-override-header')).toBe('from-request') -}) -// openaiShim test extraction seam 015 end - - -// openaiShim test extraction seam 016 start: opengateway sends Accept-Encoding: identity header on chat requests -test('opengateway sends Accept-Encoding: identity header on chat requests', async () => { - let capturedHeaders: Headers | undefined - - registerGateway({ - id: 'gitlawb-opengateway-test', - label: 'Gitlawb Opengateway', - category: 'aggregating', - defaultBaseUrl: 'https://opengateway.gitlawb.com/v1/xiaomi-mimo', - defaultModel: 'mimo-v2.5-pro', - setup: { - requiresAuth: false, - authMode: 'none', - }, - transportConfig: { - kind: 'openai-compatible', - openaiShim: { - headers: { - 'Accept-Encoding': 'identity', - }, - defaultAuthHeader: { - name: 'api-key', - scheme: 'raw', - }, - preserveReasoningContent: true, - requireReasoningContentOnAssistantMessages: true, - reasoningContentFallback: '', - maxTokensField: 'max_completion_tokens', - supportsApiFormatSelection: false, - supportsAuthHeaders: false, - }, - }, - }) - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://opengateway.gitlawb.com/v1/xiaomi-mimo' - process.env.OPENAI_MODEL = 'mimo-v2.5-pro' - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'mimo-v2.5-pro', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 8, - completion_tokens: 3, - total_tokens: 11, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create( - { - model: 'mimo-v2.5-pro', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }, - {}, - ) - - expect(capturedHeaders?.get('Accept-Encoding')).toBe('identity') -}) -// openaiShim test extraction seam 016 end - - -// openaiShim test extraction seam 017 start: strips Anthropic-specific headers on GitHub Codex transport requests -test('strips Anthropic-specific headers on GitHub Codex transport requests', async () => { - let capturedHeaders: Headers | undefined - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_API_KEY = 'github-test-key' - process.env.GITHUB_TOKEN = 'stored-secret' - delete process.env.GITHUB_COPILOT_KEY - delete process.env.OPENAI_BASE_URL - delete process.env.OPENAI_MODEL - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers) - - return new Response('', { - status: 200, - headers: { - 'Content-Type': 'text/event-stream', - }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create( - { - model: 'github:gpt-5-codex', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: true, - }, - { - headers: { - 'anthropic-version': '2023-06-01', - 'anthropic-beta': 'prompt-caching-2024-07-31', - 'x-anthropic-additional-protection': 'true', - 'x-safe-header': 'keep-me', - }, - }, - ) - - expect(capturedHeaders?.get('anthropic-version')).toBeNull() - expect(capturedHeaders?.get('anthropic-beta')).toBeNull() - expect(capturedHeaders?.get('x-anthropic-additional-protection')).toBeNull() - expect(capturedHeaders?.get('x-safe-header')).toBe('keep-me') - expect(capturedHeaders?.get('authorization')).toBe('Bearer github-test-key') - expect(capturedHeaders?.get('editor-plugin-version')).toBe('copilot-chat/0.26.7') -}) -// openaiShim test extraction seam 017 end - - -// openaiShim test extraction seam 018 start: uses direct GitHub Copilot Enterprise key for shim authentication -test('uses direct GitHub Copilot Enterprise key for shim authentication', async () => { - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.GITHUB_COPILOT_KEY = 'enterprise-direct-key' - process.env.GITHUB_ENTERPRISE_URL = 'https://github.mycompany.com' - delete process.env.OPENAI_API_KEY - delete process.env.OPENAI_BASE_URL - - const { authorization, url } = await captureChatCompletionRequest( - 'github:gpt-4o', - ) - - expect(authorization).toBe('Bearer enterprise-direct-key') - expect(url).toBe('https://github.mycompany.com/api/copilot/chat/completions') -}) -// openaiShim test extraction seam 018 end - - -// openaiShim test extraction seam 019 start: direct GitHub Copilot key wins over stale OpenAI key -test('direct GitHub Copilot key wins over stale OpenAI key', async () => { - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.GITHUB_COPILOT_KEY = 'enterprise-direct-key' - process.env.GITHUB_ENTERPRISE_URL = 'https://github.mycompany.com' - process.env.OPENAI_API_KEY = 'stale-openai-key' - delete process.env.OPENAI_BASE_URL - - const { authorization } = await captureChatCompletionRequest( - 'github:gpt-4o', - ) - - expect(authorization).toBe('Bearer enterprise-direct-key') -}) -// openaiShim test extraction seam 019 end - - -// openaiShim test extraction seam 020 start: strips Anthropic-specific headers on GitHub Codex transport with providerOverride API key -test('strips Anthropic-specific headers on GitHub Codex transport with providerOverride API key', async () => { - let capturedHeaders: Headers | undefined - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_API_KEY = 'env-should-not-win' - delete process.env.OPENAI_BASE_URL - delete process.env.OPENAI_MODEL - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers) - - return new Response('', { - status: 200, - headers: { - 'Content-Type': 'text/event-stream', - }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - providerOverride: { - model: 'github:gpt-5-codex', - baseURL: 'https://api.githubcopilot.com', - apiKey: 'provider-override-key', - }, - }) as OpenAIShimClient - - await client.beta.messages.create( - { - model: 'ignored', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: true, - }, - { - headers: { - 'anthropic-version': '2023-06-01', - 'x-claude-remote-session-id': 'remote-123', - 'x-safe-header': 'keep-me', - }, - }, - ) - - expect(capturedHeaders?.get('anthropic-version')).toBeNull() - expect(capturedHeaders?.get('x-claude-remote-session-id')).toBeNull() - expect(capturedHeaders?.get('x-safe-header')).toBe('keep-me') - expect(capturedHeaders?.get('authorization')).toBe('Bearer provider-override-key') - expect(capturedHeaders?.get('editor-plugin-version')).toBe('copilot-chat/0.26.7') -}) // openaiShim test extraction seam 020 end @@ -2287,159 +1489,6 @@ test('Gemini SSE stream rejects with idle timeout when it stalls', async () => { expect((caught as Error).name).toBe('StreamIdleTimeoutError') expect((stalled.cancelReasons[0] as Error).name).toBe('StreamIdleTimeoutError') }) -// openaiShim test extraction seam 026 end - - -// openaiShim test extraction seam 027 start: OpenAI-compatible stream rejects with idle timeout when it stalls after a chunk -test('OpenAI-compatible stream rejects with idle timeout when it stalls after a chunk', async () => { - await getStreamIdleTestApi('stream-idle-openai-stall') - process.env.CLAUDE_STREAM_IDLE_TIMEOUT_MS = '25' - const stalled = makeStallingResponse( - makeOpenAIStreamFrame({ role: 'assistant', content: 'partial' }), - ) - - globalThis.fetch = (async () => stalled.response) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - const result = await client.beta.messages - .create({ - model: 'glm-5.2', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: true, - }) - .withResponse() - - const events: Array> = [] - const startedAt = Date.now() - let caught: unknown - try { - for await (const event of result.data) { - events.push(event) - } - } catch (error) { - caught = error - } finally { - stalled.close() - } - - expect(Date.now() - startedAt).toBeLessThan(500) - expect((caught as Error).name).toBe('StreamIdleTimeoutError') - expect((stalled.cancelReasons[0] as Error).name).toBe('StreamIdleTimeoutError') - const textDeltas = events.flatMap(event => { - const eventDelta = event.delta as { type?: string; text?: string } | undefined - return eventDelta?.type === 'text_delta' && typeof eventDelta.text === 'string' - ? [eventDelta.text] - : [] - }) - expect(textDeltas).toEqual(['partial']) -}) -// openaiShim test extraction seam 027 end - - -// openaiShim test extraction seam 028 start: OpenAI-compatible stream keeps slow active chunks alive under the idle timeout -test('OpenAI-compatible stream keeps slow active chunks alive under the idle timeout', async () => { - await getStreamIdleTestApi('stream-idle-openai-active') - process.env.CLAUDE_STREAM_IDLE_TIMEOUT_MS = '500' - const startedAt = Date.now() - const encoder = new TextEncoder() - const chunks = makeStreamChunks([ - { - id: 'chatcmpl-active', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [ - { - index: 0, - delta: { role: 'assistant', content: 'hel' }, - finish_reason: null, - }, - ], - }, - { - id: 'chatcmpl-active', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [ - { - index: 0, - delta: { content: 'lo' }, - finish_reason: null, - }, - ], - }, - { - id: 'chatcmpl-active', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [ - { - index: 0, - delta: {}, - finish_reason: 'stop', - }, - ], - }, - ]) - let emitTimer: ReturnType | undefined - - globalThis.fetch = asMockFetch(mock(async () => - new Response( - new ReadableStream({ - start(controller) { - let index = 0 - const emit = () => { - emitTimer = undefined - const chunk = chunks[index++] - if (chunk === undefined) { - controller.close() - return - } - controller.enqueue(encoder.encode(chunk)) - emitTimer = setTimeout(emit, 200) - } - emit() - }, - cancel() { - if (emitTimer !== undefined) { - clearTimeout(emitTimer) - emitTimer = undefined - } - }, - }), - { - headers: { - 'Content-Type': 'text/event-stream', - }, - }, - ))) - - const client = createOpenAIShimClient({}) as OpenAIShimClient - const result = await client.beta.messages - .create({ - model: 'glm-5.2', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: true, - }) - .withResponse() - - const textDeltas: string[] = [] - for await (const event of result.data) { - const streamDelta = (event as { delta?: { type?: string; text?: string } }).delta - if ( - streamDelta?.type === 'text_delta' && - typeof streamDelta.text === 'string' - ) { - textDeltas.push(streamDelta.text) - } - } - - expect(Date.now() - startedAt).toBeGreaterThan(500) - expect(textDeltas.join('')).toBe('hello') -}) // openaiShim test extraction seam 028 end @@ -3142,445 +2191,6 @@ test('uses max_tokens instead of max_completion_tokens for local providers', asy stream: false, }) }) -// openaiShim test extraction seam 044 end - -test('does not send stream_options to local OpenAI-compatible servers', async () => { - process.env.OPENAI_BASE_URL = 'http://127.0.0.1:8000/v1' - - globalThis.fetch = (async (_input, init) => { - const body = JSON.parse(String(init?.body)) - expect(body.stream).toBe(true) - expect(body.stream_options).toBeUndefined() - return new Response('', { - headers: { 'Content-Type': 'text/event-stream' }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'local-vllm-model', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: true, - }) -}) - -// openaiShim test extraction seam 045 start: keeps max_completion_tokens for non-local non-github providers -test('keeps max_completion_tokens for non-local non-github providers', async () => { - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - - globalThis.fetch = (async (_input, init) => { - const body = JSON.parse(String(init?.body)) - expect(body.max_completion_tokens).toBe(64) - expect(body.max_tokens).toBeUndefined() - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'gpt-4o', - choices: [ - { - message: { - role: 'assistant', - content: 'hello', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 5, - completion_tokens: 1, - total_tokens: 6, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-4o', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) -}) -// openaiShim test extraction seam 045 end - - -// openaiShim test extraction seam 046 start: uses route-specific credential env vars for descriptor-backed openai-compatible routes -test('uses route-specific credential env vars for descriptor-backed openai-compatible routes', async () => { - let capturedHeaders: Headers | undefined - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://openrouter.ai/api/v1' - process.env.OPENROUTER_API_KEY = 'or-route-key' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = new Headers(init?.headers) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'openai/gpt-5-mini', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 5, - completion_tokens: 1, - total_tokens: 6, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'openai/gpt-5-mini', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - - expect(capturedHeaders?.get('authorization')).toBe('Bearer or-route-key') -}) -// openaiShim test extraction seam 046 end - - -// openaiShim test extraction seam 047 start: preserves Gemini tool call extra_content in follow-up requests - -// openaiShim test extraction seam 047 end - - -// openaiShim test extraction seam 048 start: replays Gemini tool signatures for OpenGateway Gemini models - -// openaiShim test extraction seam 048 end - - -// openaiShim test extraction seam 049 start: OpenGateway MiMo replays real reasoning_content without adding empty fallback -test('OpenGateway MiMo replays real reasoning_content without adding empty fallback', async () => { - process.env.OPENAI_BASE_URL = 'https://opengateway.gitlawb.com/v1' - process.env.OPENAI_MODEL = 'mimo-v2.5-pro' - let requestBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-opengateway-mimo', - model: 'mimo-v2.5-pro', - choices: [ - { - message: { - role: 'assistant', - content: 'done', - }, - finish_reason: 'stop', - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'mimo-v2.5-pro', - messages: [ - { role: 'user', content: 'Use an agent' }, - { - role: 'assistant', - content: [ - { - type: 'thinking', - thinking: 'Need to inspect code with an agent.', - }, - { - type: 'tool_use', - id: 'call_agent_1', - name: 'Agent', - input: { - description: 'Inspect code', - prompt: 'Look at the relevant code', - subagent_type: 'general-purpose', - }, - }, - ], - }, - { - role: 'user', - content: [ - { - type: 'tool_result', - tool_use_id: 'call_agent_1', - content: 'Agent finished', - }, - ], - }, - ], - max_tokens: 64, - stream: false, - }) - - const assistantWithToolCall = (requestBody?.messages as Array>).find( - message => Array.isArray(message.tool_calls), - ) - - expect(assistantWithToolCall).toBeDefined() - expect(assistantWithToolCall?.reasoning_content).toBe( - 'Need to inspect code with an agent.', - ) - expect(requestBody).not.toHaveProperty('store') -}) -// openaiShim test extraction seam 049 end - - -// openaiShim test extraction seam 050 start: Xiaomi MiMo replays real reasoning_content without adding empty fallback -test('Xiaomi MiMo replays real reasoning_content without adding empty fallback', async () => { - process.env.OPENAI_BASE_URL = 'https://api.xiaomimimo.com/v1' - process.env.OPENAI_MODEL = 'mimo-v2.5-pro' - process.env.MIMO_API_KEY = 'mimo-test-key' - delete process.env.OPENAI_API_KEY - let requestBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-mimo', - model: 'mimo-v2.5-pro', - choices: [ - { - message: { - role: 'assistant', - content: 'done', - }, - finish_reason: 'stop', - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'mimo-v2.5-pro', - messages: [ - { role: 'user', content: 'Use an agent' }, - { - role: 'assistant', - content: [ - { - type: 'thinking', - thinking: 'Need to inspect code with an agent.', - }, - { - type: 'tool_use', - id: 'call_agent_1', - name: 'Agent', - input: { - description: 'Inspect code', - prompt: 'Look at the relevant code', - subagent_type: 'general-purpose', - }, - }, - ], - }, - { - role: 'user', - content: [ - { - type: 'tool_result', - tool_use_id: 'call_agent_1', - content: 'Agent finished', - }, - ], - }, - ], - max_tokens: 64, - stream: false, - }) - - const assistantWithToolCall = (requestBody?.messages as Array>).find( - message => Array.isArray(message.tool_calls), - ) - - expect(assistantWithToolCall).toBeDefined() - expect(assistantWithToolCall?.reasoning_content).toBe( - 'Need to inspect code with an agent.', - ) - expect(requestBody).not.toHaveProperty('store') -}) -// openaiShim test extraction seam 050 end - - -// openaiShim test extraction seam 051 start: OpenGateway MiMo does not synthesize empty reasoning_content when missing -test('OpenGateway MiMo does not synthesize empty reasoning_content when missing', async () => { - process.env.OPENAI_BASE_URL = 'https://opengateway.gitlawb.com/v1' - process.env.OPENAI_MODEL = 'mimo-v2.5-pro' - let requestBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - - return new Response( - JSON.stringify({ - id: 'chatcmpl-opengateway-mimo', - model: 'mimo-v2.5-pro', - choices: [ - { - message: { - role: 'assistant', - content: 'done', - }, - finish_reason: 'stop', - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'mimo-v2.5-pro', - messages: [ - { role: 'user', content: 'Use an agent' }, - { - role: 'assistant', - content: [ - { - type: 'tool_use', - id: 'call_agent_1', - name: 'Agent', - input: { - description: 'Inspect code', - prompt: 'Look at the relevant code', - subagent_type: 'general-purpose', - }, - }, - ], - }, - { - role: 'user', - content: [ - { - type: 'tool_result', - tool_use_id: 'call_agent_1', - content: 'Agent finished', - }, - ], - }, - ], - max_tokens: 64, - stream: false, - }) - - const assistantWithToolCall = (requestBody?.messages as Array>).find( - message => Array.isArray(message.tool_calls), - ) - - expect(assistantWithToolCall).toBeDefined() - expect(assistantWithToolCall).not.toHaveProperty('reasoning_content') - expect(requestBody).not.toHaveProperty('store') -}) -// openaiShim test extraction seam 051 end - - -// openaiShim test extraction seam 052 start: strips unsupported stream_options for Xiaomi MiMo streams -test('strips unsupported stream_options for Xiaomi MiMo streams', async () => { - process.env.OPENAI_BASE_URL = 'https://api.xiaomimimo.com/v1' - process.env.OPENAI_MODEL = 'mimo-v2.5-pro' - process.env.MIMO_API_KEY = 'mimo-test-key' - delete process.env.OPENAI_API_KEY - let requestBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - - return makeSseResponse( - makeStreamChunks([ - { - id: 'chatcmpl-mimo', - object: 'chat.completion.chunk', - model: 'mimo-v2.5-pro', - choices: [ - { - index: 0, - delta: { role: 'assistant', content: 'done' }, - finish_reason: null, - }, - ], - }, - { - id: 'chatcmpl-mimo', - object: 'chat.completion.chunk', - model: 'mimo-v2.5-pro', - choices: [ - { - index: 0, - delta: {}, - finish_reason: 'stop', - }, - ], - }, - ]), - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'mimo-v2.5-pro', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: true, - }) - - expect(requestBody).toMatchObject({ - stream: true, - max_completion_tokens: 64, - }) - expect(requestBody).not.toHaveProperty('stream_options') - expect(requestBody).not.toHaveProperty('store') -}) // openaiShim test extraction seam 052 end @@ -3882,634 +2492,6 @@ test('preserves mixed text and image tool results as multipart content', async ( image_url: { url: 'data:image/png;base64,ZmFrZQ==' }, }) }) -// openaiShim test extraction seam 058 end - - -// openaiShim test extraction seam 059 start: uses GEMINI_ACCESS_TOKEN for Gemini OpenAI-compatible requests -test('uses GEMINI_ACCESS_TOKEN for Gemini OpenAI-compatible requests', async () => { - let capturedAuthorization: string | null = null - let capturedProject: string | null = null - let requestUrl: string | undefined - - process.env.CLAUDE_CODE_USE_GEMINI = '1' - process.env.GEMINI_AUTH_MODE = 'access-token' - process.env.GEMINI_ACCESS_TOKEN = 'gemini-access-token' - process.env.GOOGLE_CLOUD_PROJECT = 'gemini-project' - process.env.GEMINI_BASE_URL = - 'https://generativelanguage.googleapis.com/v1beta/openai' - process.env.GEMINI_MODEL = 'gemini-2.0-flash' - delete process.env.OPENAI_BASE_URL - delete process.env.OPENAI_API_KEY - delete process.env.GEMINI_API_KEY - delete process.env.GOOGLE_API_KEY - - globalThis.fetch = (async (input, init) => { - requestUrl = typeof input === 'string' ? input : input.url - const headers = init?.headers as Record | undefined - capturedAuthorization = - headers?.Authorization ?? headers?.authorization ?? null - capturedProject = - headers?.['x-goog-user-project'] ?? - headers?.['X-Goog-User-Project'] ?? - null - - return new Response( - JSON.stringify({ - id: 'chatcmpl-gemini', - model: 'gemini-2.0-flash', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 3, - completion_tokens: 1, - total_tokens: 4, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gemini-2.0-flash', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(requestUrl).toBe( - 'https://generativelanguage.googleapis.com/v1beta/openai/chat/completions', - ) - // Explicit type argument: TS narrows the closure-assigned variables to - // their `null` initializer at this point (microsoft/TypeScript#9998). - expect(capturedAuthorization).toBe('Bearer gemini-access-token') - expect(capturedProject).toBe('gemini-project') -}) -// openaiShim test extraction seam 059 end - - -// openaiShim test extraction seam 060 start: uses NVIDIA_API_KEY for NVIDIA NIM requests without OPENAI_API_KEY -test('uses NVIDIA_API_KEY for NVIDIA NIM requests without OPENAI_API_KEY', async () => { - let capturedAuthorization: string | null = null - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.NVIDIA_NIM = '1' - process.env.OPENAI_BASE_URL = 'https://integrate.api.nvidia.com/v1' - process.env.OPENAI_MODEL = 'nvidia/llama-3.1-nemotron-70b-instruct' - process.env.NVIDIA_API_KEY = 'nvidia-live-key' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - capturedAuthorization = - headers?.Authorization ?? headers?.authorization ?? null - - return new Response( - JSON.stringify({ - id: 'chatcmpl-nvidia', - model: 'nvidia/llama-3.1-nemotron-70b-instruct', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 3, - completion_tokens: 1, - total_tokens: 4, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'nvidia/llama-3.1-nemotron-70b-instruct', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(capturedAuthorization).toBe('Bearer nvidia-live-key') -}) -// openaiShim test extraction seam 060 end - - -// openaiShim test extraction seam 061 start: does not use stale NVIDIA_API_KEY for non-NVIDIA OpenAI-compatible routes -test('does not use stale NVIDIA_API_KEY for non-NVIDIA OpenAI-compatible routes', async () => { - let capturedAuthorization: string | null = null - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.NVIDIA_NIM = '1' - process.env.OPENAI_BASE_URL = 'https://openrouter.ai/api/v1' - process.env.OPENAI_MODEL = 'openai/gpt-5-mini' - process.env.NVIDIA_API_KEY = 'nvidia-live-key' - delete process.env.OPENAI_API_KEY - delete process.env.OPENROUTER_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - capturedAuthorization = - headers?.Authorization ?? headers?.authorization ?? null - - return new Response( - JSON.stringify({ - id: 'chatcmpl-openrouter', - model: 'openai/gpt-5-mini', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'openai/gpt-5-mini', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(capturedAuthorization).toBeNull() -}) -// openaiShim test extraction seam 061 end - - -// openaiShim test extraction seam 062 start: does not use MINIMAX_API_KEY for non-MiniMax OpenAI-compatible routes -test('does not use MINIMAX_API_KEY for non-MiniMax OpenAI-compatible routes', async () => { - let capturedAuthorization: string | null = null - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://openrouter.ai/api/v1' - process.env.OPENAI_MODEL = 'openai/gpt-5-mini' - process.env.MINIMAX_API_KEY = 'minimax-live-key' - delete process.env.OPENAI_API_KEY - delete process.env.OPENROUTER_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - capturedAuthorization = - headers?.Authorization ?? headers?.authorization ?? null - - return new Response( - JSON.stringify({ - id: 'chatcmpl-openrouter', - model: 'openai/gpt-5-mini', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'openai/gpt-5-mini', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(capturedAuthorization).toBeNull() -}) -// openaiShim test extraction seam 062 end - - -// openaiShim test extraction seam 063 start: xiaomi mimo route uses api-key auth header and max_completion_tokens -test('xiaomi mimo route uses api-key auth header and max_completion_tokens', async () => { - let capturedHeaders: Record | undefined - let capturedBody: Record | undefined - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.xiaomimimo.com/v1' - process.env.OPENAI_MODEL = 'mimo-v2.5-pro' - process.env.MIMO_API_KEY = 'mimo-live-key' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = init?.headers as Record - capturedBody = JSON.parse(String(init?.body)) as Record - - return new Response( - JSON.stringify({ - id: 'chatcmpl-mimo', - model: 'mimo-v2.5-pro', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'mimo-v2.5-pro', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(capturedHeaders).toMatchObject({ 'api-key': 'mimo-live-key' }) - expect(capturedHeaders).not.toHaveProperty('Authorization') - expect(capturedBody).toMatchObject({ max_completion_tokens: 32 }) - expect(capturedBody).not.toHaveProperty('max_tokens') -}) -// openaiShim test extraction seam 063 end - -// openaiShim test extraction seam 064 start: xiaomi mimo token plan uses raw api-key and OpenAI-compatible reasoning_effort -test('xiaomi mimo token plan uses raw api-key and OpenAI-compatible reasoning_effort', async () => { - let capturedHeaders: Record | undefined - let capturedBody: Record | undefined - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://token-plan-sgp.xiaomimimo.com/v1' - process.env.OPENAI_MODEL = 'mimo-v2.5-pro' - process.env.MIMO_API_KEY = 'mimo-token-key' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - capturedHeaders = init?.headers as Record - capturedBody = JSON.parse(String(init?.body)) as Record - - return makeChatCompletionResponse('mimo-v2.5-pro') - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - reasoningEffort: 'high', - }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'mimo-v2.5-pro', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(capturedHeaders).toMatchObject({ 'api-key': 'mimo-token-key' }) - expect(capturedHeaders).not.toHaveProperty('Authorization') - expect(capturedBody).toMatchObject({ - max_completion_tokens: 32, - reasoning_effort: 'high', - }) - expect(capturedBody).not.toHaveProperty('max_tokens') - expect(capturedBody).not.toHaveProperty('store') - expect(capturedBody).not.toHaveProperty('stream_options') -}) -// openaiShim test extraction seam 064 end - - -test.each([ - 'minimax-m3', - 'minimax-m2.7', - 'qwen3.7-max', - 'qwen3.7-plus', - 'qwen3.6-plus', -])('opencode go %s direct env routing ignores stale custom auth and uses the Anthropic Messages request contract', async model => { - let capturedUrl = '' - let capturedHeaders: Headers | undefined - let capturedBody: Record | undefined - - process.env.OPENAI_BASE_URL = 'https://opencode.ai/zen/go/v1' - delete process.env.OPENAI_API_KEY - process.env.OPENAI_MODEL = model - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENCODE_API_KEY = 'fake-opencode-key' - process.env.OPENAI_AUTH_HEADER = 'Authorization' - process.env.OPENAI_AUTH_SCHEME = 'bearer' - process.env.OPENAI_AUTH_HEADER_VALUE = 'stale-header-value' - - globalThis.fetch = (async (input, init) => { - capturedUrl = String(input) - capturedHeaders = new Headers(init?.headers) - capturedBody = JSON.parse(String(init?.body)) as Record - - return new Response( - JSON.stringify({ - id: 'msg_opencode_go', - type: 'message', - role: 'assistant', - model, - content: [{ type: 'text', text: 'ok' }], - stop_reason: 'end_turn', - stop_sequence: null, - usage: { - input_tokens: 1, - output_tokens: 1, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model, - system: 'test system', - messages: [ - { - role: 'user', - content: [{ type: 'text', text: 'hello' }], - }, - ], - max_tokens: 32, - stream: false, - }) - - expect(capturedUrl).toBe('https://opencode.ai/zen/go/v1/messages') - expect(capturedHeaders?.get('x-api-key')).toBe('fake-opencode-key') - expect(capturedHeaders?.get('authorization')).toBeNull() - expect(capturedBody).toEqual({ - model, - messages: [ - { - role: 'user', - content: [{ type: 'text', text: 'hello' }], - }, - ], - max_tokens: 32, - stream: false, - system: 'test system', - }) - expect(capturedBody).not.toHaveProperty('max_completion_tokens') - expect(capturedBody).not.toHaveProperty('store') -}) - -// openaiShim test extraction seam 065 start: opencode go messages endpoint rotates raw x-api-key credentials after rate-limit failure -test('opencode go messages endpoint rotates raw x-api-key credentials after rate-limit failure', async () => { - const capturedUrls: string[] = [] - const capturedKeys: Array = [] - - process.env.OPENAI_BASE_URL = 'https://opencode.ai/zen/go/v1' - delete process.env.OPENAI_API_KEY - delete process.env.OPENAI_API_KEYS - process.env.OPENAI_MODEL = 'minimax-m3' - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENCODE_API_KEY = 'fake-opencode-a,fake-opencode-b' - - globalThis.fetch = (async (input, init) => { - const headers = new Headers(init?.headers) - capturedUrls.push(String(input)) - capturedKeys.push(headers.get('x-api-key')) - - if (capturedKeys.length === 1) { - return new Response(JSON.stringify({ error: { message: 'rate limited' } }), { - status: 429, - headers: { 'Content-Type': 'application/json' }, - }) - } - - return new Response( - JSON.stringify({ - id: 'msg_opencode_go_retry', - type: 'message', - role: 'assistant', - model: 'minimax-m3', - content: [{ type: 'text', text: 'ok' }], - stop_reason: 'end_turn', - stop_sequence: null, - usage: { - input_tokens: 1, - output_tokens: 1, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'minimax-m3', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(capturedUrls).toEqual([ - 'https://opencode.ai/zen/go/v1/messages', - 'https://opencode.ai/zen/go/v1/messages', - ]) - expect(capturedKeys).toEqual(['fake-opencode-a', 'fake-opencode-b']) -}) -// openaiShim test extraction seam 065 end - - -// openaiShim test extraction seam 066 start: gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY as bearer auth despite stale generic base URL -test('gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY as bearer auth despite stale generic base URL', async () => { - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENGATEWAY_API_KEY = 'fake-ogw-key' - delete process.env.OPENAI_API_KEY - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.url).toBe('https://opengateway.gitlawb.com/v1/chat/completions') - expect(captured.authorization).toBe('Bearer fake-ogw-key') -}) -// openaiShim test extraction seam 066 end - - -// openaiShim test extraction seam 067 start: gitlawb opengateway provider flag accepts OPENAI_API_KEY compatibility fallback -test('gitlawb opengateway provider flag accepts OPENAI_API_KEY compatibility fallback', async () => { - delete process.env.OPENAI_BASE_URL - delete process.env.OPENGATEWAY_API_KEY - process.env.OPENAI_API_KEY = 'fake-openai-fallback' - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.authorization).toBe('Bearer fake-openai-fallback') -}) -// openaiShim test extraction seam 067 end - - -// openaiShim test extraction seam 068 start: gitlawb opengateway provider flag sends OPENAI_API_KEY fallback despite stale generic base URL -test('gitlawb opengateway provider flag sends OPENAI_API_KEY fallback despite stale generic base URL', async () => { - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_API_KEY = 'fake-openai-fallback' - delete process.env.OPENGATEWAY_API_KEY - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.url).toBe('https://opengateway.gitlawb.com/v1/chat/completions') - expect(captured.authorization).toBe('Bearer fake-openai-fallback') -}) -// openaiShim test extraction seam 068 end - - -// openaiShim test extraction seam 069 start: gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth -test('gitlawb opengateway provider flag trims OPENGATEWAY_API_KEY before bearer auth', async () => { - process.env.OPENGATEWAY_API_KEY = ' fake-ogw-key ' - delete process.env.OPENAI_API_KEY - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.authorization).toBe('Bearer fake-ogw-key') -}) -// openaiShim test extraction seam 069 end - - -// openaiShim test extraction seam 070 start: gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback -test('gitlawb opengateway provider flag ignores blank OPENGATEWAY_API_KEY and uses OPENAI_API_KEY fallback', async () => { - process.env.OPENGATEWAY_API_KEY = ' ' - process.env.OPENAI_API_KEY = 'fake-openai-fallback' - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.authorization).toBe('Bearer fake-openai-fallback') -}) -// openaiShim test extraction seam 070 end - - -// openaiShim test extraction seam 071 start: gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override -test('gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to OPENGATEWAY_BASE_URL override', async () => { - process.env.OPENGATEWAY_BASE_URL = 'http://localhost:8181/v1' - process.env.OPENGATEWAY_API_KEY = 'fake-ogw-key' - delete process.env.OPENAI_API_KEY - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.url).toBe('http://localhost:8181/v1/chat/completions') - expect(captured.authorization).toBe('Bearer fake-ogw-key') -}) -// openaiShim test extraction seam 071 end - - -// openaiShim test extraction seam 072 start: gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback -test('gitlawb opengateway provider flag sends OPENGATEWAY_API_KEY to custom OPENAI_BASE_URL fallback', async () => { - process.env.OPENAI_BASE_URL = 'http://localhost:8181/v1' - process.env.OPENGATEWAY_API_KEY = 'fake-ogw-key' - delete process.env.OPENGATEWAY_BASE_URL - delete process.env.OPENAI_API_KEY - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.url).toBe('http://localhost:8181/v1/chat/completions') - expect(captured.authorization).toBe('Bearer fake-ogw-key') -}) -// openaiShim test extraction seam 072 end - - -// openaiShim test extraction seam 073 start: gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL -test('gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEY for custom base URL', async () => { - process.env.OPENGATEWAY_BASE_URL = 'http://localhost:8181/v1' - process.env.OPENGATEWAY_API_KEY = 'fake-ogw-key' - process.env.OPENAI_API_KEY = 'fake-generic-openai-key' - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.url).toBe('http://localhost:8181/v1/chat/completions') - expect(captured.authorization).toBe('Bearer fake-ogw-key') -}) -// openaiShim test extraction seam 073 end - - -// openaiShim test extraction seam 074 start: gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool -test('gitlawb opengateway provider flag prefers OPENGATEWAY_API_KEY over generic OPENAI_API_KEYS pool', async () => { - process.env.OPENGATEWAY_BASE_URL = 'http://localhost:8181/v1' - process.env.OPENGATEWAY_API_KEY = 'fake-ogw-key' - process.env.OPENAI_API_KEYS = 'fake-openai-pool-a,fake-openai-pool-b' - delete process.env.OPENAI_API_KEY - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.url).toBe('http://localhost:8181/v1/chat/completions') - expect(captured.authorization).toBe('Bearer fake-ogw-key') -}) // openaiShim test extraction seam 074 end test('longcat provider flag prefers LONGCAT_API_KEY over generic OPENAI_API_KEYS pool', async () => { @@ -4702,447 +2684,6 @@ test('dedicated-only ClinePass route never falls back to generic OpenAI credenti expect(captured.authorization).toBeNull() }) - -// openaiShim test extraction seam 075 start: gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback -test('gitlawb opengateway provider flag uses generic OPENAI_API_KEYS pool before generic OPENAI_API_KEY fallback', async () => { - process.env.OPENGATEWAY_BASE_URL = 'http://localhost:8181/v1' - process.env.OPENAI_API_KEYS = 'fake-openai-pool-a,fake-openai-pool-b' - process.env.OPENAI_API_KEY = 'fake-generic-openai-key' - delete process.env.OPENGATEWAY_API_KEY - - const result = applyProviderFlag('gitlawb-opengateway', []) - expect(result.error).toBeUndefined() - - const captured = await captureChatCompletionRequest() - - expect(captured.url).toBe('http://localhost:8181/v1/chat/completions') - expect(captured.authorization).toBe('Bearer fake-openai-pool-a') -}) -// openaiShim test extraction seam 075 end - - -// openaiShim test extraction seam 076 start: gitlawb opengateway stored provider profile key becomes bearer auth -test('gitlawb opengateway stored provider profile key becomes bearer auth', async () => { - delete process.env.OPENAI_API_KEY - delete process.env.OPENGATEWAY_API_KEY - - applyProviderProfileToProcessEnv({ - id: 'stored-opengateway', - provider: 'gitlawb-opengateway', - name: 'Gitlawb Opengateway', - baseUrl: 'https://opengateway.gitlawb.com/v1', - model: 'mimo-v2.5-pro', - apiKey: 'fake-profile-key', - }) - - const captured = await captureChatCompletionRequest() - - expect(captured.authorization).toBe('Bearer fake-profile-key') -}) -// openaiShim test extraction seam 076 end - - -// openaiShim test extraction seam 077 start: openai route still sends OPENAI_API_KEY as bearer auth -test('openai route still sends OPENAI_API_KEY as bearer auth', async () => { - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEY = 'fake-openai-key' - delete process.env.OPENGATEWAY_API_KEY - - const captured = await captureChatCompletionRequest('gpt-5.5') - - expect(captured.authorization).toBe('Bearer fake-openai-key') -}) -// openaiShim test extraction seam 077 end - - -// openaiShim test extraction seam 078 start: OPENAI_API_KEYS rejects placeholder values before sending requests -test('OPENAI_API_KEYS rejects placeholder values before sending requests', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'key-a,SUA_CHAVE' - process.env.OPENAI_API_KEY = 'single-key-should-not-hide-invalid-pool' - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - return makeChatCompletionResponse('gpt-5.5') - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await expect( - client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow(/SUA_CHAVE|Authentication failed/) - - expect(authorizations).toEqual([]) -}) -// openaiShim test extraction seam 078 end - -// openaiShim test extraction seam 079 start: OPENAI_API_KEYS rotates to the next key on rate-limit failure -test('OPENAI_API_KEYS rotates to the next key on rate-limit failure', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'key-a,key-b' - process.env.OPENAI_API_KEY = 'single-key-should-not-win' - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - - if (authorizations.length === 1) { - return new Response(JSON.stringify({ error: { message: 'rate limited' } }), { - status: 429, - headers: { 'Content-Type': 'application/json' }, - }) - } - - return makeChatCompletionResponse('gpt-5.5') - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(authorizations).toEqual(['Bearer key-a', 'Bearer key-b']) -}) -// openaiShim test extraction seam 079 end - - -// openaiShim test extraction seam 080 start: OPENAI_API_KEYS does not reuse a cooled-down key after every key is rate-limited -test('OPENAI_API_KEYS does not reuse a cooled-down key after every key is rate-limited', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'key-a,key-b' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - return new Response(JSON.stringify({ error: { message: 'rate limited' } }), { - status: 429, - headers: { 'Content-Type': 'application/json' }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await expect( - client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(authorizations).toEqual(['Bearer key-a', 'Bearer key-b']) -}) -// openaiShim test extraction seam 080 end - - -// openaiShim test extraction seam 081 start: comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure -test('comma-separated OPENAI_API_KEY rotates to the next key on rate-limit failure', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEY = 'key-a,key-b' - delete process.env.OPENAI_API_KEYS - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - - if (authorizations.length === 1) { - return new Response(JSON.stringify({ error: { message: 'rate limited' } }), { - status: 429, - headers: { 'Content-Type': 'application/json' }, - }) - } - - return makeChatCompletionResponse('gpt-5.5') - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(authorizations).toEqual(['Bearer key-a', 'Bearer key-b']) -}) -// openaiShim test extraction seam 081 end - - -// openaiShim test extraction seam 082 start: OPENAI_API_KEYS does not rotate through pool on provider 5xx outage -test('OPENAI_API_KEYS does not rotate through pool on provider 5xx outage', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'key-a,key-b' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - - return new Response(JSON.stringify({ error: { message: 'server error' } }), { - status: 500, - headers: { 'Content-Type': 'application/json' }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await expect( - client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(authorizations).toEqual(['Bearer key-a']) -}) -// openaiShim test extraction seam 082 end - -// openaiShim test extraction seam 083 start: OPENAI_API_KEYS preserves cooldown state across client requests -test('OPENAI_API_KEYS preserves cooldown state across client requests', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'key-a,key-b' - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - - if (authorizations.length === 1) { - return new Response(JSON.stringify({ error: { message: 'rate limited' } }), { - status: 429, - headers: { 'Content-Type': 'application/json' }, - }) - } - - return makeChatCompletionResponse('gpt-5.5') - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - for (let i = 0; i < 2; i++) { - await client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - } - - expect(authorizations).toEqual([ - 'Bearer key-a', - 'Bearer key-b', - 'Bearer key-b', - ]) -}) -// openaiShim test extraction seam 083 end - - -// openaiShim test extraction seam 084 start: OPENAI_API_KEYS rotates Azure api-key auth on auth failure -test('OPENAI_API_KEYS rotates Azure api-key auth on auth failure', async () => { - const apiKeys: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://example.openai.azure.com/openai/deployments/test/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'azure-key-a,azure-key-b' - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - apiKeys.push(headers?.['api-key'] ?? null) - - if (apiKeys.length === 1) { - return new Response(JSON.stringify({ error: { message: 'unauthorized' } }), { - status: 401, - headers: { 'Content-Type': 'application/json' }, - }) - } - - return makeChatCompletionResponse('gpt-5.5') - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(apiKeys).toEqual(['azure-key-a', 'azure-key-b']) -}) -// openaiShim test extraction seam 084 end - - -// openaiShim test extraction seam 085 start: OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests -test('OPENAI_API_KEYS does not reuse auth-disabled credentials across client requests', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'key-a,key-b' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - - return new Response(JSON.stringify({ error: { message: 'unauthorized' } }), { - status: 401, - headers: { 'Content-Type': 'application/json' }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await expect( - client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - await expect( - client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello again' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(authorizations).toEqual(['Bearer key-a', 'Bearer key-b']) -}) -// openaiShim test extraction seam 085 end - - -// openaiShim test extraction seam 086 start: OPENAI_API_KEYS permanently evicts 403 auth failures -test('OPENAI_API_KEYS permanently evicts 403 auth failures', async () => { - const authorizations: Array = [] - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_MODEL = 'gpt-5.5' - process.env.OPENAI_API_KEYS = 'key-a,key-b' - delete process.env.OPENAI_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - - return new Response(JSON.stringify({ error: { message: 'forbidden' } }), { - status: 403, - headers: { 'Content-Type': 'application/json' }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await expect( - client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - await expect( - client.beta.messages.create({ - model: 'gpt-5.5', - messages: [{ role: 'user', content: 'hello again' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(authorizations).toEqual(['Bearer key-a', 'Bearer key-b']) -}) -// openaiShim test extraction seam 086 end - -// openaiShim test extraction seam 087 start: does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes -test('does not use BNKR_API_KEY for non-Bankr OpenAI-compatible routes', async () => { - let capturedAuthorization: string | null = null - - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://openrouter.ai/api/v1' - process.env.OPENAI_MODEL = 'openai/gpt-5-mini' - process.env.BNKR_API_KEY = 'bankr-live-key' - delete process.env.OPENAI_API_KEY - delete process.env.OPENROUTER_API_KEY - - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - capturedAuthorization = - headers?.Authorization ?? headers?.authorization ?? null - - return new Response( - JSON.stringify({ - id: 'chatcmpl-openrouter', - model: 'openai/gpt-5-mini', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'openai/gpt-5-mini', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(capturedAuthorization).toBeNull() -}) // openaiShim test extraction seam 087 end @@ -5337,264 +2878,6 @@ test('converts Gemini raw tool-call text into non-streaming tool_use blocks', as globalThis.fetch = previousFetch } }) -// openaiShim test extraction seam 092 end - - -// openaiShim test extraction seam 093 start: normalizes plain string Bash tool arguments from OpenAI-compatible responses -test('normalizes plain string Bash tool arguments from OpenAI-compatible responses', async () => { - globalThis.fetch = (async (_input, _init) => { - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'google/gemini-3.1-pro-preview', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [ - { - id: 'function-call-1', - type: 'function', - function: { - name: 'Bash', - arguments: 'pwd', - }, - }, - ], - }, - finish_reason: 'tool_calls', - }, - ], - usage: { - prompt_tokens: 12, - completion_tokens: 4, - total_tokens: 16, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const message = await client.beta.messages.create({ - model: 'google/gemini-3.1-pro-preview', - system: 'test system', - messages: [{ role: 'user', content: 'Use Bash' }], - max_tokens: 64, - stream: false, - }) as { - stop_reason?: string - content?: Array> - } - - expect(message.stop_reason).toBe('tool_use') - expect(message.content).toEqual([ - { - type: 'tool_use', - id: 'function-call-1', - name: 'Bash', - input: { command: 'pwd' }, - }, - ]) -}) -// openaiShim test extraction seam 093 end - - -// openaiShim test extraction seam 094 start: normalizes Bash tool arguments that are valid JSON strings -test('normalizes Bash tool arguments that are valid JSON strings', async () => { - globalThis.fetch = (async (_input, _init) => { - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'google/gemini-3.1-pro-preview', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [ - { - id: 'function-call-1', - type: 'function', - function: { - name: 'Bash', - arguments: '"pwd"', - }, - }, - ], - }, - finish_reason: 'tool_calls', - }, - ], - usage: { - prompt_tokens: 12, - completion_tokens: 4, - total_tokens: 16, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const message = await client.beta.messages.create({ - model: 'google/gemini-3.1-pro-preview', - system: 'test system', - messages: [{ role: 'user', content: 'Use Bash' }], - max_tokens: 64, - stream: false, - }) as { - content?: Array> - } - - expect(message.content).toEqual([ - { - type: 'tool_use', - id: 'function-call-1', - name: 'Bash', - input: { command: 'pwd' }, - }, - ]) -}) -// openaiShim test extraction seam 094 end - - -test.each([ - ['false', false], - ['null', null], - ['[]', []], -])( - 'preserves malformed Bash JSON literals as parsed values in non-streaming responses: %s', - async (argumentsValue, expectedInput) => { - globalThis.fetch = (async (_input, _init) => { - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'google/gemini-3.1-pro-preview', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [ - { - id: 'function-call-1', - type: 'function', - function: { - name: 'Bash', - arguments: argumentsValue, - }, - }, - ], - }, - finish_reason: 'tool_calls', - }, - ], - usage: { - prompt_tokens: 12, - completion_tokens: 4, - total_tokens: 16, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const message = await client.beta.messages.create({ - model: 'google/gemini-3.1-pro-preview', - system: 'test system', - messages: [{ role: 'user', content: 'Use Bash' }], - max_tokens: 64, - stream: false, - }) as { - content?: Array> - } - - expect(message.content).toEqual([ - { - type: 'tool_use', - id: 'function-call-1', - name: 'Bash', - input: expectedInput, - }, - ]) - }, -) - -// openaiShim test extraction seam 095 start: keeps terminal empty Bash tool arguments invalid in non-streaming responses -test('keeps terminal empty Bash tool arguments invalid in non-streaming responses', async () => { - globalThis.fetch = (async (_input, _init) => { - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'google/gemini-3.1-pro-preview', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [ - { - id: 'function-call-1', - type: 'function', - function: { - name: 'Bash', - arguments: '', - }, - }, - ], - }, - finish_reason: 'tool_calls', - }, - ], - usage: { - prompt_tokens: 12, - completion_tokens: 4, - total_tokens: 16, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const message = await client.beta.messages.create({ - model: 'google/gemini-3.1-pro-preview', - system: 'test system', - messages: [{ role: 'user', content: 'Use Bash' }], - max_tokens: 64, - stream: false, - }) as { - content?: Array> - } - - expect(message.content).toEqual([ - { - type: 'tool_use', - id: 'function-call-1', - name: 'Bash', - input: {}, - }, - ]) -}) // openaiShim test extraction seam 095 end @@ -6374,134 +3657,6 @@ test('repairs truncated JSON objects even without command field', async () => { expect(streamedInput).toBe('{"cwd":"/tmp"}') }) -// openaiShim test extraction seam 104 end - - -// Extraction seam: streamed tool normalization | schema and tool conversion. - -// openaiShim test extraction seam 105 start: preserves raw input for unknown plain string tool arguments -test('preserves raw input for unknown plain string tool arguments', async () => { - globalThis.fetch = (async (_input, _init) => { - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'google/gemini-3.1-pro-preview', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [ - { - id: 'function-call-1', - type: 'function', - function: { - name: 'UnknownTool', - arguments: 'pwd', - }, - }, - ], - }, - finish_reason: 'tool_calls', - }, - ], - usage: { - prompt_tokens: 12, - completion_tokens: 4, - total_tokens: 16, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const message = await client.beta.messages.create({ - model: 'google/gemini-3.1-pro-preview', - system: 'test system', - messages: [{ role: 'user', content: 'Use tool' }], - max_tokens: 64, - stream: false, - }) as { - content?: Array> - } - - expect(message.content).toEqual([ - { - type: 'tool_use', - id: 'function-call-1', - name: 'UnknownTool', - input: {}, - }, - ]) -}) -// openaiShim test extraction seam 105 end - - -// openaiShim test extraction seam 106 start: preserves parsed string input for unknown JSON string tool arguments -test('preserves parsed string input for unknown JSON string tool arguments', async () => { - globalThis.fetch = (async (_input, _init) => { - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'google/gemini-3.1-pro-preview', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [ - { - id: 'function-call-1', - type: 'function', - function: { - name: 'UnknownTool', - arguments: '"pwd"', - }, - }, - ], - }, - finish_reason: 'tool_calls', - }, - ], - usage: { - prompt_tokens: 12, - completion_tokens: 4, - total_tokens: 16, - }, - }), - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const message = await client.beta.messages.create({ - model: 'google/gemini-3.1-pro-preview', - system: 'test system', - messages: [{ role: 'user', content: 'Use tool' }], - max_tokens: 64, - stream: false, - }) as { - content?: Array> - } - - expect(message.content).toEqual([ - { - type: 'tool_use', - id: 'function-call-1', - name: 'UnknownTool', - input: 'pwd', - }, - ]) -}) // openaiShim test extraction seam 106 end @@ -6786,128 +3941,6 @@ test('non-streaming: real content takes precedence over reasoning_content', asyn { type: 'text', text: 'The answer is 42.' }, ]) }) -// openaiShim test extraction seam 115 end - - -// openaiShim test extraction seam 116 start: non-streaming: preserves response body when usage parsing fails -test('non-streaming: preserves response body when usage parsing fails', async () => { - const json = JSON as unknown as { parse: typeof JSON.parse } - const originalJSONParse = json.parse - const responseBody = JSON.stringify({ - id: 'chatcmpl-1', - model: 'glm-5', - choices: [ - { - message: { - role: 'assistant', - content: 'ok', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 10, - completion_tokens: 20, - total_tokens: 30, - }, - }) - let usageParseFailed = false - - // Throw only for the usage-extraction parse of the response body. - // A global "throw once" mock is unreliable here: Bun's native - // Response.json() does not go through JS-level JSON.parse, so the - // second parse the original test relied on never happens (parseCalls - // stays at 1 and `toBeGreaterThan(1)` fails). Scoping the failure to - // the response body targets the _doRequest parse without breaking - // unrelated JSON.parse calls in the request pipeline, and works in - // both Bun (native Response.json) and Node (undici, which does call - // JSON.parse — guarded by `usageParseFailed` so it won't throw again). - json.parse = ((text: string, reviver?: Parameters[1]) => { - if (!usageParseFailed && text === responseBody) { - usageParseFailed = true - throw new Error('simulated usage parse failure') - } - return originalJSONParse(text, reviver) - }) as typeof JSON.parse - - try { - globalThis.fetch = (async () => { - return new Response(responseBody, { - headers: { - 'Content-Type': 'application/json', - }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const result = (await client.beta.messages.create({ - model: 'glm-5', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - })) as { content: Array> } - - // Usage extraction threw, but the recreated Response still holds the - // body so downstream response.json() can read it. - expect(usageParseFailed).toBe(true) - expect(result.content).toEqual([{ type: 'text', text: 'ok' }]) - } finally { - json.parse = originalJSONParse - } -}) -// openaiShim test extraction seam 116 end - - -// openaiShim test extraction seam 117 start: non-streaming: preserves response.url routing metadata after body read -test('non-streaming: preserves response.url routing metadata after body read', async () => { - // _doRequest reads the body for usage extraction and recreates the - // Response with new Response(bodyText, ...). That drops response.url to - // "", which breaks create()'s /responses, /messages, and Gemini routing. - // This test pins an Anthropic-shaped body behind a /messages URL: if url - // is preserved, create() passes the body through unchanged; if url is - // lost, it falls through to _convertNonStreamingResponse and the - // Anthropic-only fields (stop_reason, input_tokens) surface as wrong - // output or missing content. - const anthropicBody = JSON.stringify({ - id: 'msg_1', - type: 'message', - role: 'assistant', - content: [{ type: 'text', text: 'passthrough ok' }], - model: 'claude-3', - stop_reason: 'end_turn', - usage: { input_tokens: 10, output_tokens: 20 }, - }) - - globalThis.fetch = (async () => { - const r = new Response(anthropicBody, { - headers: { 'Content-Type': 'application/json' }, - }) - // fetch() sets .url from the request; new Response() cannot. Simulate - // the fetch-attached URL so create()'s routing can see /messages. - Object.defineProperty(r, 'url', { - value: 'https://api.anthropic-shaped.example.com/v1/messages', - configurable: true, - }) - return r - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - const result = (await client.beta.messages.create({ - model: 'glm-5', - system: 'test system', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - })) as { content: Array> } - - // /messages passthrough returns the Anthropic body verbatim. If url were - // lost, _convertNonStreamingResponse would try to read OpenAI choices[] - // and content would not match. - expect(result.content).toEqual([{ type: 'text', text: 'passthrough ok' }]) -}) // openaiShim test extraction seam 117 end @@ -7263,45 +4296,6 @@ test('streaming: preserves prose without tags (no phrase-based false positive)', 'I should note that the user role requires a briefly concise friendly response format.', ) }) -// openaiShim test extraction seam 122 end - - -// Extraction boundary: response conversion | executor network behavior. -// The executor suite owns the contiguous network-classification block below. -// Keep this marker stable for independent adjacent test migrations. -// openaiShim test extraction seam 123 start: strips credentials and query params from URL in fetch network error message -test('strips credentials and query params from URL in fetch network error message', async () => { - process.env.OPENAI_BASE_URL = - 'https://user:password@internal.example.test/v1?token=abc123' - process.env.OPENAI_API_KEY = 'test-key' - - globalThis.fetch = asMockFetch(mock(async () => { - throw new TypeError( - 'fetch failed https://user:password@internal.example.test/v1?token=abc123/chat/completions', - ) - })) - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - let caught: unknown - try { - await client.beta.messages.create({ - model: 'test-model', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - } catch (error) { - caught = error - } - - const message = (caught as Error).message - expect(message).toContain('internal.example.test') - expect(message).toContain('fetch failed') - expect(message).not.toContain('password') - expect(message).not.toContain('user:') - expect(message).not.toContain('token=abc123') -}) // openaiShim test extraction seam 123 end test('redacts configured secret substrings from fetch network error messages', async () => { @@ -7369,80 +4363,6 @@ test('redacts encoded configured secrets from non-URL transport error messages', expect(message).not.toContain(fullyEncodedSecret) expect(message).not.toContain(malformedAdjacentSecret) }) - -// openaiShim test extraction seam 124 start: classifies localhost transport failures with actionable category marker -test('classifies localhost transport failures with actionable category marker', async () => { - process.env.OPENAI_BASE_URL = 'http://localhost:11434/v1' - - const transportError = Object.assign(new TypeError('fetch failed'), { - code: 'ECONNREFUSED', - }) - - globalThis.fetch = asMockFetch(mock(async () => { - throw transportError - })) - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'qwen2.5-coder:7b', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }), - ).rejects.toThrow('openai_category=connection_refused') - - await expect( - client.beta.messages.create({ - model: 'qwen2.5-coder:7b', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }), - ).rejects.toThrow('local server is running') -}) -// openaiShim test extraction seam 124 end - - -// openaiShim test extraction seam 125 start: transport failures are not labeled with HTTP status 503 -test('transport failures are not labeled with HTTP status 503', async () => { - // Issue #971: ENETDOWN (and other transport errors) are emitted before any - // HTTP response is received. Reporting them as "503" makes users believe the - // upstream server returned 503 Service Unavailable. - process.env.OPENAI_BASE_URL = 'https://intranet.example.test/v1' - - const transportError = Object.assign(new TypeError('fetch failed'), { - code: 'ENETDOWN', - }) - - globalThis.fetch = asMockFetch(mock(async () => { - throw transportError - })) - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - let caught: unknown - try { - await client.beta.messages.create({ - model: 'gpt-4o-mini', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }) - } catch (error) { - caught = error - } - - expect(caught).toBeDefined() - const err = caught as { status?: number; message: string; constructor: { name: string } } - expect(err.constructor.name).toBe('APIConnectionError') - expect(err.status).toBeUndefined() - expect(err.message).not.toMatch(/^503\b/) - expect(err.message).toContain('OpenAI API transport error') - expect(err.message).toContain('code=ENETDOWN') - expect(err.message).toContain('openai_category=network_error') -}) // openaiShim test extraction seam 125 end test('propagates caller AbortError without wrapping it as transport failure', async () => { @@ -7979,92 +4899,6 @@ test('disarms the API timeout after headers arrive while the body keeps streamin expect(fetchSignals).toHaveLength(1) expect(fetchSignals[0].aborted).toBe(false) }) -// openaiShim test extraction seam 126 end - - -// openaiShim test extraction seam 127 start: classifies chat-completions endpoint 404 failures with endpoint_not_found marker -test('classifies chat-completions endpoint 404 failures with endpoint_not_found marker', async () => { - process.env.OPENAI_BASE_URL = 'http://localhost:11434' - - globalThis.fetch = asMockFetch(mock(async () => - new Response('Not Found', { - status: 404, - headers: { - 'Content-Type': 'text/plain', - }, - }))) - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'qwen2.5-coder:7b', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }), - ).rejects.toThrow('openai_category=endpoint_not_found') -}) -// openaiShim test extraction seam 127 end - -// openaiShim test extraction seam 128 start: self-heals localhost resolution failures by retrying local loopback base URL -test('self-heals localhost resolution failures by retrying local loopback base URL', async () => { - process.env.OPENAI_BASE_URL = 'http://localhost:11434/v1' - - const requestUrls: string[] = [] - globalThis.fetch = (async (input, _init) => { - const url = typeof input === 'string' ? input : input.url - requestUrls.push(url) - - if (url.includes('localhost')) { - const error = Object.assign(new TypeError('fetch failed'), { - code: 'ENOTFOUND', - }) - throw error - } - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'qwen2.5-coder:7b', - choices: [ - { - message: { - role: 'assistant', - content: 'hello from loopback', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 4, - completion_tokens: 3, - total_tokens: 7, - }, - }), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'qwen2.5-coder:7b', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }), - ).resolves.toBeDefined() - - expect(requestUrls[0]).toBe('http://localhost:11434/api/chat') - expect(requestUrls).toContain('http://127.0.0.1:11434/api/chat') -}) // openaiShim test extraction seam 128 end @@ -8114,158 +4948,6 @@ test('uses native Ollama chat endpoint when local base URL omits /v1', async () expect(requestUrls).toEqual(['http://localhost:11434/api/chat']) }) -// openaiShim test extraction seam 129 end - - -// openaiShim test extraction seam 130 start: keeps remote Ollama-named gateways on chat completions -test('keeps remote Ollama-named gateways on chat completions', async () => { - process.env.OPENAI_BASE_URL = 'https://ollama-gateway.example.com/v1' - - const requestUrls: string[] = [] - globalThis.fetch = (async (input, init) => { - const url = typeof input === 'string' ? input : input.url - requestUrls.push(url) - const body = JSON.parse(String(init?.body)) as Record - expect(body.max_tokens).toBe(64) - expect(body.options).toBeUndefined() - - return makeChatCompletionResponse('llama3.1:8b') - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'llama3.1:8b', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }), - ).resolves.toBeDefined() - - expect(requestUrls).toEqual([ - 'https://ollama-gateway.example.com/v1/chat/completions', - ]) -}) -// openaiShim test extraction seam 130 end - - -// openaiShim test extraction seam 131 start: keeps HTTPS localhost Ollama-port proxies on chat completions -test('keeps HTTPS localhost Ollama-port proxies on chat completions', async () => { - process.env.OPENAI_BASE_URL = 'https://localhost:11434/v1' - - const requestUrls: string[] = [] - globalThis.fetch = (async (input, init) => { - const url = typeof input === 'string' ? input : input.url - requestUrls.push(url) - const body = JSON.parse(String(init?.body)) as Record - expect(body.max_tokens).toBe(64) - expect(body.options).toBeUndefined() - - return makeChatCompletionResponse('llama3.1:8b') - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'llama3.1:8b', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 64, - stream: false, - }), - ).resolves.toBeDefined() - - expect(requestUrls).toEqual([ - 'https://localhost:11434/v1/chat/completions', - ]) -}) -// openaiShim test extraction seam 131 end - - -// Extraction boundary: native Ollama routing | executor tool self-healing. -// The single retry test below moves with request execution. -// Keep this marker stable for independent adjacent test migrations. -// openaiShim test extraction seam 132 start: self-heals tool-call incompatibility by retrying local Ollama requests without tools -test('self-heals tool-call incompatibility by retrying local Ollama requests without tools', async () => { - process.env.OPENAI_BASE_URL = 'http://localhost:11434/v1' - - const requestBodies: Array> = [] - globalThis.fetch = (async (_input, init) => { - const requestBody = JSON.parse(String(init?.body)) as Record - requestBodies.push(requestBody) - - if (requestBodies.length === 1) { - return new Response('tool_calls are not supported', { - status: 400, - headers: { - 'Content-Type': 'text/plain', - }, - }) - } - - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'qwen2.5-coder:7b', - choices: [ - { - message: { - role: 'assistant', - content: 'fallback without tools', - }, - finish_reason: 'stop', - }, - ], - usage: { - prompt_tokens: 8, - completion_tokens: 4, - total_tokens: 12, - }, - }), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'qwen2.5-coder:7b', - messages: [{ role: 'user', content: 'hello' }], - tools: [ - { - name: 'Read', - description: 'Read a file', - input_schema: { - type: 'object', - properties: { - filePath: { type: 'string' }, - }, - required: ['filePath'], - }, - }, - ], - max_tokens: 64, - stream: false, - }), - ).resolves.toBeDefined() - - expect(requestBodies).toHaveLength(2) - expect(Array.isArray(requestBodies[0]?.tools)).toBe(true) - expect(requestBodies[0]?.tool_choice).toBeUndefined() - expect( - requestBodies[1]?.tools === undefined || - (Array.isArray(requestBodies[1]?.tools) && requestBodies[1]?.tools.length === 0), - ).toBe(true) - expect(requestBodies[1]?.tool_choice).toBeUndefined() - expect(requestBodies[1]?.tool_stream).toBeUndefined() -}) // openaiShim test extraction seam 132 end @@ -8498,813 +5180,6 @@ test('injects semantic assistant message when tool result is followed by user me expect(semanticMsg.content).not.toContain('interrupted') expect(semanticMsg.content).not.toContain('user') }) -// openaiShim test extraction seam 136 end - - -// Extraction boundary: executor tool self-healing | message/provider shaping. -// Provider request shaping below is not owned by the executor. -// Keep this marker stable for independent adjacent test migrations. -// openaiShim test extraction seam 137 start: Moonshot: uses max_tokens (not max_completion_tokens) and strips store -test('Moonshot: uses max_tokens (not max_completion_tokens) and strips store', async () => { - process.env.OPENAI_BASE_URL = 'https://api.moonshot.ai/v1' - process.env.OPENAI_API_KEY = 'sk-moonshot-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'kimi-k2.6', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'kimi-k2.6', - system: 'you are kimi', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 256, - stream: false, - }) - - expect(requestBody?.max_tokens).toBe(256) - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 137 end - - -// openaiShim test extraction seam 138 start: Cerebras: strips unsupported store on chat_completions (#1023) -test('Cerebras: strips unsupported store on chat_completions (#1023)', async () => { - process.env.OPENAI_BASE_URL = 'https://api.cerebras.ai/v1' - process.env.OPENAI_API_KEY = 'csk-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'llama3.1-8b', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'llama3.1-8b', - system: 'you are cerebras', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - }) - - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 138 end - - -// openaiShim test extraction seam 139 start: Local provider (vLLM/Ollama/etc.): strips unsupported store on chat_completions (#672) -test('Local provider (vLLM/Ollama/etc.): strips unsupported store on chat_completions (#672)', async () => { - process.env.OPENAI_BASE_URL = 'http://localhost:8000/v1' - process.env.OPENAI_API_KEY = 'sk-local' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'qwen-3.5-27b', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'qwen-3.5-27b', - system: 'you are local', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - }) - - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 139 end - - -// openaiShim test extraction seam 140 start: Mistral: strips unsupported store on chat_completions (#739) -test('Mistral: strips unsupported store on chat_completions (#739)', async () => { - process.env.OPENAI_BASE_URL = 'https://api.mistral.ai/v1' - process.env.OPENAI_API_KEY = 'mistral-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'codestral-2508', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'codestral-2508', - system: 'you are mistral', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - }) - - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 140 end - - -// openaiShim test extraction seam 141 start: Mistral host fallback: strips store on an unresolved Mistral-host route (#739) -test('Mistral host fallback: strips store on an unresolved Mistral-host route (#739)', async () => { - // `api.mistral.ai/v1` resolves to the Mistral descriptor route, whose - // removeBodyFields already strips `store` — so the test above passes even - // without the hasMistralApiHost fallback. This case pins the fallback's real - // value: a Mistral-host proxy (`proxy.mistral.ai`) that does NOT resolve to a - // descriptor route (resolveRouteIdFromBaseUrl returns null, no - // removeBodyFields), so `store` is stripped *only* by hasMistralApiHost. - process.env.OPENAI_BASE_URL = 'https://proxy.mistral.ai/v1' - process.env.OPENAI_API_KEY = 'mistral-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'codestral-2508', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'codestral-2508', - system: 'you are mistral', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - }) - - // The shim sets `store: false` on every chat_completions body; without the - // fallback this unresolved route would forward it and hit Mistral's 422. - expect(requestBody?.store).toBeUndefined() - // #739's Mistral 422 rejects `max_completion_tokens` as well — the host - // fallback must also map it to `max_tokens` on the unresolved route, since - // the generic config leaves the `max_completion_tokens` default. - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.max_tokens).toBe(64) -}) -// openaiShim test extraction seam 141 end - - -// openaiShim test extraction seam 142 start: hasMistralApiHost matches the Mistral host and its subdomains only - -// openaiShim test extraction seam 142 end - - -// openaiShim test extraction seam 143 start: Groq: keeps max_completion_tokens and strips unsupported store -test('Groq: keeps max_completion_tokens and strips unsupported store', async () => { - process.env.OPENAI_BASE_URL = 'https://api.groq.com/openai/v1' - process.env.OPENAI_API_KEY = 'gsk-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'llama-3.3-70b-versatile', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'llama-3.3-70b-versatile', - system: 'you are groq', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 256, - stream: false, - }) - - expect(requestBody?.max_completion_tokens).toBe(256) - expect(requestBody?.max_tokens).toBeUndefined() - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 143 end - - - -// openaiShim test extraction seam 144 start: Groq: strips reasoning_effort even when compat inference matches the model -test('Groq: strips reasoning_effort even when compat inference matches the model', async () => { - process.env.OPENAI_BASE_URL = 'https://api.groq.com/openai/v1' - process.env.OPENAI_API_KEY = 'gsk-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'deepseek-r1-distill-llama-70b', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ reasoningEffort: 'xhigh' }) as OpenAIShimClient - await client.beta.messages.create({ - model: 'deepseek-r1-distill-llama-70b', - system: 'you are groq', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 256, - stream: false, - thinking: { type: 'enabled' }, - }) - - expect(requestBody?.thinking).toEqual({ type: 'enabled' }) - expect(requestBody?.reasoning_effort).toBeUndefined() - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 144 end - -// openaiShim test extraction seam 145 start: Moonshot: echoes reasoning_content on assistant tool-call messages -test('Moonshot: echoes reasoning_content on assistant tool-call messages', async () => { - // Regression for: "API Error: 400 {"error":{"message":"thinking is enabled - // but reasoning_content is missing in assistant tool call message at index - // N"}}" when the agent sends a prior-turn assistant response back to Kimi. - // The thinking block captured from the inbound response must round-trip - // as reasoning_content on the outgoing echoed assistant message. - process.env.OPENAI_BASE_URL = 'https://api.moonshot.ai/v1' - process.env.OPENAI_API_KEY = 'sk-moonshot-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'kimi-k2.6', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'kimi-k2.6', - system: 'you are kimi', - messages: [ - { role: 'user', content: 'check the logs' }, - { - role: 'assistant', - content: [ - { - type: 'thinking', - thinking: 'Need to inspect logs via Bash; running a cat.', - }, - { type: 'text', text: "I'll inspect the logs." }, - { - type: 'tool_use', - id: 'call_bash_1', - name: 'Bash', - input: { command: 'cat /tmp/app.log' }, - }, - ], - }, - { - role: 'user', - content: [ - { - type: 'tool_result', - tool_use_id: 'call_bash_1', - content: 'log line 1\nlog line 2', - }, - ], - }, - ], - max_tokens: 256, - stream: false, - }) - - const messages = requestBody?.messages as Array> - const assistantWithToolCall = messages.find( - m => m.role === 'assistant' && Array.isArray(m.tool_calls), - ) - expect(assistantWithToolCall).toBeDefined() - expect(assistantWithToolCall?.reasoning_content).toBe( - 'Need to inspect logs via Bash; running a cat.', - ) -}) -// openaiShim test extraction seam 145 end - - -// openaiShim test extraction seam 146 start: DeepSeek echoes reasoning_content on assistant tool-call messages -test('DeepSeek echoes reasoning_content on assistant tool-call messages', async () => { - process.env.OPENAI_BASE_URL = 'https://api.deepseek.com/v1' - process.env.OPENAI_API_KEY = 'sk-deepseek' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'deepseek-v4-flash', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'deepseek-v4-flash', - system: 'test', - messages: [ - { role: 'user', content: 'hi' }, - { - role: 'assistant', - content: [ - { type: 'thinking', thinking: 'thought' }, - { type: 'text', text: 'hello' }, - { - type: 'tool_use', - id: 'call_1', - name: 'Bash', - input: { command: 'ls' }, - }, - ], - }, - { - role: 'user', - content: [ - { type: 'tool_result', tool_use_id: 'call_1', content: 'files' }, - ], - }, - ], - max_tokens: 32, - stream: false, - }) - - const messages = requestBody?.messages as Array> - const assistantWithToolCall = messages.find( - m => m.role === 'assistant' && Array.isArray(m.tool_calls), - ) - expect(assistantWithToolCall).toBeDefined() - expect(assistantWithToolCall?.reasoning_content).toBe('thought') -}) -// openaiShim test extraction seam 146 end - - -// openaiShim test extraction seam 147 start: generic OpenAI-compatible providers do not echo reasoning_content on assistant tool-call messages -test('generic OpenAI-compatible providers do not echo reasoning_content on assistant tool-call messages', async () => { - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_API_KEY = 'sk-openai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'gpt-4o', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'gpt-4o', - system: 'test', - messages: [ - { role: 'user', content: 'hi' }, - { - role: 'assistant', - content: [ - { type: 'thinking', thinking: 'thought' }, - { type: 'text', text: 'hello' }, - { - type: 'tool_use', - id: 'call_1', - name: 'Bash', - input: { command: 'ls' }, - }, - ], - }, - { - role: 'user', - content: [ - { type: 'tool_result', tool_use_id: 'call_1', content: 'files' }, - ], - }, - ], - max_tokens: 32, - stream: false, - }) - - const messages = requestBody?.messages as Array> - const assistantWithToolCall = messages.find( - m => m.role === 'assistant' && Array.isArray(m.tool_calls), - ) - expect(assistantWithToolCall).toBeDefined() - expect(assistantWithToolCall?.reasoning_content).toBeUndefined() -}) -// openaiShim test extraction seam 147 end - - -// openaiShim test extraction seam 148 start: gateway-routed DeepSeek models inherit descriptor-backed reasoning and token shaping -test('gateway-routed DeepSeek models inherit descriptor-backed reasoning and token shaping', async () => { - process.env.CLAUDE_CODE_USE_OPENAI = '1' - process.env.OPENAI_BASE_URL = 'https://openrouter.ai/api/v1' - process.env.OPENAI_API_KEY = 'sk-openrouter-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'deepseek/deepseek-reasoner', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - reasoningEffort: 'xhigh', - }) as OpenAIShimClient - await client.beta.messages.create({ - model: 'deepseek/deepseek-reasoner', - system: 'test', - messages: [ - { role: 'user', content: 'hi' }, - { - role: 'assistant', - content: [ - { type: 'thinking', thinking: 'thought' }, - { type: 'text', text: 'hello' }, - { - type: 'tool_use', - id: 'call_1', - name: 'Bash', - input: { command: 'ls' }, - }, - ], - }, - { - role: 'user', - content: [ - { type: 'tool_result', tool_use_id: 'call_1', content: 'files' }, - ], - }, - ], - max_tokens: 64, - stream: false, - thinking: { type: 'enabled' }, - }) - - const messages = requestBody?.messages as Array> - const assistantWithToolCall = messages.find( - message => message.role === 'assistant' && Array.isArray(message.tool_calls), - ) - - expect(assistantWithToolCall?.reasoning_content).toBe('thought') - expect(requestBody?.thinking).toEqual({ type: 'enabled' }) - expect(requestBody?.reasoning_effort).toBe('max') - expect(requestBody?.max_tokens).toBe(64) - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 148 end - - -// openaiShim test extraction seam 149 start: Moonshot: cn host is also detected -test('Moonshot: cn host is also detected', async () => { - process.env.OPENAI_BASE_URL = 'https://api.moonshot.cn/v1' - process.env.OPENAI_API_KEY = 'sk-moonshot-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'kimi-k2.6', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'kimi-k2.6', - system: 'you are kimi', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 256, - stream: false, - }) - - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 149 end - - -// openaiShim test extraction seam 150 start: Kimi Code endpoint inherits Moonshot max_tokens/store compatibility -test('Kimi Code endpoint inherits Moonshot max_tokens/store compatibility', async () => { - process.env.OPENAI_BASE_URL = 'https://api.kimi.com/coding/v1' - process.env.OPENAI_API_KEY = 'sk-kimi-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'kimi-for-coding', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'kimi-for-coding', - system: 'you are kimi code', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 256, - stream: false, - }) - - expect(requestBody?.max_tokens).toBe(256) - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 150 end - - -// openaiShim test extraction seam 151 start: Kimi Code endpoint echoes reasoning_content on assistant tool-call messages -test('Kimi Code endpoint echoes reasoning_content on assistant tool-call messages', async () => { - process.env.OPENAI_BASE_URL = 'https://api.kimi.com/coding/v1' - process.env.OPENAI_API_KEY = 'sk-kimi-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'kimi-for-coding', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'kimi-for-coding', - system: 'you are kimi code', - messages: [ - { role: 'user', content: 'check the logs' }, - { - role: 'assistant', - content: [ - { - type: 'thinking', - thinking: 'Need to inspect logs via Bash; running a cat.', - }, - { type: 'text', text: "I'll inspect the logs." }, - { - type: 'tool_use', - id: 'call_bash_1', - name: 'Bash', - input: { command: 'cat /tmp/app.log' }, - }, - ], - }, - { - role: 'user', - content: [ - { - type: 'tool_result', - tool_use_id: 'call_bash_1', - content: 'log line 1\nlog line 2', - }, - ], - }, - ], - max_tokens: 256, - stream: false, - }) - - const messages = requestBody?.messages as Array> - const assistantWithToolCall = messages.find( - m => m.role === 'assistant' && Array.isArray(m.tool_calls), - ) - expect(assistantWithToolCall).toBeDefined() - expect(assistantWithToolCall?.reasoning_content).toBe( - 'Need to inspect logs via Bash; running a cat.', - ) -}) -// openaiShim test extraction seam 151 end - - -// openaiShim test extraction seam 152 start: DeepSeek sends thinking toggle and normalized reasoning effort -test('DeepSeek sends thinking toggle and normalized reasoning effort', async () => { - process.env.OPENAI_BASE_URL = 'https://api.deepseek.com/v1' - process.env.OPENAI_API_KEY = 'sk-deepseek' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'deepseek-v4-pro', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - reasoningEffort: 'xhigh', - }) as OpenAIShimClient - await client.beta.messages.create({ - model: 'deepseek-v4-pro', - system: 'test', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - thinking: { type: 'enabled' }, - }) - - expect(requestBody?.thinking).toEqual({ type: 'enabled' }) - expect(requestBody?.reasoning_effort).toBe('max') - expect(requestBody?.max_tokens).toBe(64) - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 152 end - - -// openaiShim test extraction seam 153 start: NVIDIA NIM DeepSeek sends chat template thinking kwargs - -// openaiShim test extraction seam 153 end - - -// openaiShim test extraction seam 154 start: NVIDIA NIM DeepSeek omits chat template thinking kwargs when thinking is disabled - -// openaiShim test extraction seam 154 end - - -// openaiShim test extraction seam 155 start: DeepSeek omits thinking controls when the Anthropic-side request does not set them -test('DeepSeek omits thinking controls when the Anthropic-side request does not set them', async () => { - process.env.OPENAI_BASE_URL = 'https://api.deepseek.com/v1' - process.env.OPENAI_API_KEY = 'sk-deepseek' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'deepseek-v4-flash', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'deepseek-v4-flash', - system: 'test', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 32, - stream: false, - }) - - expect(requestBody?.thinking).toBeUndefined() - expect(requestBody?.reasoning_effort).toBeUndefined() -}) -// openaiShim test extraction seam 155 end - - -// openaiShim test extraction seam 156 start: DeepSeek forwards an explicit thinking disable toggle for V4 models -test('DeepSeek forwards an explicit thinking disable toggle for V4 models', async () => { - process.env.OPENAI_BASE_URL = 'https://api.deepseek.com/v1' - process.env.OPENAI_API_KEY = 'sk-deepseek' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'deepseek-v4-flash', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'deepseek-v4-flash', - system: 'test', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 32, - stream: false, - thinking: { type: 'disabled' }, - }) - - expect(requestBody?.thinking).toEqual({ type: 'disabled' }) - expect(requestBody?.reasoning_effort).toBeUndefined() -}) // openaiShim test extraction seam 156 end @@ -9536,160 +5411,6 @@ test('preserves mixed text and image tool results as multipart content', async ( expect(content[0].type).toBe('text') expect(content[1].type).toBe('image_url') }) -// openaiShim test extraction seam 159 end - - -// openaiShim test extraction seam 160 start: Z.AI: uses max_tokens (not max_completion_tokens) and strips store -test('Z.AI: uses max_tokens (not max_completion_tokens) and strips store', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'GLM-5.1', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'GLM-5.1', - system: 'you are glm', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 256, - stream: false, - }) - - expect(requestBody?.max_tokens).toBe(256) - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.store).toBeUndefined() -}) -// openaiShim test extraction seam 160 end - - -// openaiShim test extraction seam 161 start: Z.AI: thinking mode enabled when requested -test('Z.AI: thinking mode enabled when requested', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'GLM-5.1', - choices: [ - { - message: { - role: 'assistant', - content: null, - reasoning_content: 'Let me think...', - }, - finish_reason: 'stop', - }, - ], - usage: { prompt_tokens: 3, completion_tokens: 1, total_tokens: 4 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'GLM-5.1', - system: 'you are glm', - messages: [{ role: 'user', content: 'think hard' }], - max_tokens: 1024, - stream: false, - thinking: { type: 'enabled', budget_tokens: 1024 }, - }) - - expect((requestBody?.thinking as Record)?.type).toBe('enabled') - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.max_tokens).toBe(1024) -}) -// openaiShim test extraction seam 161 end - - -// openaiShim test extraction seam 162 start: Z.AI GLM-5.2: default request relies on provider thinking defaults -test('Z.AI GLM-5.2: default request relies on provider thinking defaults', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'glm-5.2', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'glm-5.2', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - }) - - expect(requestBody?.model).toBe('glm-5.2') - expect(requestBody?.thinking).toBeUndefined() - expect(requestBody?.reasoning_effort).toBeUndefined() -}) -// openaiShim test extraction seam 162 end - - -// openaiShim test extraction seam 163 start: Z.AI GLM-5.2: user-selected xhigh effort maps to provider max effort -test('Z.AI GLM-5.2: user-selected xhigh effort maps to provider max effort', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'glm-5.2', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - reasoningEffort: 'xhigh', - }) as OpenAIShimClient - await client.beta.messages.create({ - model: 'glm-5.2', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - }) - - expect(requestBody?.model).toBe('glm-5.2') - expect(requestBody?.thinking).toEqual({ type: 'enabled' }) - expect(requestBody?.reasoning_effort).toBe('max') -}) // openaiShim test extraction seam 163 end @@ -9769,456 +5490,6 @@ test.each([ expect(requestBody?.thinking).toEqual({ type: 'enabled' }) expect(requestBody?.reasoning_effort).toBeUndefined() }) - -// openaiShim test extraction seam 164 start: Z.AI GLM-5.2: model-query thinking disable omits reasoning effort -test('Z.AI GLM-5.2: model-query thinking disable omits reasoning effort', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'glm-5.2', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'glm-5.2?thinking=disabled&reasoning=xhigh', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - }) - - expect(requestBody?.model).toBe('glm-5.2') - expect(requestBody?.thinking).toEqual({ type: 'disabled' }) - expect(requestBody?.reasoning_effort).toBeUndefined() -}) -// openaiShim test extraction seam 164 end - - -// openaiShim test extraction seam 165 start: Z.AI GLM-5.2: per-turn thinking overrides model-query default -test('Z.AI GLM-5.2: per-turn thinking overrides model-query default', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'glm-5.2', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'glm-5.2?thinking=disabled&reasoning=high', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: false, - thinking: { type: 'enabled' }, - }) - - expect(requestBody?.thinking).toEqual({ type: 'enabled' }) - expect(requestBody?.reasoning_effort).toBe('high') -}) -// openaiShim test extraction seam 165 end - - -// openaiShim test extraction seam 166 start: NVIDIA NIM Z.AI GLM sends chat template thinking kwargs - -// openaiShim test extraction seam 166 end - - -// openaiShim test extraction seam 167 start: NVIDIA NIM Z.AI GLM omits chat template thinking kwargs without a reasoning request - -// openaiShim test extraction seam 167 end - - -// openaiShim test extraction seam 168 start: NVIDIA NIM Z.AI GLM omits chat template thinking kwargs when thinking is disabled - -// openaiShim test extraction seam 168 end - - -// Extraction boundary: provider reasoning compatibility | tool-stream routing. -// The gateway emission regression below remains provider/request-shaping coverage. -// Keep this marker stable for independent adjacent test migrations. -// Regression test for #1950: GLM-5.2 served through NVIDIA NIM -// (`integrate.api.nvidia.com`) must never receive the Z.AI-proprietary -// `tool_stream` parameter. Streaming tool calls are simply not streamed on -// this gateway; sending the parameter aborts the request with -// `400 Unsupported parameter(s): tool_stream`. -// openaiShim test extraction seam 169 start: NVIDIA NIM Z.AI GLM streaming request with tools does not send tool_stream (regression #1950) -test('NVIDIA NIM Z.AI GLM streaming request with tools does not send tool_stream (regression #1950)', async () => { - process.env.OPENAI_BASE_URL = 'https://integrate.api.nvidia.com/v1' - process.env.NVIDIA_API_KEY = 'nvapi-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return makeSseResponse(makeStreamChunks([ - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'z-ai/glm-5.2', - choices: [{ index: 0, delta: { content: 'ok' }, finish_reason: null }], - }, - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'z-ai/glm-5.2', - choices: [{ index: 0, delta: {}, finish_reason: 'stop' }], - }, - ])) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'z-ai/glm-5.2', - messages: [{ role: 'user', content: 'run pwd' }], - tools: [ - { - name: 'Bash', - description: 'Run a shell command', - input_schema: { - type: 'object', - properties: { command: { type: 'string' } }, - required: ['command'], - }, - }, - ], - max_tokens: 64, - stream: true, - }) - - // tool_stream is a Z.AI-only streaming extension; NVIDIA NIM rejects it with - // `400 Unsupported parameter(s): tool_stream`. Streaming tool calls simply - // aren't streamed on this gateway. - expect(requestBody?.tool_stream).toBeUndefined() -}) -// openaiShim test extraction seam 169 end - - -// Extraction boundary: provider tool-stream shaping | executor tool-stream retry. -// The three retry-state tests below move together with request execution. -// Keep this marker stable for independent adjacent test migrations. -// Regression test for #1950: even if a gateway rejects `tool_stream` with a -// 400 (e.g. NVIDIA NIM: `Unsupported parameter(s): tool_stream`), the shim -// self-heals by dropping only that parameter and retrying with tools intact. -// Here we exercise the generic self-heal using a Z.AI-contract gateway that -// actually sends `tool_stream`, then rejects it — proving the retry drops the -// parameter rather than surfacing a hard error. -// openaiShim test extraction seam 170 start: Shim self-heals a JSON `tool_stream` rejection by retrying without it (#1950) -test('Shim self-heals a JSON `tool_stream` rejection by retrying without it (#1950)', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - const requestBodies: Array> = [] - let callCount = 0 - globalThis.fetch = (async (_input, init) => { - requestBodies.push(JSON.parse(String(init?.body))) - callCount += 1 - if (callCount === 1) { - return new Response( - '{"error":{"message":"tool_stream is unsupported"}}', - { status: 400, headers: { 'Content-Type': 'application/json' } }, - ) - } - return makeSseResponse(makeStreamChunks([ - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: { content: 'ok' }, finish_reason: null }], - }, - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: {}, finish_reason: 'stop' }], - }, - ])) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - // Must not throw — the self-heal retry succeeds. - await client.beta.messages.create({ - model: 'glm-5.2', - messages: [{ role: 'user', content: 'run pwd' }], - tools: [ - { - name: 'Bash', - description: 'Run a shell command', - input_schema: { - type: 'object', - properties: { command: { type: 'string' } }, - required: ['command'], - }, - }, - ], - max_tokens: 64, - stream: true, - }) - - // First attempt sent tool_stream; the self-heal dropped it and retried. - expect(requestBodies).toHaveLength(2) - expect(requestBodies[0]?.tool_stream).toBe(true) - expect(requestBodies[1]?.tool_stream).toBeUndefined() - // Tools are preserved across the retry. - expect(Array.isArray(requestBodies[1]?.tools)).toBe(true) -}) -// openaiShim test extraction seam 170 end - - -// openaiShim test extraction seam 171 start: Shim stops after one tool_stream self-heal retry when the retry also fails (#1950) -test('Shim stops after one tool_stream self-heal retry when the retry also fails (#1950)', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - const requestBodies: Array> = [] - globalThis.fetch = (async (_input, init) => { - requestBodies.push(JSON.parse(String(init?.body))) - return new Response( - '{"error":{"message":"tool_stream is unsupported"}}', - { status: 400, headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await expect( - client.beta.messages.create({ - model: 'glm-5.2', - messages: [{ role: 'user', content: 'run pwd' }], - tools: [{ - name: 'Bash', - description: 'Run a shell command', - input_schema: { - type: 'object', - properties: { command: { type: 'string' } }, - required: ['command'], - }, - }], - max_tokens: 64, - stream: true, - }), - ).rejects.toThrow() - - expect(requestBodies).toHaveLength(2) - expect(requestBodies[0]?.tool_stream).toBe(true) - expect(requestBodies[1]?.tool_stream).toBeUndefined() -}) -// openaiShim test extraction seam 171 end - - -// openaiShim test extraction seam 172 start: Shim retries a tool_stream rejection with the same pooled credential (#1950) -test('Shim retries a tool_stream rejection with the same pooled credential (#1950)', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEYS = 'key-a,key-b' - delete process.env.OPENAI_API_KEY - - const authorizations: Array = [] - let callCount = 0 - globalThis.fetch = (async (_input, init) => { - const headers = init?.headers as Record | undefined - authorizations.push(headers?.Authorization ?? headers?.authorization ?? null) - callCount += 1 - if (callCount === 1) { - return new Response( - '{"error":{"message":"Validation: Unsupported parameter(s): `tool_stream`"}}', - { status: 400, headers: { 'Content-Type': 'application/json' } }, - ) - } - return makeSseResponse(makeStreamChunks([ - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: { content: 'ok' }, finish_reason: null }], - }, - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: {}, finish_reason: 'stop' }], - }, - ])) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'glm-5.2', - messages: [{ role: 'user', content: 'run pwd' }], - tools: [{ - name: 'Bash', - description: 'Run a shell command', - input_schema: { type: 'object', properties: { command: { type: 'string' } }, required: ['command'] }, - }], - max_tokens: 64, - stream: true, - }) - - expect(authorizations).toEqual(['Bearer key-a', 'Bearer key-a']) -}) -// openaiShim test extraction seam 172 end - - -// Extraction boundary: executor tool-stream retry | provider tool-stream shaping. -// Provider emission rules below remain with compatibility/request planning. -// Keep this marker stable for independent adjacent test migrations. -// openaiShim test extraction seam 173 start: Z.AI GLM-5.2: streaming requests with tools send tool_stream -test('Z.AI GLM-5.2: streaming requests with tools send tool_stream', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return makeSseResponse(makeStreamChunks([ - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: { content: 'ok' }, finish_reason: null }], - }, - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: {}, finish_reason: 'stop' }], - }, - ])) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'glm-5.2', - messages: [{ role: 'user', content: 'run pwd' }], - tools: [ - { - name: 'Bash', - description: 'Run a shell command', - input_schema: { - type: 'object', - properties: { command: { type: 'string' } }, - required: ['command'], - }, - }, - ], - max_tokens: 64, - stream: true, - }) - - expect(requestBody?.tool_stream).toBe(true) -}) -// openaiShim test extraction seam 173 end - - -// openaiShim test extraction seam 174 start: Hicap GLM-5.2: uses Z.AI-compatible request shaping -test('Hicap GLM-5.2: uses Z.AI-compatible request shaping', async () => { - process.env.OPENAI_BASE_URL = 'https://api.hicap.ai/v1' - process.env.HICAP_API_KEY = 'sk-hicap-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return makeSseResponse(makeStreamChunks([ - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: { content: 'ok' }, finish_reason: null }], - }, - { - id: 'chatcmpl-1', - object: 'chat.completion.chunk', - model: 'glm-5.2', - choices: [{ index: 0, delta: {}, finish_reason: 'stop' }], - }, - ])) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ reasoningEffort: 'xhigh' }) as OpenAIShimClient - await client.beta.messages.create({ - model: 'GLM-5.2', - messages: [{ role: 'user', content: 'run pwd' }], - tools: [ - { - name: 'Bash', - description: 'Run a shell command', - input_schema: { - type: 'object', - properties: { command: { type: 'string' } }, - required: ['command'], - }, - }, - ], - max_tokens: 64, - stream: true, - }) - - expect(requestBody?.model).toBe('glm-5.2') - expect(requestBody?.store).toBeUndefined() - expect(requestBody?.max_tokens).toBe(64) - expect(requestBody?.max_completion_tokens).toBeUndefined() - expect(requestBody?.thinking).toEqual({ type: 'enabled' }) - expect(requestBody?.reasoning_effort).toBe('max') - expect(requestBody?.tool_stream).toBe(true) -}) -// openaiShim test extraction seam 174 end - -// openaiShim test extraction seam 175 start: Z.AI GLM-5.2: remote tool incompatibility does not use local toolless retry -test('Z.AI GLM-5.2: remote tool incompatibility does not use local toolless retry', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - const requestBodies: Array> = [] - globalThis.fetch = (async (_input, init) => { - requestBodies.push(JSON.parse(String(init?.body)) as Record) - return new Response('tool_calls are not supported', { - status: 400, - headers: { 'Content-Type': 'text/plain' }, - }) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await expect( - client.beta.messages.create({ - model: 'glm-5.2', - messages: [{ role: 'user', content: 'run pwd' }], - tools: [ - { - name: 'Bash', - description: 'Run a shell command', - input_schema: { - type: 'object', - properties: { command: { type: 'string' } }, - required: ['command'], - }, - }, - ], - max_tokens: 64, - stream: true, - }), - ).rejects.toThrow() - - expect(requestBodies).toHaveLength(1) - expect(requestBodies[0]?.tool_stream).toBe(true) -}) // openaiShim test extraction seam 175 end @@ -10284,74 +5555,6 @@ test.each([ expect(requestBody?.tool_stream).toBeUndefined() }) - -// openaiShim test extraction seam 176 start: Z.AI GLM-5.2: preserved thinking round-trips with tool calls -test('Z.AI GLM-5.2: preserved thinking round-trips with tool calls', async () => { - process.env.OPENAI_BASE_URL = 'https://api.z.ai/api/coding/paas/v4' - process.env.OPENAI_API_KEY = 'sk-zai-test' - - let requestBody: Record | undefined - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'glm-5.2', - choices: [ - { message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }, - ], - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - await client.beta.messages.create({ - model: 'glm-5.2', - messages: [ - { role: 'user', content: 'inspect files' }, - { - role: 'assistant', - content: [ - { type: 'thinking', thinking: 'Need to list files before answering.' }, - { - type: 'tool_use', - id: 'call_bash_1', - name: 'Bash', - input: { command: 'ls' }, - }, - ], - }, - { - role: 'user', - content: [ - { type: 'tool_result', tool_use_id: 'call_bash_1', content: 'README.md' }, - ], - }, - ], - max_tokens: 64, - stream: false, - }) - - const messages = requestBody?.messages as Array> - const assistantWithToolCall = messages.find( - message => message.role === 'assistant' && Array.isArray(message.tool_calls), - ) - - expect(assistantWithToolCall?.reasoning_content).toBe( - 'Need to list files before answering.', - ) - expect(assistantWithToolCall?.tool_calls).toEqual([ - { - id: 'call_bash_1', - type: 'function', - function: { - name: 'Bash', - arguments: JSON.stringify({ command: 'ls' }), - }, - }, - ]) -}) // openaiShim test extraction seam 176 end @@ -10454,131 +5657,6 @@ test('strips Anthropic attribution header block from responses-API instructions expect(instructions).not.toContain('cc_version=') expect(instructions).toContain('You are Claude Code.') }) -// openaiShim test extraction seam 178 end - - -// openaiShim test extraction seam 179 start: emits reasoning_effort on chat_completions when reasoningEffort is passed -test('emits reasoning_effort on chat_completions when reasoningEffort is passed', async () => { - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_API_KEY = 'test-key' - // gpt-5.4 now auto-routes to /responses on api.openai.com; opt back into - // chat_completions to exercise its top-level reasoning_effort serialization. - process.env.OPENAI_API_FORMAT = 'chat_completions' - - let requestBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'gpt-5.4', - choices: [ - { - message: { role: 'assistant', content: 'ok' }, - finish_reason: 'stop', - }, - ], - usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({ - reasoningEffort: 'xhigh', - }) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-5.4', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 16, - stream: false, - }) - - expect(requestBody?.reasoning_effort).toBe('xhigh') -}) -// openaiShim test extraction seam 179 end - - -// openaiShim test extraction seam 180 start: omits reasoning_effort on chat_completions when no override and model has no alias default -test('omits reasoning_effort on chat_completions when no override and model has no alias default', async () => { - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_API_KEY = 'test-key' - - let requestBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'gpt-4o', - choices: [ - { - message: { role: 'assistant', content: 'ok' }, - finish_reason: 'stop', - }, - ], - usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-4o', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 16, - stream: false, - }) - - expect(requestBody && 'reasoning_effort' in requestBody).toBe(false) -}) -// openaiShim test extraction seam 180 end - - -// openaiShim test extraction seam 181 start: emits reasoning_effort from codex alias default when no override is passed -test('emits reasoning_effort from codex alias default when no override is passed', async () => { - process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1' - process.env.OPENAI_API_KEY = 'test-key' - // gpt-5.4 now auto-routes to /responses on api.openai.com; opt back into - // chat_completions to exercise its top-level reasoning_effort serialization. - process.env.OPENAI_API_FORMAT = 'chat_completions' - - let requestBody: Record | undefined - - globalThis.fetch = (async (_input, init) => { - requestBody = JSON.parse(String(init?.body)) - return new Response( - JSON.stringify({ - id: 'chatcmpl-1', - model: 'gpt-5.4', - choices: [ - { - message: { role: 'assistant', content: 'ok' }, - finish_reason: 'stop', - }, - ], - usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }, - }), - { headers: { 'Content-Type': 'application/json' } }, - ) - }) as unknown as FetchType - - const client = createOpenAIShimClient({}) as OpenAIShimClient - - await client.beta.messages.create({ - model: 'gpt-5.4', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 16, - stream: false, - }) - - expect(requestBody?.reasoning_effort).toBe('high') -}) // openaiShim test extraction seam 181 end @@ -11007,77 +6085,6 @@ test('GitHub Copilot responses fallback does not retry non-retryable HTTP failur ).rejects.toMatchObject({ status: 401 }) expect(fetchCalls).toBe(2) }) - -// openaiShim test extraction seam 186 start: GitHub Copilot 401 chat_completions retries with refreshed token -test('GitHub Copilot 401 chat_completions retries with refreshed token', async () => { - const realModule = realGithubModelsCredentials - try { - const refreshSpy = mock(async () => { - process.env.GITHUB_TOKEN = 'refreshed-token' - process.env.OPENAI_API_KEY = 'refreshed-token' - return true - }) - - mock.module('../../utils/githubModelsCredentials.js', () => ({ - ...realModule, - refreshCopilotTokenOn401: refreshSpy, - })) - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_BASE_URL = 'https://api.githubcopilot.com' - process.env.OPENAI_API_KEY = 'initial-token' - process.env.GITHUB_TOKEN = 'initial-token' - - let fetchCallCount = 0 - let firstAuth: string | undefined - let secondAuth: string | undefined - - globalThis.fetch = ((_input, init) => { - fetchCallCount++ - const headers = init?.headers as Record | undefined - const auth = headers?.Authorization - - if (fetchCallCount === 1) { - firstAuth = auth - return Promise.resolve( - new Response( - JSON.stringify({ error: { message: 'token expired' } }), - { status: 401, headers: { 'Content-Type': 'application/json' } }, - ), - ) - } - - if (fetchCallCount === 2) { - secondAuth = auth - return Promise.resolve(makeChatCompletionResponse('gpt-4')) - } - - throw new Error(`unexpected fetch call #${fetchCallCount}`) - }) as unknown as typeof globalThis.fetch - - const { createOpenAIShimClient: createClient } = - await importFreshOpenAIShim('copilot-401-retry') - - const client = createClient({}) as OpenAIShimClient - - const response = await client.beta.messages.create({ - model: 'gpt-4', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(refreshSpy).toHaveBeenCalledTimes(1) - expect(process.env.GITHUB_TOKEN).toBe('refreshed-token') - expect(process.env.OPENAI_API_KEY).toBe('refreshed-token') - expect(fetchCallCount).toBe(2) - expect(firstAuth).toBe('Bearer initial-token') - expect(secondAuth).toBe('Bearer refreshed-token') - expect(response).toBeDefined() - } finally { - mock.module('../../utils/githubModelsCredentials.js', () => realModule) - } -}) // openaiShim test extraction seam 186 end @@ -11157,348 +6164,6 @@ test('GitHub Copilot 401 codex_responses retries with refreshed token', async () mock.module('../../utils/githubModelsCredentials.js', () => realGithubModule) } }) -// openaiShim test extraction seam 187 end - - -// openaiShim test extraction seam 188 start: GitHub Copilot 401 with credential pool uses refreshed token not pool key -test('GitHub Copilot 401 with credential pool uses refreshed token not pool key', async () => { - const realGithubModule = realGithubModelsCredentials - try { - const refreshSpy = mock(async () => { - process.env.GITHUB_TOKEN = 'refreshed-token' - process.env.OPENAI_API_KEY = 'refreshed-token' - return true - }) - - mock.module('../../utils/githubModelsCredentials.js', () => ({ - ...realGithubModule, - refreshCopilotTokenOn401: refreshSpy, - })) - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_BASE_URL = 'https://api.githubcopilot.com' - delete process.env.OPENAI_API_KEY - process.env.OPENAI_API_KEYS = 'initial-token,second-key' - process.env.GITHUB_TOKEN = 'initial-token' - - let fetchCallCount = 0 - let usedAuthHeaders: string[] = [] - - globalThis.fetch = ((_input, init) => { - fetchCallCount++ - const headers = init?.headers as Record | undefined - usedAuthHeaders.push(headers?.Authorization ?? '') - - if (fetchCallCount === 1) { - return Promise.resolve( - new Response( - JSON.stringify({ error: { message: 'token expired' } }), - { status: 401, headers: { 'Content-Type': 'application/json' } }, - ), - ) - } - - return Promise.resolve(makeChatCompletionResponse('gpt-4')) - }) as unknown as typeof globalThis.fetch - - const { createOpenAIShimClient: createClient } = - await importFreshOpenAIShim('copilot-401-pool') - - const client = createClient({}) as OpenAIShimClient - - const response = await client.beta.messages.create({ - model: 'gpt-4', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(refreshSpy).toHaveBeenCalledTimes(1) - expect(fetchCallCount).toBe(2) - expect(usedAuthHeaders[0]).toBe('Bearer initial-token') - expect(usedAuthHeaders[1]).toBe('Bearer refreshed-token') - expect(response).toBeDefined() - } finally { - mock.module('../../utils/githubModelsCredentials.js', () => realGithubModule) - } -}) -// openaiShim test extraction seam 188 end - - -// openaiShim test extraction seam 189 start: GitHub Copilot 401 with "token has expired" triggers refresh -test('GitHub Copilot 401 with "token has expired" triggers refresh', async () => { - const realGithubModule = realGithubModelsCredentials - try { - const refreshSpy = mock(async () => { - process.env.GITHUB_TOKEN = 'refreshed-token' - process.env.OPENAI_API_KEY = 'refreshed-token' - return true - }) - - mock.module('../../utils/githubModelsCredentials.js', () => ({ - ...realGithubModule, - refreshCopilotTokenOn401: refreshSpy, - })) - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_BASE_URL = 'https://api.githubcopilot.com' - process.env.OPENAI_API_KEY = 'initial-token' - process.env.GITHUB_TOKEN = 'initial-token' - - let fetchCallCount = 0 - - globalThis.fetch = ((_input, init) => { - fetchCallCount++ - - if (fetchCallCount === 1) { - return Promise.resolve( - new Response( - JSON.stringify({ error: { message: 'token has expired' } }), - { status: 401, headers: { 'Content-Type': 'application/json' } }, - ), - ) - } - - return Promise.resolve(makeChatCompletionResponse('gpt-4')) - }) as unknown as typeof globalThis.fetch - - const { createOpenAIShimClient: createClient } = - await importFreshOpenAIShim('copilot-401-has-expired') - - const client = createClient({}) as OpenAIShimClient - - const response = await client.beta.messages.create({ - model: 'gpt-4', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }) - - expect(refreshSpy).toHaveBeenCalledTimes(1) - expect(fetchCallCount).toBe(2) - expect(response).toBeDefined() - } finally { - mock.module('../../utils/githubModelsCredentials.js', () => realGithubModule) - } -}) -// openaiShim test extraction seam 189 end - - -// openaiShim test extraction seam 190 start: GitHub Copilot 401 without expired-token message does not trigger refresh -test('GitHub Copilot 401 without expired-token message does not trigger refresh', async () => { - const realGithubModule = realGithubModelsCredentials - try { - const refreshSpy = mock(async () => true) - - mock.module('../../utils/githubModelsCredentials.js', () => ({ - ...realGithubModule, - refreshCopilotTokenOn401: refreshSpy, - })) - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_BASE_URL = 'https://api.githubcopilot.com' - process.env.OPENAI_API_KEY = 'initial-token' - process.env.GITHUB_TOKEN = 'initial-token' - - let fetchCallCount = 0 - - globalThis.fetch = ((_input) => { - fetchCallCount++ - return Promise.resolve( - new Response( - JSON.stringify({ error: { message: 'invalid token' } }), - { status: 401, headers: { 'Content-Type': 'application/json' } }, - ), - ) - }) as unknown as typeof globalThis.fetch - - const { createOpenAIShimClient: createClient } = - await importFreshOpenAIShim('copilot-401-no-refresh') - - const client = createClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'gpt-4', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(refreshSpy).toHaveBeenCalledTimes(0) - expect(fetchCallCount).toBe(1) - } finally { - mock.module('../../utils/githubModelsCredentials.js', () => realGithubModule) - } -}) -// openaiShim test extraction seam 190 end - - -// openaiShim test extraction seam 191 start: GitHub Copilot 401 refresh returning same token does not update auth -test('GitHub Copilot 401 refresh returning same token does not update auth', async () => { - const realGithubModule = realGithubModelsCredentials - try { - const refreshSpy = mock(async () => { - process.env.GITHUB_TOKEN = 'initial-token' - process.env.OPENAI_API_KEY = 'initial-token' - return true - }) - - mock.module('../../utils/githubModelsCredentials.js', () => ({ - ...realGithubModule, - refreshCopilotTokenOn401: refreshSpy, - })) - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_BASE_URL = 'https://api.githubcopilot.com' - process.env.OPENAI_API_KEY = 'initial-token' - process.env.GITHUB_TOKEN = 'initial-token' - - let fetchCallCount = 0 - let usedAuthHeaders: string[] = [] - - globalThis.fetch = ((_input, init) => { - fetchCallCount++ - const headers = init?.headers as Record | undefined - usedAuthHeaders.push(headers?.Authorization ?? '') - - return Promise.resolve( - new Response( - JSON.stringify({ error: { message: 'token expired' } }), - { status: 401, headers: { 'Content-Type': 'application/json' } }, - ), - ) - }) as unknown as typeof globalThis.fetch - - const { createOpenAIShimClient: createClient } = - await importFreshOpenAIShim('copilot-401-same-token') - - const client = createClient({}) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'gpt-4', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(refreshSpy).toHaveBeenCalledTimes(1) - expect(fetchCallCount).toBeGreaterThanOrEqual(2) - expect(usedAuthHeaders.every(h => h === 'Bearer initial-token')).toBe(true) - } finally { - mock.module('../../utils/githubModelsCredentials.js', () => realGithubModule) - } -}) -// openaiShim test extraction seam 191 end - - -// openaiShim test extraction seam 192 start: GitHub Copilot 401 codex_responses with providerOverride does not trigger refresh -test('GitHub Copilot 401 codex_responses with providerOverride does not trigger refresh', async () => { - const realGithubModule = realGithubModelsCredentials - try { - const refreshSpy = mock(async () => { - process.env.GITHUB_TOKEN = 'refreshed-token' - process.env.OPENAI_API_KEY = 'refreshed-token' - return true - }) - - mock.module('../../utils/githubModelsCredentials.js', () => ({ - ...realGithubModule, - refreshCopilotTokenOn401: refreshSpy, - })) - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_BASE_URL = 'https://api.githubcopilot.com' - process.env.OPENAI_API_KEY = 'stored-copilot-token' - process.env.GITHUB_TOKEN = 'stored-copilot-token' - - // Mock fetch so performCodexRequest gets a 401 response (no codexShim mock needed) - globalThis.fetch = (() => - Promise.resolve( - new Response( - JSON.stringify({ error: { message: 'token expired' } }), - { status: 401, headers: { 'Content-Type': 'application/json' } }, - ), - )) as unknown as typeof globalThis.fetch - - const { createOpenAIShimClient: createClient } = - await importFreshOpenAIShim('copilot-401-override-codex') - - // providerOverride.apiKey differs from OPENAI_API_KEY → credential source gate blocks refresh - const client = createClient({ - providerOverride: { model: 'gpt-5', baseURL: 'https://api.githubcopilot.com', apiKey: 'override-token' }, - }) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'gpt-5', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(refreshSpy).toHaveBeenCalledTimes(0) - } finally { - mock.module('../../utils/githubModelsCredentials.js', () => realGithubModule) - } -}) -// openaiShim test extraction seam 192 end - - -// openaiShim test extraction seam 193 start: GitHub Copilot 401 chat_completions with providerOverride does not trigger refresh -test('GitHub Copilot 401 chat_completions with providerOverride does not trigger refresh', async () => { - const realGithubModule = realGithubModelsCredentials - try { - const refreshSpy = mock(async () => { - process.env.GITHUB_TOKEN = 'refreshed-token' - process.env.OPENAI_API_KEY = 'refreshed-token' - return true - }) - - mock.module('../../utils/githubModelsCredentials.js', () => ({ - ...realGithubModule, - refreshCopilotTokenOn401: refreshSpy, - })) - - process.env.CLAUDE_CODE_USE_GITHUB = '1' - process.env.OPENAI_BASE_URL = 'https://api.githubcopilot.com' - process.env.OPENAI_API_KEY = 'stored-copilot-token' - process.env.GITHUB_TOKEN = 'stored-copilot-token' - - globalThis.fetch = (() => - Promise.resolve( - new Response( - JSON.stringify({ error: { message: 'token expired' } }), - { status: 401, headers: { 'Content-Type': 'application/json' } }, - ), - )) as unknown as typeof globalThis.fetch - - const { createOpenAIShimClient: createClient } = - await importFreshOpenAIShim('copilot-401-override-chat') - - // providerOverride.apiKey differs from OPENAI_API_KEY → credential source gate blocks refresh - const client = createClient({ - providerOverride: { model: 'gpt-4', baseURL: 'https://api.githubcopilot.com', apiKey: 'override-token' }, - }) as OpenAIShimClient - - await expect( - client.beta.messages.create({ - model: 'gpt-4', - messages: [{ role: 'user', content: 'hello' }], - max_tokens: 32, - stream: false, - }), - ).rejects.toThrow() - - expect(refreshSpy).toHaveBeenCalledTimes(0) - } finally { - mock.module('../../utils/githubModelsCredentials.js', () => realGithubModule) - } -}) // openaiShim test extraction seam 193 end @@ -11544,205 +6209,6 @@ async function collectFallbackEvents( globalThis.fetch = previousFetch } } - -// openaiShim test extraction seam 194 start: JSON fallback: preserves tool_calls as a tool_use block -test('JSON fallback: preserves tool_calls as a tool_use block', async () => { - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-tool', - model: 'fake-model', - choices: [ - { - message: { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_1', - type: 'function', - function: { name: 'Bash', arguments: '{"command":"pwd"}' }, - }, - ], - }, - finish_reason: 'tool_calls', - }, - ], - }) - - const toolStart = events.find( - event => - event.type === 'content_block_start' && - typeof event.content_block === 'object' && - event.content_block !== null && - (event.content_block as Record).type === 'tool_use', - ) as { content_block?: Record } | undefined - expect(toolStart?.content_block).toMatchObject({ - type: 'tool_use', - id: 'call_1', - name: 'Bash', - }) - - const inputDelta = events.find( - event => - event.type === 'content_block_delta' && - typeof event.delta === 'object' && - event.delta !== null && - (event.delta as Record).type === 'input_json_delta', - ) as { delta?: { partial_json?: string } } | undefined - expect(JSON.parse(inputDelta?.delta?.partial_json ?? '{}')).toEqual({ - command: 'pwd', - }) - - const stopEvent = events.find(e => e.type === 'message_delta') as - | { delta?: { stop_reason?: string } } - | undefined - expect(stopEvent?.delta?.stop_reason).toBe('tool_use') -}) -// openaiShim test extraction seam 194 end - - -// openaiShim test extraction seam 195 start: JSON fallback: maps finish_reason=length to max_tokens -test('JSON fallback: maps finish_reason=length to max_tokens', async () => { - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-len', - model: 'fake-model', - choices: [ - { message: { role: 'assistant', content: 'partial' }, finish_reason: 'length' }, - ], - }) - const stopEvent = events.find(e => e.type === 'message_delta') as - | { delta?: { stop_reason?: string } } - | undefined - expect(stopEvent?.delta?.stop_reason).toBe('max_tokens') -}) -// openaiShim test extraction seam 195 end - - -// openaiShim test extraction seam 196 start: JSON fallback: preserves OpenCode Go quota error guidance -test('JSON fallback: preserves OpenCode Go quota error guidance', async () => { - process.env.OPENAI_BASE_URL = 'https://opencode.ai/zen/go/v1' - const previousFetch = globalThis.fetch - globalThis.fetch = (async () => - withResponseUrl( - makeJsonChatCompletion({ - error: { - type: 'FreeUsageLimitError', - message: 'free usage limit reached', - }, - }), - 'https://opencode.ai/zen/go/v1/chat/completions', - )) as unknown as FetchType - - try { - const client = createOpenAIShimClient({}) as OpenAIShimClient - const result = await client.beta.messages - .create({ - model: 'fake-model', - messages: [{ role: 'user', content: 'hi' }], - max_tokens: 64, - stream: true, - }) - .withResponse() - - let caught: unknown - try { - for await (const _event of result.data) { - // Consume until the JSON error is surfaced. - } - } catch (error) { - caught = error - } - - expect(caught).toBeInstanceOf(APIError) - const apiError = caught as APIError - expect(apiError.headers?.get('x-opencode-request-url')).toBe( - 'https://opencode.ai/zen/go/v1/chat/completions', - ) - const message = getAssistantMessageFromError(apiError, 'glm-5.1') - const first = message.message.content[0] - expect(typeof first === 'object' && first && 'text' in first ? first.text : '').toBe( - OPENCODE_GO_FREE_LIMIT_ERROR_MESSAGE, - ) - } finally { - globalThis.fetch = previousFetch - } -}) -// openaiShim test extraction seam 196 end - - -// openaiShim test extraction seam 197 start: JSON fallback: strips tags from emitted text -test('JSON fallback: strips tags from emitted text', async () => { - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-think', - model: 'fake-model', - choices: [ - { - message: { role: 'assistant', content: 'private planvisible answer' }, - finish_reason: 'stop', - }, - ], - }) - const textDelta = events.find( - event => - event.type === 'content_block_delta' && - typeof event.delta === 'object' && - event.delta !== null && - (event.delta as Record).type === 'text_delta', - ) as { delta?: { text?: string } } | undefined - expect(textDelta?.delta?.text).toBe('visible answer') - expect(textDelta?.delta?.text).not.toContain('private plan') -}) -// openaiShim test extraction seam 197 end - - -// openaiShim test extraction seam 198 start: JSON fallback: normalizes array content into a text string -test('JSON fallback: normalizes array content into a text string', async () => { - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-array', - model: 'fake-model', - choices: [ - { - message: { - role: 'assistant', - content: [ - { type: 'text', text: 'line one' }, - { type: 'text', text: 'line two' }, - ], - }, - finish_reason: 'stop', - }, - ], - }) - const textDelta = events.find( - event => - event.type === 'content_block_delta' && - typeof event.delta === 'object' && - event.delta !== null && - (event.delta as Record).type === 'text_delta', - ) as { delta?: { text?: unknown } } | undefined - expect(typeof textDelta?.delta?.text).toBe('string') - expect(textDelta?.delta?.text).toBe('line one\nline two') -}) -// openaiShim test extraction seam 198 end - - -// openaiShim test extraction seam 199 start: JSON fallback: recovers raw-text tool call into tool_use block - -// openaiShim test extraction seam 199 end - - -// openaiShim test extraction seam 200 start: JSON fallback façade terminates converted messages -test('JSON fallback façade terminates converted messages', async () => { - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-boundary', - model: 'boundary-model', - choices: [{ - message: { role: 'assistant', content: 'ok' }, - finish_reason: 'stop', - }], - }) - - expect(events.at(-1)?.type).toBe('message_stop') -}) // openaiShim test extraction seam 200 end // openaiShim test extraction seam 201 start: JSON fallback: recovers Tencent HY3 text tool calls into tool_use blocks @@ -11788,111 +6254,4 @@ test('JSON fallback: recovers Tencent HY3 text tool calls into tool_use blocks', | undefined expect(stopEvent?.delta?.stop_reason).toBe('tool_use') }) -// openaiShim test extraction seam 201 end - - -// openaiShim test extraction seam 202 start: JSON fallback: preserves HY3-looking text for non-Tencent model names -test('JSON fallback: preserves HY3-looking text for non-Tencent model names', async () => { - const text = - 'TaskCreate\nsubject: merely a documentation example\n' - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-non-tencent-hy3', - model: 'other/hy3-documentation', - choices: [ - { - message: { role: 'assistant', content: text }, - finish_reason: 'stop', - }, - ], - }, 'other/hy3-documentation') - const toolStart = events.find( - event => - event.type === 'content_block_start' && - typeof event.content_block === 'object' && - event.content_block !== null && - (event.content_block as Record).type === 'tool_use', - ) - const textDelta = events.find( - event => - event.type === 'content_block_delta' && - typeof event.delta === 'object' && - event.delta !== null && - (event.delta as Record).type === 'text_delta', - ) as { delta?: { text?: string } } | undefined - - expect(toolStart).toBeUndefined() - expect(textDelta?.delta?.text).toBe(text) -}) -// openaiShim test extraction seam 202 end - - -// openaiShim test extraction seam 203 start: JSON fallback: empty tool_calls array does not block raw-text recovery -test('JSON fallback: empty tool_calls array does not block raw-text recovery', async () => { - // tool_calls: [] is truthy; it must be treated as "no structured tool calls" - // so the raw "Tool calls requested" recovery still runs. - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-empty-tc', - model: 'fake-model', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [], - content: - 'Tool calls requested:\n- Bash({"command":"ls"}) [id: call_empty_tc]', - }, - finish_reason: 'stop', - }, - ], - }) - const toolStart = events.find( - event => - event.type === 'content_block_start' && - typeof event.content_block === 'object' && - event.content_block !== null && - (event.content_block as Record).type === 'tool_use', - ) as { content_block?: Record } | undefined - expect(toolStart?.content_block).toMatchObject({ - type: 'tool_use', - id: 'call_empty_tc', - name: 'Bash', - }) -}) -// openaiShim test extraction seam 203 end - - -// openaiShim test extraction seam 204 start: JSON fallback: empty tool_calls does not block raw-text recovery on array content -test('JSON fallback: empty tool_calls does not block raw-text recovery on array content', async () => { - // Companion to the string-content case above: the array-content branch must - // also treat tool_calls: [] as "no structured tool calls" so raw recovery runs. - const events = await collectFallbackEvents({ - id: 'chatcmpl-json-empty-tc-array', - model: 'fake-model', - choices: [ - { - message: { - role: 'assistant', - tool_calls: [], - content: [ - { type: 'text', text: 'Tool calls requested:' }, - { type: 'text', text: '- Bash({"command":"ls"}) [id: call_empty_tc_arr]' }, - ], - }, - finish_reason: 'stop', - }, - ], - }) - const toolStart = events.find( - event => - event.type === 'content_block_start' && - typeof event.content_block === 'object' && - event.content_block !== null && - (event.content_block as Record).type === 'tool_use', - ) as { content_block?: Record } | undefined - expect(toolStart?.content_block).toMatchObject({ - type: 'tool_use', - id: 'call_empty_tc_arr', - name: 'Bash', - }) -}) // openaiShim test extraction seam 204 end