summaryrefslogtreecommitdiff
path: root/packages/server/src/utils/nextSpeakerChecker.test.ts
diff options
context:
space:
mode:
authorTaylor Mullen <[email protected]>2025-05-27 23:40:25 -0700
committerN. Taylor Mullen <[email protected]>2025-05-27 23:46:37 -0700
commitf2f2ecf9d83224778e5fc38cfcc4a1edddf9f7d4 (patch)
tree6ad7ce8c34f16016c67c208a5182a016739b2c07 /packages/server/src/utils/nextSpeakerChecker.test.ts
parentbfeaac844186153698d3a7079b41214bbf1e4371 (diff)
feat: Allow cancellation of in-progress Gemini requests and pre-execution checks
- Implements cancellation for Gemini requests while they are actively being processed by the model. - Extends cancellation support to the logic within tools. This allows users to cancel operations during the phase where the system is determining if a tool execution requires user confirmation, which can include potentially long-running pre-flight checks or LLM-based corrections. - Underlying LLM calls for edit corrections (within and ) and next speaker checks can now also be cancelled. - Previously, cancellation of the main request was not possible until text started streaming, and pre-execution checks were not cancellable. - This change leverages the updated SDK's ability to accept an abort token and threads s throughout the request, tool execution, and pre-execution check lifecycle. Fixes https://github.com/google-gemini/gemini-cli/issues/531
Diffstat (limited to 'packages/server/src/utils/nextSpeakerChecker.test.ts')
-rw-r--r--packages/server/src/utils/nextSpeakerChecker.test.ts57
1 files changed, 47 insertions, 10 deletions
diff --git a/packages/server/src/utils/nextSpeakerChecker.test.ts b/packages/server/src/utils/nextSpeakerChecker.test.ts
index 1d87bffb..872e00f6 100644
--- a/packages/server/src/utils/nextSpeakerChecker.test.ts
+++ b/packages/server/src/utils/nextSpeakerChecker.test.ts
@@ -44,6 +44,7 @@ describe('checkNextSpeaker', () => {
let chatInstance: GeminiChat;
let mockGeminiClient: GeminiClient;
let MockConfig: Mock;
+ const abortSignal = new AbortController().signal;
beforeEach(() => {
MockConfig = vi.mocked(Config);
@@ -71,7 +72,7 @@ describe('checkNextSpeaker', () => {
mockGoogleGenAIInstance, // This will be the instance returned by the mocked GoogleGenAI constructor
mockModelsInstance, // This is the instance returned by mockGoogleGenAIInstance.getGenerativeModel
'gemini-pro', // model name
- {}, // config
+ {},
[], // initial history
);
@@ -85,7 +86,11 @@ describe('checkNextSpeaker', () => {
it('should return null if history is empty', async () => {
(chatInstance.getHistory as Mock).mockReturnValue([]);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toBeNull();
expect(mockGeminiClient.generateJson).not.toHaveBeenCalled();
});
@@ -94,7 +99,11 @@ describe('checkNextSpeaker', () => {
(chatInstance.getHistory as Mock).mockReturnValue([
{ role: 'user', parts: [{ text: 'Hello' }] },
] as Content[]);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toBeNull();
expect(mockGeminiClient.generateJson).not.toHaveBeenCalled();
});
@@ -109,7 +118,11 @@ describe('checkNextSpeaker', () => {
};
(mockGeminiClient.generateJson as Mock).mockResolvedValue(mockApiResponse);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toEqual(mockApiResponse);
expect(mockGeminiClient.generateJson).toHaveBeenCalledTimes(1);
});
@@ -124,7 +137,11 @@ describe('checkNextSpeaker', () => {
};
(mockGeminiClient.generateJson as Mock).mockResolvedValue(mockApiResponse);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toEqual(mockApiResponse);
});
@@ -138,7 +155,11 @@ describe('checkNextSpeaker', () => {
};
(mockGeminiClient.generateJson as Mock).mockResolvedValue(mockApiResponse);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toEqual(mockApiResponse);
});
@@ -153,7 +174,11 @@ describe('checkNextSpeaker', () => {
new Error('API Error'),
);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toBeNull();
consoleWarnSpy.mockRestore();
});
@@ -166,7 +191,11 @@ describe('checkNextSpeaker', () => {
reasoning: 'This is incomplete.',
} as unknown as NextSpeakerResponse); // Type assertion to simulate invalid response
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toBeNull();
});
@@ -179,7 +208,11 @@ describe('checkNextSpeaker', () => {
next_speaker: 123, // Invalid type
} as unknown as NextSpeakerResponse);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toBeNull();
});
@@ -192,7 +225,11 @@ describe('checkNextSpeaker', () => {
next_speaker: 'neither', // Invalid enum value
} as unknown as NextSpeakerResponse);
- const result = await checkNextSpeaker(chatInstance, mockGeminiClient);
+ const result = await checkNextSpeaker(
+ chatInstance,
+ mockGeminiClient,
+ abortSignal,
+ );
expect(result).toBeNull();
});
});