start a resumed CoS agent's task immediately instead of leaving it pending for a manual Run - #6096
Merged
Merged
Conversation
…r a manual Run Resume and Relaunch both requeued the paused agent's task and stopped there. The requeue only makes a task ELIGIBLE — what spawns it is the automatic dequeue `completeAgent` schedules, and that path admits pending user tasks plus auto-approved system tasks under CoS auto-run in `execute` mode. So on an install with auto-run off, or for a task still awaiting approval, the task sat `pending` until the user opened the task list and pressed Run. One click became two, on the screen the user had just acted from. `resumeAgent` now force-spawns the task it requeued, through `forceSpawnTask` — the same door "Run now" uses — so it inherits those refusals rather than restating them. A stopped/paused daemon, an unreachable runner, a task needing approval, and a full agent pool all still mean "leave it queued"; the refusal comes back as `spawnHold` so the dialog names it instead of toasting a resume that silently didn't start. Relaunch is a pause plus a resume, so it inherits the dispatch through that composition. Deliberately not pushed deeper into `reviveBlockedTask` or the `tasks:changed` unblock listener: those are shared with the autonomous revival paths (investigation retry, orphan cooldown, completion cleanup), where force-spawning would strip the auto-run gate that withholds unattended spawns. Both doors into the new dispatch are a human clicking a button. Both dialogs render the outcome through one shared helper so neither can say "queued" for a run that already started, or omit the reason it didn't.
… name the new-task resume outcome A spawn registers its agent as running BEFORE it flips the task off pending, and the refusal that lands in that window is forceSpawnTask's own holder guard — so reading the task status alone still saw 'pending' and reported a hold for a run already under way. Check the running-agent holder too. AgentsTab had no 'new-task' wording, so a resumed replacement task that the server started reported only the generic 'Created resume task'.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pendingfor the user to find on the task list and press Run.completeAgentschedules, and that path admits pending user tasks plus auto-approved system tasks under CoS auto-run inexecutemode — so a resumed internal task on an install with auto-run off, or one still awaiting approval, sat there. One click became two, on the screen the user had just acted from.resumeAgentnow force-spawns throughforceSpawnTask— the same door "Run now" uses — so it inherits that gate's refusals rather than restating them. A stopped/paused daemon, an unreachable runner, a task needing approval, and a full agent pool all still mean "leave it queued"; the refusal comes back asspawnHoldso the dialog names it instead of toasting a resume that silently didn't start.Why
resumeAgentand not deeperNot pushed into
reviveBlockedTaskor thetasks:changedunblock listener: those are shared with the autonomous revival paths (investigation retry, orphan cooldown, completion cleanup), where force-spawning would strip the auto-run gate that deliberately withholds unattended spawns. Both doors into the new dispatch are a human clicking a button.Reporting the outcome honestly
Two ways to get the toast wrong, and both dialogs could get them wrong identically, so they share one helper (
client/src/lib/agentResumeOutcome.js): saying "queued" for a run that already started reads as the click not having taken, and saying "queued" with no reason sends the user hunting the task list for why.A spawn registers its agent as
runningbefore it flips the task offpending, so a refusal landing in that window isforceSpawnTask's own holder guard — the dispatch checks the running-agent holder as well as the task status, or it would report a hold for a run already under way.Test plan
server/services/agentManagement.test.js— force-spawns the requeued task; reports the refusal rather than claiming a resume that never started; treats a task the racing dequeue already claimed as started; treats a task claimed mid-spawn (stillpending) as started; does not dispatchalready-active/superseded; relaunch inherits the dispatch outcome. The mid-spawn test was bypass-probed — it fails when the holder half of the check is removed.client/src/components/cos/tabs/AgentsTab.test.jsx,RelaunchAgentModal.test.jsx— running vs queued wording, thespawnHoldreason, and thenew-taskreplacement outcome.client/src/components/cos/tabs/andclient/src/lib/index.test.jsgreen.