Skip to content

fix(runtime): detect SSE stream truncation and auto-continue from partial response#82

Merged
yishuiliunian merged 2 commits intomainfrom
fix/stream-truncation-auto-continue
Apr 5, 2026
Merged

fix(runtime): detect SSE stream truncation and auto-continue from partial response#82
yishuiliunian merged 2 commits intomainfrom
fix/stream-truncation-auto-continue

Conversation

@yishuiliunian
Copy link
Copy Markdown
Contributor

Summary

  • Detect SSE stream truncation (EOF without message_stop) by tracking received_done in llm.rs
  • Auto-continue from partial responses: record text, discard incomplete tool_uses, re-call LLM — bounded by max_auto_continuations
  • Cancel-safe: cancel paths excluded from both truncation detection and auto-continue

Changes

  • llm.rs: received_done flag + post-loop truncation check (excludes cancel)
  • llm_result.rs: expanded stream_error doc
  • turn_exec.rs: stream_truncated auto-continue branch + partial text preservation on cancel/error
  • turn_observer_dispatch.rs (new): extracted stop-hook and observer dispatch as lifecycle extension point
  • 13 new tests (5 unit + 6 integration + 2 edge-case) across 3 test files

Context

Sub-agents behind an API proxy would output text like "Let me create the file." then exit without executing the Write tool — because the proxy silently cut the SSE connection and the agent loop treated the truncated stream as a normal EndTurn.

Test plan

  • bazel test //crates/loopal-runtime:loopal-runtime_test — 219 tests pass
  • bazel build //... --config=clippy — zero warnings
  • CI passes

…tial response (#79)

When an API proxy silently drops SSE connections mid-stream (no
`message_stop` event), the agent loop previously treated the truncated
response as a normal EndTurn — causing sub-agents to exit with
incomplete output (e.g. "Let me create the file." without the Write
tool call).

Detection: track `received_done` in the stream loop; EOF without Done
and without cancel sets `stream_error = true`.

Recovery: stream_error with partial content triggers auto-continue
(record text, discard incomplete tool_uses, re-call LLM) — same
pattern as MaxTokens/PauseTurn. Bounded by `max_auto_continuations`.

Cancel safety: cancel paths are excluded from both truncation detection
(llm.rs) and auto-continue (turn_exec.rs) to preserve existing cancel
behavior.

Also extracts stop-hook and observer dispatch into
`turn_observer_dispatch.rs` as an independent lifecycle extension point.
@yishuiliunian yishuiliunian merged commit dacdb0f into main Apr 5, 2026
3 checks passed
@yishuiliunian yishuiliunian deleted the fix/stream-truncation-auto-continue branch April 5, 2026 02:09
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