#!/usr/bin/env python3 """Read, acknowledge, restore intent, unlock one Agent, then call the fixed connector.""" import argparse import json import os import subprocess import sys import urllib.error import urllib.request BASE_URL = "http://127.0.0.1:8031" CONNECTOR = "/usr/local/sbin/guanghu-fixed-agent-connector" def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("--intent-state", required=True) parser.add_argument("--principal-id", required=True) parser.add_argument("--subject-kind", required=True, choices=("human", "persona", "persona_system")) parser.add_argument("--human-anchor", required=True) parser.add_argument("--agent-id", required=True) parser.add_argument("--action", required=True) parser.add_argument("--target-node-id", required=True) parser.add_argument("--execute", action="store_true") return parser.parse_args() def request_json(path, token="", headers=None, payload=None): request_headers = dict(headers or {}) if token: request_headers["X-Lighthouse-Admin-Token"] = token data = None method = "GET" if payload is not None: request_headers["Content-Type"] = "application/json" data = json.dumps(payload).encode() method = "POST" request = urllib.request.Request( BASE_URL + path, data=data, method=method, headers=request_headers, ) try: with urllib.request.urlopen(request, timeout=10) as response: return json.load(response) except urllib.error.HTTPError as error: print("Gate rejected %s with HTTP %d." % (path, error.code), file=sys.stderr) raise SystemExit(4) except (OSError, ValueError) as error: print("Gate request failed: %s" % error, file=sys.stderr) raise SystemExit(4) def main(): args = parse_args() token = os.environ.get("LIGHTHOUSE_ADMIN_TOKEN", "") if not token: print("LIGHTHOUSE_ADMIN_TOKEN is required in the process environment.", file=sys.stderr) raise SystemExit(3) with open(args.intent_state, encoding="utf-8") as handle: capsule = json.load(handle) identity_headers = { "X-Guanghu-Principal-Id": args.principal_id, "X-Guanghu-Subject-Kind": args.subject_kind, "X-Guanghu-Human-Anchor": args.human_anchor, } navigation = request_json("/v2/global-navigation-map") acknowledged = request_json( "/v1/navigation-map/ack", token=token, headers=identity_headers, payload={"map_hash": navigation["map_hash"]}, ) if not acknowledged.get("ok"): raise SystemExit(4) restored = request_json( "/v1/intent-state/restore", token=token, headers=identity_headers, payload=capsule, ) if not restored.get("ok"): raise SystemExit(4) unlocked = request_json( "/v1/agents/unlock", token=token, headers=identity_headers, payload={ "agent_id": args.agent_id, "action": args.action, "target_node_id": args.target_node_id, }, ) unlock_id = unlocked.get("unlock_id", "") if not unlock_id: raise SystemExit(4) if not args.execute: print(unlock_id) return completed = subprocess.run( [ CONNECTOR, "--unlock-id", unlock_id, "--principal-id", args.principal_id, "--subject-kind", args.subject_kind, "--human-anchor", args.human_anchor, "--agent-id", args.agent_id, "--action", args.action, "--target-node-id", args.target_node_id, ], check=False, ) raise SystemExit(completed.returncode) if __name__ == "__main__": main()