Skip to content

Fix mid-stream disconnect hang; default /break off - #86

Merged
glenjbarber merged 2 commits into
mainfrom
claude/gracious-einstein-udo2ld
Oct 14, 2026
Merged

glenjbarber merged 2 commits into
mainfrom
claude/gracious-einstein-udo2ld

Conversation

@glenjbarber

Copy link
Copy Markdown
Owner

Summary

  • Fixes the bug behind "orcli disconnects from the server and disrupts the session": when a server connection dropped mid-stream (a non-EOF read error), stream() reported an EventError and returned immediately without ever emitting EventFinish. Client.Chat's own contract promises exactly one EventFinish per call, and callers (the TUI's turn state included) drive off it, so a dropped connection left the session waiting on a turn that had actually already stopped. The read error is now held and routed through the same finish/retry logic as every other failure: a disconnect before anything was delivered is retried like any other undelivered failure, and a disconnect after partial text still ends in exactly one EventFinish with Finished: false.
  • Flips break_enabled's default to false (code default and orcli.json.example). /break on and /break on save still turn the periodic screen-break reminder on for whoever wants it.

Test plan

  • go build ./...
  • go test ./internal/openrouter/... (added TestStreamDisconnectBeforeDeliveryIsRetried and TestStreamDisconnectAfterDeliveryStillFinishes regression tests)
  • go test ./internal/config/... ./cmd/orcli/...

🤖 Generated with Claude Code

https://claude.ai/code/session_01KCaxpUCVhMswb9NsLjzZxS


Generated by Claude Code

A server dropping the connection mid-stream surfaced as a non-EOF read
error in stream(), which reported EventError and returned nil without
ever emitting EventFinish. Client.Chat's own doc comment promises
exactly one EventFinish per call, and callers (the TUI included) drive
their turn state off it, so a caller was left waiting on a turn that
had actually already stopped: the disconnect disrupted the session.

Hold the read error the same way a reported failure is already held,
and let it flow through the same retry and finish logic: a disconnect
before anything was delivered costs nothing and is retried like any
other undelivered failure, and a disconnect after partial text still
ends in exactly one EventFinish with Finished false.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCaxpUCVhMswb9NsLjzZxS
Periodic screen-break reminders defaulted to on, with no setting in a
user's own config file to override it silently - a file predating this
field got the reminders whether it wanted them or not. Flip the default
to off; /break on, and /break on save, still turn it on for whoever
wants it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCaxpUCVhMswb9NsLjzZxS
@glenjbarber
glenjbarber marked this pull request as ready for review October 14, 2026 20:52
@glenjbarber
glenjbarber merged commit ea7b023 into main Oct 14, 2026
1 check passed
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