@electric-ax/agents 0.2.3 → 0.3.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/dist/entrypoint.js +474 -737
- package/dist/index.cjs +470 -733
- package/dist/index.d.cts +68 -35
- package/dist/index.d.ts +69 -36
- package/dist/index.js +489 -751
- package/docs/entities/agents/horton.md +12 -12
- package/docs/entities/agents/worker.md +18 -18
- package/docs/entities/patterns/blackboard.md +6 -6
- package/docs/entities/patterns/dispatcher.md +1 -1
- package/docs/entities/patterns/manager-worker.md +1 -1
- package/docs/entities/patterns/map-reduce.md +1 -1
- package/docs/entities/patterns/pipeline.md +1 -1
- package/docs/entities/patterns/reactive-observers.md +2 -2
- package/docs/examples/playground.md +42 -26
- package/docs/index.md +25 -23
- package/docs/quickstart.md +12 -12
- package/docs/reference/agent-config.md +20 -12
- package/docs/reference/agent-tool.md +1 -1
- package/docs/reference/built-in-collections.md +21 -21
- package/docs/reference/cli.md +39 -30
- package/docs/reference/entity-definition.md +9 -9
- package/docs/reference/entity-handle.md +2 -2
- package/docs/reference/entity-registry.md +1 -1
- package/docs/reference/handler-context.md +34 -18
- package/docs/reference/mcp-registry.md +189 -0
- package/docs/reference/mcp-server-config.md +226 -0
- package/docs/reference/runtime-handler.md +25 -23
- package/docs/reference/shared-state-handle.md +7 -7
- package/docs/reference/state-collection-proxy.md +1 -1
- package/docs/reference/wake-event.md +23 -23
- package/docs/usage/app-setup.md +24 -23
- package/docs/usage/clients-and-react.md +40 -36
- package/docs/usage/configuring-the-agent.md +25 -19
- package/docs/usage/context-composition.md +12 -12
- package/docs/usage/defining-entities.md +36 -36
- package/docs/usage/defining-tools.md +45 -45
- package/docs/usage/embedded-builtins.md +54 -43
- package/docs/usage/managing-state.md +12 -12
- package/docs/usage/mcp-servers.md +354 -0
- package/docs/usage/overview.md +50 -45
- package/docs/usage/programmatic-runtime-client.md +51 -48
- package/docs/usage/shared-state.md +32 -32
- package/docs/usage/spawning-and-coordinating.md +9 -9
- package/docs/usage/testing.md +14 -14
- package/docs/usage/waking-entities.md +13 -13
- package/docs/usage/writing-handlers.md +52 -26
- package/package.json +9 -4
- package/scripts/sync-docs.mjs +42 -0
- package/docs/examples/mega-draw.md +0 -106
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Built-in collections
|
|
3
|
-
titleTemplate:
|
|
3
|
+
titleTemplate: "... - Electric Agents"
|
|
4
4
|
description: >-
|
|
5
5
|
Reference for the 17 runtime-managed collections: runs, steps, texts, toolCalls, inbox, errors, and more.
|
|
6
6
|
outline: [2, 3]
|
|
@@ -43,7 +43,7 @@ All collections use `key` as the primary key.
|
|
|
43
43
|
```ts
|
|
44
44
|
interface Run {
|
|
45
45
|
key: string
|
|
46
|
-
status:
|
|
46
|
+
status: "started" | "completed" | "failed"
|
|
47
47
|
finish_reason?: string
|
|
48
48
|
}
|
|
49
49
|
```
|
|
@@ -55,7 +55,7 @@ interface Step {
|
|
|
55
55
|
key: string
|
|
56
56
|
run_id?: string
|
|
57
57
|
step_number: number
|
|
58
|
-
status:
|
|
58
|
+
status: "started" | "completed"
|
|
59
59
|
finish_reason?: string
|
|
60
60
|
model_provider?: string
|
|
61
61
|
model_id?: string
|
|
@@ -69,7 +69,7 @@ interface Step {
|
|
|
69
69
|
interface Text {
|
|
70
70
|
key: string
|
|
71
71
|
run_id?: string
|
|
72
|
-
status:
|
|
72
|
+
status: "streaming" | "completed"
|
|
73
73
|
}
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -91,7 +91,7 @@ interface ToolCall {
|
|
|
91
91
|
key: string
|
|
92
92
|
run_id?: string
|
|
93
93
|
tool_name: string
|
|
94
|
-
status:
|
|
94
|
+
status: "started" | "args_complete" | "executing" | "completed" | "failed"
|
|
95
95
|
args?: unknown
|
|
96
96
|
result?: unknown
|
|
97
97
|
error?: string
|
|
@@ -104,7 +104,7 @@ interface ToolCall {
|
|
|
104
104
|
```ts
|
|
105
105
|
interface Reasoning {
|
|
106
106
|
key: string
|
|
107
|
-
status:
|
|
107
|
+
status: "streaming" | "completed"
|
|
108
108
|
}
|
|
109
109
|
```
|
|
110
110
|
|
|
@@ -148,14 +148,14 @@ interface WakeEntry {
|
|
|
148
148
|
|
|
149
149
|
interface WakeChangeEntry {
|
|
150
150
|
collection: string
|
|
151
|
-
kind:
|
|
151
|
+
kind: "insert" | "update" | "delete"
|
|
152
152
|
key: string
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
interface WakeFinishedChildEntry {
|
|
156
156
|
url: string
|
|
157
157
|
type: string
|
|
158
|
-
run_status:
|
|
158
|
+
run_status: "completed" | "failed"
|
|
159
159
|
response?: string // concatenated text deltas from the finished run
|
|
160
160
|
error?: string // error message(s) if run_status is "failed"
|
|
161
161
|
}
|
|
@@ -163,7 +163,7 @@ interface WakeFinishedChildEntry {
|
|
|
163
163
|
interface WakeOtherChildEntry {
|
|
164
164
|
url: string
|
|
165
165
|
type: string
|
|
166
|
-
status:
|
|
166
|
+
status: "spawning" | "running" | "idle" | "stopped"
|
|
167
167
|
}
|
|
168
168
|
```
|
|
169
169
|
|
|
@@ -196,7 +196,7 @@ interface ChildStatusEntry {
|
|
|
196
196
|
key: string
|
|
197
197
|
entity_url: string
|
|
198
198
|
entity_type: string
|
|
199
|
-
status:
|
|
199
|
+
status: "spawning" | "running" | "idle" | "stopped"
|
|
200
200
|
}
|
|
201
201
|
```
|
|
202
202
|
|
|
@@ -249,7 +249,7 @@ type Manifest =
|
|
|
249
249
|
|
|
250
250
|
interface ManifestChildEntry {
|
|
251
251
|
key: string
|
|
252
|
-
kind:
|
|
252
|
+
kind: "child"
|
|
253
253
|
id: string
|
|
254
254
|
entity_type: string
|
|
255
255
|
entity_url: string
|
|
@@ -259,7 +259,7 @@ interface ManifestChildEntry {
|
|
|
259
259
|
|
|
260
260
|
interface ManifestSourceEntry {
|
|
261
261
|
key: string
|
|
262
|
-
kind:
|
|
262
|
+
kind: "source"
|
|
263
263
|
sourceType: string
|
|
264
264
|
sourceRef: string
|
|
265
265
|
wake?: WakeConfig
|
|
@@ -268,16 +268,16 @@ interface ManifestSourceEntry {
|
|
|
268
268
|
|
|
269
269
|
interface ManifestSharedStateEntry {
|
|
270
270
|
key: string
|
|
271
|
-
kind:
|
|
271
|
+
kind: "shared-state"
|
|
272
272
|
id: string
|
|
273
|
-
mode:
|
|
273
|
+
mode: "create" | "connect"
|
|
274
274
|
collections: Record<string, { type: string; primaryKey: string }>
|
|
275
275
|
wake?: WakeConfig
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
interface ManifestEffectEntry {
|
|
279
279
|
key: string
|
|
280
|
-
kind:
|
|
280
|
+
kind: "effect"
|
|
281
281
|
id: string
|
|
282
282
|
function_ref: string
|
|
283
283
|
config: unknown
|
|
@@ -285,7 +285,7 @@ interface ManifestEffectEntry {
|
|
|
285
285
|
|
|
286
286
|
interface ManifestContextEntry {
|
|
287
287
|
key: string
|
|
288
|
-
kind:
|
|
288
|
+
kind: "context"
|
|
289
289
|
id: string
|
|
290
290
|
name: string
|
|
291
291
|
attrs: Record<string, string | number | boolean>
|
|
@@ -295,9 +295,9 @@ interface ManifestContextEntry {
|
|
|
295
295
|
|
|
296
296
|
interface ManifestCronScheduleEntry {
|
|
297
297
|
key: string
|
|
298
|
-
kind:
|
|
298
|
+
kind: "schedule"
|
|
299
299
|
id: string
|
|
300
|
-
scheduleType:
|
|
300
|
+
scheduleType: "cron"
|
|
301
301
|
expression: string
|
|
302
302
|
timezone?: string
|
|
303
303
|
payload?: unknown
|
|
@@ -306,16 +306,16 @@ interface ManifestCronScheduleEntry {
|
|
|
306
306
|
|
|
307
307
|
interface ManifestFutureSendScheduleEntry {
|
|
308
308
|
key: string
|
|
309
|
-
kind:
|
|
309
|
+
kind: "schedule"
|
|
310
310
|
id: string
|
|
311
|
-
scheduleType:
|
|
311
|
+
scheduleType: "future_send"
|
|
312
312
|
fireAt: string
|
|
313
313
|
targetUrl: string
|
|
314
314
|
payload: unknown
|
|
315
315
|
producerId: string
|
|
316
316
|
from?: string
|
|
317
317
|
messageType?: string
|
|
318
|
-
status?:
|
|
318
|
+
status?: "pending" | "sent" | "failed"
|
|
319
319
|
sentAt?: string
|
|
320
320
|
failedAt?: string
|
|
321
321
|
lastError?: string
|
package/docs/reference/cli.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: CLI
|
|
3
|
-
titleTemplate:
|
|
3
|
+
titleTemplate: "... - Electric Agents"
|
|
4
4
|
description: >-
|
|
5
5
|
Command reference for the Electric Agents CLI: spawn, send, observe, inspect, list, and manage entities.
|
|
6
6
|
outline: [2, 3]
|
|
@@ -16,14 +16,14 @@ npm install -g electric-ax
|
|
|
16
16
|
|
|
17
17
|
## Environment variables
|
|
18
18
|
|
|
19
|
-
| Variable
|
|
20
|
-
|
|
|
21
|
-
| `ELECTRIC_AGENTS_URL`
|
|
22
|
-
| `ELECTRIC_AGENTS_IDENTITY`
|
|
23
|
-
| `ELECTRIC_AGENTS_PORT`
|
|
24
|
-
| `ELECTRIC_AGENTS_BUILTIN_PORT`
|
|
25
|
-
| `ELECTRIC_AGENTS_COMPOSE_PROJECT` | `electric-agents` | Docker Compose project name
|
|
26
|
-
| `ANTHROPIC_API_KEY`
|
|
19
|
+
| Variable | Default | Purpose |
|
|
20
|
+
| -------------------------------- | ----------------------- | -------------------------------------------- |
|
|
21
|
+
| `ELECTRIC_AGENTS_URL` | `http://localhost:4437` | Server URL for entity commands and built-ins |
|
|
22
|
+
| `ELECTRIC_AGENTS_IDENTITY` | `user@hostname` | Sender identity for messages |
|
|
23
|
+
| `ELECTRIC_AGENTS_PORT` | `4437` | Port used by `start` / `quickstart` |
|
|
24
|
+
| `ELECTRIC_AGENTS_BUILTIN_PORT` | `4448` | Webhook port for `start-builtin` |
|
|
25
|
+
| `ELECTRIC_AGENTS_COMPOSE_PROJECT` | `electric-agents` | Docker Compose project name |
|
|
26
|
+
| `ANTHROPIC_API_KEY` | - | Required for `start-builtin` and `quickstart` |
|
|
27
27
|
|
|
28
28
|
## Commands
|
|
29
29
|
|
|
@@ -142,9 +142,9 @@ Start the built-in Horton runtime and register built-in agent types with the coo
|
|
|
142
142
|
electric agents start-builtin --anthropic-api-key sk-ant-...
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
| Option
|
|
146
|
-
|
|
|
147
|
-
| `--anthropic-api-key <key>`
|
|
145
|
+
| Option | Description |
|
|
146
|
+
| ------------------------------ | ---------------------------------------------- |
|
|
147
|
+
| `--anthropic-api-key <key>` | Anthropic API key for the built-in Horton server |
|
|
148
148
|
|
|
149
149
|
### <span class="cli-command"><code>quickstart [--anthropic-api-key <key>]</code></span> {#quickstart}
|
|
150
150
|
|
|
@@ -154,9 +154,9 @@ Start the coordinator server, print onboarding commands, and run the built-in ag
|
|
|
154
154
|
electric agents quickstart --anthropic-api-key sk-ant-...
|
|
155
155
|
```
|
|
156
156
|
|
|
157
|
-
| Option
|
|
158
|
-
|
|
|
159
|
-
| `--anthropic-api-key <key>`
|
|
157
|
+
| Option | Description |
|
|
158
|
+
| ------------------------------ | ---------------------------------------------- |
|
|
159
|
+
| `--anthropic-api-key <key>` | Anthropic API key for the built-in Horton server |
|
|
160
160
|
|
|
161
161
|
### <span class="cli-command"><code>stop [--remove-volumes]</code></span> {#stop}
|
|
162
162
|
|
|
@@ -171,6 +171,15 @@ electric agents stop --remove-volumes
|
|
|
171
171
|
| ------------------ | ------------------------------ |
|
|
172
172
|
| `--remove-volumes` | Remove Docker volumes as well. |
|
|
173
173
|
|
|
174
|
+
### <span class="cli-command"><code>init [project-name]</code></span> {#init-project-name}
|
|
175
|
+
|
|
176
|
+
Scaffold a new Electric Agents project from the bundled starter template.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
electric agents init
|
|
180
|
+
electric agents init my-agents-app
|
|
181
|
+
```
|
|
182
|
+
|
|
174
183
|
### <span class="cli-command"><code>completion [action]</code></span> {#completion-action}
|
|
175
184
|
|
|
176
185
|
Set up shell completions. Without arguments, prints setup instructions.
|
|
@@ -202,32 +211,32 @@ import {
|
|
|
202
211
|
createElectricProgram,
|
|
203
212
|
getElectricCliEnv,
|
|
204
213
|
run,
|
|
205
|
-
} from
|
|
214
|
+
} from "electric-ax"
|
|
206
215
|
|
|
207
216
|
const env = getElectricCliEnv({
|
|
208
|
-
ELECTRIC_AGENTS_URL:
|
|
209
|
-
ELECTRIC_AGENTS_IDENTITY:
|
|
217
|
+
ELECTRIC_AGENTS_URL: "http://localhost:4437",
|
|
218
|
+
ELECTRIC_AGENTS_IDENTITY: "docs@example.com",
|
|
210
219
|
})
|
|
211
220
|
|
|
212
|
-
const handlers = createElectricCliHandlers(env,
|
|
221
|
+
const handlers = createElectricCliHandlers(env, "electric agents")
|
|
213
222
|
const program = createElectricProgram({
|
|
214
223
|
env,
|
|
215
224
|
handlers,
|
|
216
|
-
commandName:
|
|
217
|
-
commandPrefix:
|
|
225
|
+
commandName: "electric",
|
|
226
|
+
commandPrefix: "electric agents",
|
|
218
227
|
})
|
|
219
228
|
|
|
220
|
-
await program.parseAsync([
|
|
229
|
+
await program.parseAsync(["node", "electric", "agents", "types"])
|
|
221
230
|
```
|
|
222
231
|
|
|
223
|
-
| Export
|
|
224
|
-
|
|
|
225
|
-
| `DEFAULT_ELECTRIC_AGENTS_URL`
|
|
226
|
-
| `getElectricCliEnv(env?)`
|
|
227
|
-
| `createElectricCliHandlers()`
|
|
228
|
-
| `createElectricProgram()`
|
|
229
|
-
| `resolveCommandPrefix(argv, env?)` | Resolves help text examples for direct or package-manager invocation.
|
|
230
|
-
| `run(argv?)`
|
|
232
|
+
| Export | Purpose |
|
|
233
|
+
| --------------------------------- | ------------------------------------------------------------------------ |
|
|
234
|
+
| `DEFAULT_ELECTRIC_AGENTS_URL` | Default server URL (`"http://localhost:4437"`). |
|
|
235
|
+
| `getElectricCliEnv(env?)` | Reads `ELECTRIC_AGENTS_URL` and `ELECTRIC_AGENTS_IDENTITY`. |
|
|
236
|
+
| `createElectricCliHandlers()` | Creates the default command handlers. |
|
|
237
|
+
| `createElectricProgram()` | Creates the Commander program. |
|
|
238
|
+
| `resolveCommandPrefix(argv, env?)` | Resolves help text examples for direct or package-manager invocation. |
|
|
239
|
+
| `run(argv?)` | Runs the CLI entrypoint. |
|
|
231
240
|
|
|
232
241
|
The installed binaries are `electric` and `electric-ax`. The package also includes `electric-dev` for development workflows.
|
|
233
242
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: EntityDefinition
|
|
3
|
-
titleTemplate:
|
|
3
|
+
titleTemplate: "... - Electric Agents"
|
|
4
4
|
description: >-
|
|
5
5
|
Type reference for EntityDefinition: description, state, schemas, and handler function signature.
|
|
6
6
|
outline: [2, 3]
|
|
@@ -28,15 +28,15 @@ interface EntityDefinition {
|
|
|
28
28
|
|
|
29
29
|
## Fields
|
|
30
30
|
|
|
31
|
-
| Field | Type | Required | Description
|
|
32
|
-
| ---------------- | ---------------------------------------------------- | -------- |
|
|
33
|
-
| `description` | `string` | No | Human-readable description of the entity type. Used in type registration.
|
|
34
|
-
| `state` | `Record<string, CollectionDefinition>` | No | Custom state collections exposed via `ctx.db.actions` (writes) and `ctx.db.collections` (reads).
|
|
31
|
+
| Field | Type | Required | Description |
|
|
32
|
+
| ---------------- | ---------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
33
|
+
| `description` | `string` | No | Human-readable description of the entity type. Used in type registration. |
|
|
34
|
+
| `state` | `Record<string, CollectionDefinition>` | No | Custom state collections exposed via `ctx.db.actions` (writes) and `ctx.db.collections` (reads). |
|
|
35
35
|
| `actions` | `(collections) => Record<string, (...args) => void>` | No | Factory for custom non-CRUD actions. Receives TanStack DB collections, returns named action functions exposed on `ctx.actions`. |
|
|
36
|
-
| `creationSchema` | `StandardJSONSchemaV1` | No | JSON Schema for spawn arguments validation.
|
|
37
|
-
| `inboxSchemas` | `Record<string, StandardJSONSchemaV1>` | No | JSON Schemas for inbound message types, keyed by message type.
|
|
38
|
-
| `outputSchemas` | `Record<string, StandardJSONSchemaV1>` | No | JSON Schemas for output event types. Defaults are provided by the runtime.
|
|
39
|
-
| `handler` | `(ctx, wake) => void \| Promise<void>` | Yes | The function invoked on each wake. Receives [`HandlerContext`](./handler-context) and [`WakeEvent`](./wake-event).
|
|
36
|
+
| `creationSchema` | `StandardJSONSchemaV1` | No | JSON Schema for spawn arguments validation. |
|
|
37
|
+
| `inboxSchemas` | `Record<string, StandardJSONSchemaV1>` | No | JSON Schemas for inbound message types, keyed by message type. |
|
|
38
|
+
| `outputSchemas` | `Record<string, StandardJSONSchemaV1>` | No | JSON Schemas for output event types. Defaults are provided by the runtime. |
|
|
39
|
+
| `handler` | `(ctx, wake) => void \| Promise<void>` | Yes | The function invoked on each wake. Receives [`HandlerContext`](./handler-context) and [`WakeEvent`](./wake-event). |
|
|
40
40
|
|
|
41
41
|
## CollectionDefinition
|
|
42
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: EntityHandle
|
|
3
|
-
titleTemplate:
|
|
3
|
+
titleTemplate: "... - Electric Agents"
|
|
4
4
|
description: >-
|
|
5
5
|
API reference for EntityHandle returned by spawn and observe: streams, status, text retrieval, and messaging.
|
|
6
6
|
outline: [2, 3]
|
|
@@ -49,7 +49,7 @@ interface ChildStatusEntry {
|
|
|
49
49
|
key: string
|
|
50
50
|
entity_url: string
|
|
51
51
|
entity_type: string
|
|
52
|
-
status:
|
|
52
|
+
status: "spawning" | "running" | "idle" | "stopped"
|
|
53
53
|
}
|
|
54
54
|
```
|
|
55
55
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: HandlerContext
|
|
3
|
-
titleTemplate:
|
|
3
|
+
titleTemplate: "... - Electric Agents"
|
|
4
4
|
description: >-
|
|
5
5
|
API reference for HandlerContext: state, coordination, agent configuration, and execution control.
|
|
6
6
|
outline: [2, 3]
|
|
@@ -44,11 +44,11 @@ interface HandlerContext<TState extends StateProxy = StateProxy> {
|
|
|
44
44
|
}
|
|
45
45
|
): Promise<EntityHandle>
|
|
46
46
|
observe(
|
|
47
|
-
source: ObservationSource & { sourceType:
|
|
47
|
+
source: ObservationSource & { sourceType: "entity" },
|
|
48
48
|
opts?: { wake?: Wake }
|
|
49
49
|
): Promise<EntityHandle>
|
|
50
50
|
observe(
|
|
51
|
-
source: ObservationSource & { sourceType:
|
|
51
|
+
source: ObservationSource & { sourceType: "db" },
|
|
52
52
|
opts?: { wake?: Wake }
|
|
53
53
|
): Promise<SharedStateHandle & ObservationHandle>
|
|
54
54
|
observe(
|
|
@@ -64,6 +64,7 @@ interface HandlerContext<TState extends StateProxy = StateProxy> {
|
|
|
64
64
|
payload: unknown,
|
|
65
65
|
opts?: { type?: string; afterMs?: number }
|
|
66
66
|
): void
|
|
67
|
+
recordRun(): RunHandle
|
|
67
68
|
setTag(key: string, value: string): Promise<void>
|
|
68
69
|
removeTag(key: string): Promise<void>
|
|
69
70
|
sleep(): void
|
|
@@ -74,27 +75,27 @@ interface HandlerContext<TState extends StateProxy = StateProxy> {
|
|
|
74
75
|
|
|
75
76
|
## Properties
|
|
76
77
|
|
|
77
|
-
| Property
|
|
78
|
-
|
|
|
79
|
-
| `firstWake`
|
|
80
|
-
| `tags`
|
|
81
|
-
| `entityUrl`
|
|
82
|
-
| `entityType`
|
|
83
|
-
| `args`
|
|
84
|
-
| `db`
|
|
85
|
-
| `state`
|
|
86
|
-
| `events`
|
|
87
|
-
| `actions`
|
|
88
|
-
| `electricTools` | `AgentTool[]` | Host-provided runtime-level tools to spread into agent config when needed. May be empty.
|
|
78
|
+
| Property | Type | Description |
|
|
79
|
+
| ------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| `firstWake` | `boolean` | `true` during the initial setup pass while the entity has no persisted manifest entries. Use state checks for one-time plain state initialization. |
|
|
81
|
+
| `tags` | `Readonly<EntityTags>` | Entity tags — key/value metadata associated with this entity. |
|
|
82
|
+
| `entityUrl` | `string` | URL path of this entity (e.g. `"/chat/my-convo"`). |
|
|
83
|
+
| `entityType` | `string` | Registered type name (e.g. `"chat"`). |
|
|
84
|
+
| `args` | `Readonly<Record<string, unknown>>` | Spawn arguments passed when the entity was created. |
|
|
85
|
+
| `db` | `EntityStreamDBWithActions` | The entity's TanStack DB instance with registered actions. |
|
|
86
|
+
| `state` | `TState` | Proxy object keyed by collection name. Each property is a [`StateCollectionProxy`](./state-collection-proxy). |
|
|
87
|
+
| `events` | `Array<ChangeEvent>` | Change events that triggered this wake. |
|
|
88
|
+
| `actions` | `Record<string, (...args: unknown[]) => unknown>` | Custom non-CRUD actions from the entity definition's `actions` factory. Auto-generated CRUD actions live on `ctx.db.actions` and `ctx.state`. |
|
|
89
|
+
| `electricTools` | `AgentTool[]` | Host-provided runtime-level tools to spread into agent config when needed. May be empty. |
|
|
89
90
|
|
|
90
91
|
## Methods
|
|
91
92
|
|
|
92
93
|
| Method | Return Type | Description |
|
|
93
94
|
| --------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
94
95
|
| `useAgent(config)` | `AgentHandle` | Configure the LLM agent. Must be called before `agent.run()`. See [`AgentConfig`](./agent-config). |
|
|
95
|
-
| `useContext(config)` | `void` | Declare context sources with token budgets and cache tiers for the agent's context window. See [Context composition](/docs/agents/usage/context-composition).
|
|
96
|
-
| `timelineMessages(opts?)` | `Array<TimestampedMessage>` | Project the entity timeline into an ordered array of LLM messages. Typically used as the `content` function of a volatile source. See [Context composition](/docs/agents/usage/context-composition#timelinemessages).
|
|
97
|
-
| `insertContext(id, entry)` | `void` | Insert a durable context entry. Persists across wakes. Inserting with an existing `id` replaces the previous entry. See [Context entries](/docs/agents/usage/context-composition#context-entries).
|
|
96
|
+
| `useContext(config)` | `void` | Declare context sources with token budgets and cache tiers for the agent's context window. See [Context composition](/docs/agents/usage/context-composition). |
|
|
97
|
+
| `timelineMessages(opts?)` | `Array<TimestampedMessage>` | Project the entity timeline into an ordered array of LLM messages. Typically used as the `content` function of a volatile source. See [Context composition](/docs/agents/usage/context-composition#timelinemessages). |
|
|
98
|
+
| `insertContext(id, entry)` | `void` | Insert a durable context entry. Persists across wakes. Inserting with an existing `id` replaces the previous entry. See [Context entries](/docs/agents/usage/context-composition#context-entries). |
|
|
98
99
|
| `removeContext(id)` | `void` | Remove a context entry by id. |
|
|
99
100
|
| `getContext(id)` | `ContextEntry \| undefined` | Get a context entry by id, or `undefined` if not found. |
|
|
100
101
|
| `listContext()` | `Array<ContextEntry>` | List all context entries. |
|
|
@@ -103,6 +104,21 @@ interface HandlerContext<TState extends StateProxy = StateProxy> {
|
|
|
103
104
|
| `observe(source, opts?)` | `Promise<EntityHandle \| SharedStateHandle \| ObservationHandle>` | Observe a source. Return type depends on source type: `EntityHandle` for entities, `SharedStateHandle & ObservationHandle` for db, `ObservationHandle` otherwise. Use `entity()`, `cron()`, `entities()`, `db()` helpers to build sources. |
|
|
104
105
|
| `mkdb(id, schema)` | `SharedStateHandle<T>` | Create a new shared state stream. See [`SharedStateHandle`](./shared-state-handle). |
|
|
105
106
|
| `send(entityUrl, payload, opts?)` | `void` | Send a message to another entity. `opts` accepts `type` and `afterMs` (delay in milliseconds). |
|
|
107
|
+
| `recordRun()` | `RunHandle` | Record a non-LLM run in the built-in `runs` collection, so observers using `wake: "runFinished"` are notified when external work completes. |
|
|
106
108
|
| `setTag(key, value)` | `Promise<void>` | Set a tag on this entity. |
|
|
107
109
|
| `removeTag(key)` | `Promise<void>` | Remove a tag from this entity. |
|
|
108
110
|
| `sleep()` | `void` | End the handler without running an agent. The entity remains idle until the next wake. |
|
|
111
|
+
|
|
112
|
+
## RunHandle
|
|
113
|
+
|
|
114
|
+
`recordRun()` is for handlers that perform work outside `ctx.agent.run()` but still want to expose run lifecycle events.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
interface RunHandle {
|
|
118
|
+
readonly key: string
|
|
119
|
+
end(opts: { status: "completed" | "failed"; finishReason?: string }): void
|
|
120
|
+
attachResponse(text: string): void
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`attachResponse()` appends text deltas linked to the run, which can be included in `runFinished` wake payloads.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: McpRegistry
|
|
3
|
+
titleTemplate: "... - Electric Agents"
|
|
4
|
+
description: >-
|
|
5
|
+
API reference for the MCP Registry — addServer, applyConfig,
|
|
6
|
+
subscribe, reauthorize, and the lifecycle of an MCP server entry
|
|
7
|
+
inside the runtime.
|
|
8
|
+
outline: [2, 3]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# McpRegistry
|
|
12
|
+
|
|
13
|
+
The MCP registry owns the live set of [Model Context Protocol](https://modelcontextprotocol.io) servers a runtime is connected to. It manages stdio subprocesses and HTTP clients, drives the OAuth state machine, and emits push-based snapshots so embedders can render UI without polling.
|
|
14
|
+
|
|
15
|
+
**Source:** `@electric-ax/agents-mcp` (re-exported as `McpRegistry` from `@electric-ax/agents`)
|
|
16
|
+
|
|
17
|
+
`BuiltinAgentsServer.mcpRegistry` exposes the instance that the embedded runtime owns; the [usage guide](/docs/agents/usage/mcp-servers) walks through registering servers from agent-host code.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
interface Registry {
|
|
21
|
+
addServer(cfg: McpServerConfig): Promise<AddServerResult>
|
|
22
|
+
applyConfig(cfg: McpConfig): Promise<AddServerResult[]>
|
|
23
|
+
removeServer(name: string): Promise<void>
|
|
24
|
+
list(): ReadonlyArray<ListedEntry>
|
|
25
|
+
get(name: string): Entry | undefined
|
|
26
|
+
finishAuth(server: string, code: string, state?: string): Promise<AddServerResult>
|
|
27
|
+
reauthorize(name: string): Promise<void>
|
|
28
|
+
disable(name: string): Promise<void>
|
|
29
|
+
enable(name: string): Promise<AddServerResult>
|
|
30
|
+
subscribe(handler: RegistrySubscriber): () => void
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Methods
|
|
35
|
+
|
|
36
|
+
| Method | Description |
|
|
37
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
38
|
+
| `addServer(cfg)` | Register or reconfigure a single server. Idempotent on unchanged `(name, url, transport, authMode, scopes, command, args)`. |
|
|
39
|
+
| `applyConfig(cfg)` | Replace the full set of registered servers. Adds new ones, reconfigures changed ones, and removes anything not in `cfg`. |
|
|
40
|
+
| `removeServer(name)` | Tear down a single server: close the transport, drop tokens from the in-memory cache, remove the entry. |
|
|
41
|
+
| `list()` | Returns the current snapshot as a plain array — same shape as the `servers` field of [`RegistrySnapshot`](#registrysnapshot). |
|
|
42
|
+
| `get(name)` | Internal lookup of a single entry, with the live `transport` handle and the resolved `provider`. Used by IPC handlers. |
|
|
43
|
+
| `finishAuth(name, code, state?)` | Complete the OAuth authorization-code flow for an `authenticating` server. Called by the embedder after intercepting the redirect URI. |
|
|
44
|
+
| `reauthorize(name)` | Force a fresh OAuth flow without removing the entry. Closes the transport, drops cached tokens (hooks remain registered), and rebuilds in place. |
|
|
45
|
+
| `disable(name)` | Pause a server. Closes the transport but keeps the entry; tokens stay in the cache. |
|
|
46
|
+
| `enable(name)` | Re-add a previously-disabled server using its last-known config. |
|
|
47
|
+
| `subscribe(handler)` | Push-based view of registry state. The handler fires synchronously with a sentinel snapshot, then on every mutation. Returns an unsubscribe function. |
|
|
48
|
+
|
|
49
|
+
## `addServer` vs `applyConfig`
|
|
50
|
+
|
|
51
|
+
Both feed the same internal pipeline; pick by what you have:
|
|
52
|
+
|
|
53
|
+
- **`addServer(cfg)`** — register one server. Use when you're adding an entry in response to a user action, a per-session tool, or a one-off integration.
|
|
54
|
+
- **`applyConfig({ servers })`** — replace the full set. Anything in the registry that isn't in `cfg.servers` is removed; existing entries with unchanged config are left alone (no transport churn). This is what the file-based loaders for `mcp.json` and the desktop `settings.json` compile down to.
|
|
55
|
+
|
|
56
|
+
Idempotency is the load-bearing property: editors save spuriously, file watchers fire double events on macOS, and most apps re-apply the same baseline on every restart. Calling `applyConfig` with the same shape twice does nothing the second time, so it's safe to wire to noisy upstreams.
|
|
57
|
+
|
|
58
|
+
## `AddServerResult`
|
|
59
|
+
|
|
60
|
+
`addServer` and `finishAuth` return a discriminated union so the caller can react without inspecting the registry afterwards:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
type AddServerResult =
|
|
64
|
+
| { state: "ready"; id: string; toolCount: number }
|
|
65
|
+
| { state: "authenticating"; id: string; authUrl: string }
|
|
66
|
+
| { state: "error"; id: string; error: McpToolError }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| State | Meaning |
|
|
70
|
+
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| `ready` | Connected and tools listed; calls available at the next agent wake. |
|
|
72
|
+
| `authenticating` | OAuth required. `authUrl` is the URL to send the user to. The desktop's `openAuthorizeUrl` hook opens it in a sandboxed BrowserWindow automatically. |
|
|
73
|
+
| `error` | Connect, transport, or auth-config failure. `error.kind` and `error.message` describe what went wrong. |
|
|
74
|
+
|
|
75
|
+
`applyConfig` returns one `AddServerResult` per server in the supplied config (in the same order).
|
|
76
|
+
|
|
77
|
+
## Lifecycle of an entry
|
|
78
|
+
|
|
79
|
+
Every entry transitions through one of five statuses, surfaced on the snapshot. The states that matter to UI:
|
|
80
|
+
|
|
81
|
+
| Status | Meaning |
|
|
82
|
+
| ---------------- | ------------------------------------------------------------------------------------------------ |
|
|
83
|
+
| `connecting` | Transport is being built (DCR, HTTPS discovery) or reconnecting. |
|
|
84
|
+
| `authenticating` | OAuth flow needed; `authUrl` is set, browser window is open. |
|
|
85
|
+
| `ready` | Transport connected; tools listed and callable. |
|
|
86
|
+
| `error` | Transport or auth-config failure. The entry stays in `list()` so the UI can surface the failure. |
|
|
87
|
+
| `disabled` | Operator paused the server via `disable(name)`. Recoverable through `enable(name)`. |
|
|
88
|
+
|
|
89
|
+
Transitions are atomic with respect to subscribers: every state change fires a single snapshot in which the entry shows its new status. `reauthorize` mutates entries in place — the row never disappears from `list()`, even mid-rebuild, so renderers don't see a flicker.
|
|
90
|
+
|
|
91
|
+
## `subscribe(handler)` and `RegistrySnapshot`
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
type RegistrySubscriber = (snapshot: RegistrySnapshot) => void
|
|
95
|
+
|
|
96
|
+
interface RegistrySnapshot {
|
|
97
|
+
seq: number
|
|
98
|
+
servers: ReadonlyArray<ListedEntry>
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Subscribing is the primary way to drive a UI off the registry. The first invocation is synchronous and carries `seq: 0` as a sentinel — embedders treat it as the bootstrap snapshot, not part of the event stream. After that, every mutation increments `seq` (1, 2, 3, …) and broadcasts the full snapshot. A late subscriber still sees `seq: 0` on its first delivery; emitted events continue from the registry's current counter.
|
|
103
|
+
|
|
104
|
+
Handlers must not throw. The registry catches exceptions per subscriber so a misbehaving consumer can't break the others, but the catch is a safety net, not a feature — log and swallow inside your handler.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
const off = registry.subscribe((snap) => {
|
|
108
|
+
if (snap.seq === 0) {
|
|
109
|
+
// bootstrap — render the initial list
|
|
110
|
+
} else {
|
|
111
|
+
// diff against the previous snapshot, or just re-render
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
// ...
|
|
115
|
+
off()
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## `ListedEntry`
|
|
119
|
+
|
|
120
|
+
The shape of each `servers[]` entry inside a snapshot:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
interface ListedEntry {
|
|
124
|
+
name: string
|
|
125
|
+
status: McpServerStatus
|
|
126
|
+
toolCount: number
|
|
127
|
+
transport?: "http" | "stdio"
|
|
128
|
+
authMode?: "none" | "apiKey" | "clientCredentials" | "authorizationCode"
|
|
129
|
+
authUrl?: string
|
|
130
|
+
error?: McpToolError
|
|
131
|
+
tools: Array<{ name: string; description?: string; inputSchema: unknown }>
|
|
132
|
+
capabilities?: unknown
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
| Field | Type | Description |
|
|
137
|
+
| -------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
138
|
+
| `name` | `string` | The server's stable identifier. |
|
|
139
|
+
| `status` | `McpServerStatus` | Current lifecycle state — see the table above. |
|
|
140
|
+
| `toolCount` | `number` | Number of tools the server advertises. `0` until `status === "ready"`. |
|
|
141
|
+
| `transport` | `"http" \| "stdio"` | The transport variant in use. |
|
|
142
|
+
| `authMode` | `string` | `none` / `apiKey` / `clientCredentials` / `authorizationCode`. UI badges + "show Authorize" check use this. |
|
|
143
|
+
| `authUrl` | `string` | Set while `status === "authenticating"`. The URL to open for OAuth consent. |
|
|
144
|
+
| `error` | [`McpToolError`](#mcptoolerror) | Set while `status === "error"`. |
|
|
145
|
+
| `tools` | `Array<{ name; description?; inputSchema }>` | Tool metadata as advertised by the server. Each becomes `mcp__<server>__<tool>` for the LLM. |
|
|
146
|
+
| `capabilities` | `unknown` | Server-declared MCP capabilities object (resources, prompts, etc.). |
|
|
147
|
+
|
|
148
|
+
## `McpToolError`
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
interface McpToolError {
|
|
152
|
+
kind: McpToolErrorKind
|
|
153
|
+
message: string
|
|
154
|
+
details?: unknown
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
type McpToolErrorKind =
|
|
158
|
+
| "auth_unavailable"
|
|
159
|
+
| "transport_error"
|
|
160
|
+
| "timeout"
|
|
161
|
+
| "server_error"
|
|
162
|
+
| "tool_not_found"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The same shape surfaces on entry-level `error` (when `addServer` fails to connect) and on individual tool calls. See the [usage guide's failure modes table](/docs/agents/usage/mcp-servers#failure-modes).
|
|
166
|
+
|
|
167
|
+
## `RegistryOpts`
|
|
168
|
+
|
|
169
|
+
`BuiltinAgentsServer` constructs the registry on your behalf. You only see this shape if you instantiate `agents-mcp` directly (e.g. from a custom embedder):
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
interface RegistryOpts {
|
|
173
|
+
publicUrl?: string
|
|
174
|
+
openAuthorizeUrl?: (url: string, server: string) => void
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function createRegistry(opts: RegistryOpts): Registry
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
| Field | Description |
|
|
181
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
182
|
+
| `publicUrl` | Base URL used to construct the OAuth `redirect_uri` (full URI is `<publicUrl>/oauth/callback/<server-name>`). MUST be stable across restarts — DCR registers it with the auth server and persists it in the keychain, so a value that drifts forces re-authorization on every launch. Embedders that listen on an ephemeral port should pass a fixed loopback literal (the desktop uses `http://127.0.0.1:53117`); nothing actually listens at the URL — the embedder's BrowserWindow intercepts the redirect by prefix. |
|
|
183
|
+
| `openAuthorizeUrl` | Hook invoked when an `authorizationCode` server first needs consent. Receives the SDK-generated authorize URL. The desktop opens it in a sandboxed `BrowserWindow`; headless embedders can read the URL from the `authenticating` envelope of `addServer` and surface it themselves. |
|
|
184
|
+
|
|
185
|
+
## See also
|
|
186
|
+
|
|
187
|
+
- [MCP servers usage guide](/docs/agents/usage/mcp-servers) — the practical walkthrough of registering servers, OAuth, persistence, and the per-agent allowlist.
|
|
188
|
+
- [`McpServerConfig`](/docs/agents/reference/mcp-server-config) — schema for the `cfg` argument to `addServer` / `applyConfig`.
|
|
189
|
+
- [`BuiltinAgentsServer`](/docs/agents/usage/embedded-builtins) — host options that affect MCP, including `extraMcpServers` and `openAuthorizeUrl`.
|