KI-Konzil/backend/state.py
Claude 797f02c74d
Implement Phase 1: LangGraph backend MVP
Sets up the full backend foundation for CouncilOS:

- CouncilState TypedDict with all required fields and LangGraph reducers
- Three agent nodes: master_agent (drafts), critic_agent (scores + routes),
  writer_agent (final polish)
- LangGraph graph with cyclic rework loop: Master → Critic → (score < 8:
  back to Master | score ≥ 8: Writer → END)
- Safety valve: MAX_ITERATIONS=5 prevents infinite loops
- FastAPI app with REST endpoints (POST /api/councils/run, GET /api/councils/run/{id})
  and WebSocket endpoint (/ws/council/{run_id}) for real-time agent status events
- In-memory RunStore for Phase 1 (PostgreSQL-backed in Phase 3)
- pytest test suite: state, routing logic, critic parser, agent nodes, API endpoints
- .env.example, .gitignore, docker-compose.yml, Dockerfile

https://claude.ai/code/session_01RfMpt3TbMjZEtK3CAyP5iQ
2026-02-20 16:33:39 +00:00

47 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
CouncilState — the central data structure passed between all agents in LangGraph.
All agents must read from and write to this TypedDict. Agents must not store
state internally; everything passes through CouncilState.
"""
from typing import Annotated, List, Optional
import operator
from typing_extensions import TypedDict
class CouncilState(TypedDict):
"""
The global state shared across all agents in a council run.
Fields:
input_topic: The user's original prompt or uploaded PDF content.
current_draft: The document currently being worked on.
feedback_history: All critic feedback accumulated across loop iterations.
Agents append here — never overwrite.
route_decision: Routing signal used by conditional edges.
Values: "rework" | "approve" | custom strings.
messages: LLM message history (system prompts + responses).
Uses operator.add reducer so messages accumulate.
iteration_count: Tracks how many rework loops have occurred.
critic_score: The numeric score (010) assigned by the critic agent.
run_id: Unique identifier for this council run (for WebSocket events).
active_node: Name of the currently executing agent node (for UI updates).
"""
input_topic: str
current_draft: str
feedback_history: Annotated[List[str], operator.add]
route_decision: str
messages: Annotated[list, operator.add]
iteration_count: int
critic_score: Optional[float]
run_id: str
active_node: str
# Approval threshold: critic score must reach this value to exit the loop
APPROVAL_THRESHOLD = 8.0
# Safety limit: maximum number of rework iterations before forcing approval
MAX_ITERATIONS = 5