@zooid/core 0.7.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/LICENSE +21 -0
- package/dist/index.d.ts +491 -0
- package/dist/index.js +868 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
- package/src/__fixtures__/ec2-workspace.yaml +16 -0
- package/src/__fixtures__/opencode-vertex-gemini.yaml +34 -0
- package/src/__fixtures__/triage-agent.yaml +40 -0
- package/src/__fixtures__/zooid-dev.yaml +53 -0
- package/src/acp-config.test.ts +162 -0
- package/src/acp-registry.test.ts +217 -0
- package/src/acp-registry.ts +235 -0
- package/src/acp-types.test.ts +55 -0
- package/src/acp-types.ts +48 -0
- package/src/approval-correlator.test.ts +129 -0
- package/src/approval-correlator.ts +143 -0
- package/src/config-file.test.ts +35 -0
- package/src/config.test.ts +1317 -0
- package/src/config.ts +712 -0
- package/src/env-interpolation.ts +90 -0
- package/src/example-yaml.test.ts +35 -0
- package/src/index.ts +56 -0
- package/src/transport-context.test.ts +34 -0
- package/src/transport-context.ts +91 -0
- package/src/types.ts +213 -0
- package/src/zooid-config.test.ts +164 -0
- package/src/zooid-helpers.test.ts +54 -0
- package/src/zooid-yaml-sweep.test.ts +389 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zooid contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import { ChildProcess } from 'node:child_process';
|
|
2
|
+
import { ApprovalRequest, ApprovalDecision, PromptInput, PromptResult, AgentEvent, TapEvent } from '@zooid/acp-client';
|
|
3
|
+
export { TapEvent } from '@zooid/acp-client';
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Per-agent ACP block in zooid.yaml. XOR: either a known preset or an
|
|
8
|
+
* explicit command. The schema parser rejects both/neither.
|
|
9
|
+
*
|
|
10
|
+
* Built-in presets: `claude`, `codex`, `opencode`, `cline`, `kiro`, `gemini`.
|
|
11
|
+
* See `@zooid/acp-client`'s preset registry for the current list.
|
|
12
|
+
*/
|
|
13
|
+
type AcpAgentSpec = {
|
|
14
|
+
preset: string;
|
|
15
|
+
model?: string;
|
|
16
|
+
command?: never;
|
|
17
|
+
args?: never;
|
|
18
|
+
} | {
|
|
19
|
+
preset?: never;
|
|
20
|
+
model?: never;
|
|
21
|
+
command: string;
|
|
22
|
+
args?: string[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* A single bind mount the runtime should set up for the spawned agent
|
|
26
|
+
* process. Only DockerAcpRuntime honors mounts; LocalAcpRuntime ignores them.
|
|
27
|
+
*/
|
|
28
|
+
interface AcpMount {
|
|
29
|
+
/** Host-side source path (absolute). */
|
|
30
|
+
path: string;
|
|
31
|
+
/** Container-side target path. */
|
|
32
|
+
target: string;
|
|
33
|
+
mode: 'ro' | 'rw';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* What an `AcpRuntime` needs in order to launch the ACP agent process.
|
|
37
|
+
* Unlike the legacy `SpawnConfig`, this is just process-spawn shape — no
|
|
38
|
+
* adapter-specific concepts (no workspaceReadOnly, no sessionStateDir).
|
|
39
|
+
*/
|
|
40
|
+
interface AcpSpawnSpec {
|
|
41
|
+
command: string;
|
|
42
|
+
args: string[];
|
|
43
|
+
env?: Record<string, string>;
|
|
44
|
+
cwd?: string;
|
|
45
|
+
/** Container image. Used by DockerAcpRuntime; ignored by LocalAcpRuntime. */
|
|
46
|
+
image?: string;
|
|
47
|
+
/** Bind mounts. Used by DockerAcpRuntime; ignored by LocalAcpRuntime. */
|
|
48
|
+
mounts?: AcpMount[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A runtime knows how to spawn the ACP shim process (locally, or inside a
|
|
52
|
+
* container). Returns a ChildProcess whose stdio is wired up for ACP NDJSON.
|
|
53
|
+
*/
|
|
54
|
+
interface AcpRuntime {
|
|
55
|
+
spawn(spec: AcpSpawnSpec): ChildProcess;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* One classified line of agent stdout. Currently unused (legacy adapter
|
|
60
|
+
* machinery is gone); kept for forward compatibility with future on-disk
|
|
61
|
+
* stream parsing.
|
|
62
|
+
*/
|
|
63
|
+
/**
|
|
64
|
+
* A Transport handles inbound messages and outbound replies. Implemented in
|
|
65
|
+
* future epics (HTTP, Slack, Zooid). Declared here so the core knows the
|
|
66
|
+
* shape downstream packages will plug in to.
|
|
67
|
+
*/
|
|
68
|
+
interface InboundMessage {
|
|
69
|
+
id: string;
|
|
70
|
+
text: string;
|
|
71
|
+
sender: string;
|
|
72
|
+
thread: ThreadRef;
|
|
73
|
+
isFollowUp: boolean;
|
|
74
|
+
}
|
|
75
|
+
interface ThreadRef {
|
|
76
|
+
channelId: string;
|
|
77
|
+
threadId: string;
|
|
78
|
+
}
|
|
79
|
+
interface Transport {
|
|
80
|
+
listen(channel: string, onMessage: (msg: InboundMessage) => void): void;
|
|
81
|
+
reply(thread: ThreadRef, message: string): Promise<void> | void;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Per-agent container configuration. Holds runtime-neutral container
|
|
85
|
+
* concerns — image, env. Rejected at parse time when `runtime: local`.
|
|
86
|
+
*/
|
|
87
|
+
interface ContainerConfig {
|
|
88
|
+
image?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Env vars passed to the spawned agent container. Values support
|
|
91
|
+
* compose-style `${VAR}` / `${VAR:-default}` / `${VAR-default}`
|
|
92
|
+
* interpolation, resolved at parse time against the daemon's `process.env`.
|
|
93
|
+
* `ZOOID_*` references and `ZOOID_*` keys are rejected.
|
|
94
|
+
*/
|
|
95
|
+
env?: Record<string, string>;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Workforce-level container defaults. Currently `image` only — see
|
|
99
|
+
* [ZOD043] §Non-goals on workforce-level env.
|
|
100
|
+
*/
|
|
101
|
+
interface ZooidContainerConfig {
|
|
102
|
+
image?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Matrix transport binding. Lives under `agents.<name>.matrix:` in
|
|
106
|
+
* zooid.yaml. The block name (`matrix`) is the transport-kind
|
|
107
|
+
* discriminator: `transports[transport].type` must equal `"matrix"`.
|
|
108
|
+
*/
|
|
109
|
+
interface MatrixBinding {
|
|
110
|
+
/**
|
|
111
|
+
* Ref into `ZooidConfig.transports`. Resolved transport must have type: 'matrix'.
|
|
112
|
+
* @default if exactly one matrix transport is declared, that transport's key
|
|
113
|
+
*/
|
|
114
|
+
transport: string;
|
|
115
|
+
/**
|
|
116
|
+
* Full Matrix user ID for this agent's bot, e.g. `@architect:example.com`.
|
|
117
|
+
* @default `@<agent name>:<server>` — server is derived from the resolved
|
|
118
|
+
* transport's `user_namespace`
|
|
119
|
+
*/
|
|
120
|
+
user_id: string;
|
|
121
|
+
/**
|
|
122
|
+
* Optional human-readable display name. Written to the agent's Matrix
|
|
123
|
+
* profile on bootstrap. Falls back to the user_id localpart when absent.
|
|
124
|
+
*/
|
|
125
|
+
display_name?: string;
|
|
126
|
+
/** Room IDs / aliases this agent watches. */
|
|
127
|
+
rooms: string[];
|
|
128
|
+
/**
|
|
129
|
+
* Routing rule. `mention` requires the bot to be tagged; `any` triggers
|
|
130
|
+
* on every message.
|
|
131
|
+
* @default 'mention'
|
|
132
|
+
*/
|
|
133
|
+
trigger: 'mention' | 'any';
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* HTTP transport binding. Lives under `agents.<name>.http:` in
|
|
137
|
+
* zooid.yaml. Reserved for future HTTP-specific binding fields.
|
|
138
|
+
*/
|
|
139
|
+
interface HttpBinding {
|
|
140
|
+
/** Ref into `ZooidConfig.transports`. Resolved transport must have type: 'http'. */
|
|
141
|
+
transport: string;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Per-agent config inside a multi-agent zooid.yaml. Each agent has its
|
|
145
|
+
* own workspace, hooks, an ACP block describing the shim to spawn, and
|
|
146
|
+
* exactly one transport-kind block (`matrix` or `http`).
|
|
147
|
+
*/
|
|
148
|
+
interface AgentConfig {
|
|
149
|
+
/**
|
|
150
|
+
* Routing name. Always the agent's key in `ZooidConfig.agents` — cannot
|
|
151
|
+
* be overridden, and a `name:` field under an agent is silently ignored.
|
|
152
|
+
* The key must match /^[a-z][a-z0-9-]{0,31}$/.
|
|
153
|
+
*/
|
|
154
|
+
name: string;
|
|
155
|
+
/**
|
|
156
|
+
* Host directory for the agent's workspace.
|
|
157
|
+
* @default `./agents/<name>`
|
|
158
|
+
*/
|
|
159
|
+
workdir: string;
|
|
160
|
+
/** Per-agent hooks. Workforce-wide hooks are merged in at load time. */
|
|
161
|
+
hooks: {
|
|
162
|
+
pre_turn?: string;
|
|
163
|
+
post_turn?: string;
|
|
164
|
+
};
|
|
165
|
+
/** Required: how to launch this agent's ACP shim. */
|
|
166
|
+
acp: AcpAgentSpec;
|
|
167
|
+
/**
|
|
168
|
+
* Wall-clock timeout for pending permission requests, in milliseconds.
|
|
169
|
+
* 0 = no timeout. The paused agent's idle cost is negligible, so opt-in
|
|
170
|
+
* is the right shape — set this only if you're running in a
|
|
171
|
+
* scale-to-zero / serverless context where unbounded waits would hold
|
|
172
|
+
* resources.
|
|
173
|
+
* @default 0
|
|
174
|
+
*/
|
|
175
|
+
approval_timeout_ms: number;
|
|
176
|
+
/** Container config. Rejected at parse time when runtime: local. */
|
|
177
|
+
container?: ContainerConfig;
|
|
178
|
+
/** Exactly one of matrix / http is set per agent. */
|
|
179
|
+
matrix?: MatrixBinding;
|
|
180
|
+
http?: HttpBinding;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Matrix application-service transport. The CLI binds the AS HTTP listener
|
|
184
|
+
* to `port` (defaults to 8080).
|
|
185
|
+
*/
|
|
186
|
+
interface MatrixTransportConfig {
|
|
187
|
+
type: 'matrix';
|
|
188
|
+
homeserver: string;
|
|
189
|
+
/**
|
|
190
|
+
* Application-service token. Sent on every Client-Server API call.
|
|
191
|
+
* @default value of `$MATRIX_AS_TOKEN` in the daemon's env
|
|
192
|
+
*/
|
|
193
|
+
as_token: string;
|
|
194
|
+
/**
|
|
195
|
+
* Homeserver-to-AS token. The homeserver presents this on push.
|
|
196
|
+
* @default value of `$MATRIX_HS_TOKEN` in the daemon's env
|
|
197
|
+
*/
|
|
198
|
+
hs_token: string;
|
|
199
|
+
/**
|
|
200
|
+
* Localpart of the AS sender user (the bridge bot).
|
|
201
|
+
* @default 'zooid'
|
|
202
|
+
*/
|
|
203
|
+
sender_localpart: string;
|
|
204
|
+
/**
|
|
205
|
+
* Regex covering all bot users, e.g. `@.*:example.com`.
|
|
206
|
+
* @default `@.*:<host>` — host derived from `homeserver`
|
|
207
|
+
*/
|
|
208
|
+
user_namespace: string;
|
|
209
|
+
/**
|
|
210
|
+
* AS HTTP listener port.
|
|
211
|
+
* @default 8080
|
|
212
|
+
*/
|
|
213
|
+
port?: number;
|
|
214
|
+
/**
|
|
215
|
+
* Workforce space localpart. Resolves to alias `#<space>:<server>`.
|
|
216
|
+
* @default 'dev'
|
|
217
|
+
*/
|
|
218
|
+
space?: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Plain HTTP API transport.
|
|
222
|
+
*/
|
|
223
|
+
interface HttpTransportConfig {
|
|
224
|
+
type: 'http';
|
|
225
|
+
/**
|
|
226
|
+
* HTTP listener port.
|
|
227
|
+
* @default 8080
|
|
228
|
+
*/
|
|
229
|
+
port: number;
|
|
230
|
+
}
|
|
231
|
+
type TransportConfig = MatrixTransportConfig | HttpTransportConfig;
|
|
232
|
+
/**
|
|
233
|
+
* Parsed zooid.yaml shape. Always multi-agent — `agents:` is required and
|
|
234
|
+
* must have at least one entry. At least one transport must be declared and
|
|
235
|
+
* each agent must reference one by name.
|
|
236
|
+
*/
|
|
237
|
+
interface ZooidConfig {
|
|
238
|
+
runtime: 'local' | 'docker' | 'podman';
|
|
239
|
+
/** Workforce-wide container defaults. Image only — no workforce-level env. Rejected when runtime: local. */
|
|
240
|
+
container?: ZooidContainerConfig;
|
|
241
|
+
/** Required. Map of operator-chosen names → transport config. At least one entry. */
|
|
242
|
+
transports: Record<string, TransportConfig>;
|
|
243
|
+
/** Required. Must have at least one entry. */
|
|
244
|
+
agents: Record<string, AgentConfig>;
|
|
245
|
+
/** Workforce-wide hook defaults. Merged into each agent.hooks at load time. */
|
|
246
|
+
hooks: {
|
|
247
|
+
pre_turn?: string;
|
|
248
|
+
post_turn?: string;
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
interface CliFlags {
|
|
252
|
+
runtime?: string;
|
|
253
|
+
/** Container image override (shorthand for container.image). */
|
|
254
|
+
image?: string;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
declare function loadZooidConfig(yamlText: string): ZooidConfig;
|
|
258
|
+
declare function findTransport(cfg: ZooidConfig, name: string): TransportConfig | undefined;
|
|
259
|
+
declare function findMatrixTransport(cfg: ZooidConfig): {
|
|
260
|
+
name: string;
|
|
261
|
+
transport: MatrixTransportConfig;
|
|
262
|
+
} | null;
|
|
263
|
+
declare function findHttpTransport(cfg: ZooidConfig): {
|
|
264
|
+
name: string;
|
|
265
|
+
transport: HttpTransportConfig;
|
|
266
|
+
} | null;
|
|
267
|
+
interface FoundConfigFile {
|
|
268
|
+
path: string;
|
|
269
|
+
}
|
|
270
|
+
declare function findConfigFile(cwd: string): FoundConfigFile | null;
|
|
271
|
+
declare function mergeCliFlags(base: ZooidConfig, flags: CliFlags): ZooidConfig;
|
|
272
|
+
|
|
273
|
+
interface RegisteredApproval {
|
|
274
|
+
approvalId: string;
|
|
275
|
+
agentName: string;
|
|
276
|
+
sessionId: string;
|
|
277
|
+
toolCallId: string;
|
|
278
|
+
toolKind?: string;
|
|
279
|
+
toolTitle?: string;
|
|
280
|
+
toolInput?: unknown;
|
|
281
|
+
options: ApprovalRequest['options'];
|
|
282
|
+
decisionPromise: Promise<ApprovalDecision>;
|
|
283
|
+
}
|
|
284
|
+
interface RegisterOptions {
|
|
285
|
+
/** Wall-clock timeout in ms. 0 = no timeout. */
|
|
286
|
+
timeoutMs?: number;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Correlates ACP approval requests (mid-prompt, originating in `AcpClient`)
|
|
290
|
+
* with HTTP/transport-side decisions. The transport listens to:
|
|
291
|
+
*
|
|
292
|
+
* - `'registered'` — fires after `register()` so the transport can emit
|
|
293
|
+
* `approval.request` on the right SSE stream.
|
|
294
|
+
* - `'timeout'` — fires when an entry is auto-cancelled by the timer
|
|
295
|
+
* so the transport can emit `approval.timeout`.
|
|
296
|
+
*/
|
|
297
|
+
declare class ApprovalCorrelator extends EventEmitter {
|
|
298
|
+
private readonly pending;
|
|
299
|
+
private readonly bySession;
|
|
300
|
+
register(agentName: string, sessionId: string, req: ApprovalRequest, opts?: RegisterOptions): RegisteredApproval;
|
|
301
|
+
resolve(sessionId: string, approvalId: string, decision: ApprovalDecision): boolean;
|
|
302
|
+
cancelSession(sessionId: string): void;
|
|
303
|
+
listPending(sessionId: string): RegisteredApproval[];
|
|
304
|
+
size(): number;
|
|
305
|
+
private toPublic;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
type AcpRegistryEventHandler = (agentName: string, event: AgentEvent) => void;
|
|
309
|
+
type AcpRegistryApprovalHandler = (agentName: string, req: ApprovalRequest) => Promise<ApprovalDecision>;
|
|
310
|
+
/**
|
|
311
|
+
* Daemon-side surface of the ACP agent fleet. The transport (HTTP) consumes
|
|
312
|
+
* this; the CLI builds it via `buildAcpRegistry`. Long-lived: one
|
|
313
|
+
* `AcpClient` per agent, kept alive across prompts.
|
|
314
|
+
*/
|
|
315
|
+
interface AcpRegistry {
|
|
316
|
+
hasAgent(name: string): boolean;
|
|
317
|
+
/** Whether an agent has a transport-context provider attached. */
|
|
318
|
+
hasContextSpawn(name: string): boolean;
|
|
319
|
+
/** Per-agent approval timeout from zooid.yaml. 0 means no timeout. */
|
|
320
|
+
getApprovalTimeoutMs(name: string): number;
|
|
321
|
+
ensureSession(name: string, threadId: string, channelId?: string): Promise<string>;
|
|
322
|
+
/** Drop the in-memory session for (agent, threadId). Next prompt re-creates one. */
|
|
323
|
+
endSession(name: string, threadId: string): void;
|
|
324
|
+
prompt(name: string, input: PromptInput): Promise<PromptResult>;
|
|
325
|
+
/**
|
|
326
|
+
* Cancel an in-flight prompt for (agent, sessionId). Sends `session/cancel`
|
|
327
|
+
* via the underlying AcpClient and resolves any pending approvals with
|
|
328
|
+
* `decision: 'cancel'`. Idempotent.
|
|
329
|
+
*/
|
|
330
|
+
cancelSession(name: string, sessionId: string): Promise<void>;
|
|
331
|
+
stopAll(): Promise<void>;
|
|
332
|
+
/** Set by the transport. Receives every ACP event from any agent. */
|
|
333
|
+
onEvent: AcpRegistryEventHandler;
|
|
334
|
+
/** Set by the transport. Resolves permission requests. */
|
|
335
|
+
onApprovalRequest: AcpRegistryApprovalHandler;
|
|
336
|
+
}
|
|
337
|
+
interface AcpAgentRegistryOptions {
|
|
338
|
+
runtime: AcpRuntime;
|
|
339
|
+
agents: Record<string, AgentConfig>;
|
|
340
|
+
/** Per-agent env passed to each `AcpClient`'s spawn spec. */
|
|
341
|
+
env?: Record<string, Record<string, string>>;
|
|
342
|
+
/** Per-agent container image. Used by DockerAcpRuntime; ignored by LocalAcpRuntime. */
|
|
343
|
+
image?: Record<string, string | undefined>;
|
|
344
|
+
/** Initial event handler (the transport may overwrite at app creation). */
|
|
345
|
+
onEvent?: AcpRegistryEventHandler;
|
|
346
|
+
/** Initial approval handler (the transport may overwrite at app creation). */
|
|
347
|
+
onApprovalRequest?: AcpRegistryApprovalHandler;
|
|
348
|
+
/**
|
|
349
|
+
* Optional correlator: when set, the registry's default
|
|
350
|
+
* `onApprovalRequest` registers each request on the correlator (with the
|
|
351
|
+
* agent's `approval_timeout_ms`) and returns the registered handle's
|
|
352
|
+
* `decisionPromise`. Transports listen on the correlator's `'registered'`
|
|
353
|
+
* + `'timeout'` events to drive the SSE wire and accept HTTP decisions.
|
|
354
|
+
*/
|
|
355
|
+
approvals?: ApprovalCorrelator;
|
|
356
|
+
/** Called whenever the correlator-backed handler registers an approval. */
|
|
357
|
+
onApprovalRegistered?: (approval: RegisteredApproval) => void;
|
|
358
|
+
/**
|
|
359
|
+
* Optional observability tap. Forwarded to each AcpClient so the
|
|
360
|
+
* unfiltered ACP protocol stream + turn-boundary events are visible to
|
|
361
|
+
* the host (e.g. the dev CLI capturing them to disk).
|
|
362
|
+
*/
|
|
363
|
+
onTap?: (agentName: string, event: TapEvent) => void;
|
|
364
|
+
/**
|
|
365
|
+
* Root directory under which each agent gets a per-agent state dir
|
|
366
|
+
* (`<agentsDir>/<agentName>/`). Used by the AcpClient session store to
|
|
367
|
+
* persist ACP `sessionId`s across daemon restarts. Optional: when unset,
|
|
368
|
+
* session continuity across restarts is disabled.
|
|
369
|
+
*/
|
|
370
|
+
agentsDir?: string;
|
|
371
|
+
/**
|
|
372
|
+
* Per-agent factory that returns a `mcpServers[]` entry for the
|
|
373
|
+
* `zooid-context` MCP server. Forwarded to each AcpClient. Agents bound to
|
|
374
|
+
* transports without a context provider (e.g. HTTP) have no entry here.
|
|
375
|
+
*/
|
|
376
|
+
contextSpawns?: Record<string, ContextSpawnFactory | undefined>;
|
|
377
|
+
}
|
|
378
|
+
type ContextSpawnFactory = (threadId: string, channelId?: string) => Promise<{
|
|
379
|
+
name: 'zooid-context';
|
|
380
|
+
command: string;
|
|
381
|
+
args: string[];
|
|
382
|
+
env: Array<{
|
|
383
|
+
name: string;
|
|
384
|
+
value: string;
|
|
385
|
+
}>;
|
|
386
|
+
}>;
|
|
387
|
+
declare class AcpAgentRegistry implements AcpRegistry {
|
|
388
|
+
readonly opts: AcpAgentRegistryOptions;
|
|
389
|
+
private readonly clients;
|
|
390
|
+
onEvent: AcpRegistryEventHandler;
|
|
391
|
+
onApprovalRequest: AcpRegistryApprovalHandler;
|
|
392
|
+
constructor(opts: AcpAgentRegistryOptions);
|
|
393
|
+
hasAgent(name: string): boolean;
|
|
394
|
+
hasContextSpawn(name: string): boolean;
|
|
395
|
+
resolveSpawnEnv(name: string): Record<string, string>;
|
|
396
|
+
resolveSpawnImage(name: string): string | undefined;
|
|
397
|
+
getApprovalTimeoutMs(name: string): number;
|
|
398
|
+
ensureSession(name: string, threadId: string, channelId?: string): Promise<string>;
|
|
399
|
+
endSession(name: string, threadId: string): void;
|
|
400
|
+
cancelSession(name: string, sessionId: string): Promise<void>;
|
|
401
|
+
prompt(name: string, input: PromptInput): Promise<PromptResult>;
|
|
402
|
+
stopAll(): Promise<void>;
|
|
403
|
+
private ensureClient;
|
|
404
|
+
}
|
|
405
|
+
declare function resolveAcpAgentSpec(spec: AcpAgentSpec): {
|
|
406
|
+
command: string;
|
|
407
|
+
args: string[];
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
interface HistoryOptions {
|
|
411
|
+
/** Max messages to return. Default 50, max 200 (enforced by the MCP server). */
|
|
412
|
+
limit?: number;
|
|
413
|
+
/** Pagination cursor — opaque to the agent. Provider-defined shape. */
|
|
414
|
+
before?: string;
|
|
415
|
+
}
|
|
416
|
+
interface Message {
|
|
417
|
+
id: string;
|
|
418
|
+
sender: string;
|
|
419
|
+
text: string;
|
|
420
|
+
timestamp: string;
|
|
421
|
+
is_agent: boolean;
|
|
422
|
+
agent_name?: string;
|
|
423
|
+
/**
|
|
424
|
+
* Thread root event id when this message belongs to a thread. Absent for
|
|
425
|
+
* top-level messages. Lets agents group messages by thread or drill into
|
|
426
|
+
* a specific thread root.
|
|
427
|
+
*/
|
|
428
|
+
thread_id?: string;
|
|
429
|
+
}
|
|
430
|
+
interface Member {
|
|
431
|
+
id: string;
|
|
432
|
+
name: string;
|
|
433
|
+
is_agent: boolean;
|
|
434
|
+
agent_name?: string;
|
|
435
|
+
}
|
|
436
|
+
interface ChannelInfo {
|
|
437
|
+
id: string;
|
|
438
|
+
name: string;
|
|
439
|
+
transport: 'http' | 'matrix';
|
|
440
|
+
}
|
|
441
|
+
interface HistoryPage {
|
|
442
|
+
messages: Message[];
|
|
443
|
+
next_before?: string;
|
|
444
|
+
has_more: boolean;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* A top-level entry in a room — either a standalone message or a thread
|
|
448
|
+
* root. Lets the agent scan a room without thread-reply noise. Drill into
|
|
449
|
+
* a thread with `getThreadHistory(thread_id)` where `thread_id` is this
|
|
450
|
+
* entry's `id`.
|
|
451
|
+
*/
|
|
452
|
+
interface ThreadOverview {
|
|
453
|
+
id: string;
|
|
454
|
+
sender: string;
|
|
455
|
+
text: string;
|
|
456
|
+
timestamp: string;
|
|
457
|
+
is_agent: boolean;
|
|
458
|
+
agent_name?: string;
|
|
459
|
+
/** Number of replies in the thread under this entry. 0 = no replies yet. */
|
|
460
|
+
reply_count: number;
|
|
461
|
+
/**
|
|
462
|
+
* ISO 8601 of the latest activity in the thread (latest reply, or this
|
|
463
|
+
* entry's own timestamp when there are no replies). Useful for sorting.
|
|
464
|
+
*/
|
|
465
|
+
last_activity_at: string;
|
|
466
|
+
}
|
|
467
|
+
interface ThreadOverviewPage {
|
|
468
|
+
threads: ThreadOverview[];
|
|
469
|
+
next_before?: string;
|
|
470
|
+
has_more: boolean;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Read-only conversation-context surface for a single transport.
|
|
474
|
+
* Implemented per-transport when the transport owns (or fronts) durable
|
|
475
|
+
* conversation context. Transports that don't (e.g. current HTTP) return
|
|
476
|
+
* `null` from `Transport.getContextProvider()`.
|
|
477
|
+
*
|
|
478
|
+
* Lets agents navigate a room the way a human does:
|
|
479
|
+
* - `getRoomHistory` — every message chronologically
|
|
480
|
+
* - `getRecentThreads` — top-level entries only (scan-the-room view)
|
|
481
|
+
* - `getThreadHistory` — drill into one specific thread
|
|
482
|
+
*/
|
|
483
|
+
interface TransportContextProvider {
|
|
484
|
+
getRoomHistory(channelId: string, opts: HistoryOptions): Promise<HistoryPage>;
|
|
485
|
+
getRecentThreads(channelId: string, opts: HistoryOptions): Promise<ThreadOverviewPage>;
|
|
486
|
+
getThreadHistory(channelId: string, threadId: string, opts: HistoryOptions): Promise<HistoryPage>;
|
|
487
|
+
getChannelMembers(channelId: string): Promise<Member[]>;
|
|
488
|
+
getChannelInfo(channelId: string): Promise<ChannelInfo>;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export { AcpAgentRegistry, type AcpAgentRegistryOptions, type AcpAgentSpec, type AcpMount, type AcpRegistry, type AcpRegistryApprovalHandler, type AcpRegistryEventHandler, type AcpRuntime, type AcpSpawnSpec, type AgentConfig, ApprovalCorrelator, type ChannelInfo, type CliFlags, type ContainerConfig, type ContextSpawnFactory, type HistoryOptions, type HistoryPage, type HttpBinding, type HttpTransportConfig, type InboundMessage, type MatrixBinding, type MatrixTransportConfig, type Member, type Message, type RegisterOptions, type RegisteredApproval, type ThreadOverview, type ThreadOverviewPage, type ThreadRef, type Transport, type TransportConfig, type TransportContextProvider, type ZooidConfig, type ZooidContainerConfig, findConfigFile, findHttpTransport, findMatrixTransport, findTransport, loadZooidConfig, mergeCliFlags, resolveAcpAgentSpec };
|