Files
aios/automation/central_gpt_health_probe.py
T

87 lines
2.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""Prove a real central-model decision through the authenticated Gateway."""
from __future__ import annotations
import argparse
import time
from pathlib import Path
import uuid
from health_probe_common import (
ProbeError, atomic_receipt, gateway_base, load_config, read_token,
request_json, state_version,
)
def run(config_path: Path) -> int:
config = load_config(config_path)
endpoint = config["gateway_event_url"]
gateway_base(endpoint)
token = read_token(Path(config["gateway_token_file"]))
project = config["project_key"]
contract = config["contract_commit"]
event_id = "health-central-" + uuid.uuid4().hex
version = state_version(endpoint, project, token)
event = {
"schema_version": 1,
"project_key": project,
"contract_commit": contract,
"event_id": event_id,
"source_agent": "system",
"event_type": "central_gpt_health_probe",
"work_unit_id": "CENTRAL-GPT-HEALTH",
"status": "READY",
"state_version": version,
"implementation_commit": None,
"result_commit": None,
"blocker": None,
"evidence_refs": [],
"payload": {"probe": "side_effect_free", "nonce": event_id},
}
status, _ = request_json(endpoint, token, method="POST", payload=event)
if status not in {200, 202}:
raise ProbeError("event_not_accepted")
deadline = time.monotonic() + int(config["central_timeout_seconds"])
observed = None
while time.monotonic() < deadline:
_, observed = request_json(endpoint + "/" + event_id, token)
if observed.get("status") in {"DECIDED", "TRIGGER_FAILED"}:
break
time.sleep(float(config["poll_interval_seconds"]))
if not isinstance(observed, dict) or observed.get("status") != "DECIDED" or observed.get("decision_applied") is not True:
raise ProbeError("central_decision_not_proven")
channel = observed.get("trigger_channel")
if channel not in {"workspace_agent", "responses_api"}:
raise ProbeError("central_channel_not_proven")
now = int(time.time())
atomic_receipt(
Path(config["central_receipt_path"]),
{
"subject": "central_gpt",
"health": "HEALTHY",
"live_probe_succeeded": True,
"observed_at_epoch": now,
"event_id": event_id,
"decision_applied": True,
"state_version_after": observed["state_version_after"],
"workspace_agent": {"validated_live": channel == "workspace_agent"},
"responses_api": {"validated_live": channel == "responses_api"},
},
)
return 0
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--config", required=True, type=Path)
args = parser.parse_args()
try:
return run(args.config)
except (KeyError, OSError, ProbeError, ValueError):
return 1
if __name__ == "__main__":
raise SystemExit(main())