Skip to main content

container_argv

Function container_argv 

Source
pub(crate) fn container_argv(
    argv: Vec<String>,
    provider_id: &str,
) -> Vec<String>
Expand description

Heal a container agent’s argv IN PLACE when — and only when — it still carries the persistent controller’s flags.

A container agent runs one docker exec per turn: container_spawn.rs writes the raw message, closes stdin, and reads until EOF. There is no long-lived stdin and no control channel. The PERSISTENT argv is wrong for that in three separate ways, and it is what stale blocks carry:

  • --input-format stream-json — makes the CLI parse every stdin line as a JSON envelope, so it meets the startup markdown and dies with JSON Parse error: Unrecognized token '#'. This is the crash that kept container agents from EVER starting (verified live, 2026-08-31).
  • missing -p — the one-shot print flag. Without it the CLI is not in the mode this path drives at all.
  • --permission-prompt-tool stdio (+ a non-bypass --permission-mode) — routes tool permissions through the control protocol, which only the persistent controller speaks. A container turn has nothing to answer can_use_tool, so it rejects or hangs on the first permission check.

An earlier cut of this deleted only --input-format and left the other two (codex P1 on PR #2867) — that unblocks the immediate crash while leaving the pane in the wrong CLI mode, which is a worse failure because it looks like it works.

The cut after THAT rebuilt the argv wholesale from launch_args, which was worse again (reagent P1 on the same PR): this runs on EVERY container turn, not once per stale block, so a rebuild also threw away everything agent-model.ts legitimately appends after the base args — agent.provider_flags (user-configurable) and --fork-session (gated on providerId === "claude", not on agentMode, so container agents reach it). It would have permanently broken both for container agents, on blocks whose argv this fix had already assembled correctly.

So: subtract, don’t rebuild. Remove the flags the PERSISTENT argv carries that the one-shot argv does not, restore any one-shot flag that’s missing, and leave every other token — the user’s --model/--effort, their provider_flags, --fork-session — exactly where it was. Which flags are “persistent-only” is derived from the provider catalog rather than hardcoded, so a future flag moving between the two lists doesn’t silently strand this.

An argv carrying NO persistent-only flag is returned untouched: it was built by the fixed selectLaunchArgs path and there is nothing to heal.

The root cause is fixed at the source in launch-args.ts; this is the self-heal for blocks ALREADY persisted with the bad argv, since cmd:args lives in block meta and would otherwise stay wrong forever. Applied at the point of use so a block that never re-runs resync_controller can’t bypass it.