@electric-ax/agents 0.4.0 → 0.4.1

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.
@@ -625,8 +625,8 @@ function createHortonDocsSupport(workingDirectory, opts = {}) {
625
625
  logPrefix: `[horton-docs]`
626
626
  });
627
627
  function resolveCurrentQuestion(wake, events, inbox) {
628
- if (wake.type === `message_received`) {
629
- const eventQuestion = findLatestQuestion(events.filter((event) => event.type === `message_received`).map((event) => event.value));
628
+ if (wake.type === `inbox`) {
629
+ const eventQuestion = findLatestQuestion(events.filter((event) => event.type === `inbox`).map((event) => event.value));
630
630
  if (eventQuestion) return eventQuestion;
631
631
  }
632
632
  const wakeQuestion = payloadToText(wake.payload).trim();
@@ -1426,7 +1426,8 @@ function registerHorton(registry, options) {
1426
1426
  const { workingDirectory, streamFn, skillsRegistry = null, modelCatalog } = options;
1427
1427
  const docsUrl = options.docsUrl ?? process.env.HORTON_DOCS_URL;
1428
1428
  if (process.env.BRAVE_SEARCH_API_KEY) serverLog.info(`[horton] Web search: using Brave Search API`);
1429
- else serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY not set — web search will fall back to Anthropic built-in search (uses your ANTHROPIC_API_KEY)`);
1429
+ else if (process.env.ANTHROPIC_API_KEY) serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY not set — web search will fall back to Anthropic built-in search`);
1430
+ else serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY and ANTHROPIC_API_KEY not set — web search tool will be unavailable`);
1430
1431
  const docsSupport = createHortonDocsSupport(workingDirectory);
1431
1432
  const docsSearchTool = docsSupport?.createSearchTool();
1432
1433
  docsSupport?.ensureReady().catch((error) => {
@@ -1902,7 +1903,7 @@ function truncate(str, max) {
1902
1903
  //#endregion
1903
1904
  //#region src/bootstrap.ts
1904
1905
  async function createBuiltinAgentHandler(options) {
1905
- const { agentServerUrl, serveEndpoint, workingDirectory, streamFn, createElectricTools, publicUrl, runtimeName, serverHeaders, defaultDispatchPolicyForType } = options;
1906
+ const { agentServerUrl, serveEndpoint, workingDirectory, streamFn, createElectricTools, publicUrl, runtimeName, baseSkillsDir: baseSkillsDirOverride, serverHeaders, defaultDispatchPolicyForType } = options;
1906
1907
  const modelCatalog = await createBuiltinModelCatalog({ allowMockFallback: Boolean(streamFn) });
1907
1908
  if (!modelCatalog) {
1908
1909
  serverLog.warn(`[builtin-agents] no supported model provider API key found — set ANTHROPIC_API_KEY or OPENAI_API_KEY`);
@@ -1910,7 +1911,7 @@ async function createBuiltinAgentHandler(options) {
1910
1911
  }
1911
1912
  const cwd = workingDirectory ?? process.cwd();
1912
1913
  const here = path.dirname(fileURLToPath(import.meta.url));
1913
- const baseSkillsDir = path.resolve(here, `../skills`);
1914
+ const baseSkillsDir = baseSkillsDirOverride ?? path.resolve(here, `../skills`);
1914
1915
  let skillsRegistry = null;
1915
1916
  try {
1916
1917
  skillsRegistry = await createSkillsRegistry({
@@ -2098,6 +2099,7 @@ var BuiltinAgentsServer = class {
2098
2099
  createElectricTools: this.options.createElectricTools,
2099
2100
  publicUrl,
2100
2101
  runtimeName: `builtin-agents`,
2102
+ baseSkillsDir: this.options.baseSkillsDir,
2101
2103
  serverHeaders: pullWake.headers
2102
2104
  });
2103
2105
  if (!this.bootstrap) throw new Error(`ANTHROPIC_API_KEY or OPENAI_API_KEY must be set before starting builtin agents`);
@@ -2203,14 +2205,6 @@ function validateUrl(name, value) {
2203
2205
  throw new Error(`Invalid ${name}: "${value}"`);
2204
2206
  }
2205
2207
  }
2206
- function buildAssertedAuthHeaders(env) {
2207
- const headers = {};
2208
- const email = readEnv(env, [`ELECTRIC_ASSERTED_AUTH_EMAIL`]);
2209
- const name = readEnv(env, [`ELECTRIC_ASSERTED_AUTH_NAME`]);
2210
- if (email) headers[`X-Electric-Asserted-Email`] = email;
2211
- if (name) headers[`X-Electric-Asserted-Name`] = name;
2212
- return Object.keys(headers).length > 0 ? headers : void 0;
2213
- }
2214
2208
  function parseAdditionalServerHeaders(env) {
2215
2209
  const raw = readEnv(env, [`ELECTRIC_AGENTS_SERVER_HEADERS`]);
2216
2210
  if (!raw) return void 0;
@@ -2244,7 +2238,7 @@ function hasHeader(headers, name) {
2244
2238
  function resolveBuiltinAgentsEntrypointOptions(env = process.env, cwd = process.cwd()) {
2245
2239
  const agentServerUrl = validateUrl(`agent server URL`, readRequiredEnv(env, [`ELECTRIC_AGENTS_SERVER_URL`, `ELECTRIC_AGENTS_BASE_URL`], `agent server base URL`));
2246
2240
  const runnerId = readRequiredEnv(env, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`], `pull-wake runner id`);
2247
- const serverHeaders = mergeHeaders(buildAssertedAuthHeaders(env), parseAdditionalServerHeaders(env));
2241
+ const serverHeaders = mergeHeaders(parseAdditionalServerHeaders(env));
2248
2242
  return {
2249
2243
  agentServerUrl,
2250
2244
  workingDirectory: readEnv(env, [`ELECTRIC_AGENTS_WORKING_DIRECTORY`, `WORKING_DIRECTORY`]) ?? cwd,
package/dist/index.cjs CHANGED
@@ -648,8 +648,8 @@ function createHortonDocsSupport(workingDirectory, opts = {}) {
648
648
  logPrefix: `[horton-docs]`
649
649
  });
650
650
  function resolveCurrentQuestion(wake, events, inbox) {
651
- if (wake.type === `message_received`) {
652
- const eventQuestion = findLatestQuestion(events.filter((event) => event.type === `message_received`).map((event) => event.value));
651
+ if (wake.type === `inbox`) {
652
+ const eventQuestion = findLatestQuestion(events.filter((event) => event.type === `inbox`).map((event) => event.value));
653
653
  if (eventQuestion) return eventQuestion;
654
654
  }
655
655
  const wakeQuestion = payloadToText(wake.payload).trim();
@@ -1450,7 +1450,8 @@ function registerHorton(registry, options) {
1450
1450
  const { workingDirectory, streamFn, skillsRegistry = null, modelCatalog } = options;
1451
1451
  const docsUrl = options.docsUrl ?? process.env.HORTON_DOCS_URL;
1452
1452
  if (process.env.BRAVE_SEARCH_API_KEY) serverLog.info(`[horton] Web search: using Brave Search API`);
1453
- else serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY not set — web search will fall back to Anthropic built-in search (uses your ANTHROPIC_API_KEY)`);
1453
+ else if (process.env.ANTHROPIC_API_KEY) serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY not set — web search will fall back to Anthropic built-in search`);
1454
+ else serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY and ANTHROPIC_API_KEY not set — web search tool will be unavailable`);
1454
1455
  const docsSupport = createHortonDocsSupport(workingDirectory);
1455
1456
  const docsSearchTool = docsSupport?.createSearchTool();
1456
1457
  docsSupport?.ensureReady().catch((error) => {
@@ -1927,7 +1928,7 @@ function truncate(str, max) {
1927
1928
  //#region src/bootstrap.ts
1928
1929
  const DEFAULT_BUILTIN_AGENT_HANDLER_PATH = `/_electric/builtin-agent-handler`;
1929
1930
  async function createBuiltinAgentHandler(options) {
1930
- const { agentServerUrl, serveEndpoint, workingDirectory, streamFn, createElectricTools, publicUrl, runtimeName, serverHeaders, defaultDispatchPolicyForType } = options;
1931
+ const { agentServerUrl, serveEndpoint, workingDirectory, streamFn, createElectricTools, publicUrl, runtimeName, baseSkillsDir: baseSkillsDirOverride, serverHeaders, defaultDispatchPolicyForType } = options;
1931
1932
  const modelCatalog = await createBuiltinModelCatalog({ allowMockFallback: Boolean(streamFn) });
1932
1933
  if (!modelCatalog) {
1933
1934
  serverLog.warn(`[builtin-agents] no supported model provider API key found — set ANTHROPIC_API_KEY or OPENAI_API_KEY`);
@@ -1935,7 +1936,7 @@ async function createBuiltinAgentHandler(options) {
1935
1936
  }
1936
1937
  const cwd = workingDirectory ?? process.cwd();
1937
1938
  const here = node_path.default.dirname((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
1938
- const baseSkillsDir = node_path.default.resolve(here, `../skills`);
1939
+ const baseSkillsDir = baseSkillsDirOverride ?? node_path.default.resolve(here, `../skills`);
1939
1940
  let skillsRegistry = null;
1940
1941
  try {
1941
1942
  skillsRegistry = await createSkillsRegistry({
@@ -2133,6 +2134,7 @@ var BuiltinAgentsServer = class {
2133
2134
  createElectricTools: this.options.createElectricTools,
2134
2135
  publicUrl,
2135
2136
  runtimeName: `builtin-agents`,
2137
+ baseSkillsDir: this.options.baseSkillsDir,
2136
2138
  serverHeaders: pullWake.headers
2137
2139
  });
2138
2140
  if (!this.bootstrap) throw new Error(`ANTHROPIC_API_KEY or OPENAI_API_KEY must be set before starting builtin agents`);
@@ -2238,14 +2240,6 @@ function validateUrl(name, value) {
2238
2240
  throw new Error(`Invalid ${name}: "${value}"`);
2239
2241
  }
2240
2242
  }
2241
- function buildAssertedAuthHeaders(env) {
2242
- const headers = {};
2243
- const email = readEnv(env, [`ELECTRIC_ASSERTED_AUTH_EMAIL`]);
2244
- const name = readEnv(env, [`ELECTRIC_ASSERTED_AUTH_NAME`]);
2245
- if (email) headers[`X-Electric-Asserted-Email`] = email;
2246
- if (name) headers[`X-Electric-Asserted-Name`] = name;
2247
- return Object.keys(headers).length > 0 ? headers : void 0;
2248
- }
2249
2243
  function parseAdditionalServerHeaders(env) {
2250
2244
  const raw = readEnv(env, [`ELECTRIC_AGENTS_SERVER_HEADERS`]);
2251
2245
  if (!raw) return void 0;
@@ -2279,7 +2273,7 @@ function hasHeader(headers, name) {
2279
2273
  function resolveBuiltinAgentsEntrypointOptions(env = process.env, cwd = process.cwd()) {
2280
2274
  const agentServerUrl = validateUrl(`agent server URL`, readRequiredEnv(env, [`ELECTRIC_AGENTS_SERVER_URL`, `ELECTRIC_AGENTS_BASE_URL`], `agent server base URL`));
2281
2275
  const runnerId = readRequiredEnv(env, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`], `pull-wake runner id`);
2282
- const serverHeaders = mergeHeaders(buildAssertedAuthHeaders(env), parseAdditionalServerHeaders(env));
2276
+ const serverHeaders = mergeHeaders(parseAdditionalServerHeaders(env));
2283
2277
  return {
2284
2278
  agentServerUrl,
2285
2279
  workingDirectory: readEnv(env, [`ELECTRIC_AGENTS_WORKING_DIRECTORY`, `WORKING_DIRECTORY`]) ?? cwd,
package/dist/index.d.cts CHANGED
@@ -43,6 +43,8 @@ interface BuiltinAgentHandlerOptions {
43
43
  streamFn?: StreamFn;
44
44
  publicUrl?: string;
45
45
  runtimeName?: string;
46
+ /** Override for the built-in skills directory; required when embedders bundle this package. */
47
+ baseSkillsDir?: string;
46
48
  serverHeaders?: HeadersProvider;
47
49
  defaultDispatchPolicyForType?: (typeName: string) => DispatchPolicy | undefined;
48
50
  createElectricTools?: (context: {
@@ -125,6 +127,8 @@ interface BuiltinAgentsServerOptions {
125
127
  * so the embedder must opt in.
126
128
  */
127
129
  loadProjectMcpConfig?: boolean;
130
+ /** Override for the built-in skills directory; required when embedders bundle this package. */
131
+ baseSkillsDir?: string;
128
132
  createElectricTools?: (context: {
129
133
  entityUrl: string;
130
134
  entityType: string;
package/dist/index.d.ts CHANGED
@@ -43,6 +43,8 @@ interface BuiltinAgentHandlerOptions {
43
43
  streamFn?: StreamFn;
44
44
  publicUrl?: string;
45
45
  runtimeName?: string;
46
+ /** Override for the built-in skills directory; required when embedders bundle this package. */
47
+ baseSkillsDir?: string;
46
48
  serverHeaders?: HeadersProvider;
47
49
  defaultDispatchPolicyForType?: (typeName: string) => DispatchPolicy | undefined;
48
50
  createElectricTools?: (context: {
@@ -125,6 +127,8 @@ interface BuiltinAgentsServerOptions {
125
127
  * so the embedder must opt in.
126
128
  */
127
129
  loadProjectMcpConfig?: boolean;
130
+ /** Override for the built-in skills directory; required when embedders bundle this package. */
131
+ baseSkillsDir?: string;
128
132
  createElectricTools?: (context: {
129
133
  entityUrl: string;
130
134
  entityType: string;
package/dist/index.js CHANGED
@@ -624,8 +624,8 @@ function createHortonDocsSupport(workingDirectory, opts = {}) {
624
624
  logPrefix: `[horton-docs]`
625
625
  });
626
626
  function resolveCurrentQuestion(wake, events, inbox) {
627
- if (wake.type === `message_received`) {
628
- const eventQuestion = findLatestQuestion(events.filter((event) => event.type === `message_received`).map((event) => event.value));
627
+ if (wake.type === `inbox`) {
628
+ const eventQuestion = findLatestQuestion(events.filter((event) => event.type === `inbox`).map((event) => event.value));
629
629
  if (eventQuestion) return eventQuestion;
630
630
  }
631
631
  const wakeQuestion = payloadToText(wake.payload).trim();
@@ -1426,7 +1426,8 @@ function registerHorton(registry, options) {
1426
1426
  const { workingDirectory, streamFn, skillsRegistry = null, modelCatalog } = options;
1427
1427
  const docsUrl = options.docsUrl ?? process.env.HORTON_DOCS_URL;
1428
1428
  if (process.env.BRAVE_SEARCH_API_KEY) serverLog.info(`[horton] Web search: using Brave Search API`);
1429
- else serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY not set — web search will fall back to Anthropic built-in search (uses your ANTHROPIC_API_KEY)`);
1429
+ else if (process.env.ANTHROPIC_API_KEY) serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY not set — web search will fall back to Anthropic built-in search`);
1430
+ else serverLog.warn(`[horton] BRAVE_SEARCH_API_KEY and ANTHROPIC_API_KEY not set — web search tool will be unavailable`);
1430
1431
  const docsSupport = createHortonDocsSupport(workingDirectory);
1431
1432
  const docsSearchTool = docsSupport?.createSearchTool();
1432
1433
  docsSupport?.ensureReady().catch((error) => {
@@ -1903,7 +1904,7 @@ function truncate(str, max) {
1903
1904
  //#region src/bootstrap.ts
1904
1905
  const DEFAULT_BUILTIN_AGENT_HANDLER_PATH = `/_electric/builtin-agent-handler`;
1905
1906
  async function createBuiltinAgentHandler(options) {
1906
- const { agentServerUrl, serveEndpoint, workingDirectory, streamFn, createElectricTools, publicUrl, runtimeName, serverHeaders, defaultDispatchPolicyForType } = options;
1907
+ const { agentServerUrl, serveEndpoint, workingDirectory, streamFn, createElectricTools, publicUrl, runtimeName, baseSkillsDir: baseSkillsDirOverride, serverHeaders, defaultDispatchPolicyForType } = options;
1907
1908
  const modelCatalog = await createBuiltinModelCatalog({ allowMockFallback: Boolean(streamFn) });
1908
1909
  if (!modelCatalog) {
1909
1910
  serverLog.warn(`[builtin-agents] no supported model provider API key found — set ANTHROPIC_API_KEY or OPENAI_API_KEY`);
@@ -1911,7 +1912,7 @@ async function createBuiltinAgentHandler(options) {
1911
1912
  }
1912
1913
  const cwd = workingDirectory ?? process.cwd();
1913
1914
  const here = path.dirname(fileURLToPath(import.meta.url));
1914
- const baseSkillsDir = path.resolve(here, `../skills`);
1915
+ const baseSkillsDir = baseSkillsDirOverride ?? path.resolve(here, `../skills`);
1915
1916
  let skillsRegistry = null;
1916
1917
  try {
1917
1918
  skillsRegistry = await createSkillsRegistry({
@@ -2109,6 +2110,7 @@ var BuiltinAgentsServer = class {
2109
2110
  createElectricTools: this.options.createElectricTools,
2110
2111
  publicUrl,
2111
2112
  runtimeName: `builtin-agents`,
2113
+ baseSkillsDir: this.options.baseSkillsDir,
2112
2114
  serverHeaders: pullWake.headers
2113
2115
  });
2114
2116
  if (!this.bootstrap) throw new Error(`ANTHROPIC_API_KEY or OPENAI_API_KEY must be set before starting builtin agents`);
@@ -2214,14 +2216,6 @@ function validateUrl(name, value) {
2214
2216
  throw new Error(`Invalid ${name}: "${value}"`);
2215
2217
  }
2216
2218
  }
2217
- function buildAssertedAuthHeaders(env) {
2218
- const headers = {};
2219
- const email = readEnv(env, [`ELECTRIC_ASSERTED_AUTH_EMAIL`]);
2220
- const name = readEnv(env, [`ELECTRIC_ASSERTED_AUTH_NAME`]);
2221
- if (email) headers[`X-Electric-Asserted-Email`] = email;
2222
- if (name) headers[`X-Electric-Asserted-Name`] = name;
2223
- return Object.keys(headers).length > 0 ? headers : void 0;
2224
- }
2225
2219
  function parseAdditionalServerHeaders(env) {
2226
2220
  const raw = readEnv(env, [`ELECTRIC_AGENTS_SERVER_HEADERS`]);
2227
2221
  if (!raw) return void 0;
@@ -2255,7 +2249,7 @@ function hasHeader(headers, name) {
2255
2249
  function resolveBuiltinAgentsEntrypointOptions(env = process.env, cwd = process.cwd()) {
2256
2250
  const agentServerUrl = validateUrl(`agent server URL`, readRequiredEnv(env, [`ELECTRIC_AGENTS_SERVER_URL`, `ELECTRIC_AGENTS_BASE_URL`], `agent server base URL`));
2257
2251
  const runnerId = readRequiredEnv(env, [`ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID`, `PULL_WAKE_RUNNER_ID`], `pull-wake runner id`);
2258
- const serverHeaders = mergeHeaders(buildAssertedAuthHeaders(env), parseAdditionalServerHeaders(env));
2252
+ const serverHeaders = mergeHeaders(parseAdditionalServerHeaders(env));
2259
2253
  return {
2260
2254
  agentServerUrl,
2261
2255
  workingDirectory: readEnv(env, [`ELECTRIC_AGENTS_WORKING_DIRECTORY`, `WORKING_DIRECTORY`]) ?? cwd,
package/docs/index.md CHANGED
@@ -60,7 +60,7 @@ The function that runs when an entity wakes. Receives a [`HandlerContext`](/docs
60
60
  ```ts
61
61
  registry.define("support", {
62
62
  async handler(ctx, wake) {
63
- if (wake.type === "message_received") {
63
+ if (wake.type === "inbox") {
64
64
  ctx.useAgent({
65
65
  systemPrompt: "You are a support agent.",
66
66
  model: "claude-sonnet-4-5-20250929",
@@ -78,11 +78,11 @@ Events that trigger a handler invocation. Wake sources include incoming messages
78
78
 
79
79
  ```ts
80
80
  async handler(ctx, wake) {
81
- // wake.type — "message_received", "wake", etc.
81
+ // wake.type — "inbox", "wake", etc.
82
82
  // wake.source — who triggered the wake
83
83
  // wake.payload — message content or wake data
84
84
 
85
- if (wake.type === "message_received") {
85
+ if (wake.type === "inbox") {
86
86
  const userMessage = wake.payload
87
87
  // handle incoming message
88
88
  }
@@ -23,7 +23,7 @@ Every entity automatically has these 17 collections, populated by the runtime as
23
23
  | `toolCalls` | `tool_call` | `ToolCall` | Tool call lifecycle |
24
24
  | `reasoning` | `reasoning` | `Reasoning` | Reasoning block lifecycle |
25
25
  | `errors` | `error` | `ErrorEvent` | Diagnostic errors |
26
- | `inbox` | `message_received` | `MessageReceived` | Inbound messages |
26
+ | `inbox` | `inbox` | `MessageReceived` | Inbound messages |
27
27
  | `wakes` | `wake` | `WakeEntry` | Wake delivery records |
28
28
  | `entityCreated` | `entity_created` | `EntityCreated` | Entity bootstrap metadata |
29
29
  | `entityStopped` | `entity_stopped` | `EntityStopped` | Entity shutdown signal |
@@ -30,7 +30,7 @@ type WakeEvent = {
30
30
  | Field | Type | Description |
31
31
  | ------------ | --------- | ------------------------------------------------------------------------ |
32
32
  | `source` | `string` | URL or identifier of the stream that triggered the wake. |
33
- | `type` | `string` | Wake type. Usually `"message_received"` or `"wake"`; fallback webhook events can use `triggerEvent` or `"message"`. See catalog. |
33
+ | `type` | `string` | Wake type. Usually `"inbox"` or `"wake"`; fallback webhook events can use `triggerEvent` or `"message"`. See catalog. |
34
34
  | `fromOffset` | `number` | Start offset of new events in the source stream. |
35
35
  | `toOffset` | `number` | End offset (exclusive) of new events. |
36
36
  | `eventCount` | `number` | Number of new events in this wake. |
@@ -40,9 +40,9 @@ type WakeEvent = {
40
40
 
41
41
  ## Wake-type catalog
42
42
 
43
- Handlers usually see two values for `wake.type`. Direct inbox messages arrive as `"message_received"`. Most non-message triggers are flattened into `"wake"`, with the specifics carried on `wake.payload`. Low-level webhook fallbacks can surface `triggerEvent` directly, or `"message"` when no trigger event is provided.
43
+ Handlers usually see two values for `wake.type`. Direct inbox messages arrive as `"inbox"`. Most non-message triggers are flattened into `"wake"`, with the specifics carried on `wake.payload`. Low-level webhook fallbacks can surface `triggerEvent` directly, or `"message"` when no trigger event is provided.
44
44
 
45
- ### `"message_received"`
45
+ ### `"inbox"`
46
46
 
47
47
  An external message landed in the entity's inbox — from `ctx.send()`, the CLI's `electric agents send`, or any direct `/send` HTTP call.
48
48
 
@@ -89,7 +89,7 @@ Inspect the payload to distinguish the sub-kind:
89
89
  | Observed change | `ctx.observe(..., { wake: { on: 'change' } })` or `observe(db(...))` | `payload.changes` is non-empty |
90
90
  | Shared-state change | `await ctx.observe(db(...), { wake: { on: 'change' } })` | `payload.changes` is non-empty, `payload.source` identifies the shared-state stream |
91
91
  | Cron fired | A cron schedule entry on the entity's manifest | `payload.source` identifies the schedule; `payload.changes` is empty |
92
- | Scheduled send | A `future_send` schedule fires | Arrives as `"message_received"` (not `"wake"`) — the schedule produces a message delivery |
92
+ | Scheduled send | A `future_send` schedule fires | Arrives as `"inbox"` (not `"wake"`) — the schedule produces a message delivery |
93
93
  | Timeout | `timeoutMs` on a `change` wake config elapsed with no changes | `payload.timeout === true`, `payload.changes` is empty |
94
94
 
95
95
  For the narrative on how these are produced, see [Waking entities](../usage/waking-entities).
@@ -129,7 +129,7 @@ async handler(ctx) {
129
129
 
130
130
  const analyst = await ctx.observe(entity("/worker/analyst"))
131
131
 
132
- if (wake.type === "message_received") {
132
+ if (wake.type === "inbox") {
133
133
  analyst.send(wake.payload)
134
134
  }
135
135
  }
@@ -31,13 +31,13 @@ There are five things that can wake an entity:
31
31
 
32
32
  ### 1. An incoming message
33
33
 
34
- Any external `/send` (via the CLI, HTTP, or another entity's `ctx.send()`) appends a `message_received` event to the entity's stream, which wakes the handler:
34
+ Any external `/send` (via the CLI, HTTP, or another entity's `ctx.send()`) appends a `inbox` event to the entity's stream, which wakes the handler:
35
35
 
36
36
  ```ts
37
37
  ctx.send("/assistant/peer", { text: "hello" })
38
38
  ```
39
39
 
40
- The receiving handler sees `wake.type === "message_received"` and finds the payload on `wake.payload`.
40
+ The receiving handler sees `wake.type === "inbox"` and finds the payload on `wake.payload`.
41
41
 
42
42
  ### 2. A spawned child
43
43
 
@@ -97,7 +97,7 @@ The minimum useful pattern is to branch on `wake.type`:
97
97
 
98
98
  ```ts
99
99
  async handler(ctx, wake) {
100
- if (wake.type === "message_received") {
100
+ if (wake.type === "inbox") {
101
101
  // external input - reply, dispatch, etc.
102
102
  ctx.useAgent({ ... })
103
103
  await ctx.agent.run()
@@ -112,8 +112,8 @@ async handler(ctx, wake) {
112
112
 
113
113
  Two wake types reach handlers directly:
114
114
 
115
- - `"message_received"` — an external message was delivered to this entity's inbox.
116
- - `"wake"` — a synthesised wake for anything else (child finished, collection change, cron, timeout). The specifics are on `wake.payload`. A future-send schedule delivers a message, so it arrives as `"message_received"`.
115
+ - `"inbox"` — an external message was delivered to this entity's inbox.
116
+ - `"wake"` — a synthesised wake for anything else (child finished, collection change, cron, timeout). The specifics are on `wake.payload`. A future-send schedule delivers a message, so it arrives as `"inbox"`.
117
117
 
118
118
  For the full payload shape (`changes[]`, `finished_child`, `other_children`, `timeout`), see the [wake-type catalog](../reference/wake-event#wake-type-catalog) in the reference.
119
119
 
@@ -120,7 +120,7 @@ type WakeEvent = {
120
120
  | Field | Description |
121
121
  | ------------ | -------------------------------------------------------------- |
122
122
  | `source` | The stream or entity that caused the wake. |
123
- | `type` | The wake type: `"message_received"` for inbox messages or `"wake"` for child completion, observed changes, cron, and timeouts. |
123
+ | `type` | The wake type: `"inbox"` for inbox messages or `"wake"` for child completion, observed changes, cron, and timeouts. |
124
124
  | `fromOffset` | Start offset of the events that triggered this wake. |
125
125
  | `toOffset` | End offset of the events that triggered this wake. |
126
126
  | `eventCount` | Number of new events since last wake. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electric-ax/agents",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Built-in Electric Agents runtimes such as Horton and worker",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,14 +32,14 @@
32
32
  "@mariozechner/pi-agent-core": "^0.70.2",
33
33
  "@mariozechner/pi-ai": "^0.70.2",
34
34
  "@sinclair/typebox": "^0.34.48",
35
- "better-sqlite3": "^11.10.0",
35
+ "better-sqlite3": "^12.9.0",
36
36
  "nanoid": "^3.3.11",
37
37
  "pino": "^10.3.1",
38
38
  "pino-pretty": "^13.0.0",
39
39
  "sqlite-vec": "^0.1.9",
40
40
  "zod": "^4.3.6",
41
- "@electric-ax/agents-mcp": "0.2.1",
42
- "@electric-ax/agents-runtime": "0.2.0"
41
+ "@electric-ax/agents-mcp": "0.2.2",
42
+ "@electric-ax/agents-runtime": "0.2.1"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/better-sqlite3": "^7.6.13",