fix(frontend): denied and cold-resumed approvals render and resolve correctly - #5630
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe change updates client-tool detection and approval-resume settlement logic. Denied tool outputs are settled, approval-bearing parts are excluded from client-tool detection, and unit tests cover both behaviors. ChangesApproval tool handling
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 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 |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
fa688d5 to
9f1b25f
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
🧹 Nitpick comments (2)
web/oss/src/components/AgentChatSlice/components/clientTools/meta.test.ts (2)
24-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover the new
SETTLEDbranch directly.Both denied cases include
approval. Therefore,isClientToolPartreturns at Line 63 ofweb/oss/src/components/AgentChatSlice/components/clientTools/meta.tsbefore it evaluatesclientToolMeta(...).settled. These tests pass even ifoutput-deniedis removed fromSETTLED.Add a parked unknown tool with
state: "output-denied"and no approval metadata.Proposed test
+ it("does NOT claim a parked unknown tool after output-denied", () => { + const part = toolPart({ + type: "tool-mysteryTool", + state: "output-denied", + }) + expect(isClientToolPart(part, settledCtx)).toBe(false) + })
50-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAlign the test name with its coverage.
The test claims coverage for every state, but it checks only
output-available.isClientToolPartdeliberately rejectsapproval-requestedandapproval-responded. Rename the test or parameterize the supported non-approval states.Proposed rename
- it("claims a known client tool in every state", () => { + it("claims a known client tool with a settled output", () => {
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1639d527-5130-4a63-8f8f-ab47a692f67a
📒 Files selected for processing (5)
web/oss/src/components/AgentChatSlice/components/clientTools/meta.test.tsweb/oss/src/components/AgentChatSlice/components/clientTools/meta.tsweb/oss/vitest.config.tsweb/packages/agenta-playground/src/state/execution/agentApprovalResume.tsweb/packages/agenta-playground/tests/unit/agentApprovalResume.test.ts
927cb78 to
9e02eef
Compare
9f1b25f to
0ae32d2
Compare
0ae32d2 to
84b0e24
Compare
…not the re-raised tool call id
92797ad to
c7ac4f6
Compare
1d7e4b1 to
70b611b
Compare
What was broken
Three defects in the approval flow, all found during multi-modality QA, all in code that predates the train:
{"status":"not_handled"}, so it kept retrying the same command (reported on fix(services): resume a run when its approval is answered outside the playground (#5593) #5598).Causes and fixes
output-denied, which was missing from the client-tool dispatcher's settled set, soUnhandledClientToolauto-settled it and the AI SDK rewrote the part, erasing the{approved: false}envelope. Fix:output-deniedjoinsSETTLED, and any part carrying approval metadata is never a client-tool fallback candidate (clientTools/meta.ts);isSettledToolPartlearns the state too.approval-requestedforever. Fix: settle by the interaction id first (the wire contract guarantees it matches), re-point the tool index at the gate part, and splice the duplicate re-raised part, carrying its executed result. Both arrival orders covered (transcriptToMessages.ts).NEXT_PUBLIC_AGENT_CHAT_STEERis off, and the sibling collapses gainedinert(ApprovalDock.tsx).Tests
The dispatch decision, both cold-resume arrival orders plus a deny variant, the composer-unlock predicate, and the resume seam are all pinned (
meta.test.ts,transcriptToMessages.test.ts,agentMessageQueue.test.ts). Verified live on the dev stack: the denial envelope reaches the runner and the model changes course; reload renders each resolved call exactly once.Notes for review
reason); the steer feature remains behind its flag, untouched.https://claude.ai/code/session_01McMogkcDRV7UpSAjfd8VKG