Skip to content

fix(agents): give opencode its prompt on stdin, not as an argument - #466

Merged
aidan-sims merged 4 commits into
mainfrom
aidan/fde-2585-opencode-prompt-stdin
Nov 4, 2026
Merged

aidan-sims merged 4 commits into
mainfrom
aidan/fde-2585-opencode-prompt-stdin

Conversation

@aidan-sims

@aidan-sims aidan-sims commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Owner: Aidan Sims. Ticket: FDE-2585. Builds on #465 (builtin_tools, merged), which touched the same file.

run_opencode passed the whole prompt as a single argv element. Linux caps one argument at 128 KiB (MAX_ARG_STRLEN), so a longer prompt failed exec with E2BIG before the CLI started. opencode-ai 1.17.18 reads stdin when it isn't a TTY, so the prompt, including its output-format suffix, now goes there.

  • The prompt is no longer appended to argv. The CLI is spawned with stdin=PIPE, and _stream_cli feeds the prompt in a task that runs while stdout is read. This avoids a deadlock when the CLI prints before it has read all of its input.
  • If the CLI exits before reading stdin (BrokenPipe/ConnectionReset), the write error is ignored and the CLI's stderr explains the exit. Any other write error fails the turn, because the CLI may have received only part of the prompt.
  • Behaviour change: on main, opencode wrapped a positional prompt that contained a space in quotes and escaped its inner quotes. On stdin the model gets the prompt verbatim. This applies to every opencode run, including runs with no builtin_tools selection, so pass@k on opencode agents may shift slightly compared with earlier runs.

Validation: uv run pytest tst/unit/agents/opencode gives 119 passed, 7 skipped (Linux-only); its two builtin_tools tests now read the prompt from stdin. New tests cover first and resumed turns, a 1 MiB prompt, a real exec of a 1 MiB prompt (E2BIG on main), a CLI that exits without reading stdin, a real CLI that writes 300 KB to stdout and stderr before reading its prompt, and a write error that fails the turn. The last two were checked against mutants of the fix and fail on them. ruff check passes on the touched files.

Not in this PR:

  • A run of the opencode agent image (AC4). The real pinned CLI was run instead, against a local fake model: a 512 KiB prompt fails with E2BIG on main on Linux, and arrives byte for byte on stdin.
  • Publishing new hub agent versions (done separately by Env Pod after release).
  • Reformatting the three existing touched files, which already fail ruff format --check on main.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no actionable issues were found.

Summary

OpenCode prompts now travel through stdin instead of command arguments, avoiding the per-argument size limit.

  • OpenCode turns send the full prompt through stdin.

Diagram

sequenceDiagram
  participant Bridge
  participant CLI as OpenCode CLI
  Bridge->>CLI: Start with piped stdin, stdout, and stderr
  par Feed prompt
    Bridge->>CLI: Write prompt and close stdin
  and Read events
    CLI-->>Bridge: Stream stdout events
  and Read errors
    CLI-->>Bridge: Stream stderr
  end
  Bridge->>CLI: Wait for exit
  Bridge->>Bridge: Build turn result
Loading

Reviews (3) · Last reviewed commit: "test(agents): the builtin_tools tests re..." · Reviewed by Greptile

@aidan-sims
aidan-sims force-pushed the aidan/fde-2585-opencode-prompt-stdin branch from d070c45 to e979766 Compare November 3, 2026 15:47
@aidan-sims
aidan-sims marked this pull request as ready for review November 3, 2026 16:08
@aidan-sims
aidan-sims requested a review from a team as a code owner November 3, 2026 16:08
@aidan-sims
aidan-sims force-pushed the aidan/fde-2585-opencode-prompt-stdin branch from e979766 to d543b8a Compare November 3, 2026 16:26
Base automatically changed from aidan/fde-2584-builtin-tools-codex-opencode to main November 4, 2026 16:25
aidan-sims and others added 4 commits November 4, 2026 11:26
run_opencode passed the whole prompt as one argv element, and Linux caps a
single argument at 128 KiB (MAX_ARG_STRLEN), so a longer prompt failed exec
with E2BIG before the CLI started. opencode-ai 1.17.18 reads stdin when it
isn't a TTY, so the prompt (with its output-format suffix) now goes there,
fed while stdout is read and tolerating a CLI that exits before reading it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Covers first and resumed turns, a 1 MiB prompt with its output-format suffix,
a real exec of a 1 MiB prompt (E2BIG on main), and a CLI that exits without
reading its stdin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… its errors fail the turn

Two regression guards for the stdin hand-off: a real CLI that fills its
stdout and stderr pipes before reading a 1 MiB prompt must not deadlock the
turn, and a prompt write that fails with anything other than a closed pipe
must raise rather than report success.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aidan-sims
aidan-sims force-pushed the aidan/fde-2585-opencode-prompt-stdin branch from d543b8a to 71ba171 Compare November 4, 2026 16:26
@aidan-sims
aidan-sims merged commit 8ab7342 into main Nov 4, 2026
27 checks passed
@aidan-sims
aidan-sims deleted the aidan/fde-2585-opencode-prompt-stdin branch November 4, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants