Files
aios/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/serialization.py
T

117 lines
4.8 KiB
Python

"""JSON serialization helpers for candidate API and CLI boundaries."""
from __future__ import annotations
from datetime import datetime
from typing import Any, Mapping
from .models import ReleasePlan, ResourceBinding, RiskClass, TaskPlan, WorkflowStep
def task_plan_from_mapping(value: Mapping[str, Any]) -> TaskPlan:
binding_value = value["binding"]
binding = ResourceBinding(
repository=str(binding_value["repository"]),
branch=str(binding_value["branch"]),
base_oid=str(binding_value["base_oid"]),
allowed_paths=tuple(str(item) for item in binding_value.get("allowed_paths", ())),
)
steps = tuple(
WorkflowStep(
step_id=str(item["step_id"]),
worker_role=str(item["worker_role"]),
required_capabilities=tuple(str(cap) for cap in item.get("required_capabilities", ())),
depends_on=tuple(str(dep) for dep in item.get("depends_on", ())),
max_attempts=int(item.get("max_attempts", 1)),
timeout_seconds=int(item.get("timeout_seconds", 900)),
allowed_paths=tuple(str(path) for path in item.get("allowed_paths", ())),
)
for item in value.get("steps", ())
)
created_at_raw = value.get("created_at")
created_at = datetime.fromisoformat(created_at_raw) if created_at_raw else None
kwargs: dict[str, Any] = {
"task_id": str(value["task_id"]),
"intent": str(value["intent"]),
"binding": binding,
"risk": RiskClass(str(value.get("risk", RiskClass.MEDIUM.value))),
"steps": steps,
"evidence_requirements": tuple(str(item) for item in value.get("evidence_requirements", ())),
"production_side_effects_allowed": bool(value.get("production_side_effects_allowed", False)),
}
if created_at is not None:
kwargs["created_at"] = created_at
return TaskPlan(**kwargs)
def task_plan_to_mapping(plan: TaskPlan) -> dict[str, Any]:
return {
"task_id": plan.task_id,
"intent": plan.intent,
"binding": {
"repository": plan.binding.repository,
"branch": plan.binding.branch,
"base_oid": plan.binding.base_oid,
"allowed_paths": list(plan.binding.allowed_paths),
},
"risk": plan.risk.value,
"steps": [
{
"step_id": step.step_id,
"worker_role": step.worker_role,
"required_capabilities": list(step.required_capabilities),
"depends_on": list(step.depends_on),
"max_attempts": step.max_attempts,
"timeout_seconds": step.timeout_seconds,
"allowed_paths": list(step.allowed_paths),
}
for step in plan.steps
],
"evidence_requirements": list(plan.evidence_requirements),
"production_side_effects_allowed": plan.production_side_effects_allowed,
"created_at": plan.created_at.isoformat(),
"plan_digest": plan.digest(),
}
def release_plan_from_mapping(value: Mapping[str, Any]) -> ReleasePlan:
return ReleasePlan(
task_id=str(value["task_id"]),
repository=str(value["repository"]),
branch=str(value["branch"]),
version=str(value["version"]),
target_oid=str(value["target_oid"]),
tree_oid=str(value["tree_oid"]),
artifact_sha256=str(value["artifact_sha256"]),
manifest_sha256=str(value["manifest_sha256"]),
package_closure_sha256=str(value["package_closure_sha256"]),
evidence_closure_oid=str(value["evidence_closure_oid"]),
approval_plan_id=str(value["approval_plan_id"]),
rollback_approval_plan_id=str(value["rollback_approval_plan_id"]),
rollback_artifact_sha256=str(value["rollback_artifact_sha256"]),
expected_tag_oid=str(value["expected_tag_oid"]),
expected_target_oid=str(value["expected_target_oid"]),
production_config_sha256=str(value["production_config_sha256"]),
)
def release_plan_to_mapping(plan: ReleasePlan) -> dict[str, Any]:
return {
"task_id": plan.task_id,
"repository": plan.repository,
"branch": plan.branch,
"version": plan.version,
"target_oid": plan.target_oid,
"tree_oid": plan.tree_oid,
"artifact_sha256": plan.artifact_sha256,
"manifest_sha256": plan.manifest_sha256,
"package_closure_sha256": plan.package_closure_sha256,
"evidence_closure_oid": plan.evidence_closure_oid,
"approval_plan_id": plan.approval_plan_id,
"rollback_approval_plan_id": plan.rollback_approval_plan_id,
"rollback_artifact_sha256": plan.rollback_artifact_sha256,
"expected_tag_oid": plan.expected_tag_oid,
"expected_target_oid": plan.expected_target_oid,
"production_config_sha256": plan.production_config_sha256,
}