state_machine.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435
  1. """Legal task transitions for explicit validation."""
  2. from __future__ import annotations
  3. from typing import Dict, FrozenSet
  4. from .models import TaskStatus
  5. class InvalidTaskTransition(ValueError):
  6. pass
  7. LEGAL_TRANSITIONS: Dict[TaskStatus, FrozenSet[TaskStatus]] = {
  8. TaskStatus.PENDING: frozenset({TaskStatus.RUNNING, TaskStatus.WAITING_CHILDREN, TaskStatus.BLOCKED, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  9. TaskStatus.RUNNING: frozenset({TaskStatus.AWAITING_VALIDATION, TaskStatus.NEEDS_REPLAN, TaskStatus.BLOCKED, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  10. TaskStatus.AWAITING_VALIDATION: frozenset({TaskStatus.VALIDATING, TaskStatus.NEEDS_REPLAN, TaskStatus.BLOCKED, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  11. TaskStatus.VALIDATING: frozenset({TaskStatus.AWAITING_DECISION, TaskStatus.NEEDS_REPLAN, TaskStatus.BLOCKED, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  12. TaskStatus.AWAITING_DECISION: frozenset({TaskStatus.COMPLETED, TaskStatus.PENDING, TaskStatus.WAITING_CHILDREN, TaskStatus.BLOCKED, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  13. TaskStatus.NEEDS_REPLAN: frozenset({TaskStatus.PENDING, TaskStatus.RUNNING, TaskStatus.VALIDATING, TaskStatus.WAITING_CHILDREN, TaskStatus.BLOCKED, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  14. TaskStatus.WAITING_CHILDREN: frozenset({TaskStatus.NEEDS_REPLAN, TaskStatus.BLOCKED, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  15. TaskStatus.BLOCKED: frozenset({TaskStatus.NEEDS_REPLAN, TaskStatus.CANCELLED, TaskStatus.SUPERSEDED}),
  16. TaskStatus.COMPLETED: frozenset(),
  17. TaskStatus.CANCELLED: frozenset(),
  18. TaskStatus.SUPERSEDED: frozenset(),
  19. }
  20. def transition(current: TaskStatus, target: TaskStatus) -> TaskStatus:
  21. if target not in LEGAL_TRANSITIONS[current]:
  22. raise InvalidTaskTransition(f"Illegal task transition: {current.value} -> {target.value}")
  23. return target
  24. __all__ = ["InvalidTaskTransition", "LEGAL_TRANSITIONS", "transition"]