|
| 1 | +--- |
| 2 | +name: agents |
| 3 | +description: Agent swarm development dashboard — live Railway containers, issue queue, PR pipeline, JSONL events, pool utilization, and queue drain status. Use when checking agent dev tasks, spawning status, or monitoring issues #315-#319. |
| 4 | +argument-hint: [focus] (status, queue, events, pools, spawn <N>, full) |
| 5 | +--- |
| 6 | + |
| 7 | +# 🤖 Agent Swarm Observatory |
| 8 | + |
| 9 | +## 📡 Railway Service Pools (Live) |
| 10 | +!`curl -s -X POST "https://backboard.railway.com/graphql/v2" -H "Authorization: Bearer $(grep RAILWAY_API_TOKEN /Users/playra/trinity-w1/.env | cut -d= -f2)" -H "Content-Type: application/json" -d '{"query":"query($id:String!){project(id:$id){services{edges{node{id name deployments(first:1){edges{node{status createdAt}}}}}}}}","variables":{"id":"aa0efa7f-95e6-4466-8de6-43945a031365"}}' 2>/dev/null | python3 -c " |
| 11 | +import sys,json,datetime |
| 12 | +d=json.load(sys.stdin) |
| 13 | +nodes=[e['node'] for e in d['data']['project']['services']['edges']] |
| 14 | +total=len(nodes) |
| 15 | +agents=[n for n in nodes if n['name'].startswith('agent-')] |
| 16 | +pool0='acfee27a-74e8-4436-961c-698ae93508ca' |
| 17 | +pool1='12c2bdf9-d124-4a45-93ad-22921e842d1b' |
| 18 | +p0=[n for n in nodes if n['id']==pool0] |
| 19 | +p1=[n for n in nodes if n['id']==pool1] |
| 20 | +def st(n): |
| 21 | + if n['deployments']['edges']: |
| 22 | + return n['deployments']['edges'][0]['node']['status'] |
| 23 | + return 'NO_DEPLOY' |
| 24 | +print(json.dumps({ |
| 25 | + 'total_services': total, |
| 26 | + 'pool_0_ubuntu': {'id': pool0[:8], 'status': st(p0[0]) if p0 else 'NOT_FOUND'}, |
| 27 | + 'pool_1_agents_anywhere': {'id': pool1[:8], 'status': st(p1[0]) if p1 else 'NOT_FOUND'}, |
| 28 | + 'agent_services': [{'name':n['name'],'status':st(n)} for n in agents], |
| 29 | + 'active_building': len([n for n in nodes if st(n) in ('DEPLOYING','BUILDING')]), |
| 30 | + 'slots_used': len(agents), |
| 31 | + 'slots_free': 10-len(agents) |
| 32 | +}, indent=2)) |
| 33 | +" 2>/dev/null || echo "⚠️ Railway API unavailable"` |
| 34 | + |
| 35 | +## 📋 Agent Issues (agent:spawn + agent:queued) |
| 36 | +!`echo "=== SPAWNING ==="; gh issue list --repo gHashTag/trinity --label "agent:spawn" --state open --limit 20 --json number,title,labels,assignees,createdAt --jq '.[] | "#\(.number) \(.title) [\(.labels | map(.name) | join(","))] \(.createdAt[:10])"' 2>&1 || echo "gh unavailable"; echo ""; echo "=== QUEUED ==="; gh issue list --repo gHashTag/trinity --label "agent:queued" --state open --limit 20 --json number,title,createdAt --jq '.[] | "#\(.number) \(.title) \(.createdAt[:10])"' 2>&1 || echo "none"` |
| 37 | + |
| 38 | +## 🔀 Agent PRs (feat/issue- branches) |
| 39 | +!`gh pr list --repo gHashTag/trinity --state open --limit 15 --json number,title,headRefName,statusCheckRollup --jq '.[] | select(.headRefName | startswith("feat/issue-")) | "#\(.number) [\(.headRefName)] \(.title) checks:\(.statusCheckRollup | if . then (. | map(.conclusion // .status) | join(",")) else "none" end)"' 2>&1 || echo "No agent PRs"` |
| 40 | + |
| 41 | +## 📡 Recent Events (last 25 lines) |
| 42 | +!`if [ -f /Users/playra/trinity-w1/.trinity/cloud_events.jsonl ]; then tail -25 /Users/playra/trinity-w1/.trinity/cloud_events.jsonl | python3 -c " |
| 43 | +import sys,json |
| 44 | +for line in sys.stdin: |
| 45 | + line=line.strip() |
| 46 | + if not line: continue |
| 47 | + try: |
| 48 | + e=json.loads(line) |
| 49 | + ts=e.get('timestamp','?')[:19] |
| 50 | + typ=e.get('type','?') |
| 51 | + iss=e.get('issue','?') |
| 52 | + msg=e.get('message',e.get('event','')) |
| 53 | + emoji={'spawn':'🚀','kill':'💀','heartbeat':'💓','error':'❌','pr':'🔀','build':'🔨','test':'🧪','complete':'✅','queued':'⏳'}.get(typ,'📌') |
| 54 | + print(f'{ts} {emoji} #{iss} [{typ}] {msg}') |
| 55 | + except: print(line) |
| 56 | +" 2>/dev/null; else echo "No cloud events yet"; fi` |
| 57 | + |
| 58 | +## 🔄 GitHub Actions (agent workflows) |
| 59 | +!`gh run list --repo gHashTag/trinity --workflow agent-spawn.yml --limit 5 --json databaseId,status,conclusion,createdAt,headBranch --jq '.[] | "\(.createdAt[:16]) \(if .conclusion == "success" then "✅" elif .conclusion == "failure" then "❌" elif .status == "in_progress" then "🔄" else "⏳" end) \(.status)/\(.conclusion // "—") \(.headBranch // "—")"' 2>&1 || echo "No spawn runs"; echo "---"; gh run list --repo gHashTag/trinity --workflow agent-queue-drain.yml --limit 3 --json status,conclusion,createdAt --jq '.[] | "\(.createdAt[:16]) \(if .conclusion == "success" then "✅" else "⏳" end) drain: \(.status)/\(.conclusion // "—")"' 2>&1 || echo "No drain runs"` |
| 60 | + |
| 61 | +## 🏗️ Container Image |
| 62 | +!`gh api user/packages/container/trinity-agent/versions --jq '.[0] | "📦 trinity-agent:latest — updated \(.updated_at[:10]) tags: \(.metadata.container.tags | join(","))"' 2>/dev/null || echo "⚠️ GHCR package not accessible"` |
| 63 | + |
| 64 | +## 📊 Local Agent State |
| 65 | +!`if [ -f /Users/playra/trinity-w1/.trinity/cloud_agents.json ]; then cat /Users/playra/trinity-w1/.trinity/cloud_agents.json | python3 -c " |
| 66 | +import sys,json,datetime |
| 67 | +d=json.load(sys.stdin) |
| 68 | +agents=d if isinstance(d,list) else d.get('agents',[]) |
| 69 | +active=[a for a in agents if a.get('active',False)] |
| 70 | +inactive=[a for a in agents if not a.get('active',False)] |
| 71 | +print(f'Active: {len(active)}/{len(agents)}') |
| 72 | +for a in active: |
| 73 | + iss=a.get('issue','?') |
| 74 | + sid=a.get('service_id','?')[:8] |
| 75 | + ts=a.get('created_at','?') |
| 76 | + print(f' 🟢 #{iss} svc:{sid} started:{ts}') |
| 77 | +for a in inactive[-3:]: |
| 78 | + iss=a.get('issue','?') |
| 79 | + print(f' ⚪ #{iss} (done)') |
| 80 | +" 2>/dev/null; else echo "No local state file"; fi` |
| 81 | + |
| 82 | +## 🎯 Issue → Pool Mapping (round-robin) |
| 83 | +!`echo "Pool 0 (ubuntu/acfee27a): even issues"; echo "Pool 1 (Agents Anywhere/12c2bdf9): odd issues"; echo "---"; gh issue list --repo gHashTag/trinity --label "agent:spawn" --state open --limit 20 --json number,title --jq '.[] | "#\(.number) → Pool \(.number % 2) \(if .number % 2 == 0 then "(ubuntu)" else "(Agents Anywhere)" end) — \(.title[:60])"' 2>&1 || echo "gh unavailable"` |
| 84 | + |
| 85 | +## Task |
| 86 | + |
| 87 | +Analyze the data above and present a **rich Agent Swarm dashboard** with emojis. |
| 88 | + |
| 89 | +Focus area: $ARGUMENTS (default: status) |
| 90 | + |
| 91 | +### Dashboard Format |
| 92 | + |
| 93 | +ALWAYS output the full dashboard — never compress to one line. Use this format: |
| 94 | + |
| 95 | +``` |
| 96 | +🤖 ═══════════════════════════════════════════════════ |
| 97 | + TRINITY AGENT SWARM — DEVELOPMENT OBSERVATORY |
| 98 | + ═══════════════════════════════════════════════════ |
| 99 | +
|
| 100 | +📡 SERVICE POOLS |
| 101 | + Pool 0 (ubuntu): [status emoji] [deployment status] |
| 102 | + Pool 1 (Agents Anywhere): [status emoji] [deployment status] |
| 103 | + Active builds: N | Free slots: N/10 |
| 104 | +
|
| 105 | +📋 ISSUE QUEUE |
| 106 | + 🚀 Spawning: |
| 107 | + #N — title — pool — status |
| 108 | + ⏳ Queued: |
| 109 | + #N — title — waiting since [date] |
| 110 | +
|
| 111 | + Queue depth: N spawning + N queued = N total |
| 112 | +
|
| 113 | +🔀 AGENT PRs |
| 114 | + #N — [branch] — title — checks: [status] |
| 115 | + ... |
| 116 | + Open: N | Merged today: N |
| 117 | +
|
| 118 | +📡 LIVE EVENTS (last 10) |
| 119 | + [timestamp] [emoji] #issue [type] message |
| 120 | + ... |
| 121 | +
|
| 122 | +🔄 GITHUB ACTIONS |
| 123 | + agent-spawn: [last 5 runs with status] |
| 124 | + queue-drain: [last 3 runs with status] |
| 125 | +
|
| 126 | +🗺️ POOL MAPPING (round-robin: issue# % 2) |
| 127 | + Pool 0 (even): #316, #318, ... |
| 128 | + Pool 1 (odd): #315, #317, #319, ... |
| 129 | + ⚠️ Contention: N issues compete for Pool X |
| 130 | +
|
| 131 | +📦 INFRASTRUCTURE |
| 132 | + GHCR image: [status + last updated] |
| 133 | + Local state: N active / N total agents |
| 134 | + Events log: N entries |
| 135 | +
|
| 136 | +🎯 RECOMMENDATIONS |
| 137 | + [dynamic recommendations based on current state — see rules below] |
| 138 | +
|
| 139 | +⏱️ ESTIMATED PIPELINE |
| 140 | + [time estimate for queue drain based on 2 pools × ~1h per agent] |
| 141 | +``` |
| 142 | + |
| 143 | +### Recommendation Rules |
| 144 | + |
| 145 | +**If both pools DEPLOYING/BUILDING:** |
| 146 | +→ "⚠️ Both pools busy. Queue drain runs every 5min. ETA for next slot: ~Xmin" |
| 147 | +→ Show which issues are running vs queued |
| 148 | + |
| 149 | +**If 1 pool free:** |
| 150 | +→ "🟢 Pool N free — next queued issue #M will auto-spawn via drain" |
| 151 | +→ "💡 Manual: `tri cloud spawn <N>` to skip queue" |
| 152 | + |
| 153 | +**If both pools free + queued issues:** |
| 154 | +→ "🟢🟢 Both pools idle! Queue drain should trigger in ≤5min" |
| 155 | +→ "💡 Manual: add `agent:spawn` label or run `tri cloud spawn <N>`" |
| 156 | + |
| 157 | +**If both pools free + no queued issues:** |
| 158 | +→ "✅ All clear. Ready for new agent tasks." |
| 159 | +→ Suggest: check `gh issue list --label agent:spawn` |
| 160 | + |
| 161 | +**Contention warnings:** |
| 162 | +→ If >2 issues map to same pool: "⚠️ Pool X has N issues queued — sequential processing ~Nh" |
| 163 | +→ Suggest rebalancing or manual spawn on other pool |
| 164 | + |
| 165 | +### Queue ETA Calculation |
| 166 | +- Each agent takes ~1h (AGENT_TIMEOUT=3600s) |
| 167 | +- 2 pools = 2 parallel agents |
| 168 | +- Queue ETA = ceil(queued_issues / 2) × 1h |
| 169 | +- Show: "⏱️ 5 issues ÷ 2 pools = ~3h total (2+2+1)" |
| 170 | + |
| 171 | +### Issue Status Tracking |
| 172 | +For each tracked issue, show: |
| 173 | +- 🔵 SPAWNING — container starting |
| 174 | +- 🟢 RUNNING — claude code active |
| 175 | +- 🟡 SELF-REVIEW — build/test/format |
| 176 | +- 🔀 PR CREATED — waiting for review |
| 177 | +- ✅ MERGED — done |
| 178 | +- ❌ FAILED — needs attention |
| 179 | +- ⏳ QUEUED — waiting for pool slot |
| 180 | + |
| 181 | +### If focus=spawn <N> |
| 182 | +Trigger: `tri cloud spawn <N>` and show result. |
| 183 | + |
| 184 | +### If focus=events |
| 185 | +Show full event log (last 50 lines) with parsed JSONL. |
| 186 | + |
| 187 | +### If focus=pools |
| 188 | +Deep dive into Railway API: service details, deployment history, env vars check. |
0 commit comments