Skip to content

bug(runtime): whitespace-only tool-argument deltas keep the stream watchdog alive for 15 minutes until the upstream cuts the stream #4861

Description

@jsiu93

Environment

  • Maka 8c52a835 (origin/main 2026-09-05), CLI 0.2.0, TUI from packages/cli/dist/dev-cli.js, macOS arm64, Node 24.19.0.
  • Connection: Custom relay (OpenAI Chat-compatible) → CLIProxyAPI 7.2.140 → Codex Responses API; models gpt-6-astra and gpt-5.6-sol. Permission mode Auto.

Summary

In Auto mode the Bash tool advertises boundary_intent and required_boundary (packages/runtime/src/builtin-tools.ts:669-670). required_boundary is an optional nested object whose required lists do not cover every property, so it is not strict-compatible. @ai-sdk/openai-compatible never sends strict; a Chat-compatible relay that forwards to the Responses API therefore lets the upstream "attempt strict validation" on that schema, and the model degenerates into emitting whitespace-only argument deltas. Each delta is a stream chunk, model-adapter.ts:390 reports it as activity, ai-sdk-turn.ts:1555 resets the 120 s idle watchdog, and tool-input-delta is otherwise ignored (model-adapter.ts:1100-1103), so nothing bounds the stream. The turn dies only when the upstream closes at ~902 s with stream closed before response.completed, which is the output-free close already tracked in #4599 / #4600.

Evidence (wire capture between the TUI and the relay)

  • Auto session, two captured turns: first chunk 3.4 s; 29,914 and 29,921 chunks; 8,600,302 and 8,696,969 bytes; 29,885 and 29,887 deltas whitespace-only; max inter-chunk gap 1.6 s; SSE error at 901.9 s and 902.0 s. Aggregated arguments stop right after "boundary_intent":"current" and never close.
  • Full access session (/permissions bypass, sandbox_boundary_log shows {"kind":"bypass","revision":1}): 10 of 87 requests looped the same way (B 2, A 4, C 4). Durations 201–902 s; the largest aggregated argument string was 3,280,178 characters, 3,279,819 of them trailing whitespace, 11.8 MB on the wire. Every one of the 87 requests still carried boundary_intent and required_boundary in the Bash schema.
  • The usage ledger records latencyMs=901907 / 902037, status=interrupted, providerCode=invalid_request_error, retryable=false, usageBasis=missing.
  • In an uninstrumented Auto session the same failure hit 4 of 4 tasks (each at 901.9–902.5 s).

Isolation with curl (same request body, tool_choice forced to Bash, 60 s cap; relay 500s excluded)

variant gpt-5.6-sol gpt-6-astra total
request as Maka sends it (strict absent) 5/10 loop 4/12 loop 9/22
"strict": false on the function 0/10 0/10 0/20
required_boundary removed 0/5 0/4 0/9
"strict": true 400 Invalid schema for function 'Bash' … Missing 'filesystem' same

Replaying the exact captured bodies with tool_choice: "auto" succeeded 4/4 (sol) and 1/1 (astra), so the trigger is probabilistic per generation, not a fixed property of one conversation.

Why this is Maka's problem too

  1. The Runtime has no bound on tool-input growth or on progress-free deltas: 8.6 MB of whitespace kept a turn alive for 15 minutes on a 120 s idle watchdog. A hostile or buggy provider can hold any turn open indefinitely the same way.
  2. The Bash boundary schema is what the model trips on, and Maka ships it to openai-compatible connections without declaring strict: false.
  3. Full access did not remove the fields either, so there was no way around the schema; that part is reported as bug(runtime): Full access sessions still advertise Bash boundary parameters and the RequestSandboxBoundary tool #4859 with a fix in fix(runtime-host): drop Bash boundary declarations under Full access #4860. This issue is about the bound that Auto sessions still lack.

Expected

Relation to existing issues

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions