diff --git a/agent-team/README.md b/agent-team/README.md index 8219fe1..59fac93 100644 --- a/agent-team/README.md +++ b/agent-team/README.md @@ -43,10 +43,18 @@ agent-team/ # Gemini via the orchestrator's models.py); bind_multi_invoker() api.py # WS1 FastAPI HTTP API (bearer auth, 127.0.0.1:8765) — SEPARATE # opt-in process (api.serve()), NOT started by the coordinator + dashboard.py # read-only LAN status dashboard (FastAPI, 0.0.0.0:8770): + # /api/state /api/topology /api/task/{id} + serves web/dist SPA + topology.py # pipeline map derived from the compiled LangGraph + # (get_graph() + NODE_META sidecar) — new agents appear auto + status_page.py # read-only DATA LAYER for /api/state (build_snapshot / + # snapshot_to_dict); HTML rendering retired in the makeover billing.py # §3.1 claude_invoke billing-mode seam ci_gate.py # §3.3.2 pure-code authenticated-Checks PASS/FAIL gate task_model.py / state_store.py db/{schema.py,schema.sql} # SQLite ledger DDL + BEGIN IMMEDIATE compare-and-set + db/transitions.py # task_transitions recorder (per-task pipeline history, + # idempotent + fail-soft; written by instrumented graph nodes) ledger.py / responder.py / resume_worker.py / deadline_timer.py / recovery.py operator_cli.py nodes/ # pipeline stages + their model bindings @@ -64,9 +72,11 @@ agent-team/ slack_adapter.py + slack_live.py + slack_listener.py # Block Kit + Socket Mode + /new-task github_adapter.py + github_live.py + github_intake.py # issue-comment + issue intake claude_code_adapter.py + claude_code_live.py # file-drop responder + web/ # React/Vite/TypeScript status-dashboard SPA (React Flow map, + # task list, click-through task history); built to web/dist scripts/ # deploy-r720-ws-rollout.sh — attended WS0–WS5 UPDATE of the box ci/ # §3.3.2 split-job CI apply/verify workflow (DEPLOY-GATED) - systemd/ # agent-team-coordinator.service (not installed) + systemd/ # agent-team-coordinator.service + agent-team-status.service DEPLOY-R720.md # provisioning runbook (snapshot-first, rsync, tokens, demo) tests/ # pytest, one module per source module + sim harness ``` @@ -98,6 +108,37 @@ snake_case (`agent_team/`), per the engineering handbook. GPT-4.1 (review) and DeepSeek (builders) route through the local orchestrator `run.py`. Switching Claude billing is a config flip. +## Status dashboard (WebUI) + +A read-only LAN dashboard (FastAPI, `0.0.0.0:8770`, no auth, `mode=ro` ledger +opens) for watching the pipeline. Served by `agent_team.dashboard` (systemd unit +`agent-team-status.service`): + +- **Live pipeline map** — a React Flow graph **auto-laid-out from the real + LangGraph** (`topology.py` introspects `compiled.get_graph()` + a `NODE_META` + display sidecar). Adding an agent node in `graph.py` makes it appear on the map + with no manual coordinates; nodes group into **trees** (processes) branching off + `intake`. Node color = live state; loop-back edges (review→plan, verify→build) + render dashed. +- **Click-through task history** — selecting a task opens a timeline of its journey + through each node (entry/exit timestamps, per-node duration, per-stage cost, Q&A, + verdicts, plan), backed by the `task_transitions` ledger (schema v3) written by + the coordinator's instrumented graph nodes (`db/transitions.py`, fail-soft). + +Endpoints: `GET /api/state` (live overview + per-node state), `GET /api/topology` +(map nodes/edges/trees), `GET /api/task/{thread_id}` (one task's history; +`thread_id` is validated `^[A-Za-z0-9_-]{1,64}$`). The legacy stdlib HTML page was +retired; `status_page.py` remains as the `/api/state` data layer. + +**Build (on the Mac — the box Node is too old for Vite 5+):** +``` +cd agent-team/web +npm ci && npm run build # -> web/dist (gitignored), rsynced to the VM +npm test # Vitest + React Testing Library +``` +In dev, `npm run dev` proxies `/api` to a locally running dashboard +(`AGENT_TEAM_DASH`, default `http://127.0.0.1:8770`). + ## WS0–WS5 rollout glossary The "WS-rollout" (workstreams 0–5) layered HTTP/integration surfaces onto the diff --git a/agent-team/systemd/agent-team-status.service b/agent-team/systemd/agent-team-status.service index a131972..9eb6aa8 100644 --- a/agent-team/systemd/agent-team-status.service +++ b/agent-team/systemd/agent-team-status.service @@ -1,15 +1,20 @@ # agent-team-status.service - R720 LAN-only READ-ONLY status dashboard (sh-secrev VM, user adam). # -# A tiny stdlib http.server that renders the agent-team coordinator's queue -# (tasks/phases, who is waiting on the human gate, active/parked counts, recent -# budget spend) as a 10s-auto-refresh HTML page. It opens the SQLite ledger -# READ-ONLY (mode=ro) and never writes; it has no mutating endpoints and no auth. +# Serves the React/Vite single-page dashboard (web/dist) + its read-only JSON API +# (/api/state, /api/topology, /api/task/{id}) via FastAPI/uvicorn. The map renders +# the live pipeline (auto-laid from the real LangGraph), and a task can be clicked +# to see its history through each node. It opens the SQLite ledger READ-ONLY +# (mode=ro) and never writes; it has no mutating endpoints and no auth. # -# NETWORK POSTURE: binds AGENT_TEAM_STATUS_HOST (default 0.0.0.0) on port -# AGENT_TEAM_STATUS_PORT (default 8770). The sh-secrev VM (10.10.60.120, VLAN 60) -# has NO public NIC and sits behind the UniFi firewall, so 0.0.0.0 reaches the -# LAN/VPN only. Task descriptions may be sensitive -> keep this LAN/VPN-only, -# never expose to the public internet. +# NETWORK POSTURE: binds 0.0.0.0 on port 8770. The sh-secrev VM (10.10.60.120, +# VLAN 60) has NO public NIC and sits behind the UniFi firewall, so 0.0.0.0 +# reaches the LAN/VPN only. Task descriptions may be sensitive -> keep this +# LAN/VPN-only, never expose to the public internet. +# +# BUILD: the SPA is built on the Mac (`cd web && npm ci && npm run build`) and the +# resulting web/dist is rsynced to the VM (the box Node is too old for a Vite 5+ +# build). uvicorn serves whatever web/dist is present; if absent, the JSON API +# still works and the SPA 404s until dist is deployed. # # Install (on the VM, as root): # sudo cp agent-team-status.service /etc/systemd/system/ @@ -35,9 +40,10 @@ WorkingDirectory=/home/adam/orchestrator/agent-team # as the coordinator lets AGENT_TEAM_DB / AGENT_TEAM_STATUS_* overrides live in # one place if set there. EnvironmentFile=-/home/adam/secrev.env -# Use the agent-team venv interpreter (where langgraph + the checkpoint dep are -# installed), NOT the bare system python3 that systemd's PATH would resolve. -ExecStart=/home/adam/orchestrator/agent-team/.venv/bin/python -c "from agent_team.status_page import serve; serve()" +# Use the agent-team venv interpreter (where langgraph + fastapi/uvicorn + the +# checkpoint dep are installed), NOT the bare system python3 that systemd's PATH +# would resolve. +ExecStart=/home/adam/orchestrator/agent-team/.venv/bin/python -c "from agent_team.dashboard import serve; serve()" Restart=on-failure RestartSec=5 # Hardening - mirrors agent-team-coordinator.service, but this unit only READS