From e8bf7899614819d865d1f4c6825ad1b166833b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Tue, 9 Jun 2026 22:16:38 +0800 Subject: [PATCH] fix(provider): request non-stream OpenAI chat tests (#638) Ensure custom OpenAI-compatible provider tests explicitly request non-stream responses for both direct connectivity checks and the proxy pipeline. This avoids default SSE responses being parsed as empty JSON by provider validation. Tested: bun test src/server/__tests__/providers.test.ts --test-name-pattern "requests non-stream OpenAI Chat responses during provider tests" Tested: bun test src/server/__tests__/providers.test.ts Tested: bun test src/server/__tests__/proxy-transform.test.ts Tested: bun run check:server Confidence: high Scope-risk: narrow --- src/server/__tests__/providers.test.ts | 36 +++++++++++++++++++ .../proxy/transform/anthropicToOpenaiChat.ts | 2 +- src/server/services/providerService.ts | 2 +- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/server/__tests__/providers.test.ts b/src/server/__tests__/providers.test.ts index 7381db61..0167e211 100644 --- a/src/server/__tests__/providers.test.ts +++ b/src/server/__tests__/providers.test.ts @@ -1263,6 +1263,42 @@ describe('ProviderService', () => { } }) + test('requests non-stream OpenAI Chat responses during provider tests', async () => { + const originalFetch = globalThis.fetch + const calls: Array<{ body: Record }> = [] + globalThis.fetch = mock(async (_url: string | URL | Request, init?: RequestInit) => { + calls.push({ body: JSON.parse(String(init?.body)) as Record }) + return new Response(JSON.stringify({ + id: 'chatcmpl-1', + object: 'chat.completion', + created: 0, + model: 'deepseek-v4-flash', + choices: [{ index: 0, message: { role: 'assistant', content: 'ok' }, finish_reason: 'stop' }], + usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }, + }), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }) + }) as typeof fetch + + try { + const svc = new ProviderService() + const result = await svc.testProviderConfig({ + baseUrl: 'https://api.example.com', + apiKey: 'sk-api', + modelId: 'deepseek-v4-flash', + authStrategy: 'api_key', + apiFormat: 'openai_chat', + }) + + expect(result.connectivity.success).toBe(true) + expect(result.proxy?.success).toBe(true) + expect(calls.map((call) => call.body.stream)).toEqual([false, false]) + } finally { + globalThis.fetch = originalFetch + } + }) + test('should use configured network timeout for provider tests', async () => { await fs.writeFile( path.join(tmpDir, 'settings.json'), diff --git a/src/server/proxy/transform/anthropicToOpenaiChat.ts b/src/server/proxy/transform/anthropicToOpenaiChat.ts index 123589b6..01a14385 100644 --- a/src/server/proxy/transform/anthropicToOpenaiChat.ts +++ b/src/server/proxy/transform/anthropicToOpenaiChat.ts @@ -53,7 +53,7 @@ export function anthropicToOpenaiChat( const result: OpenAIChatRequest = { model: body.model, messages, - stream: body.stream, + stream: body.stream === true, } // max_tokens — omit to let upstream provider use its own default/max. diff --git a/src/server/services/providerService.ts b/src/server/services/providerService.ts index 7d43fc33..3d3643b6 100644 --- a/src/server/services/providerService.ts +++ b/src/server/services/providerService.ts @@ -603,7 +603,7 @@ function buildDirectTestRequest( return { url: `${base}/v1/chat/completions`, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` }, - body: { model: modelId, max_tokens: 16, messages: [{ role: 'user', content: prompt }] }, + body: { model: modelId, max_tokens: 16, stream: false, messages: [{ role: 'user', content: prompt }] }, } } if (format === 'openai_responses') {