40 lines
1.6 KiB
Python
40 lines
1.6 KiB
Python
"""Task-Lebenszyklus (→ Konzept 9.2). Übergänge werden serverseitig geprüft."""
|
|
|
|
from app.core.errors import Invalid
|
|
|
|
QUEUED = "queued"
|
|
RUNNING = "running"
|
|
WAITING_APPROVAL = "waiting_approval"
|
|
WAITING_INPUT = "waiting_input"
|
|
COMPLETED = "completed"
|
|
FAILED = "failed"
|
|
CANCELLED = "cancelled"
|
|
BLOCKED_BY_GUARDRAIL = "blocked_by_guardrail"
|
|
NEEDS_RECONCILIATION = "needs_reconciliation"
|
|
|
|
TRANSITIONS: dict[str, set[str]] = {
|
|
QUEUED: {RUNNING, CANCELLED},
|
|
RUNNING: {QUEUED, WAITING_APPROVAL, WAITING_INPUT, COMPLETED, FAILED, CANCELLED, BLOCKED_BY_GUARDRAIL,
|
|
NEEDS_RECONCILIATION},
|
|
WAITING_APPROVAL: {QUEUED, CANCELLED},
|
|
WAITING_INPUT: {QUEUED, CANCELLED},
|
|
NEEDS_RECONCILIATION: {QUEUED, FAILED},
|
|
FAILED: {QUEUED},
|
|
COMPLETED: set(),
|
|
CANCELLED: set(),
|
|
BLOCKED_BY_GUARDRAIL: set(),
|
|
}
|
|
|
|
# Zustände, in denen ein Run ohne weiteres Zutun nichts mehr tut (für das Ende eines SSE-Streams)
|
|
RESTING = {WAITING_APPROVAL, WAITING_INPUT, COMPLETED, FAILED, CANCELLED, BLOCKED_BY_GUARDRAIL,
|
|
NEEDS_RECONCILIATION}
|
|
FINAL = {COMPLETED, CANCELLED, BLOCKED_BY_GUARDRAIL}
|
|
|
|
LABELS = {QUEUED: "wartet", RUNNING: "läuft", WAITING_APPROVAL: "wartet auf Freigabe", WAITING_INPUT: "wartet auf Eingabe",
|
|
COMPLETED: "fertig", FAILED: "fehlgeschlagen", CANCELLED: "abgebrochen",
|
|
BLOCKED_BY_GUARDRAIL: "blockiert (Guardrail)", NEEDS_RECONCILIATION: "Abgleich nötig"}
|
|
|
|
|
|
def check(current: str, target: str) -> None:
|
|
if target not in TRANSITIONS[current]:
|
|
raise Invalid(f"Übergang {current} → {target} ist nicht erlaubt.")
|