@electric-ax/agents 0.4.8 → 0.4.9

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.
@@ -5,7 +5,6 @@ import pino from "pino";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { appendPathToUrl, completeWithLowCostModel, createEntityRegistry, createPullWakeRunner, createRuntimeHandler, createSkillTools, createSkillsRegistry, db, detectAvailableProviders, readCodexAccessToken, registerToolProvider, unregisterToolProvider } from "@electric-ax/agents-runtime";
7
7
  import { braveSearchTool, createBashTool, createEditTool, createEventSourceTools, createFetchUrlTool, createReadFileTool, createSendTool, createWriteTool, fetchUrlTool } from "@electric-ax/agents-runtime/tools";
8
- import { eq, not, queryOnce } from "@durable-streams/state";
9
8
  import { z } from "zod";
10
9
  import { createHash } from "node:crypto";
11
10
  import fs$1 from "node:fs/promises";
@@ -652,9 +651,9 @@ function createHortonDocsSupport(workingDirectory, opts = {}) {
652
651
  },
653
652
  createSearchTool() {
654
653
  return {
655
- name: `search_durable_agents_docs`,
656
- label: `Search Durable Agents Docs`,
657
- description: `Run a hybrid BM25 plus vector search over the local Durable Agents documentation index.`,
654
+ name: `search_electric_agents_docs`,
655
+ label: `Search Electric Agents Docs`,
656
+ description: `Run a hybrid BM25 plus vector search over the local Electric Agents documentation index.`,
658
657
  parameters: Type.Object({
659
658
  query: Type.String({ description: `The docs question or search query to run.` }),
660
659
  limit: Type.Optional(Type.Number({
@@ -1002,10 +1001,10 @@ async function generateTitle(userMessage, llmCall, onFallback) {
1002
1001
  }
1003
1002
  }
1004
1003
  function buildHortonSystemPrompt(workingDirectory, opts = {}) {
1005
- const docsTools = opts.hasDocsSupport ? `\n- search_durable_agents_docs: hybrid search over the built-in Durable Agents docs index` : ``;
1004
+ const docsTools = opts.hasDocsSupport ? `\n- search_electric_agents_docs: hybrid search over the built-in Electric Agents docs index` : ``;
1006
1005
  const eventSourceTools = opts.hasEventSourceTools ? `\n- list_event_sources: list external webhook/event feeds you can subscribe to, including available buckets and parameters\n- subscribe_event_source: subscribe yourself to one of those feeds or buckets so matching future events wake you\n- list_event_source_subscriptions: list your active event source subscriptions\n- unsubscribe_event_source: remove one of your event source subscriptions by id` : ``;
1007
1006
  const skillsTools = opts.hasSkills ? `\n- use_skill: load a skill (knowledge, instructions, or a tutorial) into your context to help with the user's request\n- remove_skill: unload a skill from context when you're done with it` : ``;
1008
- const docsGuidance = opts.hasDocsSupport ? `\n- For ANY question about Electric Agents, Durable Agents, or this framework, ALWAYS use search_durable_agents_docs FIRST. Do not use web_search or fetch_url for Electric Agents topics unless the docs search returns no useful results.\n- The search tool returns chunk content directly — you do not need to read the source files.\n- Use repo read/bash tools only for non-doc files or when you need to inspect exact implementation code in the workspace.` : ``;
1007
+ const docsGuidance = opts.hasDocsSupport ? `\n- For ANY question about Electric Agents or this framework, ALWAYS use search_electric_agents_docs FIRST. Do not use web_search or fetch_url for Electric Agents topics unless the docs search returns no useful results.\n- The search tool returns chunk content directly — you do not need to read the source files.\n- Use repo read/bash tools only for non-doc files or when you need to inspect exact implementation code in the workspace.` : ``;
1009
1008
  const skillsGuidance = opts.hasSkills ? `\n# Skills\nYou have access to skills — specialized knowledge and guided workflows you can load on demand. Your context includes a skills catalog listing what's available. When the user's request matches a skill's description or keywords, load it with use_skill.
1010
1009
 
1011
1010
  Some skills are user-invocable — the user can trigger them with a slash command like \`/quickstart\`. When you see a message starting with \`/\` followed by a skill name, load that skill immediately with use_skill. Pass any text after the skill name as args.
@@ -1024,7 +1023,7 @@ Do NOT load a skill and then ignore its instructions. The skill is there because
1024
1023
  When a user is new or asks how to get started with Electric Agents, **don't assume a single path**. Present the options and let them choose:
1025
1024
 
1026
1025
  - **Learn the concepts first** → Explain what Electric Agents is, answer questions, point to docs.
1027
- Use search_durable_agents_docs to look up answers. Only load the quickstart skill if the user explicitly asks for a hands-on guided tutorial.
1026
+ Use search_electric_agents_docs to look up answers. Only load the quickstart skill if the user explicitly asks for a hands-on guided tutorial.
1028
1027
 
1029
1028
  - **Hands-on guided tutorial** → Load the quickstart skill (or tell them to type \`/quickstart\`).
1030
1029
  This is a step-by-step build that takes them from zero to a running app.
@@ -1034,11 +1033,11 @@ When a user is new or asks how to get started with Electric Agents, **don't assu
1034
1033
  This sets up project structure and orients them in the codebase.
1035
1034
 
1036
1035
  - **Have a specific question?** → Answer it directly.
1037
- Use search_durable_agents_docs first, then fall back to fetch_url or general knowledge if needed.
1036
+ Use search_electric_agents_docs first, then fall back to fetch_url or general knowledge if needed.
1038
1037
 
1039
1038
  Don't force onboarding. If someone just wants to chat or code, let them. When in doubt, ask what they'd like to do rather than picking a path for them.`;
1040
1039
  const docsUrlGuidance = opts.docsUrl ? `\n# Electric Agents documentation
1041
- - ${opts.hasDocsSupport ? `If search_durable_agents_docs is available, use it first (faster, hybrid search).` : `Use fetch_url to look up documentation pages.`}
1040
+ - ${opts.hasDocsSupport ? `If search_electric_agents_docs is available, use it first (faster, hybrid search).` : `Use fetch_url to look up documentation pages.`}
1042
1041
  - The Electric Agents docs site is at ${opts.docsUrl}
1043
1042
  - The docs site covers: Usage (entity definition, handlers, tools, state, spawning, coordination, waking, shared state, client integration, app setup), Reference (handler context, entity definitions, configurations, tools, state proxies, wake events, registries), Entities (Horton, Worker), and Patterns (Manager-Worker, Pipeline, Map-Reduce, Dispatcher, Blackboard, Reactive Observers).
1044
1043
  - For general coding questions unrelated to Electric Agents, use web_search or your own knowledge.` : ``;
@@ -1124,11 +1123,14 @@ function payloadToTitleText(payload) {
1124
1123
  return String(payload);
1125
1124
  }
1126
1125
  async function extractFirstUserMessage(ctx) {
1127
- const firstMessage = await queryOnce((q) => q.from({ inbox: ctx.db.collections.inbox }).where(({ inbox }) => not(eq(inbox.from, `system`))).orderBy(({ inbox }) => inbox._seq, `asc`).findOne());
1126
+ const firstMessage = ctx.db.collections.inbox.toArray.filter((message) => message.from !== `system`).sort((left, right) => messageSeq(left) - messageSeq(right))[0];
1128
1127
  if (!firstMessage) return null;
1129
1128
  const text = payloadToTitleText(firstMessage.payload);
1130
1129
  return text.length > 0 ? text : null;
1131
1130
  }
1131
+ function messageSeq(message) {
1132
+ return typeof message._seq === `number` ? message._seq : -1;
1133
+ }
1132
1134
  function readAgentsMd(workingDirectory) {
1133
1135
  const agentsMdPath = path.join(workingDirectory, `AGENTS.md`);
1134
1136
  try {
@@ -1290,15 +1292,7 @@ function registerHorton(registry, options) {
1290
1292
  creationSchema: hortonCreationSchema,
1291
1293
  handler: assistantHandler
1292
1294
  });
1293
- const typeNames = [`horton`];
1294
- if (streamFn) {
1295
- registry.define(`chat`, {
1296
- description: `Compatibility alias for the built-in assistant type.`,
1297
- handler: assistantHandler
1298
- });
1299
- typeNames.push(`chat`);
1300
- }
1301
- return typeNames;
1295
+ return [`horton`];
1302
1296
  }
1303
1297
 
1304
1298
  //#endregion
package/dist/index.cjs CHANGED
@@ -29,7 +29,6 @@ const __electric_ax_agents_runtime = __toESM(require("@electric-ax/agents-runtim
29
29
  const __electric_ax_agents_runtime_tools = __toESM(require("@electric-ax/agents-runtime/tools"));
30
30
  const node_fs = __toESM(require("node:fs"));
31
31
  const pino = __toESM(require("pino"));
32
- const __durable_streams_state = __toESM(require("@durable-streams/state"));
33
32
  const zod = __toESM(require("zod"));
34
33
  const node_crypto = __toESM(require("node:crypto"));
35
34
  const node_fs_promises = __toESM(require("node:fs/promises"));
@@ -676,9 +675,9 @@ function createHortonDocsSupport(workingDirectory, opts = {}) {
676
675
  },
677
676
  createSearchTool() {
678
677
  return {
679
- name: `search_durable_agents_docs`,
680
- label: `Search Durable Agents Docs`,
681
- description: `Run a hybrid BM25 plus vector search over the local Durable Agents documentation index.`,
678
+ name: `search_electric_agents_docs`,
679
+ label: `Search Electric Agents Docs`,
680
+ description: `Run a hybrid BM25 plus vector search over the local Electric Agents documentation index.`,
682
681
  parameters: __sinclair_typebox.Type.Object({
683
682
  query: __sinclair_typebox.Type.String({ description: `The docs question or search query to run.` }),
684
683
  limit: __sinclair_typebox.Type.Optional(__sinclair_typebox.Type.Number({
@@ -1027,10 +1026,10 @@ async function generateTitle(userMessage, llmCall, onFallback) {
1027
1026
  }
1028
1027
  }
1029
1028
  function buildHortonSystemPrompt(workingDirectory, opts = {}) {
1030
- const docsTools = opts.hasDocsSupport ? `\n- search_durable_agents_docs: hybrid search over the built-in Durable Agents docs index` : ``;
1029
+ const docsTools = opts.hasDocsSupport ? `\n- search_electric_agents_docs: hybrid search over the built-in Electric Agents docs index` : ``;
1031
1030
  const eventSourceTools = opts.hasEventSourceTools ? `\n- list_event_sources: list external webhook/event feeds you can subscribe to, including available buckets and parameters\n- subscribe_event_source: subscribe yourself to one of those feeds or buckets so matching future events wake you\n- list_event_source_subscriptions: list your active event source subscriptions\n- unsubscribe_event_source: remove one of your event source subscriptions by id` : ``;
1032
1031
  const skillsTools = opts.hasSkills ? `\n- use_skill: load a skill (knowledge, instructions, or a tutorial) into your context to help with the user's request\n- remove_skill: unload a skill from context when you're done with it` : ``;
1033
- const docsGuidance = opts.hasDocsSupport ? `\n- For ANY question about Electric Agents, Durable Agents, or this framework, ALWAYS use search_durable_agents_docs FIRST. Do not use web_search or fetch_url for Electric Agents topics unless the docs search returns no useful results.\n- The search tool returns chunk content directly — you do not need to read the source files.\n- Use repo read/bash tools only for non-doc files or when you need to inspect exact implementation code in the workspace.` : ``;
1032
+ const docsGuidance = opts.hasDocsSupport ? `\n- For ANY question about Electric Agents or this framework, ALWAYS use search_electric_agents_docs FIRST. Do not use web_search or fetch_url for Electric Agents topics unless the docs search returns no useful results.\n- The search tool returns chunk content directly — you do not need to read the source files.\n- Use repo read/bash tools only for non-doc files or when you need to inspect exact implementation code in the workspace.` : ``;
1034
1033
  const skillsGuidance = opts.hasSkills ? `\n# Skills\nYou have access to skills — specialized knowledge and guided workflows you can load on demand. Your context includes a skills catalog listing what's available. When the user's request matches a skill's description or keywords, load it with use_skill.
1035
1034
 
1036
1035
  Some skills are user-invocable — the user can trigger them with a slash command like \`/quickstart\`. When you see a message starting with \`/\` followed by a skill name, load that skill immediately with use_skill. Pass any text after the skill name as args.
@@ -1049,7 +1048,7 @@ Do NOT load a skill and then ignore its instructions. The skill is there because
1049
1048
  When a user is new or asks how to get started with Electric Agents, **don't assume a single path**. Present the options and let them choose:
1050
1049
 
1051
1050
  - **Learn the concepts first** → Explain what Electric Agents is, answer questions, point to docs.
1052
- Use search_durable_agents_docs to look up answers. Only load the quickstart skill if the user explicitly asks for a hands-on guided tutorial.
1051
+ Use search_electric_agents_docs to look up answers. Only load the quickstart skill if the user explicitly asks for a hands-on guided tutorial.
1053
1052
 
1054
1053
  - **Hands-on guided tutorial** → Load the quickstart skill (or tell them to type \`/quickstart\`).
1055
1054
  This is a step-by-step build that takes them from zero to a running app.
@@ -1059,11 +1058,11 @@ When a user is new or asks how to get started with Electric Agents, **don't assu
1059
1058
  This sets up project structure and orients them in the codebase.
1060
1059
 
1061
1060
  - **Have a specific question?** → Answer it directly.
1062
- Use search_durable_agents_docs first, then fall back to fetch_url or general knowledge if needed.
1061
+ Use search_electric_agents_docs first, then fall back to fetch_url or general knowledge if needed.
1063
1062
 
1064
1063
  Don't force onboarding. If someone just wants to chat or code, let them. When in doubt, ask what they'd like to do rather than picking a path for them.`;
1065
1064
  const docsUrlGuidance = opts.docsUrl ? `\n# Electric Agents documentation
1066
- - ${opts.hasDocsSupport ? `If search_durable_agents_docs is available, use it first (faster, hybrid search).` : `Use fetch_url to look up documentation pages.`}
1065
+ - ${opts.hasDocsSupport ? `If search_electric_agents_docs is available, use it first (faster, hybrid search).` : `Use fetch_url to look up documentation pages.`}
1067
1066
  - The Electric Agents docs site is at ${opts.docsUrl}
1068
1067
  - The docs site covers: Usage (entity definition, handlers, tools, state, spawning, coordination, waking, shared state, client integration, app setup), Reference (handler context, entity definitions, configurations, tools, state proxies, wake events, registries), Entities (Horton, Worker), and Patterns (Manager-Worker, Pipeline, Map-Reduce, Dispatcher, Blackboard, Reactive Observers).
1069
1068
  - For general coding questions unrelated to Electric Agents, use web_search or your own knowledge.` : ``;
@@ -1149,11 +1148,14 @@ function payloadToTitleText(payload) {
1149
1148
  return String(payload);
1150
1149
  }
1151
1150
  async function extractFirstUserMessage(ctx) {
1152
- const firstMessage = await (0, __durable_streams_state.queryOnce)((q) => q.from({ inbox: ctx.db.collections.inbox }).where(({ inbox }) => (0, __durable_streams_state.not)((0, __durable_streams_state.eq)(inbox.from, `system`))).orderBy(({ inbox }) => inbox._seq, `asc`).findOne());
1151
+ const firstMessage = ctx.db.collections.inbox.toArray.filter((message) => message.from !== `system`).sort((left, right) => messageSeq(left) - messageSeq(right))[0];
1153
1152
  if (!firstMessage) return null;
1154
1153
  const text = payloadToTitleText(firstMessage.payload);
1155
1154
  return text.length > 0 ? text : null;
1156
1155
  }
1156
+ function messageSeq(message) {
1157
+ return typeof message._seq === `number` ? message._seq : -1;
1158
+ }
1157
1159
  function readAgentsMd(workingDirectory) {
1158
1160
  const agentsMdPath = node_path.default.join(workingDirectory, `AGENTS.md`);
1159
1161
  try {
@@ -1315,15 +1317,7 @@ function registerHorton(registry, options) {
1315
1317
  creationSchema: hortonCreationSchema,
1316
1318
  handler: assistantHandler
1317
1319
  });
1318
- const typeNames = [`horton`];
1319
- if (streamFn) {
1320
- registry.define(`chat`, {
1321
- description: `Compatibility alias for the built-in assistant type.`,
1322
- handler: assistantHandler
1323
- });
1324
- typeNames.push(`chat`);
1325
- }
1326
- return typeNames;
1320
+ return [`horton`];
1327
1321
  }
1328
1322
 
1329
1323
  //#endregion
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { AgentConfig, AgentTool, AvailableProvider, DispatchPolicy, EntityRegistry, HandlerContext, HeadersProvider, ProcessWakeConfig, PullWakeRunnerConfig, RuntimeHandler, SkillsRegistry, WakeEvent } from "@electric-ax/agents-runtime";
2
2
  import { braveSearchTool } from "@electric-ax/agents-runtime/tools";
3
- import { ChangeEvent } from "@durable-streams/state";
4
3
  import { ListedEntry as McpListedEntry, McpConfig, McpServerConfig, McpServerConfig as McpServerConfig$1, Registry, Registry as McpRegistry, RegistrySnapshot, RegistrySubscriber } from "@electric-ax/agents-mcp";
5
4
  import { AgentTool as AgentTool$1, StreamFn } from "@mariozechner/pi-agent-core";
6
5
  import { IncomingMessage, ServerResponse } from "node:http";
6
+ import { ChangeEvent } from "@durable-streams/state";
7
7
 
8
8
  //#region src/bootstrap.d.ts
9
9
  declare const DEFAULT_BUILTIN_AGENT_HANDLER_PATH = "/_electric/builtin-agent-handler";
package/dist/index.js CHANGED
@@ -5,7 +5,6 @@ import { appendPathToUrl, completeWithLowCostModel, createEntityRegistry, create
5
5
  import { braveSearchTool, braveSearchTool as braveSearchTool$1, createBashTool, createEditTool, createEventSourceTools, createFetchUrlTool, createReadFileTool, createSendTool, createWriteTool, fetchUrlTool } from "@electric-ax/agents-runtime/tools";
6
6
  import fs from "node:fs";
7
7
  import pino from "pino";
8
- import { eq, not, queryOnce } from "@durable-streams/state";
9
8
  import { z } from "zod";
10
9
  import { createHash } from "node:crypto";
11
10
  import fs$1 from "node:fs/promises";
@@ -652,9 +651,9 @@ function createHortonDocsSupport(workingDirectory, opts = {}) {
652
651
  },
653
652
  createSearchTool() {
654
653
  return {
655
- name: `search_durable_agents_docs`,
656
- label: `Search Durable Agents Docs`,
657
- description: `Run a hybrid BM25 plus vector search over the local Durable Agents documentation index.`,
654
+ name: `search_electric_agents_docs`,
655
+ label: `Search Electric Agents Docs`,
656
+ description: `Run a hybrid BM25 plus vector search over the local Electric Agents documentation index.`,
658
657
  parameters: Type.Object({
659
658
  query: Type.String({ description: `The docs question or search query to run.` }),
660
659
  limit: Type.Optional(Type.Number({
@@ -1003,10 +1002,10 @@ async function generateTitle(userMessage, llmCall, onFallback) {
1003
1002
  }
1004
1003
  }
1005
1004
  function buildHortonSystemPrompt(workingDirectory, opts = {}) {
1006
- const docsTools = opts.hasDocsSupport ? `\n- search_durable_agents_docs: hybrid search over the built-in Durable Agents docs index` : ``;
1005
+ const docsTools = opts.hasDocsSupport ? `\n- search_electric_agents_docs: hybrid search over the built-in Electric Agents docs index` : ``;
1007
1006
  const eventSourceTools = opts.hasEventSourceTools ? `\n- list_event_sources: list external webhook/event feeds you can subscribe to, including available buckets and parameters\n- subscribe_event_source: subscribe yourself to one of those feeds or buckets so matching future events wake you\n- list_event_source_subscriptions: list your active event source subscriptions\n- unsubscribe_event_source: remove one of your event source subscriptions by id` : ``;
1008
1007
  const skillsTools = opts.hasSkills ? `\n- use_skill: load a skill (knowledge, instructions, or a tutorial) into your context to help with the user's request\n- remove_skill: unload a skill from context when you're done with it` : ``;
1009
- const docsGuidance = opts.hasDocsSupport ? `\n- For ANY question about Electric Agents, Durable Agents, or this framework, ALWAYS use search_durable_agents_docs FIRST. Do not use web_search or fetch_url for Electric Agents topics unless the docs search returns no useful results.\n- The search tool returns chunk content directly — you do not need to read the source files.\n- Use repo read/bash tools only for non-doc files or when you need to inspect exact implementation code in the workspace.` : ``;
1008
+ const docsGuidance = opts.hasDocsSupport ? `\n- For ANY question about Electric Agents or this framework, ALWAYS use search_electric_agents_docs FIRST. Do not use web_search or fetch_url for Electric Agents topics unless the docs search returns no useful results.\n- The search tool returns chunk content directly — you do not need to read the source files.\n- Use repo read/bash tools only for non-doc files or when you need to inspect exact implementation code in the workspace.` : ``;
1010
1009
  const skillsGuidance = opts.hasSkills ? `\n# Skills\nYou have access to skills — specialized knowledge and guided workflows you can load on demand. Your context includes a skills catalog listing what's available. When the user's request matches a skill's description or keywords, load it with use_skill.
1011
1010
 
1012
1011
  Some skills are user-invocable — the user can trigger them with a slash command like \`/quickstart\`. When you see a message starting with \`/\` followed by a skill name, load that skill immediately with use_skill. Pass any text after the skill name as args.
@@ -1025,7 +1024,7 @@ Do NOT load a skill and then ignore its instructions. The skill is there because
1025
1024
  When a user is new or asks how to get started with Electric Agents, **don't assume a single path**. Present the options and let them choose:
1026
1025
 
1027
1026
  - **Learn the concepts first** → Explain what Electric Agents is, answer questions, point to docs.
1028
- Use search_durable_agents_docs to look up answers. Only load the quickstart skill if the user explicitly asks for a hands-on guided tutorial.
1027
+ Use search_electric_agents_docs to look up answers. Only load the quickstart skill if the user explicitly asks for a hands-on guided tutorial.
1029
1028
 
1030
1029
  - **Hands-on guided tutorial** → Load the quickstart skill (or tell them to type \`/quickstart\`).
1031
1030
  This is a step-by-step build that takes them from zero to a running app.
@@ -1035,11 +1034,11 @@ When a user is new or asks how to get started with Electric Agents, **don't assu
1035
1034
  This sets up project structure and orients them in the codebase.
1036
1035
 
1037
1036
  - **Have a specific question?** → Answer it directly.
1038
- Use search_durable_agents_docs first, then fall back to fetch_url or general knowledge if needed.
1037
+ Use search_electric_agents_docs first, then fall back to fetch_url or general knowledge if needed.
1039
1038
 
1040
1039
  Don't force onboarding. If someone just wants to chat or code, let them. When in doubt, ask what they'd like to do rather than picking a path for them.`;
1041
1040
  const docsUrlGuidance = opts.docsUrl ? `\n# Electric Agents documentation
1042
- - ${opts.hasDocsSupport ? `If search_durable_agents_docs is available, use it first (faster, hybrid search).` : `Use fetch_url to look up documentation pages.`}
1041
+ - ${opts.hasDocsSupport ? `If search_electric_agents_docs is available, use it first (faster, hybrid search).` : `Use fetch_url to look up documentation pages.`}
1043
1042
  - The Electric Agents docs site is at ${opts.docsUrl}
1044
1043
  - The docs site covers: Usage (entity definition, handlers, tools, state, spawning, coordination, waking, shared state, client integration, app setup), Reference (handler context, entity definitions, configurations, tools, state proxies, wake events, registries), Entities (Horton, Worker), and Patterns (Manager-Worker, Pipeline, Map-Reduce, Dispatcher, Blackboard, Reactive Observers).
1045
1044
  - For general coding questions unrelated to Electric Agents, use web_search or your own knowledge.` : ``;
@@ -1125,11 +1124,14 @@ function payloadToTitleText(payload) {
1125
1124
  return String(payload);
1126
1125
  }
1127
1126
  async function extractFirstUserMessage(ctx) {
1128
- const firstMessage = await queryOnce((q) => q.from({ inbox: ctx.db.collections.inbox }).where(({ inbox }) => not(eq(inbox.from, `system`))).orderBy(({ inbox }) => inbox._seq, `asc`).findOne());
1127
+ const firstMessage = ctx.db.collections.inbox.toArray.filter((message) => message.from !== `system`).sort((left, right) => messageSeq(left) - messageSeq(right))[0];
1129
1128
  if (!firstMessage) return null;
1130
1129
  const text = payloadToTitleText(firstMessage.payload);
1131
1130
  return text.length > 0 ? text : null;
1132
1131
  }
1132
+ function messageSeq(message) {
1133
+ return typeof message._seq === `number` ? message._seq : -1;
1134
+ }
1133
1135
  function readAgentsMd(workingDirectory) {
1134
1136
  const agentsMdPath = path.join(workingDirectory, `AGENTS.md`);
1135
1137
  try {
@@ -1291,15 +1293,7 @@ function registerHorton(registry, options) {
1291
1293
  creationSchema: hortonCreationSchema,
1292
1294
  handler: assistantHandler
1293
1295
  });
1294
- const typeNames = [`horton`];
1295
- if (streamFn) {
1296
- registry.define(`chat`, {
1297
- description: `Compatibility alias for the built-in assistant type.`,
1298
- handler: assistantHandler
1299
- });
1300
- typeNames.push(`chat`);
1301
- }
1302
- return typeNames;
1296
+ return [`horton`];
1303
1297
  }
1304
1298
 
1305
1299
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electric-ax/agents",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "description": "Built-in Electric Agents runtimes such as Horton and worker",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,7 +49,7 @@
49
49
  "sqlite-vec": "^0.1.9",
50
50
  "zod": "^4.3.6",
51
51
  "@electric-ax/agents-mcp": "0.2.2",
52
- "@electric-ax/agents-runtime": "0.3.4"
52
+ "@electric-ax/agents-runtime": "0.3.5"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/better-sqlite3": "^7.6.13",
@@ -58,7 +58,7 @@
58
58
  "cross-env": "^10.1.0",
59
59
  "tsdown": "^0.9.0",
60
60
  "tsx": "^4.19.0",
61
- "typescript": "^5.0.0",
61
+ "typescript": "^5.9.3",
62
62
  "vitest": "^4.1.0"
63
63
  },
64
64
  "files": [
@@ -100,7 +100,7 @@ IMPORTANT: Never write files until the user explicitly confirms. "Ask to write"
100
100
 
101
101
  - **Continue building** — add an HTTP API route and a React frontend to this app so users can interact with the analyzer from the browser.
102
102
  - **Start a new app** — use the `agents-chat-starter` template for a full multi-agent chat app with rooms, agent spawning, and a Slack-style UI. Load the init skill or tell them to type `/init`.
103
- - **Explore the docs** — read about other coordination patterns (blackboard, pipeline, map-reduce), dive into the API reference, or learn about shared state, context assembly, and other advanced features. Use `search_durable_agents_docs` to look things up.
103
+ - **Explore the docs** — read about other coordination patterns (blackboard, pipeline, map-reduce), dive into the API reference, or learn about shared state, context assembly, and other advanced features. Use `search_electric_agents_docs` to look things up.
104
104
 
105
105
  Wait for the user to choose. Only proceed to Step 4 if they want to continue building.
106
106
 
@@ -116,7 +116,7 @@ Wait for the user to choose. Only proceed to Step 4 if they want to continue bui
116
116
  - `server.ts` is at the working directory root. Entity files go in `entities/`.
117
117
  - Worker spawn args MUST include `tools` array (at least one tool, e.g. `tools: ["bash"]`).
118
118
  - Use `edit` tool for small changes (like updating server.ts). Use `write` for full entity file updates.
119
- - If the user asks a question about Electric Agents concepts, APIs, or patterns between steps, use the `search_durable_agents_docs` tool to look up the answer in the built-in documentation before guessing or searching the web.
119
+ - If the user asks a question about Electric Agents concepts, APIs, or patterns between steps, use the `search_electric_agents_docs` tool to look up the answer in the built-in documentation before guessing or searching the web.
120
120
 
121
121
  ---
122
122