Repository navigation
fix: harden tool approval resume flow - #1180
LukasParke wants to merge 2 commits into
Conversation
|
I'll fix CI failures and address comments from users with write access that start with 'Devin'.
Original prompt from Luke
|
…est #517/#518 toolRequiresApproval now mirrors typescript-agent's #94 fix: - the call-level requireApproval receives a schema-parsed copy of the call (defaults/coercions applied, original not mutated), or the raw call when parsing fails; its decision is honored either way - the tool-level predicate fails closed (requires approval) when the arguments fail schema validation or parse to a non-object, instead of falling back to the raw arguments Adds regression tests for #520 (coercion, fail-closed, call-level parsing) and ModelResult tests for #518 (duplicate approve/reject IDs, approve+reject conflict) and #517 (decision-less resume stays paused and sends no request). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Pushed 461cb7a on top of this branch. It's a normal, non-force commit.
Not ported: typescript-agent's clearer "awaiting approval" error from 🤖 Generated with Claude Code |
Summary
This PR fixes three defects in the hand-written
callModelapproval flow insrc/lib. Persistent edits are enabled, so these changes survive regeneration.toolRequiresApprovalpassed the raw model arguments to a tool'srequireApproval(args)predicate. A model could leave out a field whose schema default is sensitive, the predicate would seeundefinedand skip approval, and the tool would then execute with the default. The predicate now receivesz4.safeParse(inputSchema, args).dataand falls back to the raw args only when parsing fails. In that case execution fails validation anyway.approveToolCallsandrejectToolCallsare now de-duplicated, so an ID listed twice no longer executes a side-effecting tool twice. TheModelResultconstructor now throws when an ID appears in both lists, instead of executing the tool and also recording a rejection.awaiting_approvalconversation with no decision advances it without recording an approval #517: Resuming a conversation in theawaiting_approvalstate with no decisions used to fall through to normal initialization and move the conversation toin_progress. It now returns early withisResumingFromApproval = true. This is the same path a partial-decision resume already takes, sogetToolExecutionexits while the conversation stays paused.Added a unit test for #520. The test fails without the change. Full unit suite: 211 tests pass.
Searched existing PRs; none matched.
Link to Devin session: https://openrouter.devinenterprise.com/sessions/78072f08dc274fda9d8309045b1ab806
Open in Devin Desktop: https://openrouter.devinenterprise.com/desktop/session/78072f08dc274fda9d8309045b1ab806?variant=devin
Requested by: @LukasParke