Startup agent picker — fetch GET /agents when --new without --agent (TUI) #8
Closed
opened 2026-05-22 19:10:44 -07:00 by vh
·
1 comment
No Branch/Tag Specified
main
diag/r30-gap-injection-harness
diag/r30-phi0-step-response
diag/r29-pad-series
graphify-tooling
v0.22.3
v0.22.2
v0.22.1
v0.22.0
v0.21.20
v0.21.19
v0.21.18
v0.21.17
v0.21.16
v0.21.15
v0.21.14
v0.21.13
v0.21.12
v0.21.11
v0.21.10
v0.21.9
v0.21.8
v0.21.7
v0.21.6
v0.21.5
v0.21.4
v0.21.3
v0.21.2
v0.21.1
v0.21.0
v0.20.17
v0.20.16
v0.20.15
v0.20.14
v0.20.13
v0.20.12
v0.20.11
v0.20.10
v0.20.9
v0.20.8
v0.20.7
v0.20.6
v0.20.5
v0.20.4
v0.20.3
v0.20.2
v0.20.1
v0.20.0
v0.19.9
v0.19.8
v0.19.7
v0.19.6
v0.19.5
v0.19.4
v0.19.3
v0.19.2
v0.19.1
v0.19.0
v0.18.11
v0.18.10
v0.18.9
v0.18.8
v0.18.7
v0.18.6
v0.18.5
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.17
v0.17.16
v0.17.15
v0.17.14
v0.17.13
v0.17.12
v0.17.11
v0.17.10
v0.17.9
v0.17.8
v0.17.7
v0.17.6
v0.17.5
v0.17.4
v0.17.3
v0.17.2
v0.17.1
v0.17.0
v0.16.1
v0.16.0
v0.15.1
v0.15.0
v0.14.2
v0.14.1
v0.14.0
v0.13.0
v0.12.0
v0.11.0
v0.10.0
v0.9.0
v0.8.2
v0.8.1
v0.8.0
v0.7.1
v0.7.0
v0.6.5
v0.6.4
v0.6.3
v0.6.2
v0.6.1
v0.6.0
v0.5.1
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.1
v0.2.0
v0.1.0
Labels
Clear labels
blocked-needs-contract
blocked-needs-dependency
bug
cli
documentation
duplicate
enhancement
invalid
needs-architect-decision
needs-info
needs-triage
observability
ready-for-agent
sse-client
task
tui
wontfix
Sleipnir refuses dispatch — issue-scoped contract missing
Sleipnir holds dispatch — INV-029 dependency-aware gate
Something is not working
Command-line surface (--send, --new, --session, etc.)
Docs / contract / spec work
Duplicate of another issue
New feature or improvement
Not a real issue
Escalated for a design call
More info required from reporter
Newly filed, not yet sorted
Log-pane / debug-surface work (persona, admin events, Bifrost, tools)
Gates AFK dispatch via Sleipnir (applied by /sleipnir-preflight)
SSE consumer module (src/ratatoskr/sse_client.py)
Implementation task
Textual app shell + presenters
Accepted as not-fixing
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: vh/ratatoskr#8
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Today,
ratatoskr --new --agent <id>requires the--agentflag. If theoperator omits it,
_parse_argsraisesUsageError("--agent is required when --new is passed"). That's the right behavior for--sendmode(non-interactive, can't prompt). It's the wrong behavior for the TUI: the
operator might not know which agents are available, doesn't want to look
them up out-of-band, and would prefer to pick from a list at startup.
The Worldtree spec exposes
GET /agents(spec line 832; vendored atdocs/conversation-api-spec.mdat SHA55101e9...). It returns a JSONarray with at minimum
agent_id,name,descriptionper agent; somecarry
version,capabilities,supported_models,persona_traits,and
ui_hints(icon + color_hint). Ratatoskr could fetch this list andlet the operator pick.
Solution
Minimal startup agent picker for the TUI when
--newis passed without--agent. Three pieces:ratatoskr.sessions(issue #2 amendment): newlist_agents()function.AgentInfois a new frozen dataclass with all fields the spec lists; thenon-required fields default to
None/[]/{}when omitted from theserver response (mirrors the
SessionInfoorigin-conditional-defaultspattern from INV-001/INV-002 of issue #2).
ratatoskr.cli(issue #3 amendment):--agentbecomes conditionallyoptional.
--agentrequirement now depends on mode:--send --new(non-interactive create):--agentSTILL required;no way to prompt.
UsageErrorpreserved.--new(TUI create):--agentOPTIONAL. When omitted, the TUIlaunches an agent-picker screen before the chat pane.
--session <id>(any mode):--agentSTILL forbidden (existingINV-004 behavior; preserved).
_parse_argsSTEP 3 validates the mode-conditional requirement.ratatoskr.tui(issue #4 amendment): newAgentPickerScreen.Pushed onto the App's screen stack BEFORE
on_mount's session-createwhen
args.newANDargs.agent_id is None. Layout:On Enter, the picker pops itself off the screen stack and stores the
selection in
self.agent_id; control returns to the chat-pane screenwhich proceeds with
create_session(client, agent_id=self.agent_id, end_user_id=self.args.end_user_id). (Theend_user_idthreading isissue #5's amendment; this issue and #5 compose naturally.)
On Esc (or Ctrl-D / Ctrl-C from the picker): exit cleanly with code 0.
No session was created.
Out of scope (this issue)
installed-agent count grows large enough to need search, file a
follow-up.
ui_hintsrendering.iconandcolor_hintfrom the spec aredeclared in
AgentInfofor future use but the picker just showsagent_id · name — descriptionin v1. Pretty-print is a follow-up.show up in
GET /agentsif the server has them; the picker showsthem like any other; ratatoskr doesn't distinguish.
persona_traits/capabilitiespreview pane. Side detail whenthe operator highlights an agent. Future polish.
--sendmode.--sendis non-interactiveby design (design-brief §8b). Operators using
--sendmust knowthe agent_id; they can shell out to
curl GET /agents | jqif theyforget.
ratatoskrlaunchfetches fresh. v1 over-fetches by design — agent list is small,
cheap, and rarely stale; cache-coherence is a real cost.
Benefits
ratatoskr --newJust Works for interactive use.
naturally on next launch.
--end-user-id): if both are needed, operatorpasses
--end-user-idon the CLI and picks the agent in the TUI.screen, one CLI conditional. Doesn't reshape the existing
modules' invariants.
Acceptance
list_agentscoverage + new TUIpicker coverage).
uv run ruff check src/ tests/clean.ratatoskr --new(no--agent) → picker appears with all agentsfrom personal Worldtree; pick mimir → proceeds to chat pane;
type a message → response streams cleanly.
ratatoskr --new --agent mimir(with--agent) → picker skipped;behavior unchanged from today.
ratatoskr --send "hello" --new(no--agent) → UsageError; noTUI launch. (Regression check.)
ratatoskr --session s-1→ no picker; no agent fetch; attachesto the existing session. (Regression check.)
Dependencies
ratatoskr.sessions) — landed on main; this issue addslist_agents()+AgentInfodataclass.ratatoskr.cli) — landed on main; this issue amends_parse_argsfor conditional--agentrequirement.ratatoskr.tui) — landed on main; this issue addsAgentPickerScreenand a startup branch.--end-user-id) — independent; composes naturally if bothland but neither blocks the other.
Shipped at
d30be12(v0.3.0).ratatoskr.sessions:list_agents()+AgentInfofrozen dataclass.ratatoskr.cli:--agentmode-conditional (required for--send --new; optional for bare--new; forbidden with--session).ratatoskr.tui: newAgentPickerApp(separate Textual App, opens beforeRatatoskrAppsolist_agentserrors land on real stderr — preserves issue #6 INV-001)._resolve_then_rungains the pre-create picker branch.Contract:
docs/contracts/issues/8.contract.md(drift-check clean).+18 tests; 227 total GREEN; ruff clean. Live smoke against personal Worldtree returned 12 agents; programmatic picker drive auto-picked
lofnand created a real session withend_user_id="ratatoskr-tui". Interactive eyeball still pending — auto-pick covered the wiring.