45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""HTTP integration helpers for canonical Task projection recovery.
|
|
|
|
This module intentionally contains no HTTP server. Existing Task Plane /
|
|
projection-owner handlers should call ``recover_from_json`` only after their
|
|
normal service-side ``agent-task:control`` authorization succeeds.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any, Mapping
|
|
|
|
from aios_agent_task_projection_recovery import (
|
|
CanonicalTaskProjectionIntent,
|
|
CanonicalTaskProjectionStore,
|
|
ProjectionRecoveryError,
|
|
)
|
|
|
|
|
|
def recover_from_json(
|
|
db_path: Path | str,
|
|
task_id: str,
|
|
body: Mapping[str, Any],
|
|
) -> tuple[int, dict[str, Any]]:
|
|
try:
|
|
intent = CanonicalTaskProjectionIntent.from_mapping(body)
|
|
if intent.task.task_id != task_id:
|
|
raise ProjectionRecoveryError("PROJECTION_TASK_IDENTITY_MISMATCH", 409)
|
|
result = CanonicalTaskProjectionStore(db_path).reconcile(intent)
|
|
return (200 if result.get("idempotent") else 201), result
|
|
except ProjectionRecoveryError as exc:
|
|
return exc.status, {"error": exc.code}
|
|
|
|
|
|
def get_projection(
|
|
db_path: Path | str,
|
|
task_id: str,
|
|
) -> tuple[int, dict[str, Any]]:
|
|
try:
|
|
result = CanonicalTaskProjectionStore(db_path).get_projection(task_id)
|
|
except ProjectionRecoveryError as exc:
|
|
return exc.status, {"error": exc.code}
|
|
if result is None:
|
|
return 404, {"error": "TASK_PROJECTION_NOT_FOUND"}
|
|
return 200, result
|