Repository navigation
Modes: a switch mid-task takes effect on the model's next turn - #395
Merged
Merged
Conversation
shift+tab during a task said "applies on the next task", and did: the pending mode was applied only when the whole task ended — while the README claimed "the next turn". Now it is the next turn. The choice is queued for the agent, which takes it at the start of the model's next turn, before the call — never in the middle of a turn, so a turn's calls are judged under one mode. Manual takes effect for the call gate right there; a switch into or out of plan mode goes into the conversation as plan mode's directive or its OFF note, and the plan backstop follows. A "mode" event brings the UI along and logs "⇄ manual mode on — from step N"; switching into plan mid-task gets the PLAN READY handshake at the end. A task that ends before the model takes another turn applies the choice to the next task, as before. Read-only mode is not switchable this way. Agent.planMode is atomic now: the agent writes it between turns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
If your organization's extra usage balance is empty, an organization admin can add extra usage credits at claude.ai/admin-settings/usage. If its monthly spend limit was reached, an admin can raise it on the same page. If neither applies, contact Anthropic support.
Once extra usage is available, someone with write access to this repository can comment @claude review on this pull request to trigger a review.
- takeMode sets the app's plan mode too, on the agent's goroutine: a sub-agent spawned on the turn after a switch to plan read the old mode until the UI caught up, and could write. app.planMode is atomic now. - The "mode" event only clears the pending choice. It called setMode, so an event read late could set back a newer switch the agent had taken since, mid-turn. - PLAN READY is decided by the mode the run ended in, not by the order its last mode event and taskDoneMsg arrive in. - force-detach applies a pending choice and drops the queue, and an idle shift+tab drops it too: the fresh agent took the abandoned run's mode on its first turn, over one chosen since. - shift+tab works while an approval waits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- What the task's end (or a force-detach) applies is what is still in the queue — what the agent did not take — instead of the UI's pending copy, which a late or stale "mode" event had to clear by name. The event now only logs. - setMode empties the queue: /plan typed after a shift+tab during /compact was undone by the next task's first turn. - takeMode takes and stores under one lock, and force-detach pops the queue before building the fresh agent, so a detached run's late take cannot leave the app and the new agent in different modes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A run paused between its own detached check and the take could, after a force-detach and a new task, take the choice queued for the new run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
shift+tab during a task printed "applies on the next task", and that was accurate. The pending mode was applied only when the whole task ended (
applyPendingModeintaskDoneMsg), while the README claimed "the next turn". It now applies on the next turn.How it works:
app.queueMode). The agent takes it at the start of the model's next turn (SetModeSwitch→app.takeMode, throughAgent.switchMode). That happens before the call and never in the middle of a turn, so all of a turn's tool calls are judged under one mode.app.manualis atomic. Plan mode is set by the agent itself. A switch into plan sends plan mode's directive into the conversation, and a switch out of plan sends its OFF note. The plan backstop inexecOnefollows the new value.modeevent updates the UI. It logs⇄ manual mode on — from step N, updates the indicator, and clears the pending choice. A switch into plan mid-task gets the PLAN READY handshake at the end.Agent.planModeis now anatomic.Bool, since the agent writes it between turns.Tests:
TestAModeChosenMidTaskTakesEffectOnTheNextTurn(agent) covers auto→plan mid-run (second write refused, directive sent, event emitted), plan→auto (OFF note sent, write runs) and read-only staying put.TestAModeChosenMidTaskIsTakenAtTheNextTurn(cmd) covers the queue, a single take, manual applying for the gate, the event updating the UI, the plan handshake, and a task ending before the take.A sabotage pass made 11 mutations, and every one failed a test. The wiring line
a.ag.SetModeSwitch(a.takeMode)inwire()has no direct test.🤖 Generated with Claude Code