Make cancel not explode.
- We were console.erroring, throwing and early aborting. Instead we now treat cancels like a normal user message and show an indicator in the UI Fixes https://b.corp.google.com/issues/416515841
This commit is contained in:
parent
28f9a2adfa
commit
090198a7d6
|
@ -17,7 +17,7 @@ export const InfoMessage: React.FC<InfoMessageProps> = ({ text }) => {
|
||||||
const prefixWidth = prefix.length;
|
const prefixWidth = prefix.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box flexDirection="row">
|
<Box flexDirection="row" marginTop={1}>
|
||||||
<Box width={prefixWidth}>
|
<Box width={prefixWidth}>
|
||||||
<Text color={Colors.AccentYellow}>{prefix}</Text>
|
<Text color={Colors.AccentYellow}>{prefix}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
@ -177,8 +177,6 @@ export const useGeminiStream = (
|
||||||
let geminiMessageBuffer = '';
|
let geminiMessageBuffer = '';
|
||||||
|
|
||||||
for await (const event of stream) {
|
for await (const event of stream) {
|
||||||
if (signal.aborted) break;
|
|
||||||
|
|
||||||
if (event.type === ServerGeminiEventType.Content) {
|
if (event.type === ServerGeminiEventType.Content) {
|
||||||
if (
|
if (
|
||||||
pendingHistoryItemRef.current?.type !== 'gemini' &&
|
pendingHistoryItemRef.current?.type !== 'gemini' &&
|
||||||
|
@ -293,6 +291,18 @@ export const useGeminiStream = (
|
||||||
);
|
);
|
||||||
setStreamingState(StreamingState.WaitingForConfirmation);
|
setStreamingState(StreamingState.WaitingForConfirmation);
|
||||||
return; // Wait for user confirmation
|
return; // Wait for user confirmation
|
||||||
|
} else if (event.type === ServerGeminiEventType.UserCancelled) {
|
||||||
|
// Flush out existing pending history item.
|
||||||
|
if (pendingHistoryItemRef.current) {
|
||||||
|
addItem(pendingHistoryItemRef.current, userMessageTimestamp);
|
||||||
|
setPendingHistoryItem(null);
|
||||||
|
}
|
||||||
|
addItem(
|
||||||
|
{ type: 'info', text: 'User cancelled the request.' },
|
||||||
|
userMessageTimestamp,
|
||||||
|
);
|
||||||
|
setStreamingState(StreamingState.Idle);
|
||||||
|
return; // Stop processing the stream
|
||||||
}
|
}
|
||||||
} // End stream loop
|
} // End stream loop
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ export enum GeminiEventType {
|
||||||
ToolCallRequest = 'tool_call_request',
|
ToolCallRequest = 'tool_call_request',
|
||||||
ToolCallResponse = 'tool_call_response',
|
ToolCallResponse = 'tool_call_response',
|
||||||
ToolCallConfirmation = 'tool_call_confirmation',
|
ToolCallConfirmation = 'tool_call_confirmation',
|
||||||
|
UserCancelled = 'user_cancelled',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ToolCallRequestInfo {
|
export interface ToolCallRequestInfo {
|
||||||
|
@ -74,7 +75,8 @@ export type ServerGeminiStreamEvent =
|
||||||
| {
|
| {
|
||||||
type: GeminiEventType.ToolCallConfirmation;
|
type: GeminiEventType.ToolCallConfirmation;
|
||||||
value: ServerToolCallConfirmationDetails;
|
value: ServerToolCallConfirmationDetails;
|
||||||
};
|
}
|
||||||
|
| { type: GeminiEventType.UserCancelled };
|
||||||
|
|
||||||
// A turn manages the agentic loop turn within the server context.
|
// A turn manages the agentic loop turn within the server context.
|
||||||
export class Turn {
|
export class Turn {
|
||||||
|
@ -108,7 +110,8 @@ export class Turn {
|
||||||
for await (const resp of responseStream) {
|
for await (const resp of responseStream) {
|
||||||
this.debugResponses.push(resp);
|
this.debugResponses.push(resp);
|
||||||
if (signal?.aborted) {
|
if (signal?.aborted) {
|
||||||
throw this.abortError();
|
yield { type: GeminiEventType.UserCancelled };
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const text = getResponseText(resp);
|
const text = getResponseText(resp);
|
||||||
|
@ -240,12 +243,6 @@ export class Turn {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private abortError(): Error {
|
|
||||||
const error = new Error('Request cancelled by user during stream.');
|
|
||||||
error.name = 'AbortError';
|
|
||||||
return error; // Return instead of throw, let caller handle
|
|
||||||
}
|
|
||||||
|
|
||||||
getConfirmationDetails(): ToolCallConfirmationDetails[] {
|
getConfirmationDetails(): ToolCallConfirmationDetails[] {
|
||||||
return this.confirmationDetails;
|
return this.confirmationDetails;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue