-
feat(local_agents): tier-3 index + picker merge (v0.8.0)
released this
2026-05-24 21:13:30 -07:00 | 249 commits to main since this releaseWorldtree's GET /agents doesn't return consumer-defined (tier-3)
agents — the public list excludes them by design. Confirmed live in
v0.7.0's smoke. Without server-side knowledge, ratatoskr's picker
couldn't show tier-3 agents the operator had defined; the workflow
was "remember the agent_id, pass --agent ratatoskr:
explicitly." Friction grows with every tier-3 agent.Fix: client-side index, merged at picker time
New module
ratatoskr.local_agentsmaintains a JSON-backed index at
$XDG_CONFIG_HOME/ratatoskr/local_agents.json (override via
$RATATOSKR_LOCAL_AGENTS).tier3CLI define / patch / delete update
the index as side-effects.tui._resolve_then_runloads the index
afterlist_agents(client)and appends entries not already in the
remote list (dedup by agent_id; remote wins on conflict).Library-level
tier3.define_agent/patch_agent/delete_agent
stay pure — local persistence lives in the CLI layer (_run_define
etc.), not in the library functions. Tests of the library don't
touch the filesystem.Public surface
ratatoskr.local_agents:
LocalAgentEntry (frozen dataclass)
load_local_agents() -> list[LocalAgentEntry]
add_local_agent(entry)
update_local_agent(entry) # same semantics as add (agent_id key)
remove_local_agent(agent_id)
make_description(system_prompt) -> str # synthetic picker labelFailure modes are lenient: missing file → empty index; corrupt JSON
or schema mismatch → empty index (no crash). The picker continues
to show foundational agents either way; tier-3 surface degrades to
the pre-v0.8.0 workflow.Picker integration
Local entries convert to ratatoskr.sessions.AgentInfo with synthetic
fields:
name = agent_name (from LocalAgentEntry)
description = "(tier 3) "
version, capabilities, supported_models, persona_traits, ui_hints
= None / [] / [] / {} / {}If Worldtree later starts returning tier-3 in GET /agents, this
module's role narrows to redundant local cache; can be removed
cleanly since the dedup-by-agent-id keeps remote-wins behavior.Tests
286/286 GREEN (was 265, +21: 20 local_agents + 1 picker-merge
integration). Ruff clean. Tests isolate the index via
$RATATOSKR_LOCAL_AGENTS pointed at pytest's tmp_path — no pollution
of operator's real ~/.config/ratatoskr/.Manual smoke
Sindra-like define against personal Worldtree:
python -m ratatoskr.tier3 define --name foo --system-prompt "..." --model X
cat ~/.config/ratatoskr/local_agents.jsonratatoskr --new picker now shows ratatoskr:foo alongside mimir et al.
Cross-machine: the file is per-host. Operator can sync via dotfiles
if needed; out of scope for this commit.Minor bump (v0.7.1 → v0.8.0) — new public module + new picker
behavior (more agents shown). No caller-side breaking changes.Downloads