| """State schema: everything the loop, tools and LLM share flows through here."""
|
| from __future__ import annotations
|
|
|
| from dataclasses import dataclass, field, asdict
|
| from typing import Any, Literal, Optional
|
|
|
|
|
| @dataclass
|
| class StepRecord:
|
| step: int
|
| thought: str
|
| action: Optional[dict]
|
| observation: str
|
| progress: Literal["progress", "no_progress", "n/a"]
|
| replanned: bool = False
|
| replan_reason: str = ""
|
|
|
|
|
| @dataclass
|
| class AgentState:
|
| task: str
|
| steps: list[StepRecord] = field(default_factory=list)
|
| scratchpad: dict[str, Any] = field(default_factory=dict)
|
| best_known_answer: Optional[str] = None
|
| status: Literal["running", "completed", "partial", "failed"] = "running"
|
| stop_reason: str = ""
|
|
|
| def to_report(self, budget_snapshot: dict) -> dict:
|
| return {
|
| "task": self.task,
|
| "status": self.status,
|
| "stop_reason": self.stop_reason,
|
| "final_answer": self.best_known_answer,
|
| "steps_completed": len(self.steps),
|
| "replanning_events": [
|
| {"step": s.step, "reason": s.replan_reason}
|
| for s in self.steps if s.replanned
|
| ],
|
| "budget": budget_snapshot,
|
| "trace": [asdict(s) for s in self.steps],
|
| }
|
|
|