diff options
Diffstat (limited to 'packages/cli/src/ui/hooks')
| -rw-r--r-- | packages/cli/src/ui/hooks/useGeminiStream.ts | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts index 21d57b3b..9fa23c52 100644 --- a/packages/cli/src/ui/hooks/useGeminiStream.ts +++ b/packages/cli/src/ui/hooks/useGeminiStream.ts @@ -141,6 +141,8 @@ export const useGeminiStream = ( [toolCalls], ); + const loopDetectedRef = useRef(false); + const onExec = useCallback(async (done: Promise<void>) => { setIsResponding(true); await done; @@ -450,6 +452,16 @@ export const useGeminiStream = ( [addItem, config], ); + const handleLoopDetectedEvent = useCallback(() => { + addItem( + { + type: 'info', + text: `A potential loop was detected. This can happen due to repetitive tool calls or other model behavior. The request has been halted.`, + }, + Date.now(), + ); + }, [addItem]); + const processGeminiStreamEvents = useCallback( async ( stream: AsyncIterable<GeminiEvent>, @@ -489,6 +501,11 @@ export const useGeminiStream = ( case ServerGeminiEventType.MaxSessionTurns: handleMaxSessionTurnsEvent(); break; + case ServerGeminiEventType.LoopDetected: + // handle later because we want to move pending history to history + // before we add loop detected message to history + loopDetectedRef.current = true; + break; default: { // enforces exhaustive switch-case const unreachable: never = event; @@ -579,6 +596,10 @@ export const useGeminiStream = ( addItem(pendingHistoryItemRef.current, userMessageTimestamp); setPendingHistoryItem(null); } + if (loopDetectedRef.current) { + loopDetectedRef.current = false; + handleLoopDetectedEvent(); + } } catch (error: unknown) { if (error instanceof UnauthorizedError) { onAuthError(); @@ -616,6 +637,7 @@ export const useGeminiStream = ( config, startNewPrompt, getPromptCount, + handleLoopDetectedEvent, ], ); |
