Files
ai-video-fullstack/backend/services/workflow/models.py
Xin Wang bdf3d3dd9c Refactor workflow agent and routing components for improved functionality
- Introduce WorkflowAgentStage to manage agent stage configurations and enhance interaction with the workflow engine.
- Implement WorkflowEdgeEvaluator for priority-aware edge evaluation, improving routing decisions based on conditions and user turns.
- Update WorkflowBrain to handle user turns and routing more effectively, ensuring agents cannot have only one default path.
- Enhance CallEndCoordinator to track speech events and manage call termination based on queued speech.
- Add new models and output handling for workflow interactions, improving clarity and maintainability.
- Update tests to validate the new routing logic and agent behavior under various scenarios.
2026-07-17 22:37:15 +08:00

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"
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