fix(collab): separate courier presence from model state
This commit is contained in:
parent
359e11fe6f
commit
01e8c2ec5c
9 changed files with 82 additions and 8 deletions
|
|
@ -87,6 +87,7 @@ def scan() -> dict[str, Any]:
|
|||
hosts: list[dict[str, Any]] = []
|
||||
for host in registry["hosts"]:
|
||||
endpoint = Path(host["endpoint"])
|
||||
presence_path = endpoint.parent / "presence/CURRENT.json"
|
||||
host_events: list[dict[str, Any]] = []
|
||||
if endpoint.is_dir():
|
||||
for path in sorted(endpoint.glob("*.json")):
|
||||
|
|
@ -109,6 +110,16 @@ def scan() -> dict[str, Any]:
|
|||
heartbeat = next((item for item in reversed(host_events) if item["event_type"] == "HEARTBEAT"), None)
|
||||
decision = next((item for item in reversed(host_events) if item["event_type"] in contract.get("autonomous_decision_event_types", [])), None)
|
||||
latest = host_events[-1] if host_events else None
|
||||
presence = None
|
||||
presence_age = None
|
||||
if presence_path.is_file() and not presence_path.is_symlink() and presence_path.stat().st_size <= 16_384:
|
||||
try:
|
||||
candidate = load(presence_path)
|
||||
if candidate.get("schema") == "guanghu.heartbeat-multipath-courier-presence/v1" and candidate.get("development_id") == host["development_id"] and candidate.get("authority_granted") is False:
|
||||
presence = candidate
|
||||
presence_age = max(0.0, (datetime.now().astimezone() - datetime.fromisoformat(candidate["updated_at"])).total_seconds())
|
||||
except Exception:
|
||||
presence = None
|
||||
heartbeat_age = None
|
||||
if heartbeat:
|
||||
heartbeat_age = max(0.0, (datetime.now().astimezone() - datetime.fromisoformat(heartbeat["emitted_at"])).total_seconds())
|
||||
|
|
@ -116,10 +127,12 @@ def scan() -> dict[str, Any]:
|
|||
operational_state = "NOT_JOINED"
|
||||
elif decision and decision["event_type"] in {"PAUSE", "BLOCKED", "EXIT", "RESUME_REQUEST"}:
|
||||
operational_state = decision["event_type"]
|
||||
elif heartbeat_age is None or heartbeat_age > 120:
|
||||
operational_state = "COURIER_HEARTBEAT_STALE_MODEL_STATE_UNKNOWN"
|
||||
elif presence_age is not None and presence_age <= 45 and (heartbeat_age is None or heartbeat_age > 120):
|
||||
operational_state = "COURIER_ONLINE_MODEL_COGNITION_STALE_OR_UNKNOWN"
|
||||
elif presence_age is None or presence_age > 45:
|
||||
operational_state = "COURIER_PRESENCE_STALE_MODEL_STATE_UNKNOWN"
|
||||
else:
|
||||
operational_state = "COURIER_ONLINE_MODEL_STATE_FROM_EVENT_ONLY"
|
||||
operational_state = "COURIER_AND_MODEL_EVENT_RECENT"
|
||||
hosts.append({
|
||||
"host": host["host"],
|
||||
"development_id": host["development_id"],
|
||||
|
|
@ -131,6 +144,9 @@ def scan() -> dict[str, Any]:
|
|||
"last_event_at": latest and latest["emitted_at"],
|
||||
"last_heartbeat_at": heartbeat and heartbeat["emitted_at"],
|
||||
"heartbeat_age_seconds": heartbeat_age,
|
||||
"presence_path": str(presence_path),
|
||||
"courier_presence_age_seconds": presence_age,
|
||||
"courier_presence_fresh": presence_age is not None and presence_age <= 45,
|
||||
"operational_state": operational_state,
|
||||
"last_autonomous_decision": decision and {key: decision.get(key) for key in ["event_id", "event_type", "emitted_at", "payload", "evidence"]},
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue