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.
21 lines
512 B
Python
21 lines
512 B
Python
from typing import Annotated, Literal
|
|
from typing_extensions import TypedDict
|
|
from langgraph.graph.message import add_messages
|
|
from langchain_core.messages import AnyMessage
|
|
|
|
|
|
class OrchestratorState(TypedDict):
|
|
messages: Annotated[list[AnyMessage], add_messages]
|
|
task: str
|
|
route: Literal[
|
|
"implementer",
|
|
"reviewer",
|
|
"researcher",
|
|
"cross_reviewer",
|
|
"scanner",
|
|
"fast_coder",
|
|
"connector",
|
|
"done",
|
|
"unknown",
|
|
]
|
|
result: str
|