93 lines
2.3 KiB
Python
93 lines
2.3 KiB
Python
"""Readable runtime values shared by Workflow orchestration modules."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from enum import StrEnum
|
|
from typing import Any
|
|
|
|
|
|
class WorkflowStatus(StrEnum):
|
|
"""The small set of states useful to operators and future debug tooling."""
|
|
|
|
STARTING = "starting"
|
|
WAITING_USER = "waiting_user"
|
|
ROUTING = "routing"
|
|
RUNNING_AGENT = "running_agent"
|
|
RUNNING_ACTION = "running_action"
|
|
RUNNING_MESSAGE = "running_message"
|
|
HANDOFF = "handoff"
|
|
ENDED = "ended"
|
|
|
|
|
|
class RouteStatus(StrEnum):
|
|
"""A routing error is deliberately different from a valid no-match."""
|
|
|
|
MATCHED = "matched"
|
|
NO_MATCH = "no_match"
|
|
ERROR = "error"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class UserTurn:
|
|
"""One committed user turn that may cross automatic Workflow nodes."""
|
|
|
|
id: int
|
|
text: str
|
|
|
|
|
|
@dataclass
|
|
class WorkflowRuntimeState:
|
|
"""Mutable per-call state; graph definitions remain immutable."""
|
|
|
|
current_node_id: str
|
|
status: WorkflowStatus = WorkflowStatus.STARTING
|
|
pending_user_turn: UserTurn | None = None
|
|
transition_id: int = 0
|
|
automatic_hops: int = 0
|
|
ended: bool = False
|
|
_next_turn_id: int = 1
|
|
|
|
def begin_user_turn(self, text: str) -> UserTurn:
|
|
turn = UserTurn(id=self._next_turn_id, text=text)
|
|
self._next_turn_id += 1
|
|
self.pending_user_turn = turn
|
|
self.automatic_hops = 0
|
|
return turn
|
|
|
|
def enter(self, node_id: str, status: WorkflowStatus) -> None:
|
|
self.current_node_id = node_id
|
|
self.status = status
|
|
|
|
def begin_transition(self) -> int:
|
|
self.transition_id += 1
|
|
return self.transition_id
|
|
|
|
def consume_user_turn(self) -> UserTurn | None:
|
|
turn = self.pending_user_turn
|
|
self.pending_user_turn = None
|
|
return turn
|
|
|
|
def finish(self) -> None:
|
|
self.ended = True
|
|
self.status = WorkflowStatus.ENDED
|
|
self.pending_user_turn = None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class LLMRouteResult:
|
|
"""Control-plane result returned by the small routing LLM."""
|
|
|
|
status: RouteStatus
|
|
function_name: str | None = None
|
|
error: str | None = None
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class EdgeEvaluation:
|
|
"""Final graph-level decision after expression, LLM and default handling."""
|
|
|
|
status: RouteStatus
|
|
edge: dict[str, Any] | None = None
|
|
error: str | None = None
|