summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/hooks/useGeminiStream.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/hooks/useGeminiStream.ts')
-rw-r--r--packages/cli/src/ui/hooks/useGeminiStream.ts50
1 files changed, 49 insertions, 1 deletions
diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts
index 9fa23c52..295b5650 100644
--- a/packages/cli/src/ui/hooks/useGeminiStream.ts
+++ b/packages/cli/src/ui/hooks/useGeminiStream.ts
@@ -14,6 +14,7 @@ import {
ServerGeminiContentEvent as ContentEvent,
ServerGeminiErrorEvent as ErrorEvent,
ServerGeminiChatCompressedEvent,
+ ServerGeminiFinishedEvent,
getErrorMessage,
isNodeError,
MessageSenderType,
@@ -26,7 +27,7 @@ import {
UserPromptEvent,
DEFAULT_GEMINI_FLASH_MODEL,
} from '@google/gemini-cli-core';
-import { type Part, type PartListUnion } from '@google/genai';
+import { type Part, type PartListUnion, FinishReason } from '@google/genai';
import {
StreamingState,
HistoryItem,
@@ -422,6 +423,46 @@ export const useGeminiStream = (
[addItem, pendingHistoryItemRef, setPendingHistoryItem, config],
);
+ const handleFinishedEvent = useCallback(
+ (event: ServerGeminiFinishedEvent, userMessageTimestamp: number) => {
+ const finishReason = event.value;
+
+ const finishReasonMessages: Record<FinishReason, string | undefined> = {
+ [FinishReason.FINISH_REASON_UNSPECIFIED]: undefined,
+ [FinishReason.STOP]: undefined,
+ [FinishReason.MAX_TOKENS]: 'Response truncated due to token limits.',
+ [FinishReason.SAFETY]: 'Response stopped due to safety reasons.',
+ [FinishReason.RECITATION]: 'Response stopped due to recitation policy.',
+ [FinishReason.LANGUAGE]:
+ 'Response stopped due to unsupported language.',
+ [FinishReason.BLOCKLIST]: 'Response stopped due to forbidden terms.',
+ [FinishReason.PROHIBITED_CONTENT]:
+ 'Response stopped due to prohibited content.',
+ [FinishReason.SPII]:
+ 'Response stopped due to sensitive personally identifiable information.',
+ [FinishReason.OTHER]: 'Response stopped for other reasons.',
+ [FinishReason.MALFORMED_FUNCTION_CALL]:
+ 'Response stopped due to malformed function call.',
+ [FinishReason.IMAGE_SAFETY]:
+ 'Response stopped due to image safety violations.',
+ [FinishReason.UNEXPECTED_TOOL_CALL]:
+ 'Response stopped due to unexpected tool call.',
+ };
+
+ const message = finishReasonMessages[finishReason];
+ if (message) {
+ addItem(
+ {
+ type: 'info',
+ text: `⚠️ ${message}`,
+ },
+ userMessageTimestamp,
+ );
+ }
+ },
+ [addItem],
+ );
+
const handleChatCompressionEvent = useCallback(
(eventValue: ServerGeminiChatCompressedEvent['value']) =>
addItem(
@@ -501,6 +542,12 @@ export const useGeminiStream = (
case ServerGeminiEventType.MaxSessionTurns:
handleMaxSessionTurnsEvent();
break;
+ case ServerGeminiEventType.Finished:
+ handleFinishedEvent(
+ event as ServerGeminiFinishedEvent,
+ userMessageTimestamp,
+ );
+ break;
case ServerGeminiEventType.LoopDetected:
// handle later because we want to move pending history to history
// before we add loop detected message to history
@@ -524,6 +571,7 @@ export const useGeminiStream = (
handleErrorEvent,
scheduleToolCalls,
handleChatCompressionEvent,
+ handleFinishedEvent,
handleMaxSessionTurnsEvent,
],
);