Skip to content

[Fix] Approvals no longer check parallel calls with another call's arguments - #3347

Merged
daniel-lxs merged 6 commits into
developfrom
fix/approval-parallel-calls
Sep 30, 2026
Merged

daniel-lxs merged 6 commits into
developfrom
fix/approval-parallel-calls

Conversation

@daniel-lxs

@daniel-lxs daniel-lxs commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Related issue

Internal follow-up to #3185; no separate issue is linked.

Why this PR exists

  • A maintainer explicitly invited this PR in the linked issue or discussion
  • I am a maintainer / this is internal Roomote work

What changed

In a session, integration tools run inside one code-mode execute script. When a script calls the same tool several times at once (for example Promise.all over three deletes), OpenCode raises one approval ask per call. Every ask carries the same outer call id and no arguments. The bridge picked the most recent child call's arguments for every ask, so the approval card, the audit row and Auto's assessment could all describe a different call from the one that would run. Locally, three parallel deletes were all recorded and assessed as draft-3.

The bridge now uses the status OpenCode records for each child call:

  • Which call: only child calls of this tool that are still running can be the paused one. One such call, or several with identical arguments, identifies the arguments exactly. Sequential calls in one script are unchanged.
  • Several different calls at once (they can't be told apart):
    • Auto: every call is assessed. If all of them would run, they all run.
    • Needs a person: the batch gets one card listing every call ("Let Mock Files run these 3 calls?", each call under Details). This covers an "Ask first" tool, or Auto flagging any call in the batch. Allowing runs the whole batch, denying or expiry stops it, and the card is consumed once.
    • Session "allow" for the tool: they run.
  • One decision per call: calls waiting at the same time share one decision per distinct call (script, tool, arguments), and identical calls running together share one card. Identical parallel calls can't get conflicting decisions, and one ask can't fail the whole script. A later call in the same script is assessed again, so a steer in between is taken into account.
  • Batch marker: a batch is recorded as a list of calls, which a single call's arguments (always an object) never are, so no tool argument can make a card look like a batch.

Tasks are unaffected: they don't use code mode, so every call has its own id.

How it was tested

  • New tests:
    • running vs finished child calls, and identical vs different parallel arguments;
    • one batch card that runs or stops every call and is consumed once;
    • Auto running a batch only when every call would run, and otherwise asking with its reason on the batch card;
    • shared assessments, including identical parallel calls;
    • the batch card heading and call list.
  • The parallel tests fail on develop. The paused-call recovery test checks that status is kept. Session approval tests (76) and card tests (10) pass. pnpm lint, uncached pnpm check-types, and the Judgement check pass (Judgement reports incomplete coverage with no violations).
  • Live on a local stack (develop + this PR) with Auto on and a local MCP server:
    • Before: three parallel deletes were each recorded and assessed as the same file.
    • After:
      • Two parallel list_files reads with different folders were auto-approved and ran.
      • Three parallel deletes produced one card listing all three files. Allow once ran each delete with its own file.
      • Denying a two-call batch card stopped both calls.
      • A script awaiting two deletes one after another got the correct file on each ask.

This PR and #3335 both change the assessment block in fast-agent-tool-approvals.ts. Whichever lands second needs a small rebase: keep this PR's shared assessment around #3335's session-context lookup.

Checklist

  • The PR title follows the repo convention: [Fix], [Feat], [Improve], [Refactor], [Docs], or [Chore] followed by a user-facing description
  • This PR is small and scoped to one change
  • pnpm lint and pnpm check-types pass locally
  • I added tests or included a clear manual validation note above
  • I removed secrets, tokens, private keys, and customer data from code, logs, and screenshots
  • If this change should appear in the changelog, I ran pnpm changeset

@roomote-community

roomote-community Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

No new code issues found. See task

  • Identical-argument parallel calls can still split across separate human approval cards.
  • Sequential identical calls reuse a stale Auto decision after a human steer.
  • A normal tool argument named roomote.parallelCalls is displayed as a batch card instead of a single call.

Reviewed 0557e46

Comment thread apps/web/src/components/sessions/PendingIntegrationToolApprovals.tsx Outdated
@daniel-lxs
daniel-lxs merged commit d2043d0 into develop Sep 30, 2026
25 checks passed
@daniel-lxs
daniel-lxs deleted the fix/approval-parallel-calls branch September 30, 2026 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant