@buihongduc132/pi-acp-agents 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +311 -211
- package/index.ts +309 -41
- package/package.json +1 -1
- package/src/acp-widget.ts +197 -0
- package/src/config/config.ts +9 -0
- package/src/config/types.ts +96 -0
- package/src/dag/dag-executor.ts +966 -0
- package/src/dag/dag-store.ts +408 -0
- package/src/dag/dag-validator.ts +202 -0
- package/src/dag/template-resolver.ts +174 -0
- package/src/management/governance-store.ts +10 -3
- package/src/management/legacy-migration.ts +79 -0
- package/src/management/mailbox-manager.ts +10 -3
- package/src/management/runtime-paths.ts +18 -7
- package/src/management/session-archive-store.ts +1 -1
- package/src/management/session-store-factory.ts +58 -0
- package/src/management/task-store.ts +10 -3
- package/src/management/worker-store.ts +10 -3
- package/src/settings/config.ts +3 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @buihongduc132/pi-acp-agents
|
|
2
2
|
|
|
3
|
-
> Multi-agent orchestration for pi — spawn, control, and coordinate ACP-compatible agents (Gemini CLI, Claude, Codex,
|
|
3
|
+
> Multi-agent orchestration for pi — spawn, control, and coordinate ACP-compatible agents (Gemini CLI, Claude, Codex, custom) as first-class tools within the pi coding agent.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@buihongduc132/pi-acp-agents)
|
|
6
6
|
[](https://github.com/buihongduc132/pi-acp-agents/actions/workflows/ci.yml)
|
|
@@ -8,26 +8,97 @@
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [What works vs what does not](#what-works-vs-what-does-not) ← **read this first**
|
|
14
|
+
- [Install](#install)
|
|
15
|
+
- [Quick start](#quick-start)
|
|
16
|
+
- [Tool surface](#tool-surface)
|
|
17
|
+
- [DAG delegation](#dag-delegation)
|
|
18
|
+
- [Alias resolver + fallback chains](#alias-resolver--fallback-chains)
|
|
19
|
+
- [Persistent workers](#persistent-workers)
|
|
20
|
+
- [Configuration](#configuration)
|
|
21
|
+
- [Architecture](#architecture)
|
|
22
|
+
- [Resilience](#resilience)
|
|
23
|
+
- [Logs](#logs)
|
|
24
|
+
- [Supported agents](#supported-agents)
|
|
25
|
+
- [Development](#development)
|
|
26
|
+
- [Release process](#release-process)
|
|
27
|
+
- [Further documentation](#further-documentation)
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## What works vs what does not
|
|
32
|
+
|
|
33
|
+
Status as of `0.4.0`. Verified by full test suite (`npx vitest run` → 1627 passed / 0 failed / 83 skipped / 1 todo). Counts: **16 tools registered** (verified via `rg -c 'pi.registerTool' index.ts`), **42 entries** in `ACP_TOOL_NAMES` legacy schema.
|
|
34
|
+
|
|
35
|
+
### ✅ Working
|
|
36
|
+
|
|
37
|
+
| Capability | Notes |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `acp_prompt` (single agent) | Session create / reuse / archive-reload |
|
|
40
|
+
| `acp_status` (diagnostic) | Agent list, sessions, circuit breaker |
|
|
41
|
+
| `acp_cancel` (in-flight prompt abort) | Calls `adapter.cancel()`, archives handle |
|
|
42
|
+
| `acp_broadcast` (one prompt → N agents) | Scoped to caller session's agents |
|
|
43
|
+
| `acp_task_create` / `acp_task_update` | Multiplexed: status / assignee / deps / bulk `*` filter |
|
|
44
|
+
| `acp_message` (send + list) | DM / steer / broadcast via `kind` param |
|
|
45
|
+
| `acp_dag_submit` / `acp_dag_status` / `acp_dag_cancel` | Wave-based topological DAG execution, persistent resume |
|
|
46
|
+
| `acp_worker_spawn` / `_list` / `_steer` / `_shutdown` / `_kill` / `_prune` | Persistent named workers in `WorkerStore` |
|
|
47
|
+
| **Alias resolver** (failover + race) | `AliasResolver` class — sequential fallback OR parallel first-wins with cancel of losers |
|
|
48
|
+
| **Circuit breaker** | 3 failures → open, 60s → half-open, auto-recover |
|
|
49
|
+
| **Health monitor** | 30s background polling; distinct no-response vs completed-idle timers |
|
|
50
|
+
| **Session-scoped stores** | `tasks`/`mailboxes`/`governance`/`workers` partitioned per host session ID; `session-archive`/`session-name-registry`/`event-log` global |
|
|
51
|
+
| **Legacy migration** | Non-destructive flat → `legacy/` on first run after partitioning |
|
|
52
|
+
| **DAG widget** | `dagIndexEntryToWidgetDag` helper renders DAG state in TUI |
|
|
53
|
+
| **TUI widget** | Real-time session + DAG status panel |
|
|
54
|
+
| **Gemini CLI adapter** | Auto-auth, default |
|
|
55
|
+
| **Custom adapter** | Any ACP-speaking stdio agent |
|
|
56
|
+
| **Stall timeout** | Per-op with SIGTERM → SIGKILL escalation |
|
|
57
|
+
| **EPIPE safety** | stdin/stdout broken-pipe handled |
|
|
58
|
+
| **Tag-triggered CI publish** | `git push --follow-tags` → npm publish with provenance |
|
|
59
|
+
|
|
60
|
+
### ❌ Not working / not implemented
|
|
61
|
+
|
|
62
|
+
| Gap | Status |
|
|
63
|
+
|---|---|
|
|
64
|
+
| **One-call parallel batch delegate** | No `acp_delegate_parallel` — must `acp_worker_spawn` × N + `acp_prompt` × N |
|
|
65
|
+
| **Plan approval flow as tool** | `acp_plan_request` / `acp_plan_resolve` are command-only stubs, not tools |
|
|
66
|
+
| **Hooks policy** | No `hooks_policy_*` — retry governance absent |
|
|
67
|
+
| **Model policy as tool** | `acp_model_policy_get` / `_check` are command-only |
|
|
68
|
+
| **Predefined teams** | No `predefined_teams_*` |
|
|
69
|
+
| **Workspace isolation (worktree mode)** | Workers use `cwd` only — no `git worktree` isolation |
|
|
70
|
+
| **Context inheritance** | No `contextMode: "branch"` (clone leader session) |
|
|
71
|
+
| **`task_dep_ls`** | Only add/rm via `task_update` — cannot list blockers |
|
|
72
|
+
| **`task_get` (single)** | Not exposed — only create + update |
|
|
73
|
+
| **Diagnostics as tools** | `acp_doctor`, `acp_runtime_info`, `acp_event_log`, `acp_env`, `acp_cleanup` are slash commands only |
|
|
74
|
+
| **Session lifecycle tools** | `acp_session_list` / `_shutdown` / `_kill` / `_prune` / `_set_model` / `_set_mode` are not exposed (automation-only) |
|
|
75
|
+
| **Streaming responses** | Planned — currently returns after full prompt completes |
|
|
76
|
+
| **Tool use forwarding** | Planned — ACP agent tool calls not relayed back to pi |
|
|
77
|
+
| **OAuth / token auth** | Planned — env vars only |
|
|
78
|
+
| **Config hot-reload** | Manual restart required |
|
|
79
|
+
| **Retry with backoff** | Circuit breaker handles fail-closed; no exponential backoff |
|
|
80
|
+
| **Session sharing across pi instances** | Single-host only |
|
|
81
|
+
| **Metrics export (Prometheus)** | Planned |
|
|
82
|
+
| **Agent routing (auto-select)** | Manual via alias or explicit |
|
|
83
|
+
| **Ensemble / chain-of-agents** | Manual via DAG composition |
|
|
84
|
+
| **Cost tracking** | Planned |
|
|
85
|
+
| **Claude Code / Codex ACP adapters** | Pending upstream ACP mode |
|
|
86
|
+
|
|
87
|
+
### ⚠️ Known surface drift
|
|
88
|
+
|
|
89
|
+
`src/settings/config.ts` ships a legacy `ACP_TOOL_NAMES` array of **42 entries** (a settings toggle schema) while only **16 tools are actually registered** in `index.ts`. The 26-entry delta is NOT missing tools — it is the per-tool enable/disable toggle schema for `/acp settings`. See [`../pi-plugins/flow/intentions/pi-acp-agents/tool-consolidation.md`](https://github.com/buihongduc132/pi-plugins/blob/main/flow/intentions/pi-acp-agents/tool-consolidation.md) for the planned consolidation (42 → 7 multiplexed tools).
|
|
19
90
|
|
|
20
91
|
---
|
|
21
92
|
|
|
22
|
-
##
|
|
93
|
+
## Install
|
|
23
94
|
|
|
24
|
-
### For
|
|
95
|
+
### For humans
|
|
25
96
|
|
|
26
97
|
```bash
|
|
27
98
|
npm install @buihongduc132/pi-acp-agents
|
|
28
99
|
```
|
|
29
100
|
|
|
30
|
-
### For AI
|
|
101
|
+
### For AI agents
|
|
31
102
|
|
|
32
103
|
Add to `~/.pi/agent/settings.json`:
|
|
33
104
|
|
|
@@ -37,29 +108,13 @@ Add to `~/.pi/agent/settings.json`:
|
|
|
37
108
|
}
|
|
38
109
|
```
|
|
39
110
|
|
|
40
|
-
Or
|
|
41
|
-
|
|
42
|
-
### Humans
|
|
111
|
+
Or:
|
|
43
112
|
|
|
44
113
|
```bash
|
|
45
114
|
pi install npm:@buihongduc132/pi-acp-agents
|
|
46
115
|
```
|
|
47
116
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
npm install @buihongduc132/pi-acp-agents
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### AI Agents (pip install)
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
pi install npm:@buihongduc132/pi-acp-agents
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### Git-sourced for pi
|
|
61
|
-
|
|
62
|
-
Add to `~/.pi/agent/settings.json`:
|
|
117
|
+
### Git-sourced
|
|
63
118
|
|
|
64
119
|
```json
|
|
65
120
|
{
|
|
@@ -69,32 +124,18 @@ Add to `~/.pi/agent/settings.json`:
|
|
|
69
124
|
}
|
|
70
125
|
```
|
|
71
126
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
git clone https://github.com/buihongduc132/pi-acp-agents.git
|
|
76
|
-
cd pi-acp-agents && npm install
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Then reference the local path in `settings.json`:
|
|
80
|
-
|
|
81
|
-
```json
|
|
82
|
-
{
|
|
83
|
-
"packages": ["/path/to/pi-acp-agents"]
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
```
|
|
127
|
+
---
|
|
87
128
|
|
|
88
|
-
## Quick
|
|
129
|
+
## Quick start
|
|
89
130
|
|
|
90
|
-
1.
|
|
131
|
+
1. Install an ACP agent (Gemini CLI default):
|
|
91
132
|
|
|
92
133
|
```bash
|
|
93
134
|
gemini --version
|
|
94
135
|
gemini # first run to authenticate
|
|
95
136
|
```
|
|
96
137
|
|
|
97
|
-
2.
|
|
138
|
+
2. (Optional) Configure:
|
|
98
139
|
|
|
99
140
|
```bash
|
|
100
141
|
mkdir -p ~/.pi/acp-agents
|
|
@@ -113,102 +154,138 @@ Then reference the local path in `settings.json`:
|
|
|
113
154
|
```
|
|
114
155
|
|
|
115
156
|
3. Use in pi:
|
|
157
|
+
|
|
116
158
|
```
|
|
117
159
|
Use the acp_prompt tool to ask gemini "What is the capital of France?"
|
|
118
160
|
```
|
|
119
161
|
|
|
120
|
-
|
|
162
|
+
For full usage patterns, DAG examples, alias configuration, and worker orchestration see [`docs/USAGE.md`](docs/USAGE.md).
|
|
121
163
|
|
|
122
|
-
|
|
164
|
+
---
|
|
123
165
|
|
|
124
|
-
|
|
166
|
+
## Tool surface
|
|
125
167
|
|
|
126
|
-
|
|
168
|
+
**16 tools registered** (gated by `/acp settings` per-tool toggles):
|
|
127
169
|
|
|
128
|
-
| Tool
|
|
129
|
-
|
|
130
|
-
| `acp_prompt` | Send a prompt to an ACP agent, get the text response
|
|
170
|
+
| Tool | Purpose |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `acp_prompt` | Send a prompt to an ACP agent, get the text response |
|
|
131
173
|
| `acp_status` | Show configured agents, active sessions, circuit breaker state |
|
|
174
|
+
| `acp_cancel` | Cancel an ongoing prompt by ID or friendly name |
|
|
175
|
+
| `acp_broadcast` | Send same prompt to multiple agents in parallel |
|
|
176
|
+
| `acp_task_create` | Create a persistent task in the runtime task store |
|
|
177
|
+
| `acp_task_update` | Multiplexed mutations: status, assignee, deps, result, bulk `*` |
|
|
178
|
+
| `acp_message` | Send or list messages (dm / steer / broadcast) |
|
|
179
|
+
| `acp_dag_submit` | Submit a DAG of tasks (validates, persists, starts background exec) |
|
|
180
|
+
| `acp_dag_status` | Get DAG state by `dagId`, or list all DAGs when called without it |
|
|
181
|
+
| `acp_dag_cancel` | Cancel a running DAG |
|
|
182
|
+
| `acp_worker_spawn` | Spawn a persistent named worker |
|
|
183
|
+
| `acp_worker_list` | List workers + status |
|
|
184
|
+
| `acp_worker_steer` | In-flight redirect — inject context mid-prompt |
|
|
185
|
+
| `acp_worker_shutdown` | Graceful shutdown |
|
|
186
|
+
| `acp_worker_kill` | Force kill |
|
|
187
|
+
| `acp_worker_prune` | Prune stale workers |
|
|
188
|
+
|
|
189
|
+
**Slash command surface** (`/acp ...`):
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
/acp session <new|load|list|shutdown|kill|prune|set-model|set-mode|cancel>
|
|
193
|
+
/acp prompt
|
|
194
|
+
/acp delegate
|
|
195
|
+
/acp broadcast
|
|
196
|
+
/acp compare
|
|
197
|
+
/acp task <create|list|get|assign|set-status|dep-add|dep-rm|clear>
|
|
198
|
+
/acp message <send|list>
|
|
199
|
+
/acp plan <request|resolve>
|
|
200
|
+
/acp runtime <status|config|env|info|event-log|cleanup|doctor>
|
|
201
|
+
/acp settings — configure tool visibility
|
|
202
|
+
Aliases: /acp-doctor, /acp-config
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
For tool-parameter reference and examples see [`docs/USAGE.md`](docs/USAGE.md).
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## DAG delegation
|
|
210
|
+
|
|
211
|
+
Submit a complete DAG of ACP agent tasks in a single call. The DAG executor:
|
|
212
|
+
- **Validates statically** (cycles, dangling refs, duplicate IDs, agent availability)
|
|
213
|
+
- **Persists state** to disk under `<runtimeDir>/dag/`
|
|
214
|
+
- **Executes in topological wave-order** (parallel within wave, serial across waves)
|
|
215
|
+
- **Resumes automatically** after pi restart (running steps retried, completed steps skipped)
|
|
216
|
+
|
|
217
|
+
### Submission JSON
|
|
132
218
|
|
|
133
|
-
|
|
219
|
+
```json
|
|
220
|
+
{
|
|
221
|
+
"tasks": [
|
|
222
|
+
{ "id": "analyze", "agent": "gemini", "prompt": "Analyze the codebase for security issues" },
|
|
223
|
+
{ "id": "fix", "agent": "claude", "prompt": "Fix the issues: {analyze.output}", "dependsOn": ["analyze"] },
|
|
224
|
+
{ "id": "verify", "agent": "gemini", "prompt": "Verify: {fix.output}", "dependsOn": ["fix"], "gate": "after" }
|
|
225
|
+
],
|
|
226
|
+
"args": { "project": "my-app" },
|
|
227
|
+
"options": { "failFast": true, "maxRetries": 0 },
|
|
228
|
+
"cwd": "/path/to/project"
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Template variables
|
|
134
233
|
|
|
135
|
-
|
|
|
136
|
-
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `acp_session_set_mode` | Change the mode (thinking level) for an active session by ID or friendly name |
|
|
141
|
-
| `acp_cancel` | Cancel an ongoing prompt by ID or friendly name |
|
|
234
|
+
| Variable | Resolves to |
|
|
235
|
+
|---|---|
|
|
236
|
+
| `{<step-id>.output}` | Output of referenced step (truncated to `dagOutputTruncateChars`) |
|
|
237
|
+
| `{<step-id>.status}` | Terminal status (`completed` / `failed` / `skipped` / `cancelled`) |
|
|
238
|
+
| `{dag.args.<key>}` | Workflow arg from `args` at submission |
|
|
142
239
|
|
|
143
|
-
|
|
240
|
+
Unresolvable variables fail the step at dispatch time.
|
|
144
241
|
|
|
145
|
-
|
|
146
|
-
| --------------- | ---------------------------------------------------- |
|
|
147
|
-
| `acp_delegate` | Delegate a task (short-lived session, auto-disposed) |
|
|
148
|
-
| `acp_broadcast` | Send same prompt to multiple agents in parallel |
|
|
149
|
-
| `acp_compare` | Get responses from multiple agents and compare them |
|
|
242
|
+
### Gates
|
|
150
243
|
|
|
151
|
-
|
|
244
|
+
| Gate | Behavior |
|
|
245
|
+
|---|---|
|
|
246
|
+
| `needs` (default) | **Success-gate** — all deps must `complete`. Failure cascades. |
|
|
247
|
+
| `after` | **Completion-gate** — deps just need a terminal state. Use for cleanup/verify steps. |
|
|
152
248
|
|
|
153
|
-
|
|
249
|
+
### Config
|
|
250
|
+
|
|
251
|
+
| Option | Default | Description |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| `dagStaleTimeoutMs` | `3_600_000` (1h) | No step transitions for this long → `stale` |
|
|
254
|
+
| `dagOutputTruncateChars` | `8000` | Max chars injected into downstream prompts |
|
|
255
|
+
|
|
256
|
+
For DAG executor internals, persistence model, and resume semantics see [`docs/USAGE.md`](docs/USAGE.md).
|
|
154
257
|
|
|
155
258
|
---
|
|
156
259
|
|
|
157
|
-
##
|
|
260
|
+
## Alias resolver + fallback chains
|
|
158
261
|
|
|
159
|
-
|
|
160
|
-
┌─────────────────────────────────────────────────┐
|
|
161
|
-
│ pi agent │
|
|
162
|
-
│ │
|
|
163
|
-
│ acp_prompt ──┐ │
|
|
164
|
-
│ acp_status ──┤ │
|
|
165
|
-
│ acp_session ─┤──► AgentCoordinator ──┐ │
|
|
166
|
-
│ acp_cancel ──┤ │ │
|
|
167
|
-
│ acp_compare ─┘ ▼ │
|
|
168
|
-
│ AcpCircuitBreaker │
|
|
169
|
-
│ │ │
|
|
170
|
-
│ ┌────────┴────────┐ │
|
|
171
|
-
│ │ Adapter Factory │ │
|
|
172
|
-
│ └────┬───────┬────┘ │
|
|
173
|
-
│ GeminiAdapter │ │
|
|
174
|
-
│ CustomAdapter │
|
|
175
|
-
│ │ │
|
|
176
|
-
│ AcpClient (stdio) │
|
|
177
|
-
│ │ │
|
|
178
|
-
│ HealthMonitor ◄──────┤
|
|
179
|
-
│ SessionManager │
|
|
180
|
-
└─────────────────────────────────────────────────┘
|
|
181
|
-
│
|
|
182
|
-
┌────────┴────────┐
|
|
183
|
-
│ ACP Agent (gemini│
|
|
184
|
-
│ --acp, claude, │
|
|
185
|
-
│ codex, custom) │
|
|
186
|
-
└─────────────────┘
|
|
187
|
-
```
|
|
262
|
+
Resolves an alias name to a concrete agent using configurable strategies. Used internally by `acp_prompt` / `acp_delegate` when called with an alias name.
|
|
188
263
|
|
|
189
|
-
|
|
264
|
+
| Strategy | Behavior |
|
|
265
|
+
|---|---|
|
|
266
|
+
| **failover** (sequential) | Try agents in order; first success wins; throws `AllAgentsFailedError` if all fail |
|
|
267
|
+
| **race** (parallel) | Send to all healthy agents in parallel; first success cancels losers (default race timeout 30s) |
|
|
268
|
+
|
|
269
|
+
Both strategies consult the circuit breaker (`isHealthyFn`) before dispatching and skip unhealthy agents.
|
|
190
270
|
|
|
191
|
-
|
|
192
|
-
| ------------------- | ----------------------------------------------------------- |
|
|
193
|
-
| **Adapter** (GoF) | `AcpAgentAdapter` → `GeminiAcpAdapter` / `CustomAcpAdapter` |
|
|
194
|
-
| **Factory** | `createAdapter()` — string dispatch |
|
|
195
|
-
| **Circuit Breaker** | Closed → Open → Half-Open with configurable thresholds |
|
|
196
|
-
| **Health Monitor** | Background polling with distinct 1-hour no-response and completed-idle auto-close |
|
|
197
|
-
| **Coordinator** | Multi-agent delegate/broadcast/compare |
|
|
271
|
+
For alias configuration schema and examples see [`docs/USAGE.md`](docs/USAGE.md).
|
|
198
272
|
|
|
199
273
|
---
|
|
200
274
|
|
|
201
|
-
##
|
|
275
|
+
## Persistent workers
|
|
276
|
+
|
|
277
|
+
Spawn long-lived named workers via `acp_worker_spawn`. Workers persist across task completions and are managed via:
|
|
278
|
+
|
|
279
|
+
| Tool | Purpose |
|
|
280
|
+
|---|---|
|
|
281
|
+
| `acp_worker_spawn` | Spawn worker + bind to ACP session + optional init prompt |
|
|
282
|
+
| `acp_worker_list` | List workers + status (online / offline / busy / disposed) |
|
|
283
|
+
| `acp_worker_steer` | In-flight redirect — inject context mid-prompt |
|
|
284
|
+
| `acp_worker_shutdown` | Graceful shutdown |
|
|
285
|
+
| `acp_worker_kill` | Force kill |
|
|
286
|
+
| `acp_worker_prune` | Prune stale workers |
|
|
202
287
|
|
|
203
|
-
|
|
204
|
-
| --------------- | ----------------- | ----------------------------------------------------------- |
|
|
205
|
-
| Circuit breaker | 3 failures → open | Auto-recovers after 60s in half-open state |
|
|
206
|
-
| Stall timeout | 1 hour | Per-operation timeout with SIGTERM→SIGKILL escalation |
|
|
207
|
-
| Health polling | 30s | Background monitor enforces separate no-response and completed-idle timers |
|
|
208
|
-
| Busy mutex | per-session | Prevents concurrent prompts on the same session |
|
|
209
|
-
| Process safety | SIGTERM→SIGKILL | Graceful process shutdown with escalation |
|
|
210
|
-
| EPIPE handling | stdin/stdout | Prevents crashes on broken pipes |
|
|
211
|
-
| Non-blocking | all paths | Errors return as tool error results, never unhandled throws |
|
|
288
|
+
Workers share the caller's filesystem (no `git worktree` isolation). For parallel worktree-isolated delegation use the `teams` pi-plugin instead.
|
|
212
289
|
|
|
213
290
|
---
|
|
214
291
|
|
|
@@ -219,15 +296,8 @@ Config file: `~/.pi/acp-agents/config.json`
|
|
|
219
296
|
```json
|
|
220
297
|
{
|
|
221
298
|
"agent_servers": {
|
|
222
|
-
"gemini": {
|
|
223
|
-
|
|
224
|
-
"args": ["--acp"],
|
|
225
|
-
"default_model": "gemini-2.5-pro"
|
|
226
|
-
},
|
|
227
|
-
"custom": {
|
|
228
|
-
"command": "/path/to/my-acp-agent",
|
|
229
|
-
"args": ["--mode", "acp"]
|
|
230
|
-
}
|
|
299
|
+
"gemini": { "command": "gemini", "args": ["--acp"], "default_model": "gemini-2.5-pro" },
|
|
300
|
+
"custom": { "command": "/path/to/my-acp-agent", "args": ["--mode", "acp"] }
|
|
231
301
|
},
|
|
232
302
|
"defaultAgent": "gemini",
|
|
233
303
|
"staleTimeoutMs": 3600000,
|
|
@@ -238,94 +308,116 @@ Config file: `~/.pi/acp-agents/config.json`
|
|
|
238
308
|
}
|
|
239
309
|
```
|
|
240
310
|
|
|
241
|
-
### Global
|
|
242
|
-
|
|
243
|
-
| Field
|
|
244
|
-
|
|
245
|
-
| `agent_servers`
|
|
246
|
-
| `defaultAgent`
|
|
247
|
-
| `staleTimeoutMs`
|
|
248
|
-
| `healthCheckIntervalMs`
|
|
249
|
-
| `circuitBreakerMaxFailures` | `3`
|
|
250
|
-
| `circuitBreakerResetMs`
|
|
251
|
-
| `stallTimeoutMs`
|
|
252
|
-
| `logsDir`
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
|
259
|
-
|
|
260
|
-
| `
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
311
|
+
### Global
|
|
312
|
+
|
|
313
|
+
| Field | Default | Description |
|
|
314
|
+
|---|---|---|
|
|
315
|
+
| `agent_servers` | `{ gemini: {...} }` | Map of agent name → config |
|
|
316
|
+
| `defaultAgent` | `"gemini"` | Agent used when not specified |
|
|
317
|
+
| `staleTimeoutMs` | `3600000` (1h) | Auto-close: stalled-no-response AND completed-idle |
|
|
318
|
+
| `healthCheckIntervalMs` | `30000` (30s) | Background health polling interval |
|
|
319
|
+
| `circuitBreakerMaxFailures` | `3` | Consecutive failures before circuit opens |
|
|
320
|
+
| `circuitBreakerResetMs` | `60000` (60s) | Time before circuit half-opens |
|
|
321
|
+
| `stallTimeoutMs` | `3600000` (1h) | Per-operation timeout |
|
|
322
|
+
| `logsDir` | `~/.pi/acp-agents/logs` | Log directory |
|
|
323
|
+
| `dagStaleTimeoutMs` | `3600000` | DAG stale threshold |
|
|
324
|
+
| `dagOutputTruncateChars` | `8000` | DAG downstream prompt truncation |
|
|
325
|
+
|
|
326
|
+
### Per-agent
|
|
327
|
+
|
|
328
|
+
| Field | Required | Description |
|
|
329
|
+
|---|---|---|
|
|
330
|
+
| `command` | **yes** | Executable to spawn |
|
|
331
|
+
| `args` | no | Args (e.g. `["--acp"]`) |
|
|
332
|
+
| `env` | no | Extra env vars |
|
|
333
|
+
| `cwd` | no | Working dir override |
|
|
334
|
+
| `default_model` | no | Default model ID |
|
|
335
|
+
|
|
336
|
+
For aliases, model policy, and runtime store paths see [`docs/USAGE.md`](docs/USAGE.md).
|
|
263
337
|
|
|
264
338
|
---
|
|
265
339
|
|
|
266
|
-
##
|
|
267
|
-
|
|
268
|
-
Central logs: `~/.pi/acp-agents/logs/`
|
|
269
|
-
|
|
270
|
-
- `main.log` — general structured JSON log
|
|
271
|
-
- `session-{id}/trace.jsonl` — per-session ACP JSON-RPC traces
|
|
340
|
+
## Architecture
|
|
272
341
|
|
|
273
|
-
|
|
342
|
+
```
|
|
343
|
+
┌─────────────────────────────────────────────────────┐
|
|
344
|
+
│ pi agent │
|
|
345
|
+
│ │
|
|
346
|
+
│ acp_prompt ──┐ │
|
|
347
|
+
│ acp_status ──┤ │
|
|
348
|
+
│ acp_cancel ──┤──► AliasResolver ──► Coordinator ──┐ │
|
|
349
|
+
│ acp_dag_* ───┤ │ │ │
|
|
350
|
+
│ acp_worker_* ┤ ▼ │ │
|
|
351
|
+
│ acp_message ─┤ AcpCircuitBreaker │ │
|
|
352
|
+
│ acp_task_* ──┘ │ │ │
|
|
353
|
+
│ ┌────────┴────────┐ │ │
|
|
354
|
+
│ │ Adapter Factory │ │ │
|
|
355
|
+
│ └────┬───────┬────┘ │ │
|
|
356
|
+
│ GeminiAdapter│ │ │
|
|
357
|
+
│ CustomAdapter │ │
|
|
358
|
+
│ │ │ │
|
|
359
|
+
│ AcpClient (stdio) │ │
|
|
360
|
+
│ │ │ │
|
|
361
|
+
│ HealthMonitor ◄───────┤ │
|
|
362
|
+
│ SessionManager │ │
|
|
363
|
+
│ DagStore + DagExecutor│ │
|
|
364
|
+
│ WorkerStore │ │
|
|
365
|
+
│ SessionStoreFactory │ │
|
|
366
|
+
└─────────────────────────────────────────────────────┘
|
|
367
|
+
```
|
|
274
368
|
|
|
275
|
-
|
|
369
|
+
### Patterns
|
|
276
370
|
|
|
277
|
-
|
|
|
278
|
-
|
|
279
|
-
| **
|
|
280
|
-
| **
|
|
281
|
-
| **
|
|
282
|
-
| **
|
|
371
|
+
| Pattern | Implementation |
|
|
372
|
+
|---|---|
|
|
373
|
+
| **Adapter** | `AcpAgentAdapter` → `GeminiAcpAdapter` / `CustomAcpAdapter` |
|
|
374
|
+
| **Factory** | `createAdapter()` — string dispatch |
|
|
375
|
+
| **Circuit breaker** | Closed → Open → Half-Open with configurable thresholds |
|
|
376
|
+
| **Health monitor** | Background polling; distinct no-response and completed-idle auto-close |
|
|
377
|
+
| **Coordinator** | Multi-agent delegate / broadcast / compare |
|
|
378
|
+
| **Alias resolver** | failover (sequential) + race (parallel first-wins) |
|
|
379
|
+
| **DAG executor** | Topological wave-execution + persistent resume |
|
|
380
|
+
| **Session-store factory** | Per-host-session lazy-instantiated stores (4 session-scoped + 3 global) |
|
|
283
381
|
|
|
284
382
|
---
|
|
285
383
|
|
|
286
|
-
##
|
|
287
|
-
|
|
288
|
-
### v0.2.x — Current (Foundation)
|
|
289
|
-
|
|
290
|
-
- [x] ACP stdio JSON-RPC client
|
|
291
|
-
- [x] Gemini CLI adapter with auto-auth
|
|
292
|
-
- [x] Session lifecycle (new, load, set model/mode, cancel)
|
|
293
|
-
- [x] Circuit breaker + health monitor
|
|
294
|
-
- [x] Multi-agent: delegate, broadcast, compare
|
|
295
|
-
- [x] TUI widget for session status
|
|
296
|
-
- [x] 148 unit + integration tests
|
|
297
|
-
- [x] CI/CD pipeline with provenance publishing
|
|
384
|
+
## Resilience
|
|
298
385
|
|
|
299
|
-
|
|
386
|
+
| Feature | Default | Description |
|
|
387
|
+
|---|---|---|
|
|
388
|
+
| Circuit breaker | 3 failures → open | Auto-recovers after 60s in half-open state |
|
|
389
|
+
| Stall timeout | 1 hour | Per-operation timeout with SIGTERM → SIGKILL escalation |
|
|
390
|
+
| Health polling | 30s | Background monitor with separate no-response and completed-idle timers |
|
|
391
|
+
| Busy mutex | per-session | Prevents concurrent prompts on the same session |
|
|
392
|
+
| Process safety | SIGTERM → SIGKILL | Graceful shutdown with escalation |
|
|
393
|
+
| EPIPE handling | stdin / stdout | Prevents crashes on broken pipes |
|
|
394
|
+
| Non-blocking | all paths | Errors return as tool error results, never unhandled throws |
|
|
395
|
+
| Alias failover | automatic | Sequential fallback on agent failure |
|
|
396
|
+
| Alias race | 30s timeout | Parallel first-wins with cancel of losers |
|
|
397
|
+
| DAG resume | on pi restart | `resumeAll()` discovers running DAGs, skips completed steps |
|
|
300
398
|
|
|
301
|
-
|
|
302
|
-
- [ ] **Tool use forwarding** — expose ACP agent tool calls back to pi's tool registry
|
|
303
|
-
- [ ] **OAuth/token auth** — support API key and OAuth flows per-agent
|
|
304
|
-
- [ ] **Config hot-reload** — watch config file, reload without restart
|
|
305
|
-
- [ ] **Retry with backoff** — exponential backoff for transient failures
|
|
306
|
-
- [ ] Custom adapter smoke tests
|
|
399
|
+
---
|
|
307
400
|
|
|
308
|
-
|
|
401
|
+
## Logs
|
|
309
402
|
|
|
310
|
-
|
|
311
|
-
- [ ] **Session sharing** — share ACP sessions between pi instances via file lock
|
|
312
|
-
- [x] **Checkpoint/resume** — archived runtime metadata reopens auto-closed ACP sessions by original session ID
|
|
313
|
-
- [ ] **Metrics export** — Prometheus-compatible metrics (session count, latency, error rate)
|
|
403
|
+
Central logs at `~/.pi/acp-agents/logs/`:
|
|
314
404
|
|
|
315
|
-
|
|
405
|
+
- `main.log` — general structured JSON log
|
|
406
|
+
- `session-{id}/trace.jsonl` — per-session ACP JSON-RPC traces
|
|
407
|
+
- `<runtimeDir>/dag/<dagId>.json` + `dag-index.json` — DAG state persistence
|
|
408
|
+
- `<runtimeDir>/<sessionId>/{tasks,mailboxes,governance,workers}.json` — session-scoped stores
|
|
409
|
+
- `<runtimeDir>/{events,session-archive,session-name-registry}.jsonl|json` — global stores
|
|
316
410
|
|
|
317
|
-
|
|
318
|
-
- [ ] **Ensemble mode** — run same prompt across N agents, merge via configurable strategy (vote, rank, consensus)
|
|
319
|
-
- [ ] **Chain-of-agents** — pipe output of one agent as input to next
|
|
320
|
-
- [ ] **Cost tracking** — per-agent, per-session token usage and cost estimation
|
|
321
|
-
- [ ] **Agent health dashboard** — web UI for monitoring all connected agents
|
|
411
|
+
---
|
|
322
412
|
|
|
323
|
-
|
|
413
|
+
## Supported agents
|
|
324
414
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
415
|
+
| Agent | Status | Config |
|
|
416
|
+
|---|---|---|
|
|
417
|
+
| **Gemini CLI** | ✅ Built-in | `command: "gemini", args: ["--acp"]` |
|
|
418
|
+
| **Claude Code** | 🔜 Planned | ACP mode pending upstream |
|
|
419
|
+
| **Codex** | 🔜 Planned | ACP mode pending upstream |
|
|
420
|
+
| **Custom** | ✅ Via `CustomAcpAdapter` | Any command speaking ACP over stdio |
|
|
329
421
|
|
|
330
422
|
---
|
|
331
423
|
|
|
@@ -333,27 +425,35 @@ Central logs: `~/.pi/acp-agents/logs/`
|
|
|
333
425
|
|
|
334
426
|
```bash
|
|
335
427
|
npm install
|
|
336
|
-
npm test #
|
|
337
|
-
npm run test:ci #
|
|
428
|
+
npm test # all tests
|
|
429
|
+
npm run test:ci # with coverage
|
|
338
430
|
npm run typecheck # TypeScript validation
|
|
339
431
|
npm run publish:dry # verify package contents before publish
|
|
340
432
|
```
|
|
341
433
|
|
|
342
|
-
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## Release process
|
|
343
437
|
|
|
344
438
|
```bash
|
|
345
|
-
npm run release:patch # 0.
|
|
346
|
-
npm run release:minor # 0.
|
|
347
|
-
npm run release:beta # 0.
|
|
439
|
+
npm run release:patch # 0.4.0 → 0.4.1
|
|
440
|
+
npm run release:minor # 0.4.0 → 0.5.0
|
|
441
|
+
npm run release:beta # 0.4.0 → 0.4.1-beta.0
|
|
348
442
|
git push --follow-tags # triggers CI → auto-publish with provenance
|
|
349
443
|
```
|
|
350
444
|
|
|
351
445
|
---
|
|
352
446
|
|
|
353
|
-
##
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
447
|
+
## Further documentation
|
|
448
|
+
|
|
449
|
+
| Topic | Location |
|
|
450
|
+
|---|---|
|
|
451
|
+
| **Full usage guide** (DAG examples, alias config, worker patterns, slash command reference) | [`docs/USAGE.md`](docs/USAGE.md) |
|
|
452
|
+
| **Tool consolidation plan** (39 → 7 multiplexed tools) | [`../pi-plugins/flow/intentions/pi-acp-agents/tool-consolidation.md`](https://github.com/buihongduc132/pi-plugins/blob/main/flow/intentions/pi-acp-agents/tool-consolidation.md) |
|
|
453
|
+
| **ACP vs teams gap analysis** | [`../pi-plugins/flow/findings/acp-vs-teams-analysis.md`](https://github.com/buihongduc132/pi-plugins/blob/main/flow/findings/acp-vs-teams-analysis.md) |
|
|
454
|
+
| **DAG delegation design** | [`openspec/changes/archive/2026-06-20-acp-dag-delegation/`](openspec/changes/archive/2026-06-20-acp-dag-delegation/) |
|
|
455
|
+
| **DAG widget design** | [`openspec/changes/archive/2026-06-22-acp-dag-widget/`](openspec/changes/archive/2026-06-22-acp-dag-widget/) |
|
|
456
|
+
| **Session-scoped runtime stores** | [`openspec/changes/archive/2026-06-19-scope-runtime-stores-per-session/`](openspec/changes/archive/2026-06-19-scope-runtime-stores-per-session/) |
|
|
457
|
+
| **Branch consolidation record** (this release) | [`docs/branch-consolidation-2026-06-22.md`](docs/branch-consolidation-2026-06-22.md) |
|
|
458
|
+
| **OpenSpec changes** | [`openspec/changes/`](openspec/changes/) |
|
|
459
|
+
| **Specs (canonical)** | [`openspec/specs/`](openspec/specs/) |
|