Skip to content

feat: top-5 improvements — model split, render coalescing, auto-reconnect - #14

Merged
jkyberneees merged 3 commits into
mainfrom
feat/top-5-improvements
Jul 27, 2026
Merged

feat: top-5 improvements — model split, render coalescing, auto-reconnect#14
jkyberneees merged 3 commits into
mainfrom
feat/top-5-improvements

Conversation

@jkyberneees

Copy link
Copy Markdown
Contributor

Summary

Implements the actionable items from the top-5 improvement review (see commit list). Deliberately excluded: swapping the WebSocket library (rejected — stays on golang.org/x/net/websocket) and the cross-repo protocol contract test (deferred; it needs an odek-side fixture to be meaningful).

Commits

  • refactor(tui): split model.go into events, input, and approval files — the 1.2k-line god file becomes model.go (627) + events.go + input.go + approval.go; tests drive Model directly so nothing breaks.
  • perf(tui): coalesce streaming renders into one flush per 80ms — high-frequency events (token/thinking) no longer trigger a glamour re-render + full viewport SetContent per token; renders batch into one flush per 80ms tick.
  • feat(tui): reconnect with backoff and resume the session after a socket drop — previously a dropped socket was terminal (_disconnected → dead TUI). odek serve cancels the turn on disconnect but the session (id + auth token) survives, so bodek now redials with exponential backoff (500ms → 8s, 5 attempts) and the next prompt transparently re-binds the session — every prompt already carries session_id + auth_token. The badge reads reconnecting… during retries; a server that stays down keeps the old terminal disconnected state with the log-path hint.

Already on main (from the same review)

  • Transient skill/memory/signal notices auto-dismiss after 3s (fix/skill-notices-auto-dismiss-3s).

Checklist

  • make fmt / make vet / make lint (0 issues) / make test (race) — all green
  • README updated (auto-reconnect bullet)
  • New behavior covered: internal/tui/reconnect_test.go (schedule/success/retry-exhaustion/stale-result/backoff/badge)

model.go had grown to 1268 lines mixing event ingestion, keyboard
handling, autocomplete, and approvals. Move whole functions into
events.go (client.Event handling, notices, step previews), input.go
(completion popup state + key capture, prompt submit), and approval.go
(approval key capture + answer). Pure refactor: no behavior change,
tests pass unchanged.
token/thinking events used to rebuild the viewport — re-running glamour
on the streaming tail — on every single event. They now share one
coalesced flush (renderFlushMsg) per streamRenderInterval; done, error,
and disconnect still render eagerly and drop any pending flush.
…et drop

A dropped WebSocket used to be terminal: one _disconnected event and the
TUI settled into a dead state even though the session (id + auth token)
survives server-side. Now a drop schedules redials with exponential
backoff (500ms-8s, 5 attempts) via a Reconnect hook wired in main. On
success the client and event stream are swapped and the next prompt
re-binds the session transparently; on exhaustion the previous terminal
disconnected state (with the server log hint) is kept. The badge reads
"reconnecting…" while retries are in flight.
@jkyberneees
jkyberneees merged commit 8d82973 into main Jul 27, 2026
5 checks 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.

1 participant