fix(mothership): report a browser-claimed workflow tool from its settled execution - #8481
Conversation
…led execution When a browser claims a Chat workflow tool, the execute route runs the workflow and keeps running it after the browser detaches, but only the browser's confirmation completed the tool call. A tab that closed, lost its network, or dropped its pagehide beacon left the Chat turn waiting for the full client wait while the worker swept the call. The execute route now records the bound execution's structural completion itself once it settles, guarded on the call still running under that execution's claim, so a browser report or background detach that lands first is kept and nothing is delivered twice.
|
@cubic-dev-ai review this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 5 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
…rowser-claimed workflow tool
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 6 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
Problem. When the browser claims a Chat workflow tool (
run_workflowand friends), a tab that closes, loses its network, or drops itspagehidebeacon leaves the Chat turn waiting for the full client wait, even though the workflow itself finished.Root cause.
/api/workflows/[id]/executetakes the single-winner execution claim for the tool call and keeps running the workflow after the browser detaches. Only the browser's confirmation marked the tool call complete, though. With no confirmation, the call stayedrunningunder the execution's claim until the worker swept it.Fix. Once a claimed execution settles, the execute route reports its outcome.
reportSettledClientWorkflowToolreads the trusted execution log, builds the same structural completion the browser would send, and records it through a newcompleteClientWorkflowToolCall. That write only applies while the call is stillrunningunder this execution's claim (completeClaimedAsyncToolCall). A confirmation is published only when this write wins, so a browser report or background detach that lands first is kept and the waiting turn never gets two deliveries. If the report fails, the route logs a warning and leaves the call to the existing client path.Behaviour changes
pagehidebackground detach that lands first still wins. The settled-execution report does nothing in that case.async: true) is moved to the background by the route once it is queued, the same report the browser sends after the 202.Test plan
workflow-client-settlement.integration.tsagainst real Postgres: a completed, failed, or cancelled run reaches the waiting turn when the browser never reports; an earlier browser report is kept; apagehidedetach is kept; a stray execution cannot complete another execution's call; an execution with no log is reported failed while a paused one is left alone; a queued async run is moved to the background, and a browser report that landed first is keptapp/api/workflows,lib/mothership/request/tools,lib/mothership/async-runs) passbun run type-check, biome,check:test-patterns,check:api-validation:strictrun_workflowcall and confirm the turn continues when the run settles