diff --git a/packages/core/src/code_assist/server.test.ts b/packages/core/src/code_assist/server.test.ts index 89ce45e1aa..8ec8cb8dad 100644 --- a/packages/core/src/code_assist/server.test.ts +++ b/packages/core/src/code_assist/server.test.ts @@ -408,6 +408,48 @@ describe('CodeAssistServer', () => { expect(results[1].candidates?.[0].content?.parts?.[0].text).toBe(' World'); }); + it('should handle Web ReadableStream in generateContentStream', async () => { + const { server, mockRequest } = createTestServer(); + + // Create a mock Web ReadableStream + const mockWebStream = new ReadableStream({ + start(controller) { + const mockResponseData = { + response: { + candidates: [{ content: { parts: [{ text: 'Hello Web' }] } }], + }, + }; + controller.enqueue( + new TextEncoder().encode( + 'data: ' + JSON.stringify(mockResponseData) + '\n\n', + ), + ); + controller.close(); + }, + }); + + mockRequest.mockResolvedValue({ data: mockWebStream }); + + const stream = await server.generateContentStream( + { + model: 'test-model', + contents: [{ role: 'user', parts: [{ text: 'request' }] }], + }, + 'user-prompt-id', + LlmRole.MAIN, + ); + + const results = []; + for await (const res of stream) { + results.push(res); + } + + expect(results).toHaveLength(1); + expect(results[0].candidates?.[0].content?.parts?.[0].text).toBe( + 'Hello Web', + ); + }); + it('should ignore malformed SSE data', async () => { const { server, mockRequest } = createTestServer(); diff --git a/packages/core/src/code_assist/server.ts b/packages/core/src/code_assist/server.ts index 871af4cbfa..ba9b96bcb3 100644 --- a/packages/core/src/code_assist/server.ts +++ b/packages/core/src/code_assist/server.ts @@ -36,6 +36,7 @@ import type { GenerateContentResponse, } from '@google/genai'; import * as readline from 'node:readline'; +import { Readable } from 'node:stream'; import type { ContentGenerator } from '../core/contentGenerator.js'; import { UserTierId } from './types.js'; import type { @@ -341,7 +342,7 @@ export class CodeAssistServer implements ContentGenerator { req: object, signal?: AbortSignal, ): Promise> { - const res = await this.client.request({ + const res = await this.client.request>({ url: this.getMethodUrl(method), method: 'POST', params: { @@ -358,8 +359,7 @@ export class CodeAssistServer implements ContentGenerator { return (async function* (): AsyncGenerator { const rl = readline.createInterface({ - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion - input: res.data as NodeJS.ReadableStream, + input: Readable.from(res.data), crlfDelay: Infinity, // Recognizes '\r\n' and '\n' as line breaks });