Phase 1 stabilization. Removes the four-copy prompt/agent-description drift
surface and the silent router fallback.
- models.py: hoist model IDs to module-level constants; add with_retries()
helper (2 retries on Anthropic+OpenAI transient errors via with_retry).
- agents.py: single AGENTS dict (model_fn, prompt, description) and a
make_agent_node() factory that collapses six near-identical node functions.
- graph.py: router prompt is generated from AGENTS; router_node uses
with_structured_output(RouteDecision) and returns an explicit "unknown"
route instead of the silent "researcher" fallback. New unknown_node wires
to END. All LLM invocations go through with_retries.
- state.py: add "unknown" to the route Literal.
- run.py: --route-only now imports router_node from graph.py, killing the
fourth prompt copy.
- tests/: pytest golden-set (20 labelled tasks + size guard). Skips cleanly
without ANTHROPIC_API_KEY or COMPOSIO_API_KEY. Validated 21/21 passing.
Multi-model agent routing with 7 agent nodes (Sonnet, Haiku,
GPT-4.1, Gemini, DeepSeek) and 15 pre-loaded Composio tools
for Slack, Notion, GitHub, and Google Drive integration.