Files
aios/active-runtime/app/agent_pull_runner_cli.py
T
AIOS Governed Continuation f557f18620 feat(governed): ANNEX-2.3 R2 agent auto-claim chain (SchedulabilityProof→recheck→claim→pull→receipt)
Implement governed auto-claim loop on task_plane:
- SchedulabilityProof model (5-segment persisted diagnostic snapshot) + ProofBuilder
- authoritative_claim_recheck (A23: cross-tenant/task/generation/lease/capacity)
- SchedulingService wiring TaskScheduler to HTTP long_poll/poll/schedule
- governed_claim single-transaction (proof→recheck→claim→receipt→event)
- HttpRunnerTransport (real transport, renew with claim_id self-resolution)
- AgentPullRunner discover_once handles idle/no-task (REQ-03c)
- receipt/readback endpoints (/proofs, /receipts, /tasks/{id}/receipts)

Pure stdlib, no new deps; 25 tests pass (22 R2 + 2 heartbeat + 1 idle). Base: 3c320ae.
2026-09-14 14:37:42 +08:00

56 lines
2.4 KiB
Python

"""Small operational CLI for the Agent Pull Runner contract.
Default mode talks to a live governed TaskPlane HTTP API via HttpRunnerTransport
(--base-url / --token). --self-test keeps an in-process stub transport for
offline smoke checks.
"""
from __future__ import annotations
import argparse
import json
from agent_pull_runner import AgentPullRunner, RunnerConfig
from task_plane.http_transport import HttpRunnerTransport
class _NoopTransport:
def register_worker(self, worker_id, capabilities): return {"status": "registered", "worker_id": worker_id, "capabilities": list(capabilities)}
def heartbeat(self, worker_id): return {"status": "alive", "worker_id": worker_id}
def long_poll(self, worker_id, timeout_seconds): return None
def poll(self, worker_id): return None
def claim(self, worker_id, task): return task
def renew(self, worker_id, task_id): return {"status": "renewed", "task_id": task_id}
def report_progress(self, worker_id, task_id, payload): return {"status": "progress_recorded", "task_id": task_id}
def report_result(self, worker_id, task_id, payload): return {"status": "result_recorded", "task_id": task_id}
def report_evidence(self, worker_id, task_id, payload): return {"status": "evidence_recorded", "task_id": task_id}
def main() -> int:
parser = argparse.ArgumentParser(description="AIOS Agent Pull Runner")
parser.add_argument("--worker-id", default="self-test-worker")
parser.add_argument("--base-url", default="http://127.0.0.1:8000")
parser.add_argument("--token", default="")
parser.add_argument("--actor-identity", default="")
parser.add_argument("--self-test", action="store_true")
args = parser.parse_args()
if args.self_test:
transport = _NoopTransport()
else:
transport = HttpRunnerTransport(
args.base_url,
token=args.token,
actor_identity=args.actor_identity or None,
)
runner = AgentPullRunner(
RunnerConfig(worker_id=args.worker_id, fallback_seconds=60), transport
)
if args.self_test:
print(json.dumps({"status": "PASS", "registration": runner.register(), "fallback_seconds": runner.config.fallback_seconds}, sort_keys=True))
return 0
print(json.dumps({"status": "READY", "worker_id": args.worker_id, "base_url": args.base_url}, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())