summaryrefslogtreecommitdiff
path: root/packages/cli/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src')
-rw-r--r--packages/cli/src/ui/hooks/useGeminiStream.ts22
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,
],
);