Skip to content

agent: raise default SPROUT_AGENT_MAX_OUTPUT_TOKENS to 32768#565

Merged
tlongwell-block merged 1 commit into
mainfrom
dawn/bump-default-max-output-tokens
May 13, 2026
Merged

agent: raise default SPROUT_AGENT_MAX_OUTPUT_TOKENS to 32768#565
tlongwell-block merged 1 commit into
mainfrom
dawn/bump-default-max-output-tokens

Conversation

@tlongwell-block

Copy link
Copy Markdown
Collaborator

Problem

When the sprout-agent's per-response token cap fires inside a tool_use block (typical for large shell command values — e.g. file creation via heredoc), the provider returns the block with whatever input JSON parsed cleanly so far. That's often {} if the cap hit mid-value of the first field. The MCP then rejects the call with:

Tool call rejected: Mcp error: -32602: failed to deserialize parameters: missing field `command`

From the user's perspective the MCP "errors on file creation," but the trigger is response length, not quoting or content. The session loops because the model has no signal that its emission was truncated.

Reproduced empirically: command values up to ~5-7KB succeed; ~10KB+ trigger the truncation. Same MCP, same model, same harness.

Fix

Raise the default SPROUT_AGENT_MAX_OUTPUT_TOKENS from 4096 to 32768.

  • Sonnet 4 and Opus 4 (the models offered in the ACP settings panel at crates/sprout-acp/src/acp.rs:1530-1531) both support up to 64K output tokens, so 32K leaves comfortable headroom.
  • Providers bill on tokens generated, not on the cap, so normal-turn cost is unchanged — only the ceiling moves.
  • The env override (SPROUT_AGENT_MAX_OUTPUT_TOKENS) still wins for any deployment that wants to pin a lower value.

Files

  • crates/sprout-agent/src/config.rs — default literal.
  • crates/sprout-agent/README.md — env-var table row + a one-line note explaining the value.

Verification

cargo build -p sprout-agent     # clean
cargo test -p sprout-agent       # 17/17 pass
cargo fmt -p sprout-agent --check
cargo clippy -p sprout-agent -- -D warnings

Lefthook pre-commit and pre-push hooks ran clean (rust-fmt, rust-clippy, rust-tests, plus the desktop/web/mobile checks).

Follow-ups (separate PRs, not blocking this one)

  • Agent-side MaxTokens guard: detect stop_reason: max_tokens with non-empty tool_calls in crates/sprout-agent/src/agent.rs and refuse to forward the partial tool_use, returning a corrective synthetic tool-result instead. Defense in depth for sessions that still exceed the new 32K ceiling, or for deployments pinning the env override lower.
  • write_file MCP tool in sprout-dev-mcp: takes {path, content} as plain JSON fields, sidestepping bash heredoc quoting footguns entirely (indented EOF, space-indent under <<-, unquoted-delimiter $var expansion). Removes the dominant "one giant command value" usage pattern that creates the truncation pressure in the first place.

The previous default (4096) caused frequent mid-tool-use truncation when
the model emits a large `command` value (e.g. file creation via heredoc).
When the per-response token cap fires inside a `tool_use` block, the
provider returns the block with whatever `input` JSON parsed cleanly so
far — often `{}` if the cap hit mid-value — and the MCP rejects the call
with `-32602: missing field \`command\``. From the user's perspective
the MCP "errors on file creation," but the trigger is response length.

Sonnet 4 and Opus 4 (the two models offered in the ACP settings panel)
both support up to 64K output tokens, so 32K leaves comfortable headroom.

The cost shape is unchanged: providers bill on tokens *generated*, not
on the cap, so normal turns cost the same. Only the ceiling moves.

The env override (`SPROUT_AGENT_MAX_OUTPUT_TOKENS`) still wins for any
deployment that wants to pin a lower value.
@tlongwell-block tlongwell-block enabled auto-merge (squash) May 13, 2026 13:03
@tlongwell-block tlongwell-block merged commit 80b79c4 into main May 13, 2026
15 checks passed
@tlongwell-block tlongwell-block deleted the dawn/bump-default-max-output-tokens branch May 13, 2026 13:03
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.

1 participant