@zooid/acp-client 0.12.0 → 0.14.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/package.json +1 -1
- package/src/acp-client.context.test.ts +9 -4
- package/src/acp-client.ts +23 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zooid/acp-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Zooid's ACP client: spawn agent subprocesses, drive them via Agent Client Protocol, route events and permission requests through callbacks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,7 +53,7 @@ describe('AcpClient — context MCP wiring', () => {
|
|
|
53
53
|
})
|
|
54
54
|
injectConnection(client, calls)
|
|
55
55
|
await client.ensureSession('!room:hs')
|
|
56
|
-
expect(contextSpawn).toHaveBeenCalledWith('!room:hs', undefined)
|
|
56
|
+
expect(contextSpawn).toHaveBeenCalledWith('!room:hs', undefined, '!room:hs')
|
|
57
57
|
const params = calls.find((c) => c.method === 'newSession')!.params as {
|
|
58
58
|
mcpServers: Array<{ name: string; args: string[] }>
|
|
59
59
|
}
|
|
@@ -80,7 +80,12 @@ describe('AcpClient — context MCP wiring', () => {
|
|
|
80
80
|
})
|
|
81
81
|
const conn = injectConnection(client, calls)
|
|
82
82
|
// @ts-expect-error
|
|
83
|
-
client.store = {
|
|
83
|
+
client.store = {
|
|
84
|
+
load: async () => {},
|
|
85
|
+
get: () => 'sess-old',
|
|
86
|
+
set: async () => {},
|
|
87
|
+
delete: async () => {},
|
|
88
|
+
}
|
|
84
89
|
// @ts-expect-error
|
|
85
90
|
client.storeLoaded = Promise.resolve()
|
|
86
91
|
await client.ensureSession('!room:hs')
|
|
@@ -109,7 +114,7 @@ describe('AcpClient — context MCP wiring', () => {
|
|
|
109
114
|
// Handoff-arc session: key is composed, context ref is the real root —
|
|
110
115
|
// zooid_get_history must read the real Matrix thread.
|
|
111
116
|
await client.ensureSession('$root|$p1', '!r:example.com', '$root')
|
|
112
|
-
expect(contextSpawn).toHaveBeenCalledWith('$root', '!r:example.com')
|
|
117
|
+
expect(contextSpawn).toHaveBeenCalledWith('$root', '!r:example.com', '$root|$p1')
|
|
113
118
|
})
|
|
114
119
|
|
|
115
120
|
it('defaults the context ref to the session key when contextThreadId is omitted (back-compat)', async () => {
|
|
@@ -128,6 +133,6 @@ describe('AcpClient — context MCP wiring', () => {
|
|
|
128
133
|
})
|
|
129
134
|
injectConnection(client, calls)
|
|
130
135
|
await client.ensureSession('$root', '!r:example.com')
|
|
131
|
-
expect(contextSpawn).toHaveBeenCalledWith('$root', '!r:example.com')
|
|
136
|
+
expect(contextSpawn).toHaveBeenCalledWith('$root', '!r:example.com', '$root')
|
|
132
137
|
})
|
|
133
138
|
})
|
package/src/acp-client.ts
CHANGED
|
@@ -11,10 +11,7 @@ import { AgentProcess } from './agent-process.js'
|
|
|
11
11
|
import { SessionMap } from './session-map.js'
|
|
12
12
|
import { JsonFileSessionStore } from './session-store.js'
|
|
13
13
|
import { resolvePreset } from './presets.js'
|
|
14
|
-
import {
|
|
15
|
-
acpUpdateToAgentEvent,
|
|
16
|
-
approvalDecisionToPermissionResponse,
|
|
17
|
-
} from './event-mapping.js'
|
|
14
|
+
import { acpUpdateToAgentEvent, approvalDecisionToPermissionResponse } from './event-mapping.js'
|
|
18
15
|
import { TurnTracker, type TapEvent } from './turn-tracker.js'
|
|
19
16
|
import { classify } from './errors.js'
|
|
20
17
|
import type {
|
|
@@ -73,7 +70,11 @@ export interface AcpClientOptions {
|
|
|
73
70
|
* connects to the daemon-side zooid-context MCP server for the session
|
|
74
71
|
* lifetime. Called once per `ensureSession(threadId)`.
|
|
75
72
|
*/
|
|
76
|
-
contextSpawn?: (
|
|
73
|
+
contextSpawn?: (
|
|
74
|
+
threadId: string,
|
|
75
|
+
channelId?: string,
|
|
76
|
+
sessionKey?: string,
|
|
77
|
+
) => Promise<{
|
|
77
78
|
name: 'zooid-context'
|
|
78
79
|
command: string
|
|
79
80
|
args: string[]
|
|
@@ -177,13 +178,19 @@ export class AcpClient {
|
|
|
177
178
|
if (cached) return cached.sessionId
|
|
178
179
|
|
|
179
180
|
const mcpServers = this.options.contextSpawn
|
|
180
|
-
? [await this.options.contextSpawn(contextThreadId ?? threadId, channelId)]
|
|
181
|
+
? [await this.options.contextSpawn(contextThreadId ?? threadId, channelId, threadId)]
|
|
181
182
|
: []
|
|
182
183
|
process.stderr.write(
|
|
183
184
|
`[acp-client:${this.options.agent.id}] ensureSession(${threadId}) mcpServers=${
|
|
184
185
|
mcpServers.length === 0
|
|
185
186
|
? '[]'
|
|
186
|
-
: JSON.stringify(
|
|
187
|
+
: JSON.stringify(
|
|
188
|
+
mcpServers.map((s) => ({
|
|
189
|
+
name: s.name,
|
|
190
|
+
command: s.command,
|
|
191
|
+
args: s.args,
|
|
192
|
+
})),
|
|
193
|
+
)
|
|
187
194
|
}\n`,
|
|
188
195
|
)
|
|
189
196
|
|
|
@@ -264,20 +271,22 @@ export class AcpClient {
|
|
|
264
271
|
let sessionId: string | null = null
|
|
265
272
|
let turnId: string | null = null
|
|
266
273
|
try {
|
|
267
|
-
sessionId = await this.ensureSession(
|
|
268
|
-
input.threadId,
|
|
269
|
-
input.channelId,
|
|
270
|
-
input.contextThreadId,
|
|
271
|
-
)
|
|
274
|
+
sessionId = await this.ensureSession(input.threadId, input.channelId, input.contextThreadId)
|
|
272
275
|
const promptText = stringifyPromptForLog(input.content)
|
|
273
276
|
turnId = this.turns?.startTurn({ sessionId, promptText }) ?? null
|
|
274
|
-
debugLog(this.options.agent.id, 'prompt →', {
|
|
277
|
+
debugLog(this.options.agent.id, 'prompt →', {
|
|
278
|
+
sessionId,
|
|
279
|
+
content: input.content,
|
|
280
|
+
})
|
|
275
281
|
const result = await this.connection!.prompt({
|
|
276
282
|
sessionId,
|
|
277
283
|
prompt: input.content,
|
|
278
284
|
})
|
|
279
285
|
this.turns?.endTurn({ sessionId, stopReason: result.stopReason })
|
|
280
|
-
debugLog(this.options.agent.id, 'prompt ←', {
|
|
286
|
+
debugLog(this.options.agent.id, 'prompt ←', {
|
|
287
|
+
sessionId,
|
|
288
|
+
stopReason: result.stopReason,
|
|
289
|
+
})
|
|
281
290
|
return { stopReason: result.stopReason }
|
|
282
291
|
} catch (err) {
|
|
283
292
|
const c = classify(err)
|