Files
state-hub/api/task_status.py

85 lines
2.3 KiB
Python

from __future__ import annotations
from typing import Any
CANONICAL_TASK_STATUSES: tuple[str, ...] = (
"wait",
"todo",
"progress",
"done",
"cancel",
)
TASK_STATUS_CODES: dict[str, str] = {
"WAIT": "wait",
"TODO": "todo",
"PROG": "progress",
"DONE": "done",
"CNCL": "cancel",
}
LEGACY_TASK_STATUS_ALIASES: dict[str, str] = {
"blocked": "wait",
"waiting": "wait",
"in_progress": "progress",
"in-progress": "progress",
"prog": "progress",
"cancelled": "cancel",
"canceled": "cancel",
"cncl": "cancel",
}
OPEN_TASK_STATUSES: frozenset[str] = frozenset({"wait", "todo", "progress"})
ACTIVE_TASK_STATUSES: frozenset[str] = frozenset({"wait", "progress"})
TERMINAL_TASK_STATUSES: frozenset[str] = frozenset({"done", "cancel"})
TASK_STATUS_ORDER: dict[str, int] = {
"todo": 0,
"wait": 1,
"progress": 1,
"done": 2,
"cancel": 2,
}
TASK_STATUS_LABELS: dict[str, str] = {
"wait": "wait",
"todo": "todo",
"progress": "progress",
"done": "done",
"cancel": "cancel",
}
def raw_status_value(status: Any) -> str:
if hasattr(status, "value"):
status = status.value
return str(status or "").strip()
def normalize_task_status(status: Any, *, default: str | None = None) -> str:
"""Normalize canon task statuses plus legacy aliases to stored values."""
value = raw_status_value(status).lower()
if not value:
if default is not None:
return default
raise ValueError("task status is required")
value = LEGACY_TASK_STATUS_ALIASES.get(value, value)
if value not in CANONICAL_TASK_STATUSES:
allowed = ", ".join(CANONICAL_TASK_STATUSES)
aliases = ", ".join(sorted(LEGACY_TASK_STATUS_ALIASES))
raise ValueError(f"task status must be one of {allowed}; legacy aliases: {aliases}")
return value
def status_value(status: Any, *, default: str | None = None) -> str:
"""Compatibility wrapper used by lifecycle and reconciliation code."""
return normalize_task_status(status, default=default)
def is_open_task_status(status: Any) -> bool:
return normalize_task_status(status, default="todo") in OPEN_TASK_STATUSES
def is_terminal_task_status(status: Any) -> bool:
return normalize_task_status(status, default="todo") in TERMINAL_TASK_STATUSES