Make /auto continuous, autonomous, and narrated - #215
Merged
Merged
Conversation
A bare /auto <goal> previously stopped after the configured iteration cap (default 10). It now runs continuously: the loop count no longer halts it (max_loops = Inf), and the run is governed by the monitor subagent and the finite resource caps -- tool calls, tokens, time, cost, and the stall guard -- rather than an iteration count. That matches the "work until done, stop at the boundary" model of an Auto approval mode, where completion is judged (the worker's AUTO_STATUS, checked by the monitor against disk evidence) rather than counted. --loops N still sets an explicit iteration cap. auto_validate_bounds accepts Inf only for max_loops and still rejects it for every other cap; max_tool_calls and stall_loops stay finite, so a continuous run always stops on some cap or a monitor verdict and is never truly unbounded. A goal is still required, same as a fresh Codex run.
The first prompt of an auto run now states its operating policy the way a well-phrased Codex task states its own: act on reasonable assumptions rather than pausing to ask or report progress; stop only for an ambiguity that would materially change the intended outcome, and report it for a human instead of guessing; and judge completion by evidence such as passing tests. Auto mode governs how freely the worker acts, not what the goal is or when it is done -- the model decides those, and this is the policy it decides under. The policy is stated in full once, in the initial prompt. The per-iteration continuation prompt keeps only a one-line reminder, so the stance survives compaction without paying for the whole policy on every turn (the continuation prompt stays under its length budget).
The "communicating while you work" policy leaned toward a line before
every tool call ("don't go more than a couple of tool calls without a
word"), which reproduces a cadence rather than the behaviour worth
having. Rewrite it around belief-state updates with adaptive batching:
send a brief update when a chunk of work finishes, when evidence changes
the working hypothesis, when the approach is about to change
substantially, or after several silent tool calls -- and keep working
after, since an update is informational, not a stop. Routine calls that
only confirm an expectation need no narration, and a question is not an
update.
The silent-streak backstop already existed (nudge after
corteza.narration_streak tool-call turns, default 3); its wording is
aligned to ask for what was learned and what's next, not just "what
you're doing".
Codex review found the narration and autonomy behaviour was described but not delivered. Three fixes: 1. Render the model's running commentary. Previously assistant_text reached only cli_tool_explanation() inside the approval prompt, so an auto-approved call (every call in an unattended run) showed nothing -- forcing verbose did not help. cli_commentary_lines() now prints the commentary once per model response, independent of approval, on both the CLI observer and chat()'s observer_progress(). 2. Stop auto runs blocking on plan approval. task_create routed to the human task_approval_cb before the auto gate, so an unattended run hung (interactive readline) or default-denied and stalled. .task_read_approval() now accepts a plan when session$auto_run_id is set, and the task addendum drops the ask-first / wait-for-approval steps in auto mode. Attended sessions prompt exactly as before. 3. Give a human-input request a real stop. The autonomy prompt told a blocked worker to emit AUTO_STATUS: continue with prose, which parses as continuation and depends on the monitor reading the prose. Add AUTO_STATUS: blocked, treated as a fail-closed escalation that stops the loop before the monitor query. Also reconcile the attended "check in whenever it could go more than one way" posture with the auto reasonable-assumptions policy, which now explicitly overrides it.
Two edge cases from the Codex review: 1. auto_parse_status() scanned the whole AUTO_STATUS line for status words and defaulted to continue on a multi-match, so "blocked - cannot continue" and a separate blocked line alongside a continue line both read as continue -- a fail-closed stop silently downgraded. Parse the status token (the first word after the colon) apart from its explanation, and let a blocked token win outright. Prose is no longer load-bearing: "continue, not blocked" stays continue, and "blocked - cannot continue" stops. The permissive done/continue default is unchanged. 2. The running commentary rendered only on "start"/"task", and cli_commentary_lines() only fires for the first call of a batch. When that first call was denied (a monitor refusal fires "deny"/"declined", never "start"), the whole response went uncommented even though a later call ran. Both observers now render commentary on a denied or refused first call too, still once per response.
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.
/autonow behaves like a Codex-style autonomous run rather than a fixed-iteration loop.What changed
/auto <goal>(no--loops) runs until done, governed by the monitor subagent and the resource caps (tool calls, tokens, time, cost, stall) instead of a loop count.--loops Nstill sets an explicit cap.max_loops = Infis accepted only for this case;max_tool_calls/stall_loopsstay finite by validation, so a run is never truly unbounded. A goal is still required.chat()), once per model response and independent of the approval prompt — including denied/refused first calls. Previously it appeared only inside an approval prompt, which auto-approved calls skip.task_createno longer blocks on human plan approval inside an auto run (it hung interactive runs and default-denied non-interactive ones); the task guidance drops the ask-first / wait-for-approval steps in auto mode. Attended approval is unchanged.AUTO_STATUS: blockedstops the run for a human before the monitor query, parsed from the status token so prose ("blocked - cannot continue") or a stray continue line can't flip a fail-closed stop into a continuation.Tests
Full
test_packagesuite green (4861 assertions, 0 failures). New coverage for continuous mode, the autonomy/continuation prompts,blockedparsing and loop behaviour, task auto-approval in auto mode, and commentary rendering including denied first calls.