feat(sessions,cli,tui): issue #8 — startup agent picker (v0.3.0)

Adds GET /agents fetch + ListView picker for bare `--new` (TUI mode
without --agent). Three in-place amendments:

- ratatoskr.sessions: new `list_agents()` + `AgentInfo` frozen
  dataclass with omit-when-null/empty defaults mirroring SessionInfo's
  INV-001/INV-002 origin-conditional pattern. Non-200 responses raise
  the existing SessionApiFailed (no new exception).
- ratatoskr.cli: `_parse_args` softens `--agent` from absolute to
  mode-conditional — required for `--send --new`, optional for bare
  `--new`, forbidden with `--session` (unchanged INV-004).
- ratatoskr.tui: new `AgentPickerApp(App[str | None])` — separate
  Textual App (not Screen-within-RatatoskrApp) so list_agents errors
  land on real stderr before any alt-screen opens (preserves issue
  #6's INV-001). `_resolve_then_run` gains a pre-create branch:
  fetch agents → empty list → exit 13; non-200 → exit 20; network
  error → exit 21; picker dismissed → exit 0; otherwise thread chosen
  agent_id into create_session.

Contract: docs/contracts/issues/8.contract.md (drift-check clean).

Tests: +18 (227 total, was 209). Live smoke against personal Worldtree
(:8081) returned 12 agents; programmatic picker drive auto-picked lofn
and created a real session with `end_user_id="ratatoskr-tui"`.
This commit is contained in:
vh
2026-05-23 17:58:22 -07:00
parent a77a872810
commit d30be12deb
10 changed files with 986 additions and 43 deletions
+28 -33
View File
@@ -1,6 +1,6 @@
# Persistent memory — ratatoskr
_Last updated: 2026-05-23_
_Last updated: 2026-05-24_
This file captures durable intent and supporting evidence (goals, decisions,
foot-gun warnings, in-flight state) across context resets. Read it at session
@@ -32,51 +32,47 @@ separate dev team rather than an in-tree Worldtree tool.
## Current state / in-flight
_As of 2026-05-23 (end of day, post-v0.2.1 layout fix):_
_As of 2026-05-24 (post-v0.3.0 startup agent picker):_
**Status: v0.2.0 + v0.2.1 shipped and pushed.** Seven core issues
complete (`sse_client` #1, `sessions` #2, `cli` #3, `tui` #4,
`--end-user-id` #5, TUI startup error visibility #6, presenter
contract semantics amendment #12) + robustness fix #7 (MalformedSseData
+ empty-skip) + v0.2.1 TUI layout fix on top. 209/209 tests GREEN;
ruff clean; working tree clean; both v0.2.0 and v0.2.1 tags on
`origin/main`.
**Status: v0.3.0 shipped.** Eight core issues complete (`sse_client`
#1, `sessions` #2, `cli` #3, `tui` #4, `--end-user-id` #5, TUI
startup error visibility #6, presenter contract semantics amendment
#12, startup agent picker #8) + robustness fix #7 (MalformedSseData
+ empty-skip) + v0.2.1 TUI layout fix. 227/227 tests GREEN; ruff
clean.
Last commits on `main`:
- v0.3.0 feat(sessions,cli,tui): issue #8 — startup agent picker
- `c85f6bd` fix(tui): anchor layout via dock so Input never moves (v0.2.1)
- `3b9c610` feat(cli,tui): issue #12 — presenter contract semantics amendment (v0.2.0)
- `8282156` snapshot: persistent-memory Heimdall scope-model foot-gun
- `804c2df` feat(sessions,cli,tui): issues #5 + #6 + worldtree-dev follow-up (v0.1.0)
**Smoke status:**
- `--send` v0.1.0 mimir smoke clean earlier today (`[done] turn_id=116
duration_ms=5467`).
- `--send` v0.2.0 mimir smoke survived a Worldtree-side stall (see
Tried-and-abandoned for the 2-events-then-silence diagnostic shape).
After worldtree-dev's operator-side `:8081` restart, mimir responded
cleanly with the new v0.2.0 rendering shape: coalesced thinking
runs, `. ` ASCII prefix for demoted telemetry, `duration=11.8s` /
`usage 40764 in -> 850 out (41614 total, 0 cached)` formatting.
- `--send --new --agent mimir` v0.3.0 smoke clean
(`[done] turn_id=141 model=qwen3.6-35-a3b duration=2.2s`).
- Live `list_agents` smoke against personal Worldtree returned 12
agents (actor, bragi, cara, domari, forseti, glados, leif, lofn,
mimir, soong, troi, saga).
- Picker end-to-end smoke against live Worldtree: bare `--new` →
list_agents → picker (auto-picked lofn programmatically since
driving alt-screen interactively from CLI smoke isn't possible)
→ POST /sessions with end_user_id="ratatoskr-tui" succeeded;
RatatoskrApp constructed with agent_id="lofn".
- TUI v0.2.0 was visually broken (Input pane bouncing with thinking
runs); v0.2.1 fixed via dock-based layout. Operator confirmed
"a lot better" interactively.
- Lofn smoke is **auth-unblocked** (Tier 1 agent.call:* baseline
covers it; the phantom-scope-add diagnosis is settled in
Tried-and-abandoned). Not yet run.
**Outstanding operator-side todos:**
- **Post-v0.2.1 lofn smoke** — `source env.sh && uv run ratatoskr
--new --agent lofn --send "hello"`. Now unblocked on auth.
- **Interactive TUI picker eyeball** — `source env.sh && uv run
ratatoskr --new` (no flags after) should show the picker; pick
lofn; type a message; verify response streams cleanly. Auto-pick
smoke confirmed the wiring; visual confirmation pending.
- **Post-v0.2.1 TUI multi-turn eyeball** — confirm thinking-run
bouncing is gone across multiple turns; the layout fix has only
been confirmed for a single turn so far.
**Pending issues filed but not started:**
- **Issue #8 (startup agent picker)** — filed but unscaffolded.
Worldtree-dev confirmed `GET /agents` requires no special scope;
auth side is unblocked. Composes with #5 (both thread through
`ParsedArgs` → `_resolve_then_run`). **This is the next planned
feature** (see Recent decisions §5-sequencing).
- **Issue #9 (spec-pin refresh v0.19.0 → v0.22.1)** — filed
2026-05-23. Documentation debt; defer unless we need a v0.20.0+
capability.
@@ -101,15 +97,14 @@ Branch: `main` (clean). Remote:
**Next natural moves:**
1. **Lofn smoke** — quick operator-side eyeball.
2. **Issue #8 (startup agent picker)** — scaffold + contract +
TDD. Independent of layout work; gates §5 side-panes work per
the 2026-05-23 sequencing decision.
3. **§5 side-panes work** — Persona pane first per design-brief; the
1. **Interactive picker eyeball** — operator confirms the TUI
picker UX (rendering, Enter pick, Esc dismiss) against personal
Worldtree.
2. **§5 side-panes work** — Persona pane first per design-brief; the
collapsible Thinking pane + Debug pane proposals fold IN as
additional `TabbedContent` tabs alongside Persona/Tools/AdminEvents.
Reshapes layout from vertical-stack to Horizontal two-column.
4. **Issue #9 (spec-pin refresh)** — defer unless we need a v0.20.0+
3. **Issue #9 (spec-pin refresh)** — defer unless we need a v0.20.0+
capability (e.g., `memory_context` for Phase 2.1).
## Recent decisions