fix(ui): hide synthetic stop tool part when loop action is "stop" (closes #267)#551
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Astro-Han
left a comment
There was a problem hiding this comment.
Opus second-pass review (product layer / three questions / live-stream behavior)
Conclusion: approve
Diff is exactly the brief shape. Reactive hide pattern, no unintended surface touched.
Three questions
Could this be even less? 17 added lines plus 1 changed <Show> condition plus 2 source-level lock tests. The lock tests are not optional — they protect both the reactive pattern and the <Show> composition from drifting in future edits. This is already the minimum that preserves the contract. Check.
Is what remains good enough?
hideSyntheticStopplaced afterpartMetadata()declaration, matching the order GPT-X specified.<Show when={!hideQuestion() && !hideSyntheticStop()}>composes cleanly with the existing question-pending hide; no precedence or short-circuit surprises.- The synthetic stop tool part disappears from the conversation transcript; the rendered Chinese summary text part remains the user-facing stop message.
- Check.
Is it reassuring? Live-stream path traced:
- Tool part starts as
status: "running"(no metadata) →hideSyntheticStop()returnsfalse→ bubble renders briefly. - Wrapper writes
status: "error"withmetadata.diagnostics.loop.loopAction = "stop"→partMetadata()accessor reads fresh state → memo recomputes totrue→<Show>hides the bubble. - Export untouched:
Export.deriveSnapshotDiagnosticskeeps reading the metadata directly off the part; the 32 passing export tests are the audit trail proof. - Check.
Findings
P3-1 (consider in follow-up, not blocking): there is a brief visible flicker between tool-input-start and the wrapper's stop settle. The user might see a "running" tool bubble for a few hundred milliseconds before it disappears. The acceptance criteria do not require suppressing the running phase, and adding a "predictive hide" would require coupling UI to in-flight loop-gate state, which is out of scope here. If post-merge user reports flag the flicker, that becomes its own polish task.
No P0/P1/P2.
Approve
There was a problem hiding this comment.
Code Review
This pull request introduces logic to hide synthetic stop tool parts in the UI while maintaining access to their metadata for diagnostics. It adds a hideSyntheticStop memoized value in message-part.tsx and updates the conditional rendering logic to suppress these parts. Corresponding unit tests were added to message-part-stale.test.ts to verify the implementation. I have no feedback to provide.
GPT-X engineering final reviewResult: pass. I found no P0/P1/P2 issues. Engineering checks
Binary checkThis is not a crash fix: v1 can run without it. But the redundant failed-tool bubble is directly user-visible in the stop path, while the intended user-facing output is the synthetic summary text part. Hiding the synthetic carrier part is the right lowest layer because the metadata must remain available for export diagnostics. NotesThe brief running-state flicker before the wrapper settles the part is acceptable for this PR. Preventing that would require coupling the UI to pending loop-gate state before the metadata exists, which is a separate product/architecture decision. |
Summary
Hide synthetic stop tool parts from the conversation UI when their metadata carries
diagnostics.loop.loopAction === "stop".Why
Closes #267. The loop gate already renders a user-facing synthetic summary text part when it stops a loop. The paired synthetic tool part is only an internal audit carrier, so rendering it as a failed tool bubble is redundant and confusing.
Related Issue
Closes #267
Human Review Status
Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.
Review Focus
createMemo + <Show>, not a top-level return.<Show>condition.Risk Notes
Low UI-rendering risk. The underlying tool part and metadata remain in session data and exports. Manual stop-scenario smoke was skipped because the deterministic UI source test and existing export audit tests cover the changed behavior without requiring a live loop-gate repro.
Behavior
Synthetic tool parts that carry
metadata.diagnostics.loop.loopAction === "stop"are now hidden from the conversation UI via a reactivecreateMemo + <Show>pattern, parallel to the existinghideQuestionhide for pending question tools.The metadata stays on the part:
Export.deriveSnapshotDiagnosticsstill emitsdiagnostics.loop.lastwith the full audit trailHow To Verify
Screenshots or Recordings
Not applicable. The target state is absence of the redundant failed-tool bubble, covered by the deterministic UI render contract test.
Checklist
dev, and my PR title and commit messages use Conventional Commits in English