@electric-ax/agents 0.4.19 → 0.6.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/docs/entities/agents/horton.md +22 -17
- package/docs/entities/agents/worker.md +13 -6
- package/docs/entities/patterns/blackboard.md +1 -1
- package/docs/entities/patterns/dispatcher.md +1 -1
- package/docs/entities/patterns/manager-worker.md +10 -5
- package/docs/entities/patterns/map-reduce.md +1 -1
- package/docs/entities/patterns/pipeline.md +1 -1
- package/docs/entities/patterns/reactive-observers.md +1 -1
- package/docs/index.md +6 -4
- package/docs/quickstart.md +2 -2
- package/docs/reference/agent-config.md +13 -3
- package/docs/reference/built-in-collections.md +128 -9
- package/docs/reference/cli.md +34 -4
- package/docs/reference/entity-definition.md +39 -7
- package/docs/reference/entity-handle.md +19 -1
- package/docs/reference/handler-context.md +130 -5
- package/docs/reference/runtime-handler.md +42 -14
- package/docs/reference/wake-event.md +29 -1
- package/docs/usage/app-setup.md +38 -7
- package/docs/usage/attachments.md +129 -0
- package/docs/usage/clients-and-react.md +23 -2
- package/docs/usage/configuring-the-agent.md +15 -5
- package/docs/usage/context-composition.md +2 -1
- package/docs/usage/defining-entities.md +9 -5
- package/docs/usage/defining-tools.md +1 -1
- package/docs/usage/embedded-builtins.md +82 -31
- package/docs/usage/managing-state.md +5 -0
- package/docs/usage/mcp-servers.md +16 -8
- package/docs/usage/overview.md +39 -14
- package/docs/usage/permissions-and-principals.md +160 -0
- package/docs/usage/programmatic-runtime-client.md +158 -16
- package/docs/usage/sandboxing.md +162 -0
- package/docs/usage/signals.md +138 -0
- package/docs/usage/spawning-and-coordinating.md +30 -11
- package/docs/usage/testing.md +1 -1
- package/docs/usage/waking-entities.md +34 -6
- package/docs/usage/webhook-sources.md +171 -0
- package/docs/usage/writing-handlers.md +13 -55
- package/docs/walkthrough.md +13 -5
- package/package.json +3 -3
|
@@ -26,31 +26,36 @@ npx electric-ax agents observe /horton/my-horton
|
|
|
26
26
|
|
|
27
27
|
Horton is configured with `ctx.electricTools` plus the base Horton tool set:
|
|
28
28
|
|
|
29
|
-
| Tool
|
|
30
|
-
|
|
|
31
|
-
| `bash`
|
|
32
|
-
| `read`
|
|
33
|
-
| `write`
|
|
34
|
-
| `edit`
|
|
35
|
-
| `
|
|
36
|
-
| `fetch_url`
|
|
37
|
-
| `spawn_worker`
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
| Tool | Purpose |
|
|
30
|
+
| ----------------- | -------------------------------------------------------- |
|
|
31
|
+
| `bash` | Run shell commands in the working directory. |
|
|
32
|
+
| `read` | Read a file. Tracked in a per-wake `readSet`. |
|
|
33
|
+
| `write` | Create or overwrite a file. |
|
|
34
|
+
| `edit` | Targeted string replacement (file must be `read` first). |
|
|
35
|
+
| `web_search` | Web search via the configured search provider. |
|
|
36
|
+
| `fetch_url` | Fetch a URL and return it as markdown. |
|
|
37
|
+
| `spawn_worker` | Dispatch a subagent for an isolated subtask. |
|
|
38
|
+
| `fork` | Branch a session at its latest completed response. |
|
|
39
|
+
| `observe_pg_sync` | Observe an Electric Postgres shape and wake on changes. |
|
|
40
|
+
| `unobserve_pg_sync` | Remove an existing pg-sync observation. |
|
|
41
|
+
| `send` | Send a message to another entity. |
|
|
42
|
+
| `set_title` | Rename the current chat session title. |
|
|
43
|
+
|
|
44
|
+
`web_search` uses the search provider configured by the built-in runtime; Brave search requires `BRAVE_SEARCH_API_KEY`.
|
|
45
|
+
|
|
46
|
+
When docs support or skills are available, Horton also adds the docs search tool and skill tools during bootstrap. Built-in runtimes also provide `ctx.electricTools`, including schedule tools and webhook-source tools when configured.
|
|
42
47
|
|
|
43
48
|
## Title generation
|
|
44
49
|
|
|
45
|
-
After the first agent run completes, Horton calls `generateTitle()`
|
|
50
|
+
After the first agent run completes, Horton calls `generateTitle()` using the configured low-cost model to summarise the user's first message into a 3-5 word session title and stores it via `ctx.setTag('title', title)`. Failures are logged and ignored — the entity continues without a title.
|
|
46
51
|
|
|
47
52
|
## Details
|
|
48
53
|
|
|
49
54
|
| Property | Value |
|
|
50
55
|
| ----------------- | ------------------------------------------------- |
|
|
51
56
|
| Type name | `horton` |
|
|
52
|
-
| Model | `HORTON_MODEL` (`claude-sonnet-4-
|
|
53
|
-
| Title model |
|
|
57
|
+
| Model | `HORTON_MODEL` (`claude-sonnet-4-6` by default) |
|
|
58
|
+
| Title model | Configured low-cost model |
|
|
54
59
|
| Tools | `ctx.electricTools` + base Horton tool set, plus docs/skill tools when configured |
|
|
55
60
|
| Working directory | Passed at bootstrap (defaults to `process.cwd()`) |
|
|
56
61
|
| Title generation | Yes, after the first run if no title tag exists |
|
|
@@ -75,7 +80,7 @@ registry.define("my-assistant", {
|
|
|
75
80
|
model: HORTON_MODEL,
|
|
76
81
|
tools: [
|
|
77
82
|
...ctx.electricTools,
|
|
78
|
-
...createHortonTools(
|
|
83
|
+
...createHortonTools(ctx.sandbox, ctx, readSet),
|
|
79
84
|
myCustomTool,
|
|
80
85
|
],
|
|
81
86
|
})
|
|
@@ -20,6 +20,9 @@ interface WorkerArgs {
|
|
|
20
20
|
tools?: Array<WorkerToolName>
|
|
21
21
|
sharedDb?: { id: string; schema: SharedStateSchemaMap }
|
|
22
22
|
sharedDbToolMode?: "full" | "write-only"
|
|
23
|
+
model?: string
|
|
24
|
+
provider?: string
|
|
25
|
+
reasoningEffort?: string
|
|
23
26
|
}
|
|
24
27
|
```
|
|
25
28
|
|
|
@@ -29,8 +32,11 @@ interface WorkerArgs {
|
|
|
29
32
|
| `tools` | No | Subset of valid tool names (see below). Unknown names throw at parse time. |
|
|
30
33
|
| `sharedDb` | No | Shared state stream id and schema to connect to. |
|
|
31
34
|
| `sharedDbToolMode` | No | Shared state tool mode: `"full"` (default) or `"write-only"`. |
|
|
35
|
+
| `model` | No | Model id override. Usually inherited from `spawn_worker` / Horton model config. |
|
|
36
|
+
| `provider` | No | Model provider override paired with `model`. |
|
|
37
|
+
| `reasoningEffort` | No | Reasoning effort override for compatible reasoning models. |
|
|
32
38
|
|
|
33
|
-
`registerWorker(registry, { workingDirectory, streamFn? })` is called by the dev server during bootstrap; you don't usually call it yourself.
|
|
39
|
+
`registerWorker(registry, { workingDirectory, modelCatalog, streamFn? })` is called by the dev server during bootstrap; you don't usually call it yourself. The bootstrap path supplies the required `modelCatalog`.
|
|
34
40
|
|
|
35
41
|
## Valid tool names
|
|
36
42
|
|
|
@@ -40,9 +46,10 @@ type WorkerToolName =
|
|
|
40
46
|
| "read"
|
|
41
47
|
| "write"
|
|
42
48
|
| "edit"
|
|
43
|
-
| "
|
|
49
|
+
| "web_search"
|
|
44
50
|
| "fetch_url"
|
|
45
51
|
| "spawn_worker"
|
|
52
|
+
| "send"
|
|
46
53
|
```
|
|
47
54
|
|
|
48
55
|
These are the same primitives Horton uses. Pick the smallest subset the worker needs — tools are the worker's permission set.
|
|
@@ -57,7 +64,7 @@ The canonical way to spawn a worker is the `spawn_worker` tool, which Horton cal
|
|
|
57
64
|
spawn_worker({
|
|
58
65
|
systemPrompt:
|
|
59
66
|
"You are a focused researcher. Find the three most-cited papers on X and return their titles, authors, and DOIs as a markdown table.",
|
|
60
|
-
tools: ["
|
|
67
|
+
tools: ["web_search", "fetch_url"],
|
|
61
68
|
initialMessage: "Begin research now.",
|
|
62
69
|
})
|
|
63
70
|
```
|
|
@@ -75,7 +82,7 @@ The spawn uses `wake: { on: 'runFinished', includeResponse: true }`, so the spaw
|
|
|
75
82
|
1. Parses `ctx.args` into `WorkerArgs`. Throws if `systemPrompt` is empty, if `tools` contains an unknown name, or if neither `tools` nor `sharedDb` is provided.
|
|
76
83
|
2. Builds the requested tool instances against the worker's `workingDirectory` (and a fresh per-wake `readSet` for the read-first-then-edit guard).
|
|
77
84
|
3. If `sharedDb` is present, connects with `ctx.observe(db(id, schema))` and exposes generated `read_*`, `write_*`, `update_*`, and `delete_*` tools (`write_*` only in `"write-only"` mode).
|
|
78
|
-
4. Configures the agent with `HORTON_MODEL` (`claude-sonnet-4-
|
|
85
|
+
4. Configures the agent with `HORTON_MODEL` (`claude-sonnet-4-6` by default), the provided system prompt (with a brief reporting-back footer appended), and the assembled tool list.
|
|
79
86
|
5. Runs the agent until the LLM stops.
|
|
80
87
|
|
|
81
88
|
::: warning Least-privilege sandbox
|
|
@@ -96,7 +103,7 @@ When you finish, respond with a concise report covering what was done and any ke
|
|
|
96
103
|
| Property | Value |
|
|
97
104
|
| ----------------- | --------------------------------------------------------------------- |
|
|
98
105
|
| Type name | `worker` |
|
|
99
|
-
| Model | `HORTON_MODEL` (`claude-sonnet-4-
|
|
100
|
-
| Tools | Subset of
|
|
106
|
+
| Model | `HORTON_MODEL` (`claude-sonnet-4-6` by default) |
|
|
107
|
+
| Tools | Subset of 8 primitives plus optional shared-state tools. **No `ctx.electricTools`.** |
|
|
101
108
|
| Working directory | Provided to `registerWorker` at bootstrap |
|
|
102
109
|
| Description | `Internal — generic worker spawned by other agents. Configure via spawn args (systemPrompt + tools + optional sharedDb).` |
|
|
@@ -58,7 +58,7 @@ export function registerDebate(registry: EntityRegistry) {
|
|
|
58
58
|
|
|
59
59
|
ctx.useAgent({
|
|
60
60
|
systemPrompt: DEBATE_SYSTEM_PROMPT,
|
|
61
|
-
model: `claude-sonnet-4-
|
|
61
|
+
model: `claude-sonnet-4-6`,
|
|
62
62
|
tools: [...ctx.electricTools, startTool, checkTool, endTool],
|
|
63
63
|
})
|
|
64
64
|
await ctx.agent.run()
|
|
@@ -24,7 +24,7 @@ export function registerDispatcher(registry: EntityRegistry) {
|
|
|
24
24
|
|
|
25
25
|
ctx.useAgent({
|
|
26
26
|
systemPrompt: DISPATCHER_SYSTEM_PROMPT,
|
|
27
|
-
model: `claude-sonnet-4-
|
|
27
|
+
model: `claude-sonnet-4-6`,
|
|
28
28
|
tools: [...ctx.electricTools, dispatchTool],
|
|
29
29
|
})
|
|
30
30
|
await ctx.agent.run()
|
|
@@ -27,7 +27,7 @@ export function registerManagerWorker(registry: EntityRegistry) {
|
|
|
27
27
|
|
|
28
28
|
ctx.useAgent({
|
|
29
29
|
systemPrompt: MANAGER_SYSTEM_PROMPT,
|
|
30
|
-
model: `claude-sonnet-4-
|
|
30
|
+
model: `claude-sonnet-4-6`,
|
|
31
31
|
tools: [...ctx.electricTools, analyzeTool],
|
|
32
32
|
})
|
|
33
33
|
await ctx.agent.run()
|
|
@@ -92,10 +92,15 @@ Do not wait for worker output inside the same wake. Spawn workers with `wake: {
|
|
|
92
92
|
```ts
|
|
93
93
|
const finished = wake.payload?.finished_child
|
|
94
94
|
if (finished) {
|
|
95
|
-
ctx.state.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
const child = ctx.state.children.toArray.find(
|
|
96
|
+
(entry) => entry.url === finished.url
|
|
97
|
+
)
|
|
98
|
+
if (child) {
|
|
99
|
+
ctx.state.children.update(child.key, (draft) => {
|
|
100
|
+
draft.status = finished.run_status
|
|
101
|
+
draft.output = finished.response ?? ""
|
|
102
|
+
})
|
|
103
|
+
}
|
|
99
104
|
}
|
|
100
105
|
```
|
|
101
106
|
|
|
@@ -25,7 +25,7 @@ export function registerMapReduce(registry: EntityRegistry) {
|
|
|
25
25
|
async handler(ctx) {
|
|
26
26
|
ctx.useAgent({
|
|
27
27
|
systemPrompt: MAP_REDUCE_SYSTEM_PROMPT,
|
|
28
|
-
model: `claude-sonnet-4-
|
|
28
|
+
model: `claude-sonnet-4-6`,
|
|
29
29
|
tools: [...ctx.electricTools, createMapChunksTool(ctx)],
|
|
30
30
|
})
|
|
31
31
|
await ctx.agent.run()
|
|
@@ -25,7 +25,7 @@ export function registerPipeline(registry: EntityRegistry) {
|
|
|
25
25
|
async handler(ctx) {
|
|
26
26
|
ctx.useAgent({
|
|
27
27
|
systemPrompt: PIPELINE_SYSTEM_PROMPT,
|
|
28
|
-
model: `claude-sonnet-4-
|
|
28
|
+
model: `claude-sonnet-4-6`,
|
|
29
29
|
tools: [...ctx.electricTools, createRunStageTool(ctx)],
|
|
30
30
|
})
|
|
31
31
|
await ctx.agent.run()
|
|
@@ -50,7 +50,7 @@ export function registerMonitor(registry: EntityRegistry) {
|
|
|
50
50
|
|
|
51
51
|
ctx.useAgent({
|
|
52
52
|
systemPrompt: MONITOR_SYSTEM_PROMPT,
|
|
53
|
-
model: `claude-sonnet-4-
|
|
53
|
+
model: `claude-sonnet-4-6`,
|
|
54
54
|
tools: [...ctx.electricTools, observeTool],
|
|
55
55
|
})
|
|
56
56
|
await ctx.agent.run()
|
package/docs/index.md
CHANGED
|
@@ -44,7 +44,7 @@ The runtime SDK is a layer over three foundations:
|
|
|
44
44
|
- **[TanStack DB](https://tanstack.com/db)** — typed local reads and writes via collections.
|
|
45
45
|
- **Mario Zechner's [pi](https://github.com/badlogic/pi-mono) toolkit** — `pi-ai` (unified multi-provider LLM API) and `pi-agent-core` (agent runtime) for the LLM agent loop.
|
|
46
46
|
|
|
47
|
-
**One stream per entity.** The runtime projects that stream into a typed local DB of collections — an `EntityStreamDB`. Inside a handler, that DB is `ctx.db`: writes go through `ctx.db.actions` (which append events to the stream), reads come from `ctx.db.collections`. The runtime ships [built-in collections](#built-in-collections) for runs, tool calls, text deltas, errors, inbox, and more, and you add your own typed [state](
|
|
47
|
+
**One stream per entity.** The runtime projects that stream into a typed local DB of collections — an `EntityStreamDB`. Inside a handler, that DB is `ctx.db`: writes go through `ctx.db.actions` (which append events to the stream), reads come from `ctx.db.collections`. The runtime ships [built-in collections](#built-in-collections) for runs, tool calls, text deltas, errors, inbox, and more, and you add your own typed [state](/docs/agents/usage/managing-state) collections per entity type.
|
|
48
48
|
|
|
49
49
|
**Inside a handler.** When a handler calls `ctx.useAgent()`, the runtime configures the agent on its behalf and routes every step — model call, text delta, tool invocation, error — through the same projection, so the agent loop becomes durable events on the entity's stream.
|
|
50
50
|
|
|
@@ -75,7 +75,7 @@ registry.define("support", {
|
|
|
75
75
|
if (wake.type === "inbox") {
|
|
76
76
|
ctx.useAgent({
|
|
77
77
|
systemPrompt: "You are a support agent.",
|
|
78
|
-
model: "claude-sonnet-4-
|
|
78
|
+
model: "claude-sonnet-4-6",
|
|
79
79
|
tools: [...ctx.electricTools, searchKbTool],
|
|
80
80
|
})
|
|
81
81
|
await ctx.agent.run()
|
|
@@ -110,7 +110,7 @@ The core pattern is [`ctx.useAgent()`](/docs/agents/reference/agent-config) foll
|
|
|
110
110
|
```ts
|
|
111
111
|
ctx.useAgent({
|
|
112
112
|
systemPrompt: "You are a helpful assistant.",
|
|
113
|
-
model: "claude-sonnet-4-
|
|
113
|
+
model: "claude-sonnet-4-6",
|
|
114
114
|
tools: [...ctx.electricTools, myCustomTool],
|
|
115
115
|
})
|
|
116
116
|
|
|
@@ -228,5 +228,7 @@ See [Managing state](/docs/agents/usage/managing-state) for more information.
|
|
|
228
228
|
- [Writing handlers](/docs/agents/usage/writing-handlers) — handler lifecycle and the `ctx` API.
|
|
229
229
|
- [Configuring the agent](/docs/agents/usage/configuring-the-agent) — `useAgent`, models, tools, and streaming.
|
|
230
230
|
- [Spawning & coordinating](/docs/agents/usage/spawning-and-coordinating) — multi-entity topologies and shared state.
|
|
231
|
-
- [
|
|
231
|
+
- [Permissions & principals](/docs/agents/usage/permissions-and-principals) — entity access control and principal-scoped clients.
|
|
232
|
+
- [Sandboxing](/docs/agents/usage/sandboxing), [Attachments](/docs/agents/usage/attachments), [Signals](/docs/agents/usage/signals), and [Webhook sources](/docs/agents/usage/webhook-sources) — newer runtime capabilities for hosted agents.
|
|
233
|
+
- [Built-in agents](/docs/agents/entities/agents/horton) — Horton and Worker, the agents that ship with the runtime.
|
|
232
234
|
- [Examples](/docs/agents/examples/playground) — pattern walkthroughs and demo apps.
|
package/docs/quickstart.md
CHANGED
|
@@ -121,7 +121,7 @@ registry.define("assistant", {
|
|
|
121
121
|
async handler(ctx) {
|
|
122
122
|
ctx.useAgent({
|
|
123
123
|
systemPrompt: "You are a helpful assistant.",
|
|
124
|
-
model: "claude-sonnet-4-
|
|
124
|
+
model: "claude-sonnet-4-6",
|
|
125
125
|
tools: [...ctx.electricTools],
|
|
126
126
|
})
|
|
127
127
|
await ctx.agent.run()
|
|
@@ -202,4 +202,4 @@ See the [CLI reference](./reference/cli#start) for the full set of commands.
|
|
|
202
202
|
- [Defining entities](./usage/defining-entities) — entity types, schemas, and configuration.
|
|
203
203
|
- [Writing handlers](./usage/writing-handlers) — handler lifecycle and the `ctx` API.
|
|
204
204
|
- [Configuring the agent](./usage/configuring-the-agent) — `useAgent`, models, tools, and streaming.
|
|
205
|
-
- [Built-in agents](./entities/agents/horton) — Horton
|
|
205
|
+
- [Built-in agents](./entities/agents/horton) — Horton and Worker, the agents that ship with the runtime.
|
|
@@ -16,13 +16,20 @@ Configuration for the LLM agent loop. Passed to `ctx.useAgent()`.
|
|
|
16
16
|
interface AgentConfig {
|
|
17
17
|
systemPrompt: string
|
|
18
18
|
model: string | Model<any>
|
|
19
|
-
provider?:
|
|
19
|
+
provider?: Provider
|
|
20
20
|
tools: AgentTool[]
|
|
21
21
|
streamFn?: StreamFn
|
|
22
22
|
getApiKey?: (
|
|
23
23
|
provider: string
|
|
24
24
|
) => Promise<string | undefined> | string | undefined
|
|
25
25
|
onPayload?: SimpleStreamOptions["onPayload"]
|
|
26
|
+
onStepEnd?: (stats: {
|
|
27
|
+
input: number
|
|
28
|
+
uncachedInput: number
|
|
29
|
+
output: number
|
|
30
|
+
}) => void
|
|
31
|
+
modelTimeoutMs?: number
|
|
32
|
+
modelMaxRetries?: number
|
|
26
33
|
testResponses?: string[] | TestResponseFn
|
|
27
34
|
}
|
|
28
35
|
```
|
|
@@ -32,12 +39,15 @@ interface AgentConfig {
|
|
|
32
39
|
| Field | Type | Required | Description |
|
|
33
40
|
| --------------- | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------- |
|
|
34
41
|
| `systemPrompt` | `string` | Yes | System prompt sent to the LLM on each step. |
|
|
35
|
-
| `model` | `string \| Model<any>` | Yes | Model identifier (e.g. `"claude-sonnet-4-
|
|
36
|
-
| `provider` | `
|
|
42
|
+
| `model` | `string \| Model<any>` | Yes | Model identifier (e.g. `"claude-sonnet-4-6"`) or a resolved model object. |
|
|
43
|
+
| `provider` | `Provider` | No | pi-ai provider to use when `model` is a string. Defaults to `"anthropic"`. |
|
|
37
44
|
| `tools` | `AgentTool[]` | Yes | Tools available to the LLM. Spread `ctx.electricTools` when your runtime host provides runtime-level tools. See [`AgentTool`](./agent-tool). |
|
|
38
45
|
| `streamFn` | `StreamFn` | No | Optional streaming callback passed to the underlying agent. |
|
|
39
46
|
| `getApiKey` | `(provider) => string \| Promise<string> \| undefined` | No | Optional API-key resolver passed through to the model layer. |
|
|
40
47
|
| `onPayload` | `SimpleStreamOptions["onPayload"]` | No | Optional callback for raw streaming payloads from the model layer. |
|
|
48
|
+
| `onStepEnd` | `(stats) => void` | No | Callback after each model step with provider-reported token counts. |
|
|
49
|
+
| `modelTimeoutMs` | `number` | No | Timeout for individual model calls, in milliseconds. |
|
|
50
|
+
| `modelMaxRetries` | `number` | No | Maximum retry count for model calls. |
|
|
41
51
|
| `testResponses` | `string[] \| TestResponseFn` | No | Mock LLM responses for testing. When set, no real LLM calls are made. |
|
|
42
52
|
|
|
43
53
|
## TestResponseFn
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
title: Built-in collections
|
|
3
3
|
titleTemplate: "... - Electric Agents"
|
|
4
4
|
description: >-
|
|
5
|
-
Reference for the
|
|
5
|
+
Reference for the 20 runtime-managed collections: runs, steps, texts, toolCalls, inbox, signals, errors, slashCommands, and more.
|
|
6
6
|
outline: [2, 3]
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Built-in collections
|
|
10
10
|
|
|
11
|
-
Every entity automatically has these
|
|
11
|
+
Every entity automatically has these 20 collections, populated by the runtime as the agent operates. Custom state collections defined in `EntityDefinition.state` are merged with these at creation time.
|
|
12
12
|
|
|
13
13
|
**Source:** `@electric-ax/agents-runtime` -- `entity-schema.ts`
|
|
14
14
|
|
|
@@ -22,19 +22,22 @@ Every entity automatically has these 17 collections, populated by the runtime as
|
|
|
22
22
|
| `textDeltas` | `text_delta` | `TextDelta` | Incremental text content |
|
|
23
23
|
| `toolCalls` | `tool_call` | `ToolCall` | Tool call lifecycle |
|
|
24
24
|
| `reasoning` | `reasoning` | `Reasoning` | Reasoning block lifecycle |
|
|
25
|
+
| `reasoningDeltas` | `reasoning_delta` | `ReasoningDelta` | Incremental reasoning content |
|
|
25
26
|
| `errors` | `error` | `ErrorEvent` | Diagnostic errors |
|
|
26
27
|
| `inbox` | `inbox` | `MessageReceived` | Inbound messages |
|
|
27
28
|
| `wakes` | `wake` | `WakeEntry` | Wake delivery records |
|
|
28
29
|
| `entityCreated` | `entity_created` | `EntityCreated` | Entity bootstrap metadata |
|
|
29
30
|
| `entityStopped` | `entity_stopped` | `EntityStopped` | Entity shutdown signal |
|
|
31
|
+
| `signals` | `signal` | `Signal` | Lifecycle signal records |
|
|
30
32
|
| `childStatus` | `child_status` | `ChildStatusEntry` | Child/observed entity status |
|
|
31
33
|
| `tags` | `tags` | `TagEntry` | Entity tags |
|
|
34
|
+
| `slashCommands` | `slash_command` | `SlashCommandEntry` | Composer slash commands |
|
|
35
|
+
| `manifests` | `manifest` | `Manifest` | Durable resource manifests |
|
|
32
36
|
| `contextInserted` | `context_inserted` | `ContextInserted` | Context additions |
|
|
33
37
|
| `contextRemoved` | `context_removed` | `ContextRemoved` | Context removals |
|
|
34
|
-
| `manifests` | `manifest` | `Manifest` | Durable resource manifests |
|
|
35
38
|
| `replayWatermarks` | `replay_watermark` | `ReplayWatermark` | Replay progress tracking |
|
|
36
39
|
|
|
37
|
-
All collections use `key` as the primary key.
|
|
40
|
+
All collections use `key` as the primary key. Runtime-managed timeline rows may also include `_timeline_order` for stable timeline sorting.
|
|
38
41
|
|
|
39
42
|
## Type definitions
|
|
40
43
|
|
|
@@ -60,6 +63,8 @@ interface Step {
|
|
|
60
63
|
model_provider?: string
|
|
61
64
|
model_id?: string
|
|
62
65
|
duration_ms?: number
|
|
66
|
+
input_tokens?: number
|
|
67
|
+
output_tokens?: number
|
|
63
68
|
}
|
|
64
69
|
```
|
|
65
70
|
|
|
@@ -90,6 +95,7 @@ interface TextDelta {
|
|
|
90
95
|
interface ToolCall {
|
|
91
96
|
key: string
|
|
92
97
|
run_id?: string
|
|
98
|
+
tool_call_id?: string
|
|
93
99
|
tool_name: string
|
|
94
100
|
status: "started" | "args_complete" | "executing" | "completed" | "failed"
|
|
95
101
|
args?: unknown
|
|
@@ -104,7 +110,21 @@ interface ToolCall {
|
|
|
104
110
|
```ts
|
|
105
111
|
interface Reasoning {
|
|
106
112
|
key: string
|
|
113
|
+
run_id?: string
|
|
107
114
|
status: "streaming" | "completed"
|
|
115
|
+
encrypted?: string
|
|
116
|
+
summary_title?: string
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### ReasoningDelta
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
interface ReasoningDelta {
|
|
124
|
+
key: string
|
|
125
|
+
reasoning_id: string
|
|
126
|
+
run_id: string
|
|
127
|
+
delta: string
|
|
108
128
|
}
|
|
109
129
|
```
|
|
110
130
|
|
|
@@ -126,10 +146,15 @@ interface ErrorEvent {
|
|
|
126
146
|
```ts
|
|
127
147
|
interface MessageReceived {
|
|
128
148
|
key: string
|
|
129
|
-
from
|
|
149
|
+
from?: string
|
|
130
150
|
payload?: unknown
|
|
131
|
-
timestamp
|
|
151
|
+
timestamp?: string
|
|
132
152
|
message_type?: string
|
|
153
|
+
mode?: "immediate" | "queued" | "paused" | "steer"
|
|
154
|
+
status?: "pending" | "processed" | "cancelled"
|
|
155
|
+
position?: string
|
|
156
|
+
processed_at?: string
|
|
157
|
+
cancelled_at?: string
|
|
133
158
|
}
|
|
134
159
|
```
|
|
135
160
|
|
|
@@ -150,6 +175,10 @@ interface WakeChangeEntry {
|
|
|
150
175
|
collection: string
|
|
151
176
|
kind: "insert" | "update" | "delete"
|
|
152
177
|
key: string
|
|
178
|
+
from?: string
|
|
179
|
+
payload?: unknown
|
|
180
|
+
timestamp?: string
|
|
181
|
+
message_type?: string
|
|
153
182
|
}
|
|
154
183
|
|
|
155
184
|
interface WakeFinishedChildEntry {
|
|
@@ -163,7 +192,7 @@ interface WakeFinishedChildEntry {
|
|
|
163
192
|
interface WakeOtherChildEntry {
|
|
164
193
|
url: string
|
|
165
194
|
type: string
|
|
166
|
-
status: "spawning" | "running" | "idle" | "stopped"
|
|
195
|
+
status: "spawning" | "running" | "idle" | "paused" | "stopping" | "stopped" | "killed"
|
|
167
196
|
}
|
|
168
197
|
```
|
|
169
198
|
|
|
@@ -189,6 +218,25 @@ interface EntityStopped {
|
|
|
189
218
|
}
|
|
190
219
|
```
|
|
191
220
|
|
|
221
|
+
### Signal
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
interface Signal {
|
|
225
|
+
key: string
|
|
226
|
+
signal: "SIGINT" | "SIGHUP" | "SIGTERM" | "SIGKILL" | "SIGSTOP" | "SIGCONT" | "SIGUSR"
|
|
227
|
+
status: "unhandled" | "handled"
|
|
228
|
+
sender?: string
|
|
229
|
+
reason?: string
|
|
230
|
+
payload?: unknown
|
|
231
|
+
timestamp: string
|
|
232
|
+
handled_at?: string
|
|
233
|
+
handled_by?: string
|
|
234
|
+
outcome?: "transitioned" | "ignored" | "invalid_for_state" | "delivered" | "aborted" | "shutdown_requested" | "failed"
|
|
235
|
+
previous_state?: ChildStatusEntry["status"]
|
|
236
|
+
new_state?: ChildStatusEntry["status"]
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
192
240
|
### ChildStatusEntry
|
|
193
241
|
|
|
194
242
|
```ts
|
|
@@ -196,7 +244,7 @@ interface ChildStatusEntry {
|
|
|
196
244
|
key: string
|
|
197
245
|
entity_url: string
|
|
198
246
|
entity_type: string
|
|
199
|
-
status: "spawning" | "running" | "idle" | "stopped"
|
|
247
|
+
status: "spawning" | "running" | "idle" | "paused" | "stopping" | "stopped" | "killed"
|
|
200
248
|
}
|
|
201
249
|
```
|
|
202
250
|
|
|
@@ -209,6 +257,39 @@ interface TagEntry {
|
|
|
209
257
|
}
|
|
210
258
|
```
|
|
211
259
|
|
|
260
|
+
### SlashCommandEntry
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
interface SlashCommandEntry {
|
|
264
|
+
key: string
|
|
265
|
+
name: string
|
|
266
|
+
description?: string
|
|
267
|
+
arguments?: Array<{
|
|
268
|
+
name: string
|
|
269
|
+
type: "string" | "number" | "boolean"
|
|
270
|
+
required?: boolean
|
|
271
|
+
description?: string
|
|
272
|
+
}>
|
|
273
|
+
source: "static" | "dynamic"
|
|
274
|
+
owner?: string
|
|
275
|
+
version?: string
|
|
276
|
+
updated_at: string
|
|
277
|
+
dynamic_layers?: Array<{
|
|
278
|
+
name: string
|
|
279
|
+
description?: string
|
|
280
|
+
arguments?: Array<{
|
|
281
|
+
name: string
|
|
282
|
+
type: "string" | "number" | "boolean"
|
|
283
|
+
required?: boolean
|
|
284
|
+
description?: string
|
|
285
|
+
}>
|
|
286
|
+
owner?: string
|
|
287
|
+
version?: string
|
|
288
|
+
updated_at: string
|
|
289
|
+
}>
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
212
293
|
### ContextInserted
|
|
213
294
|
|
|
214
295
|
```ts
|
|
@@ -243,9 +324,11 @@ type Manifest =
|
|
|
243
324
|
| ManifestSourceEntry
|
|
244
325
|
| ManifestSharedStateEntry
|
|
245
326
|
| ManifestEffectEntry
|
|
327
|
+
| ManifestAttachmentEntry
|
|
246
328
|
| ManifestContextEntry
|
|
247
329
|
| ManifestCronScheduleEntry
|
|
248
330
|
| ManifestFutureSendScheduleEntry
|
|
331
|
+
| ManifestGoalEntry
|
|
249
332
|
|
|
250
333
|
interface ManifestChildEntry {
|
|
251
334
|
key: string
|
|
@@ -260,7 +343,7 @@ interface ManifestChildEntry {
|
|
|
260
343
|
interface ManifestSourceEntry {
|
|
261
344
|
key: string
|
|
262
345
|
kind: "source"
|
|
263
|
-
sourceType: string
|
|
346
|
+
sourceType: "entity" | "cron" | "entities" | "db" | "webhook" | "pgSync" | string
|
|
264
347
|
sourceRef: string
|
|
265
348
|
wake?: WakeConfig
|
|
266
349
|
config: Record<string, unknown>
|
|
@@ -283,6 +366,27 @@ interface ManifestEffectEntry {
|
|
|
283
366
|
config: unknown
|
|
284
367
|
}
|
|
285
368
|
|
|
369
|
+
interface ManifestAttachmentEntry {
|
|
370
|
+
key: string
|
|
371
|
+
kind: "attachment"
|
|
372
|
+
id: string
|
|
373
|
+
streamPath: string
|
|
374
|
+
status: "pending" | "complete" | "failed"
|
|
375
|
+
subject: {
|
|
376
|
+
type: "inbox" | "run" | "text" | "tool_call" | "context"
|
|
377
|
+
key: string
|
|
378
|
+
}
|
|
379
|
+
role: "input" | "output"
|
|
380
|
+
mimeType: string
|
|
381
|
+
filename?: string
|
|
382
|
+
byteLength?: number
|
|
383
|
+
sha256?: string
|
|
384
|
+
createdAt: string
|
|
385
|
+
createdBy?: string
|
|
386
|
+
error?: string
|
|
387
|
+
meta?: Record<string, JsonValue>
|
|
388
|
+
}
|
|
389
|
+
|
|
286
390
|
interface ManifestContextEntry {
|
|
287
391
|
key: string
|
|
288
392
|
kind: "context"
|
|
@@ -320,8 +424,23 @@ interface ManifestFutureSendScheduleEntry {
|
|
|
320
424
|
failedAt?: string
|
|
321
425
|
lastError?: string
|
|
322
426
|
}
|
|
427
|
+
|
|
428
|
+
interface ManifestGoalEntry {
|
|
429
|
+
key: string
|
|
430
|
+
kind: "goal"
|
|
431
|
+
id: string
|
|
432
|
+
objective: string
|
|
433
|
+
status: "active" | "complete" | "budget_limited"
|
|
434
|
+
tokenBudget: number | null
|
|
435
|
+
tokensUsed: number
|
|
436
|
+
summary?: string
|
|
437
|
+
createdAt: string
|
|
438
|
+
updatedAt: string
|
|
439
|
+
}
|
|
323
440
|
```
|
|
324
441
|
|
|
442
|
+
`pgSync()` observations are stored as `sourceType: "pgSync"` manifest rows and project matching Postgres shape changes into the observed source's `changes` collection.
|
|
443
|
+
|
|
325
444
|
### ReplayWatermark
|
|
326
445
|
|
|
327
446
|
```ts
|
package/docs/reference/cli.md
CHANGED
|
@@ -23,7 +23,8 @@ npm install -g electric-ax
|
|
|
23
23
|
| `ELECTRIC_AGENTS_PRINCIPAL` | - | Optional principal key sent as `Electric-Principal` |
|
|
24
24
|
| `ELECTRIC_AGENTS_SERVER_HEADERS` | - | Optional JSON object of additional server headers |
|
|
25
25
|
| `ELECTRIC_AGENTS_PORT` | `4437` | Port used by `start` / `quickstart` |
|
|
26
|
-
| `
|
|
26
|
+
| `ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID` | `builtin-{identity}` | Pull-wake runner id for `start-builtin` |
|
|
27
|
+
| `PULL_WAKE_RUNNER_ID` | - | Legacy alias for `ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID` |
|
|
27
28
|
| `ELECTRIC_AGENTS_COMPOSE_PROJECT` | `electric-agents` | Docker Compose project name |
|
|
28
29
|
| `ANTHROPIC_API_KEY` | - | Required for `start-builtin` and `quickstart` |
|
|
29
30
|
|
|
@@ -94,6 +95,19 @@ electric agents observe /chat/my-convo --from 0
|
|
|
94
95
|
| ----------------- | -------------------------------- |
|
|
95
96
|
| `--from <offset>` | Start streaming from this offset |
|
|
96
97
|
|
|
98
|
+
### <span class="cli-command"><code>view <url> [--from <offset>]</code></span> {#view-url-from-offset}
|
|
99
|
+
|
|
100
|
+
Print an entity conversation once.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
electric agents view /chat/my-convo
|
|
104
|
+
electric agents view /chat/my-convo --from 0
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
| Option | Description |
|
|
108
|
+
| ----------------- | --------------------------- |
|
|
109
|
+
| `--from <offset>` | Start reading from this offset |
|
|
110
|
+
|
|
97
111
|
### <span class="cli-command"><code>inspect <url></code></span> {#inspect-url}
|
|
98
112
|
|
|
99
113
|
Show entity details. Outputs JSON.
|
|
@@ -120,9 +134,23 @@ electric agents ps --parent /manager/my-manager
|
|
|
120
134
|
|
|
121
135
|
Output shows `URL`, `STATUS`, `CREATED`, and `LAST ACTIVE` columns with human-readable relative timestamps. Results are sorted by most recently active first.
|
|
122
136
|
|
|
137
|
+
### <span class="cli-command"><code>signal <url> <signal> [--reason <text>] [--payload <json>]</code></span> {#signal-url-signal}
|
|
138
|
+
|
|
139
|
+
Send a lifecycle signal to an entity.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
electric agents signal /chat/my-convo SIGINT --reason "stop current run"
|
|
143
|
+
electric agents signal /chat/my-convo SIGUSR --payload '{"refresh":true}'
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
| Option | Description |
|
|
147
|
+
| ------------------ | ----------------------------------- |
|
|
148
|
+
| `--reason <text>` | Human-readable signal reason |
|
|
149
|
+
| `--payload <json>` | JSON payload to attach to the signal |
|
|
150
|
+
|
|
123
151
|
### <span class="cli-command"><code>kill <url></code></span> {#kill-url}
|
|
124
152
|
|
|
125
|
-
|
|
153
|
+
Send `SIGKILL` to an entity.
|
|
126
154
|
|
|
127
155
|
```bash
|
|
128
156
|
electric agents kill /chat/my-convo
|
|
@@ -138,7 +166,7 @@ electric agents start
|
|
|
138
166
|
|
|
139
167
|
### <span class="cli-command"><code>start-builtin [--anthropic-api-key <key>]</code></span> {#start-builtin}
|
|
140
168
|
|
|
141
|
-
Start the built-in Horton runtime
|
|
169
|
+
Start the built-in Horton and worker runtime, register built-in agent types, and run a pull-wake runner.
|
|
142
170
|
|
|
143
171
|
```bash
|
|
144
172
|
electric agents start-builtin --anthropic-api-key sk-ant-...
|
|
@@ -216,8 +244,10 @@ import {
|
|
|
216
244
|
} from "electric-ax"
|
|
217
245
|
|
|
218
246
|
const env = getElectricCliEnv({
|
|
247
|
+
...process.env,
|
|
219
248
|
ELECTRIC_AGENTS_URL: "http://localhost:4437",
|
|
220
249
|
ELECTRIC_AGENTS_IDENTITY: "docs@example.com",
|
|
250
|
+
ELECTRIC_AGENTS_PRINCIPAL: "user:docs@example.com",
|
|
221
251
|
})
|
|
222
252
|
|
|
223
253
|
const handlers = createElectricCliHandlers(env, "electric agents")
|
|
@@ -234,7 +264,7 @@ await program.parseAsync(["node", "electric", "agents", "types"])
|
|
|
234
264
|
| Export | Purpose |
|
|
235
265
|
| --------------------------------- | ------------------------------------------------------------------------ |
|
|
236
266
|
| `DEFAULT_ELECTRIC_AGENTS_URL` | Default server URL (`"http://localhost:4437"`). |
|
|
237
|
-
| `getElectricCliEnv(env?)` | Reads `ELECTRIC_AGENTS_URL` and `
|
|
267
|
+
| `getElectricCliEnv(env?)` | Reads `ELECTRIC_AGENTS_URL`, `ELECTRIC_AGENTS_IDENTITY`, `ELECTRIC_AGENTS_PRINCIPAL`, and `ELECTRIC_AGENTS_SERVER_HEADERS`. |
|
|
238
268
|
| `createElectricCliHandlers()` | Creates the default command handlers. |
|
|
239
269
|
| `createElectricProgram()` | Creates the Commander program. |
|
|
240
270
|
| `resolveCommandPrefix(argv, env?)` | Resolves help text examples for direct or package-manager invocation. |
|