mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-12 23:21:27 -07:00
[cherrypic][hotfix] Do not call nextSpeakerCheck in case of API error (#7140)
This commit is contained in:
@@ -50,6 +50,8 @@ vi.mock('./turn', () => {
|
||||
GeminiEventType: {
|
||||
MaxSessionTurns: 'MaxSessionTurns',
|
||||
ChatCompressed: 'ChatCompressed',
|
||||
Error: 'error',
|
||||
Content: 'content',
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -1863,6 +1865,89 @@ ${JSON.stringify(
|
||||
expect(JSON.stringify(finalCall)).toContain('fileC.ts');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not call checkNextSpeaker when turn.run() yields an error', async () => {
|
||||
// Arrange
|
||||
const { checkNextSpeaker } = await import(
|
||||
'../utils/nextSpeakerChecker.js'
|
||||
);
|
||||
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
|
||||
|
||||
const mockStream = (async function* () {
|
||||
yield {
|
||||
type: GeminiEventType.Error,
|
||||
value: { error: { message: 'test error' } },
|
||||
};
|
||||
})();
|
||||
mockTurnRunFn.mockReturnValue(mockStream);
|
||||
|
||||
const mockChat: Partial<GeminiChat> = {
|
||||
addHistory: vi.fn(),
|
||||
getHistory: vi.fn().mockReturnValue([]),
|
||||
};
|
||||
client['chat'] = mockChat as GeminiChat;
|
||||
|
||||
const mockGenerator: Partial<ContentGenerator> = {
|
||||
countTokens: vi.fn().mockResolvedValue({ totalTokens: 0 }),
|
||||
generateContent: mockGenerateContentFn,
|
||||
};
|
||||
client['contentGenerator'] = mockGenerator as ContentGenerator;
|
||||
|
||||
// Act
|
||||
const stream = client.sendMessageStream(
|
||||
[{ text: 'Hi' }],
|
||||
new AbortController().signal,
|
||||
'prompt-id-error',
|
||||
);
|
||||
for await (const _ of stream) {
|
||||
// consume stream
|
||||
}
|
||||
|
||||
// Assert
|
||||
expect(mockCheckNextSpeaker).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call checkNextSpeaker when turn.run() yields a value then an error', async () => {
|
||||
// Arrange
|
||||
const { checkNextSpeaker } = await import(
|
||||
'../utils/nextSpeakerChecker.js'
|
||||
);
|
||||
const mockCheckNextSpeaker = vi.mocked(checkNextSpeaker);
|
||||
|
||||
const mockStream = (async function* () {
|
||||
yield { type: GeminiEventType.Content, value: 'some content' };
|
||||
yield {
|
||||
type: GeminiEventType.Error,
|
||||
value: { error: { message: 'test error' } },
|
||||
};
|
||||
})();
|
||||
mockTurnRunFn.mockReturnValue(mockStream);
|
||||
|
||||
const mockChat: Partial<GeminiChat> = {
|
||||
addHistory: vi.fn(),
|
||||
getHistory: vi.fn().mockReturnValue([]),
|
||||
};
|
||||
client['chat'] = mockChat as GeminiChat;
|
||||
|
||||
const mockGenerator: Partial<ContentGenerator> = {
|
||||
countTokens: vi.fn().mockResolvedValue({ totalTokens: 0 }),
|
||||
generateContent: mockGenerateContentFn,
|
||||
};
|
||||
client['contentGenerator'] = mockGenerator as ContentGenerator;
|
||||
|
||||
// Act
|
||||
const stream = client.sendMessageStream(
|
||||
[{ text: 'Hi' }],
|
||||
new AbortController().signal,
|
||||
'prompt-id-error',
|
||||
);
|
||||
for await (const _ of stream) {
|
||||
// consume stream
|
||||
}
|
||||
|
||||
// Assert
|
||||
expect(mockCheckNextSpeaker).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('generateContent', () => {
|
||||
|
||||
@@ -517,6 +517,9 @@ export class GeminiClient {
|
||||
return turn;
|
||||
}
|
||||
yield event;
|
||||
if (event.type === GeminiEventType.Error) {
|
||||
return turn;
|
||||
}
|
||||
}
|
||||
if (!turn.pendingToolCalls.length && signal && !signal.aborted) {
|
||||
// Check if model was switched during the call (likely due to quota error)
|
||||
|
||||
Reference in New Issue
Block a user