mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 01:07:46 +00:00
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
This commit is contained in:
committed by
N. Taylor Mullen
parent
bfeaac8441
commit
f2f2ecf9d8
@@ -157,7 +157,7 @@ export class GeminiClient {
|
||||
async *sendMessageStream(
|
||||
chat: GeminiChat,
|
||||
request: PartListUnion,
|
||||
signal?: AbortSignal,
|
||||
signal: AbortSignal,
|
||||
turns: number = this.MAX_TURNS,
|
||||
): AsyncGenerator<ServerGeminiStreamEvent> {
|
||||
if (!turns) {
|
||||
@@ -169,8 +169,8 @@ export class GeminiClient {
|
||||
for await (const event of resultStream) {
|
||||
yield event;
|
||||
}
|
||||
if (!turn.pendingToolCalls.length) {
|
||||
const nextSpeakerCheck = await checkNextSpeaker(chat, this);
|
||||
if (!turn.pendingToolCalls.length && signal && !signal.aborted) {
|
||||
const nextSpeakerCheck = await checkNextSpeaker(chat, this, signal);
|
||||
if (nextSpeakerCheck?.next_speaker === 'model') {
|
||||
const nextRequest = [{ text: 'Please continue.' }];
|
||||
yield* this.sendMessageStream(chat, nextRequest, signal, turns - 1);
|
||||
@@ -181,6 +181,7 @@ export class GeminiClient {
|
||||
async generateJson(
|
||||
contents: Content[],
|
||||
schema: SchemaUnion,
|
||||
abortSignal: AbortSignal,
|
||||
model: string = 'gemini-2.0-flash',
|
||||
config: GenerateContentConfig = {},
|
||||
): Promise<Record<string, unknown>> {
|
||||
@@ -188,6 +189,7 @@ export class GeminiClient {
|
||||
const userMemory = this.config.getUserMemory();
|
||||
const systemInstruction = getCoreSystemPrompt(userMemory);
|
||||
const requestConfig = {
|
||||
abortSignal,
|
||||
...this.generateContentConfig,
|
||||
...config,
|
||||
};
|
||||
@@ -232,6 +234,11 @@ export class GeminiClient {
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (abortSignal.aborted) {
|
||||
// Regular cancellation error, fail normally
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Avoid double reporting for the empty response case handled above
|
||||
if (
|
||||
error instanceof Error &&
|
||||
|
||||
Reference in New Issue
Block a user