Coverage for little_loops / fsm / types.py: 100%
31 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-05-22 16:19 -0500
« prev ^ index » next coverage.py v7.12.0, created at 2026-05-22 16:19 -0500
1"""FSM result types for loop and action execution."""
3from __future__ import annotations
5from collections.abc import Callable
6from dataclasses import dataclass
7from typing import TYPE_CHECKING, Any
9if TYPE_CHECKING:
10 from little_loops.fsm.evaluators import EvaluationResult
11 from little_loops.fsm.interpolation import InterpolationContext
12 from little_loops.fsm.schema import EvaluateConfig
15@dataclass
16class ExecutionResult:
17 """Result from FSM execution.
19 Attributes:
20 final_state: Name of the state when execution stopped
21 iterations: Total iterations executed
22 terminated_by: Reason for termination (terminal, max_iterations, timeout, signal, error, handoff)
23 duration_ms: Total execution time in milliseconds
24 captured: All captured variable values
25 error: Error message if terminated_by is "error"
26 handoff: True if execution stopped due to handoff signal
27 continuation_prompt: Continuation context from handoff signal
28 """
30 final_state: str
31 iterations: int
32 terminated_by: str # "terminal", "max_iterations", "timeout", "signal", "error", "handoff", "cycle_detected"
33 duration_ms: int
34 captured: dict[str, dict[str, Any]]
35 error: str | None = None
36 handoff: bool = False
37 continuation_prompt: str | None = None
39 def to_dict(self) -> dict[str, Any]:
40 """Convert to dictionary for JSON serialization."""
41 result: dict[str, Any] = {
42 "final_state": self.final_state,
43 "iterations": self.iterations,
44 "terminated_by": self.terminated_by,
45 "duration_ms": self.duration_ms,
46 "captured": self.captured,
47 }
48 if self.error is not None:
49 result["error"] = self.error
50 if self.handoff:
51 result["handoff"] = self.handoff
52 if self.continuation_prompt is not None:
53 result["continuation_prompt"] = self.continuation_prompt
54 return result
57@dataclass
58class ActionResult:
59 """Result from action execution.
61 Attributes:
62 output: stdout from the action
63 stderr: stderr from the action
64 exit_code: Exit code from the action
65 duration_ms: Execution time in milliseconds
66 """
68 output: str
69 stderr: str
70 exit_code: int
71 duration_ms: int
74# Type for event callback
75EventCallback = Callable[[dict[str, Any]], None]
77# Type for evaluator functions
78# Parameter order: config, output, exit_code, context — matches evaluate() call signature
79Evaluator = Callable[
80 ["EvaluateConfig", str, int, "InterpolationContext"],
81 "EvaluationResult",
82]