Skip to content

Commit 32c77da

Browse files
gundermancsripasg
authored andcommitted
Fixes 'input.on' is not a function error in Gemini CLI (#19691)
1 parent 7179d0d commit 32c77da

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

packages/core/src/code_assist/server.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,48 @@ describe('CodeAssistServer', () => {
408408
expect(results[1].candidates?.[0].content?.parts?.[0].text).toBe(' World');
409409
});
410410

411+
it('should handle Web ReadableStream in generateContentStream', async () => {
412+
const { server, mockRequest } = createTestServer();
413+
414+
// Create a mock Web ReadableStream
415+
const mockWebStream = new ReadableStream({
416+
start(controller) {
417+
const mockResponseData = {
418+
response: {
419+
candidates: [{ content: { parts: [{ text: 'Hello Web' }] } }],
420+
},
421+
};
422+
controller.enqueue(
423+
new TextEncoder().encode(
424+
'data: ' + JSON.stringify(mockResponseData) + '\n\n',
425+
),
426+
);
427+
controller.close();
428+
},
429+
});
430+
431+
mockRequest.mockResolvedValue({ data: mockWebStream });
432+
433+
const stream = await server.generateContentStream(
434+
{
435+
model: 'test-model',
436+
contents: [{ role: 'user', parts: [{ text: 'request' }] }],
437+
},
438+
'user-prompt-id',
439+
LlmRole.MAIN,
440+
);
441+
442+
const results = [];
443+
for await (const res of stream) {
444+
results.push(res);
445+
}
446+
447+
expect(results).toHaveLength(1);
448+
expect(results[0].candidates?.[0].content?.parts?.[0].text).toBe(
449+
'Hello Web',
450+
);
451+
});
452+
411453
it('should ignore malformed SSE data', async () => {
412454
const { server, mockRequest } = createTestServer();
413455

packages/core/src/code_assist/server.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import type {
3636
GenerateContentResponse,
3737
} from '@google/genai';
3838
import * as readline from 'node:readline';
39+
import { Readable } from 'node:stream';
3940
import type { ContentGenerator } from '../core/contentGenerator.js';
4041
import { UserTierId } from './types.js';
4142
import type {
@@ -341,7 +342,7 @@ export class CodeAssistServer implements ContentGenerator {
341342
req: object,
342343
signal?: AbortSignal,
343344
): Promise<AsyncGenerator<T>> {
344-
const res = await this.client.request({
345+
const res = await this.client.request<AsyncIterable<unknown>>({
345346
url: this.getMethodUrl(method),
346347
method: 'POST',
347348
params: {
@@ -358,8 +359,7 @@ export class CodeAssistServer implements ContentGenerator {
358359

359360
return (async function* (): AsyncGenerator<T> {
360361
const rl = readline.createInterface({
361-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
362-
input: res.data as NodeJS.ReadableStream,
362+
input: Readable.from(res.data),
363363
crlfDelay: Infinity, // Recognizes '\r\n' and '\n' as line breaks
364364
});
365365

0 commit comments

Comments
 (0)