Conversation
* fix(recap): skip when there's no LLM conversation to summarize
Reported: the recap card fires after slash commands like /commit and
the model has nothing to summarize, so it hallucinates output like
"I don't have access to any previous conversation — this appears to
be the start of our session."
Cause: useRecap watches streamingState transitions and counts UI-level
tool_group entries to decide if a turn was tool-heavy. Slash commands
do flip streamingState and do produce many tool_group entries, but
they bypass GeminiChat — `geminiClient.getHistory()` is empty when the
recap fires. generateRecap then ships its prompt with no prior context
and the model can only hallucinate.
Fix: gate the recap on the conversation containing at least one
model-role AND one user-role entry. Slash-command-only turns
short-circuit before the LLM call. Real LLM turns (single or
multi-turn) still recap as before.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(cli): cancel must stop the tool-result feedback loop
The earlier fix unblocked streamingState by force-cancelling stuck
toolCalls in the UI display state, but it missed the upstream cause
of why submitQuery kept dropping new prompts: handleCompletedTools
was still feeding tool results back to the model even after the user
cancelled.
Repro from Langfuse session d795ff07 at 01:11:47Z:
- User starts a turn. Turn span opens (4.4s)
- User presses Esc, cancelOngoingRequest fires:
- abort signal sent
- turnCancelledRef = true
- endTurnSpan('ok') closes the turn span
- But a shell command was already in-flight. It runs another 11.4s
and finishes with status='success' (didn't honor abort)
- handleCompletedTools fires for the completed shell. The existing
isResponding guard passes (cancel set it false). The function
decides this is a legitimate gemini-bound tool result and calls
submitQuery(SendMessageType.ToolResult, ...)
- submitQuery(ToolResult) at line 1341:
abortControllerRef.current = abortController; // fresh, not aborted
turnCancelledRef.current = false; // cancel undone
- Loop continues. New LLM call (3.9s) at 01:12:03, then another
(1.2s) at 01:12:07 — all OUTSIDE any turn span (orphan), and the
streamingState ping-pongs between Idle and Responding.
- Every user-typed prompt during this cascade hits submitQuery's
silent-drop guard at line 1305 because streamingState !== Idle
at the moment of submission.
Net symptom: "any time Request Cancelled I cant restart" — exactly
the user's report.
Fix: handleCompletedTools, immediately after the isResponding guard,
checks turnCancelledRef.current. If the user already cancelled, it
marks the completed tools as submitted (so streamingState clears)
but does NOT call submitQuery. The loop ends where the user wanted
it to. Tools that finished after the abort signal but before cleanup
have their results discarded — the desired behavior for an explicit
cancel.
Tests: 3,767 cli pass; 49 cancellation tests in useGeminiStream.test.tsx
remain green.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Automaker <automaker@localhost>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
✅ Files skipped from review due to trivial changes (6)
WalkthroughThe tool-completion pipeline in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
Summary
The deeper layer of the cancel-stuck bug: `handleCompletedTools` was feeding tool results back to the model after cancel, which reset `turnCancelledRef` and undid the cancel. This PR adds a `turnCancelledRef` check at the top of `handleCompletedTools` so post-cancel tool completions don't re-arm the turn loop.
Merge strategy
Use merge commit per branch-strategy.
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Chores