@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.
Files changed (49) hide show
  1. package/dist/entrypoint.js +474 -737
  2. package/dist/index.cjs +470 -733
  3. package/dist/index.d.cts +68 -35
  4. package/dist/index.d.ts +69 -36
  5. package/dist/index.js +489 -751
  6. package/docs/entities/agents/horton.md +12 -12
  7. package/docs/entities/agents/worker.md +18 -18
  8. package/docs/entities/patterns/blackboard.md +6 -6
  9. package/docs/entities/patterns/dispatcher.md +1 -1
  10. package/docs/entities/patterns/manager-worker.md +1 -1
  11. package/docs/entities/patterns/map-reduce.md +1 -1
  12. package/docs/entities/patterns/pipeline.md +1 -1
  13. package/docs/entities/patterns/reactive-observers.md +2 -2
  14. package/docs/examples/playground.md +42 -26
  15. package/docs/index.md +25 -23
  16. package/docs/quickstart.md +12 -12
  17. package/docs/reference/agent-config.md +20 -12
  18. package/docs/reference/agent-tool.md +1 -1
  19. package/docs/reference/built-in-collections.md +21 -21
  20. package/docs/reference/cli.md +39 -30
  21. package/docs/reference/entity-definition.md +9 -9
  22. package/docs/reference/entity-handle.md +2 -2
  23. package/docs/reference/entity-registry.md +1 -1
  24. package/docs/reference/handler-context.md +34 -18
  25. package/docs/reference/mcp-registry.md +189 -0
  26. package/docs/reference/mcp-server-config.md +226 -0
  27. package/docs/reference/runtime-handler.md +25 -23
  28. package/docs/reference/shared-state-handle.md +7 -7
  29. package/docs/reference/state-collection-proxy.md +1 -1
  30. package/docs/reference/wake-event.md +23 -23
  31. package/docs/usage/app-setup.md +24 -23
  32. package/docs/usage/clients-and-react.md +40 -36
  33. package/docs/usage/configuring-the-agent.md +25 -19
  34. package/docs/usage/context-composition.md +12 -12
  35. package/docs/usage/defining-entities.md +36 -36
  36. package/docs/usage/defining-tools.md +45 -45
  37. package/docs/usage/embedded-builtins.md +54 -43
  38. package/docs/usage/managing-state.md +12 -12
  39. package/docs/usage/mcp-servers.md +354 -0
  40. package/docs/usage/overview.md +50 -45
  41. package/docs/usage/programmatic-runtime-client.md +51 -48
  42. package/docs/usage/shared-state.md +32 -32
  43. package/docs/usage/spawning-and-coordinating.md +9 -9
  44. package/docs/usage/testing.md +14 -14
  45. package/docs/usage/waking-entities.md +13 -13
  46. package/docs/usage/writing-handlers.md +52 -26
  47. package/package.json +9 -4
  48. package/scripts/sync-docs.mjs +42 -0
  49. package/docs/examples/mega-draw.md +0 -106
@@ -0,0 +1,226 @@
1
+ ---
2
+ title: McpServerConfig
3
+ titleTemplate: "... - Electric Agents"
4
+ description: >-
5
+ Schema reference for MCP server entries — transports, auth modes, and
6
+ persistence callbacks accepted by Registry.addServer, applyConfig, and
7
+ the mcp.json / settings.json layers.
8
+ outline: [2, 3]
9
+ ---
10
+
11
+ # McpServerConfig
12
+
13
+ Shape of a server entry in the MCP registry. Identical between declarative (`mcp.json`, desktop `settings.json`) and programmatic (`Registry.addServer`) creation paths.
14
+
15
+ **Source:** `@electric-ax/agents` (re-exported from `@electric-ax/agents-mcp`)
16
+
17
+ ```ts
18
+ type McpServerConfig = McpHttpServerConfig | McpStdioServerConfig
19
+ ```
20
+
21
+ The variant is selected by the `transport` field.
22
+
23
+ ## McpHttpServerConfig
24
+
25
+ Streamable HTTP transport per the current MCP spec.
26
+
27
+ ```ts
28
+ interface McpHttpServerConfig {
29
+ name: string
30
+ transport: "http"
31
+ url: string
32
+ auth: McpAuthConfig
33
+ timeoutMs?: number
34
+ }
35
+ ```
36
+
37
+ | Field | Type | Required | Description |
38
+ | ----------- | --------------- | -------- | ---------------------------------------------------------------------------- |
39
+ | `name` | `string` | Yes | Stable identifier. Used as the keychain account, the IPC verb argument, and the `mcp__<name>__<tool>` tool prefix. |
40
+ | `transport` | `"http"` | Yes | Discriminator selecting the HTTP variant. |
41
+ | `url` | `string` | Yes | The MCP server's HTTPS endpoint. Streamable transport with SSE inside. |
42
+ | `auth` | `McpAuthConfig` | Yes | One of the auth modes below. Use `{ mode: "none" }` for unauthenticated servers. |
43
+ | `timeoutMs` | `number` | No | Per-call timeout override. Default `30000` (30 seconds). |
44
+
45
+ ## McpStdioServerConfig
46
+
47
+ Locally-spawned subprocess speaking the MCP stdio protocol.
48
+
49
+ ```ts
50
+ interface McpStdioServerConfig {
51
+ name: string
52
+ transport: "stdio"
53
+ command: string
54
+ args?: string[]
55
+ env?: Record<string, string>
56
+ auth?: McpAuthConfig
57
+ timeoutMs?: number
58
+ }
59
+ ```
60
+
61
+ | Field | Type | Required | Description |
62
+ | ----------- | ------------------------ | -------- | ------------------------------------------------------------------------ |
63
+ | `name` | `string` | Yes | Stable identifier (see HTTP variant). |
64
+ | `transport` | `"stdio"` | Yes | Discriminator selecting the stdio variant. |
65
+ | `command` | `string` | Yes | Executable name or absolute path. Resolved against `PATH`. |
66
+ | `args` | `string[]` | No | CLI arguments. `${workspaceRoot}` is the only built-in expansion. |
67
+ | `env` | `Record<string, string>` | No | Environment variables for the subprocess. Inherits the parent's `PATH`. |
68
+ | `auth` | `McpAuthConfig` | No | Typically `{ mode: "none" }`. Defaults to `none` when omitted. |
69
+ | `timeoutMs` | `number` | No | Per-call timeout override. Default `30000`. |
70
+
71
+ The subprocess is spawned lazily on the first tool call, kept alive across calls, and restarted on crash. One process per server, multiplexed via JSON-RPC `id`.
72
+
73
+ ## McpAuthConfig
74
+
75
+ Discriminated union covering the four supported credential modes.
76
+
77
+ ```ts
78
+ type McpAuthConfig =
79
+ | { mode: "none" }
80
+ | ApiKeyAuth
81
+ | ClientCredentialsAuth
82
+ | AuthorizationCodeAuth
83
+ ```
84
+
85
+ ### `none`
86
+
87
+ ```ts
88
+ { mode: "none" }
89
+ ```
90
+
91
+ No authentication. Required for stdio servers that don't need credentials; rare for HTTP servers.
92
+
93
+ ### `apiKey`
94
+
95
+ ```ts
96
+ interface ApiKeyAuth {
97
+ mode: "apiKey"
98
+ key: string
99
+ headerName?: string // default "Authorization"
100
+ valuePrefix?: string // e.g. "Bearer "
101
+ }
102
+ ```
103
+
104
+ | Field | Type | Required | Description |
105
+ | ------------- | -------- | -------- | ---------------------------------------------------------------------------- |
106
+ | `key` | `string` | Yes | Raw secret. Inline at the call site (e.g. `process.env.X_API_KEY`). |
107
+ | `headerName` | `string` | No | HTTP header name. Defaults to `Authorization`. |
108
+ | `valuePrefix` | `string` | No | Prepended to the key. Use `"Bearer "` for bearer tokens; empty for raw keys. |
109
+
110
+ ### `clientCredentials`
111
+
112
+ OAuth 2.1 client-credentials grant. Unattended; no user interaction.
113
+
114
+ ```ts
115
+ interface ClientCredentialsAuth {
116
+ mode: "clientCredentials"
117
+ tokenUrl: string
118
+ clientId: string
119
+ clientSecret: string
120
+ scopes?: string[]
121
+ audience?: string
122
+ resource?: string
123
+ }
124
+ ```
125
+
126
+ | Field | Type | Required | Description |
127
+ | -------------- | ---------- | -------- | --------------------------------------------------------------------------- |
128
+ | `tokenUrl` | `string` | Yes | OAuth token endpoint. |
129
+ | `clientId` | `string` | Yes | Inline at the call site (e.g. `process.env.X_CLIENT_ID`). |
130
+ | `clientSecret` | `string` | Yes | Inline at the call site (e.g. `process.env.X_CLIENT_SECRET`). |
131
+ | `scopes` | `string[]` | No | Requested OAuth scopes. |
132
+ | `audience` | `string` | No | Auth0/OIDC `audience` claim, when the auth server requires it. |
133
+ | `resource` | `string` | No | RFC 8707 resource indicator. |
134
+
135
+ The runtime exchanges the credentials for a short-lived access token, retries the exchange on 401, and never surfaces user-facing errors during steady state.
136
+
137
+ ### `authorizationCode`
138
+
139
+ OAuth 2.1 authorization-code grant with PKCE. Requires a one-time browser flow per user.
140
+
141
+ ```ts
142
+ interface AuthorizationCodeAuth {
143
+ mode: "authorizationCode"
144
+ scopes?: string[]
145
+ resource?: string
146
+ redirectUri?: string
147
+ client?: OAuthClientInfo
148
+ tokens?: OAuthTokens
149
+ onTokensChanged?: (tokens: OAuthTokens) => void | Promise<void>
150
+ onClientRegistered?: (client: OAuthClientInfo) => void | Promise<void>
151
+ oauthProviderRef?: string
152
+ }
153
+ ```
154
+
155
+ | Field | Type | Required | Description |
156
+ | -------------------- | --------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
157
+ | `scopes` | `string[]` | No | Requested OAuth scopes. |
158
+ | `resource` | `string` | No | RFC 8707 resource indicator. |
159
+ | `redirectUri` | `string` | No | Override the default `${publicUrl}/oauth/callback/<server>` sentinel. Most embedders don't need this. |
160
+ | `client` | `OAuthClientInfo` | No | Pre-registered OAuth client (`client_id`, optional `client_secret`). When present, RFC 7591 Dynamic Client Registration is skipped. |
161
+ | `tokens` | `OAuthTokens` | No | Pre-existing tokens to seed the in-process cache. The OAuth flow is skipped on boot; refresh-token rotation still happens transparently. |
162
+ | `onTokensChanged` | `(tokens) => void \| Promise<void>` | No | Fires after initial auth and on every refresh. Wire to a persistence layer if tokens should survive process restarts. |
163
+ | `onClientRegistered` | `(client) => void \| Promise<void>` | No | Fires once after RFC 7591 DCR completes. Pair with `client` on the next boot to skip DCR. |
164
+ | `oauthProviderRef` | `string` | No | Reference into a per-process map of pre-built `OAuthClientProvider` instances. Escape hatch for mTLS, OIDC quirks, etc. |
165
+
166
+ ### `OAuthTokens`
167
+
168
+ ```ts
169
+ interface OAuthTokens {
170
+ accessToken: string
171
+ refreshToken?: string
172
+ expiresAt?: number // Unix seconds
173
+ }
174
+ ```
175
+
176
+ ### `OAuthClientInfo`
177
+
178
+ ```ts
179
+ interface OAuthClientInfo {
180
+ clientId: string
181
+ clientSecret?: string
182
+ // RFC 7591 metadata (issued_at, expires_at, redirect_uris, …)
183
+ // — preserved verbatim from the DCR response.
184
+ [key: string]: unknown
185
+ }
186
+ ```
187
+
188
+ ## Validation
189
+
190
+ `mcp.json` and programmatic configs are validated when first applied:
191
+
192
+ - `transport` must be `"http"` or `"stdio"`.
193
+ - `auth.mode` must be one of `none` / `apiKey` / `clientCredentials` / `authorizationCode`.
194
+ - `mcp.json` rejects forbidden reference keys (`clientIdRef`, `clientSecretRef`, `valueRef`, …) — secrets must be passed inline at the call site, not declared as references.
195
+ - Inline `${VAR}` placeholders in `mcp.json` are expanded against `process.env` before validation.
196
+
197
+ Invalid entries surface as `error`-state entries in `Registry.list()` with a structured `McpToolError`. The rest of the registry continues to operate.
198
+
199
+ ## Persistence helpers
200
+
201
+ Two opt-in helpers from `@electric-ax/agents-mcp` produce auth-config slices that satisfy the persistence callback contract:
202
+
203
+ ```ts
204
+ import { keychainPersistence, filePersistence } from "@electric-ax/agents-mcp"
205
+
206
+ const tokens = await keychainPersistence({ server: "honeycomb" })
207
+ // → { tokens?, client?, onTokensChanged, onClientRegistered }
208
+
209
+ await registry.addServer({
210
+ name: "honeycomb",
211
+ transport: "http",
212
+ url: "https://mcp.honeycomb.io/mcp",
213
+ auth: { mode: "authorizationCode", scopes: ["mcp:read"], ...tokens },
214
+ })
215
+ ```
216
+
217
+ | Helper | Backing store | Notes |
218
+ | ----------------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------- |
219
+ | `keychainPersistence({ server })` | macOS `security`, Linux `secret-tool`. Throws on Windows. | Service `electric-agents`, accounts `tokens:<server>` / `client:<server>`. |
220
+ | `filePersistence({ path, server })` | Mode-`0600` JSON file. Refuses to read files with looser permissions. | Use for CI / containers without an OS keychain. |
221
+
222
+ ## See also
223
+
224
+ - [MCP servers usage guide](/docs/agents/usage/mcp-servers) — programmatic, file-based, and desktop-settings paths end-to-end.
225
+ - [`McpRegistry`](/docs/agents/reference/mcp-registry) — the API that consumes this config (`addServer` / `applyConfig` / lifecycle).
226
+ - [`BuiltinAgentsServer`](/docs/agents/usage/embedded-builtins) — host options that affect MCP, including `extraMcpServers` and `openAuthorizeUrl`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: RuntimeHandler
3
- titleTemplate: '... - Electric Agents'
3
+ titleTemplate: "... - Electric Agents"
4
4
  description: >-
5
5
  API reference for RuntimeHandler: webhook handling, type registration, and deployment configuration.
6
6
  outline: [2, 3]
@@ -28,16 +28,16 @@ interface RuntimeRouter {
28
28
  }
29
29
  ```
30
30
 
31
- | Method | Return Type | Description |
32
- | ----------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
33
- | `handleRequest(request)` | `Promise<Response \| null>` | Route a fetch `Request`. Returns `null` if the request path does not match `webhookPath`. |
34
- | `handleWebhookRequest(request)` | `Promise<Response>` | Handle a webhook request directly, without route matching. |
35
- | `dispatchWebhookWake(notification)` | `void` | Dispatch an already-parsed webhook notification. Runs the wake handler in the background. |
36
- | `drainWakes()` | `Promise<void>` | Wait for all in-flight wake handlers to settle. Throws if any wake errored. |
37
- | `waitForSettled()` | `Promise<void>` | Wait for all in-flight wake handlers to settle. |
38
- | `abortWakes()` | `void` | Abort in-flight wakes so host shutdown can complete quickly. |
39
- | `debugState()` | `RuntimeDebugState` | Return a runtime-local snapshot for tests and shutdown diagnostics. |
40
- | `typeNames` | `string[]` | Names of all registered entity types (read-only). |
31
+ | Method | Return Type | Description |
32
+ | ----------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------- |
33
+ | `handleRequest(request)` | `Promise<Response \| null>` | Route a fetch `Request`. Returns `null` if the request path does not match `webhookPath`. |
34
+ | `handleWebhookRequest(request)` | `Promise<Response>` | Handle a webhook request directly, without route matching. |
35
+ | `dispatchWebhookWake(notification)` | `void` | Dispatch an already-parsed webhook notification. Runs the wake handler in the background. |
36
+ | `drainWakes()` | `Promise<void>` | Wait for all in-flight wake handlers to settle. Throws if any wake errored. |
37
+ | `waitForSettled()` | `Promise<void>` | Wait for all in-flight wake handlers to settle. |
38
+ | `abortWakes()` | `void` | Abort in-flight wakes so host shutdown can complete quickly. |
39
+ | `debugState()` | `RuntimeDebugState` | Return a runtime-local snapshot for tests and shutdown diagnostics. |
40
+ | `typeNames` | `string[]` | Names of all registered entity types (read-only). |
41
41
  | `registerTypes()` | `Promise<void>` | Register all entity types with the Electric Agents runtime server. Uses upsert semantics — safe to call on every startup. |
42
42
 
43
43
  ## RuntimeHandler
@@ -89,6 +89,7 @@ interface RuntimeRouterConfig {
89
89
  baseUrl: string
90
90
  serveEndpoint?: string
91
91
  webhookPath?: string
92
+ handlerUrl?: string
92
93
  registry?: EntityRegistry
93
94
  subscriptionPathForType?: (typeName: string) => string
94
95
  idleTimeout?: number
@@ -122,15 +123,16 @@ interface RuntimeRouterConfig {
122
123
  }
123
124
  ```
124
125
 
125
- | Field | Type | Default | Description |
126
- | ------------------------- | ------------------------------------------ | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
127
- | `baseUrl` | `string` | - | Base URL of the Electric Agents runtime server (e.g. `"http://localhost:4437"`). Required. |
128
- | `serveEndpoint` | `string` | - | Full webhook callback URL exposed by your app. Used for type registration. |
129
- | `webhookPath` | `string` | pathname from `serveEndpoint`, or `"/electric-agents"` | Path matched by `handleRequest()`. |
130
- | `registry` | `EntityRegistry` | default registry | Entity registry for this handler. Falls back to the module-level default registry. |
131
- | `subscriptionPathForType` | `(typeName: string) => string` | - | Override the webhook subscription path used per entity type registration. |
132
- | `idleTimeout` | `number` | `20000` | Idle timeout in milliseconds before closing a wake. |
133
- | `heartbeatInterval` | `number` | `30000` | Heartbeat interval in milliseconds. |
134
- | `createElectricTools` | `(context) => AgentTool[] \| Promise<...>` | - | Optional tool factory invoked for each wake context before handler execution. Provides extra tools to the agent. |
135
- | `onWakeError` | `(error: Error) => boolean \| void` | - | Observer for background wake failures. Return `true` to mark the error as handled so it is not rethrown on drain. |
136
- | `registrationConcurrency` | `number` | `8` | Max number of concurrent entity-type registrations. |
126
+ | Field | Type | Default | Description |
127
+ | ------------------------- | ------------------------------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
128
+ | `baseUrl` | `string` | - | Base URL of the Electric Agents runtime server (e.g. `"http://localhost:4437"`). Required. |
129
+ | `serveEndpoint` | `string` | - | Full webhook callback URL exposed by your app. Used for type registration. |
130
+ | `webhookPath` | `string` | pathname from `serveEndpoint` / `handlerUrl`, or `"/electric-agents"` | Path matched by `handleRequest()`. |
131
+ | `handlerUrl` | `string` | - | Backward-compatible alias for `serveEndpoint`; prefer `serveEndpoint` in new code. |
132
+ | `registry` | `EntityRegistry` | default registry | Entity registry for this handler. Falls back to the module-level default registry. |
133
+ | `subscriptionPathForType` | `(typeName: string) => string` | - | Override the webhook subscription path used per entity type registration. |
134
+ | `idleTimeout` | `number` | `20000` | Idle timeout in milliseconds before closing a wake. |
135
+ | `heartbeatInterval` | `number` | `30000` | Heartbeat interval in milliseconds. |
136
+ | `createElectricTools` | `(context) => AgentTool[] \| Promise<...>` | - | Optional tool factory invoked for each wake context before handler execution. Provides extra tools to the agent. |
137
+ | `onWakeError` | `(error: Error) => boolean \| void` | - | Observer for background wake failures. Return `true` to mark the error as handled so it is not rethrown on drain. |
138
+ | `registrationConcurrency` | `number` | `8` | Max number of concurrent entity-type registrations. |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: SharedStateHandle
3
- titleTemplate: '... - Electric Agents'
3
+ titleTemplate: "... - Electric Agents"
4
4
  description: >-
5
5
  Type reference for SharedStateHandle: collection proxies and SharedStateSchemaMap interface.
6
6
  outline: [2, 3]
@@ -54,7 +54,7 @@ interface SharedStateCollectionSchema {
54
54
  ## Example
55
55
 
56
56
  ```ts
57
- import { db } from '@electric-ax/agents-runtime'
57
+ import { db } from "@electric-ax/agents-runtime"
58
58
 
59
59
  const schema = {
60
60
  findings: {
@@ -63,12 +63,12 @@ const schema = {
63
63
  domain: z.string(),
64
64
  finding: z.string(),
65
65
  }),
66
- type: 'finding',
67
- primaryKey: 'key',
66
+ type: "finding",
67
+ primaryKey: "key",
68
68
  },
69
69
  }
70
70
 
71
- ctx.mkdb('research-findings', schema)
72
- const shared = await ctx.observe(db('research-findings', schema))
73
- shared.findings.insert({ key: 'f1', domain: 'security', finding: '...' })
71
+ ctx.mkdb("research-findings", schema)
72
+ const shared = await ctx.observe(db("research-findings", schema))
73
+ shared.findings.insert({ key: "f1", domain: "security", finding: "..." })
74
74
  ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: StateCollectionProxy
3
- titleTemplate: '... - Electric Agents'
3
+ titleTemplate: "... - Electric Agents"
4
4
  description: >-
5
5
  API reference for StateCollectionProxy: insert, update, delete, get, and toArray operations.
6
6
  outline: [2, 3]
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: WakeEvent
3
- titleTemplate: '... - Electric Agents'
3
+ titleTemplate: "... - Electric Agents"
4
4
  description: >-
5
5
  Type reference for WakeEvent and Wake configuration: runFinished and change-based wake conditions.
6
6
  outline: [2, 3]
@@ -27,16 +27,16 @@ type WakeEvent = {
27
27
 
28
28
  ## Fields
29
29
 
30
- | Field | Type | Description |
31
- | ------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------- |
32
- | `source` | `string` | URL or identifier of the stream that triggered the wake. |
30
+ | Field | Type | Description |
31
+ | ------------ | --------- | ------------------------------------------------------------------------ |
32
+ | `source` | `string` | URL or identifier of the stream that triggered the wake. |
33
33
  | `type` | `string` | Wake type. Usually `"message_received"` or `"wake"`; fallback webhook events can use `triggerEvent` or `"message"`. See catalog. |
34
- | `fromOffset` | `number` | Start offset of new events in the source stream. |
35
- | `toOffset` | `number` | End offset (exclusive) of new events. |
36
- | `eventCount` | `number` | Number of new events in this wake. |
37
- | `payload` | `unknown` | Optional payload data associated with the wake. Shape depends on `type`. |
38
- | `summary` | `string` | Optional human-readable summary of the wake reason. |
39
- | `fullRef` | `string` | Optional full reference identifier for the wake source. |
34
+ | `fromOffset` | `number` | Start offset of new events in the source stream. |
35
+ | `toOffset` | `number` | End offset (exclusive) of new events. |
36
+ | `eventCount` | `number` | Number of new events in this wake. |
37
+ | `payload` | `unknown` | Optional payload data associated with the wake. Shape depends on `type`. |
38
+ | `summary` | `string` | Optional human-readable summary of the wake reason. |
39
+ | `fullRef` | `string` | Optional full reference identifier for the wake source. |
40
40
 
41
41
  ## Wake-type catalog
42
42
 
@@ -63,20 +63,20 @@ type WakeMessage = {
63
63
  timeout: boolean
64
64
  changes: Array<{
65
65
  collection: string
66
- kind: 'insert' | 'update' | 'delete'
66
+ kind: "insert" | "update" | "delete"
67
67
  key: string
68
68
  }>
69
69
  finished_child?: {
70
70
  url: string
71
71
  type: string
72
- run_status: 'completed' | 'failed'
72
+ run_status: "completed" | "failed"
73
73
  response?: string
74
74
  error?: string
75
75
  }
76
76
  other_children?: Array<{
77
77
  url: string
78
78
  type: string
79
- status: 'spawning' | 'running' | 'idle' | 'stopped'
79
+ status: "spawning" | "running" | "idle" | "stopped"
80
80
  }>
81
81
  }
82
82
  ```
@@ -100,12 +100,12 @@ The `Wake` type configures when a parent should be woken in response to a child,
100
100
 
101
101
  ```ts
102
102
  type Wake =
103
- | 'runFinished'
104
- | { on: 'runFinished'; includeResponse?: boolean }
103
+ | "runFinished"
104
+ | { on: "runFinished"; includeResponse?: boolean }
105
105
  | {
106
- on: 'change'
106
+ on: "change"
107
107
  collections?: string[]
108
- ops?: ('insert' | 'update' | 'delete')[]
108
+ ops?: ("insert" | "update" | "delete")[]
109
109
  debounceMs?: number
110
110
  timeoutMs?: number
111
111
  }
@@ -123,10 +123,10 @@ Object form of `runFinished` with options. Set `includeResponse: false` to omit
123
123
 
124
124
  Wake the parent when changes occur in the observed stream.
125
125
 
126
- | Field | Type | Description |
127
- | ------------- | ---------- | --------------------------------------------------------------------- |
128
- | `on` | `'change'` | Required discriminant. |
129
- | `collections` | `string[]` | Optional filter. Only wake on changes to these collections. |
126
+ | Field | Type | Description |
127
+ | ------------- | ---------- | ------------------------------------------------------------- |
128
+ | `on` | `'change'` | Required discriminant. |
129
+ | `collections` | `string[]` | Optional filter. Only wake on changes to these collections. |
130
130
  | `ops` | `string[]` | Optional operation filter: `"insert"`, `"update"`, and/or `"delete"`. |
131
- | `debounceMs` | `number` | Debounce interval in milliseconds. Batches rapid changes. |
132
- | `timeoutMs` | `number` | Maximum time to wait before waking, even if no changes occur. |
131
+ | `debounceMs` | `number` | Debounce interval in milliseconds. Batches rapid changes. |
132
+ | `timeoutMs` | `number` | Maximum time to wait before waking, even if no changes occur. |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: App setup
3
- titleTemplate: '... - Electric Agents'
3
+ titleTemplate: "... - Electric Agents"
4
4
  description: >-
5
5
  Connect your app to the Electric Agents runtime with createRuntimeHandler, webhooks, and type registration.
6
6
  outline: [2, 3]
@@ -18,14 +18,14 @@ Creates a runtime with a Node HTTP adapter:
18
18
  import {
19
19
  createEntityRegistry,
20
20
  createRuntimeHandler,
21
- } from '@electric-ax/agents-runtime'
21
+ } from "@electric-ax/agents-runtime"
22
22
 
23
23
  const registry = createEntityRegistry()
24
24
  // ... register entity types ...
25
25
 
26
26
  const runtime = createRuntimeHandler({
27
- baseUrl: 'http://localhost:4437',
28
- serveEndpoint: 'http://localhost:3000/webhook',
27
+ baseUrl: "http://localhost:4437",
28
+ serveEndpoint: "http://localhost:3000/webhook",
29
29
  registry,
30
30
  })
31
31
  ```
@@ -37,6 +37,7 @@ interface RuntimeRouterConfig {
37
37
  baseUrl: string // Electric Agents server URL
38
38
  serveEndpoint?: string // Webhook callback URL
39
39
  webhookPath?: string // Path to match (default: derived from serveEndpoint)
40
+ handlerUrl?: string // legacy alias for serveEndpoint
40
41
  registry?: EntityRegistry
41
42
  subscriptionPathForType?: (typeName: string) => string
42
43
  idleTimeout?: number // ms before closing idle wake (default: 20000)
@@ -75,10 +76,10 @@ interface RuntimeRouterConfig {
75
76
  Your app needs an HTTP server to receive webhook callbacks from the Electric Agents runtime server. Forward webhook POSTs to the runtime handler:
76
77
 
77
78
  ```ts
78
- import http from 'node:http'
79
+ import http from "node:http"
79
80
 
80
81
  const server = http.createServer(async (req, res) => {
81
- if (req.url === '/webhook' && req.method === 'POST') {
82
+ if (req.url === "/webhook" && req.method === "POST") {
82
83
  await runtime.onEnter(req, res)
83
84
  return
84
85
  }
@@ -131,24 +132,24 @@ interface RuntimeDebugState {
131
132
  }
132
133
  ```
133
134
 
134
- | Method | Description |
135
- | ---------------------- | ---------------------------------------------------------------------------------------- |
136
- | `onEnter` | Node HTTP adapter — reads the request body and delegates to `handleWebhookRequest` |
137
- | `handleRequest` | Fetch-native router — returns `null` if the path does not match `webhookPath` |
138
- | `handleWebhookRequest` | Processes a webhook POST directly, without path matching |
139
- | `dispatchWebhookWake` | Dispatches a pre-parsed notification (fire-and-forget) |
140
- | `drainWakes` | Waits for all in-flight wake handlers to settle; throws on errors |
141
- | `waitForSettled` | Waits for all in-flight wakes; throws on errors |
142
- | `abortWakes` | Cancels all in-flight wake handlers immediately |
143
- | `debugState` | Returns a snapshot of internal runtime state for diagnostics |
144
- | `registerTypes` | Registers entity types and webhook subscriptions with the Electric Agents runtime server |
135
+ | Method | Description |
136
+ | ---------------------- | ---------------------------------------------------------------------------------- |
137
+ | `onEnter` | Node HTTP adapter — reads the request body and delegates to `handleWebhookRequest` |
138
+ | `handleRequest` | Fetch-native router — returns `null` if the path does not match `webhookPath` |
139
+ | `handleWebhookRequest` | Processes a webhook POST directly, without path matching |
140
+ | `dispatchWebhookWake` | Dispatches a pre-parsed notification (fire-and-forget) |
141
+ | `drainWakes` | Waits for all in-flight wake handlers to settle; throws on errors |
142
+ | `waitForSettled` | Waits for all in-flight wakes; throws on errors |
143
+ | `abortWakes` | Cancels all in-flight wake handlers immediately |
144
+ | `debugState` | Returns a snapshot of internal runtime state for diagnostics |
145
+ | `registerTypes` | Registers entity types and webhook subscriptions with the Electric Agents runtime server |
145
146
 
146
147
  ## createRuntimeRouter
147
148
 
148
149
  Fetch-native alternative with no Node HTTP dependency:
149
150
 
150
151
  ```ts
151
- import { createRuntimeRouter } from '@electric-ax/agents-runtime'
152
+ import { createRuntimeRouter } from "@electric-ax/agents-runtime"
152
153
 
153
154
  const router = createRuntimeRouter(config)
154
155
  const response = await router.handleRequest(request)
@@ -158,8 +159,8 @@ Use this when integrating with non-Node frameworks or edge runtimes.
158
159
 
159
160
  ## Environment variables
160
161
 
161
- | Variable | Default | Purpose |
162
- | --------------------- | ----------------------- | ---------------------------------- |
163
- | `ELECTRIC_AGENTS_URL` | `http://localhost:4437` | Electric Agents runtime server URL |
164
- | `PORT` | `3000` | Your app's HTTP port |
165
- | `ANTHROPIC_API_KEY` | — | Claude API key |
162
+ | Variable | Default | Purpose |
163
+ | ------------------- | ----------------------- | ------------------------ |
164
+ | `ELECTRIC_AGENTS_URL` | `http://localhost:4437` | Electric Agents runtime server URL |
165
+ | `PORT` | `3000` | Your app's HTTP port |
166
+ | `ANTHROPIC_API_KEY` | — | Claude API key |