@electric-ax/agents 0.4.12 → 0.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -39,6 +39,7 @@ const sqlite_vec = __toESM(require("sqlite-vec"));
39
39
  const nanoid = __toESM(require("nanoid"));
40
40
  const __mariozechner_pi_ai = __toESM(require("@mariozechner/pi-ai"));
41
41
  const __electric_ax_agents_mcp = __toESM(require("@electric-ax/agents-mcp"));
42
+ const undici = __toESM(require("undici"));
42
43
 
43
44
  //#region src/log.ts
44
45
  const LOG_LEVEL = process.env.ELECTRIC_AGENTS_LOG_LEVEL ?? `info`;
@@ -889,6 +890,15 @@ async function fetchAvailableModelIds(provider) {
889
890
  function knownModelsForProvider(provider) {
890
891
  return provider === __electric_ax_agents_runtime.MOONSHOT_PROVIDER ? (0, __electric_ax_agents_runtime.getMoonshotModels)() : (0, __mariozechner_pi_ai.getModels)(provider);
891
892
  }
893
+ function resolveBuiltinModelContextWindow(modelConfig) {
894
+ const modelId = String(modelConfig.model);
895
+ if (modelConfig.provider === __electric_ax_agents_runtime.MOONSHOT_PROVIDER) return (0, __electric_ax_agents_runtime.getMoonshotModel)(modelId)?.contextWindow ?? null;
896
+ if (!modelConfig.provider) return null;
897
+ return knownModelsForProvider(modelConfig.provider).find((model) => model.id === modelId)?.contextWindow ?? null;
898
+ }
899
+ function resolveBuiltinModelSourceBudget(modelConfig) {
900
+ return resolveBuiltinModelContextWindow(modelConfig) ?? 1e5;
901
+ }
892
902
  function choiceForKnownModel(provider, model) {
893
903
  return {
894
904
  provider,
@@ -992,6 +1002,8 @@ function modelInputSchemaDefs(catalog) {
992
1002
  const HORTON_MODEL = `claude-sonnet-4-6`;
993
1003
  const TITLE_SYSTEM_PROMPT = "You generate concise chat session titles in 3-5 words. Respond with only the title, no quotes, no punctuation, no preamble.";
994
1004
  const TITLE_USER_PROMPT = (userMessage) => `User request:\n${userMessage}`;
1005
+ const TITLE_GENERATION_TIMEOUT_MS = 8e3;
1006
+ const HORTON_SKILLS_SLASH_COMMAND_OWNER = `horton:skills`;
995
1007
  const TITLE_STOP_WORDS = new Set([
996
1008
  `a`,
997
1009
  `an`,
@@ -1071,6 +1083,17 @@ function createConfiguredTitleCall(catalog, modelConfig, logPrefix) {
1071
1083
  maxTokens: 64
1072
1084
  });
1073
1085
  }
1086
+ function withTimeout(promise, ms, description) {
1087
+ let timeout;
1088
+ const timeoutPromise = new Promise((_resolve, reject) => {
1089
+ timeout = setTimeout(() => {
1090
+ reject(new Error(`${description} timed out after ${ms}ms`));
1091
+ }, ms);
1092
+ });
1093
+ return Promise.race([promise, timeoutPromise]).finally(() => {
1094
+ if (timeout) clearTimeout(timeout);
1095
+ });
1096
+ }
1074
1097
  async function generateTitle(userMessage, llmCall, onFallback) {
1075
1098
  try {
1076
1099
  const raw = await llmCall(TITLE_USER_PROMPT(userMessage));
@@ -1200,8 +1223,12 @@ function payloadToTitleText(payload) {
1200
1223
  if (typeof payload === `string`) return payload;
1201
1224
  if (payload == null) return ``;
1202
1225
  if (typeof payload === `object`) {
1203
- const text = payload.text;
1204
- return typeof text === `string` ? text : JSON.stringify(payload);
1226
+ const record = payload;
1227
+ const text = record.text;
1228
+ if (typeof text === `string`) return text;
1229
+ const source = record.source;
1230
+ if (typeof source === `string`) return source;
1231
+ return JSON.stringify(payload);
1205
1232
  }
1206
1233
  return String(payload);
1207
1234
  }
@@ -1259,10 +1286,13 @@ async function readAgentsMd(sandbox) {
1259
1286
  }
1260
1287
  function createAssistantHandler(options) {
1261
1288
  const { streamFn, docsSupport, docsSearchTool, skillsRegistry, modelCatalog, docsUrl } = options;
1262
- const hasSkills = Boolean(skillsRegistry && skillsRegistry.catalog.size > 0);
1289
+ const skillLoader = (0, __electric_ax_agents_runtime.createContextSkillLoader)(skillsRegistry, { slashCommandOwner: HORTON_SKILLS_SLASH_COMMAND_OWNER });
1290
+ const hasSkills = skillLoader.hasSkills;
1263
1291
  return async function assistantHandler(ctx, wake) {
1292
+ const loadedSkills = await skillLoader.load(ctx);
1264
1293
  const readSet = new Set();
1265
1294
  const modelConfig = resolveBuiltinModelConfig(modelCatalog, ctx.args);
1295
+ const sourceBudget = resolveBuiltinModelSourceBudget(modelConfig);
1266
1296
  const sandboxCwd = ctx.sandbox.workingDirectory;
1267
1297
  const agentsMd = await readAgentsMd(ctx.sandbox);
1268
1298
  const tools = [
@@ -1273,7 +1303,7 @@ function createAssistantHandler(options) {
1273
1303
  modelCatalog,
1274
1304
  logPrefix: `[horton ${ctx.entityUrl}]`
1275
1305
  }),
1276
- ...skillsRegistry && skillsRegistry.catalog.size > 0 ? (0, __electric_ax_agents_runtime.createSkillTools)(skillsRegistry, ctx) : [],
1306
+ ...loadedSkills.tools,
1277
1307
  ...__electric_ax_agents_mcp.mcp.tools()
1278
1308
  ];
1279
1309
  const hasEventSourceTools = tools.some((tool) => getToolName(tool) === `list_event_sources`);
@@ -1282,21 +1312,22 @@ function createAssistantHandler(options) {
1282
1312
  if (!firstUserMessage) return;
1283
1313
  let title = null;
1284
1314
  try {
1285
- const result = await generateTitle(firstUserMessage, createConfiguredTitleCall(modelCatalog, modelConfig, `[horton ${ctx.entityUrl}]`), (reason) => {
1315
+ const result = await generateTitle(firstUserMessage, (prompt) => withTimeout(createConfiguredTitleCall(modelCatalog, modelConfig, `[horton ${ctx.entityUrl}]`)(prompt), TITLE_GENERATION_TIMEOUT_MS, `title generation`), (reason) => {
1286
1316
  serverLog.warn(`[horton ${ctx.entityUrl}] title generation fell back to local title: ${reason}`);
1287
1317
  });
1288
1318
  if (result.length > 0) title = result;
1289
1319
  } catch (err) {
1290
1320
  serverLog.warn(`[horton ${ctx.entityUrl}] title generation failed: ${err instanceof Error ? err.message : String(err)}`);
1321
+ title = buildFallbackTitle(firstUserMessage);
1291
1322
  }
1292
1323
  if (title !== null) try {
1293
- await ctx.setTag(`title`, title);
1324
+ await withTimeout(ctx.setTag(`title`, title), TITLE_GENERATION_TIMEOUT_MS, `set title tag`);
1294
1325
  } catch (err) {
1295
1326
  serverLog.warn(`[horton ${ctx.entityUrl}] setTag failed: ${err instanceof Error ? err.message : String(err)}`);
1296
1327
  }
1297
1328
  })() : Promise.resolve();
1298
1329
  if (docsSupport) ctx.useContext({
1299
- sourceBudget: 1e5,
1330
+ sourceBudget,
1300
1331
  sources: {
1301
1332
  docs_toc: {
1302
1333
  content: () => docsSupport.renderCompressedToc(),
@@ -1317,21 +1348,13 @@ function createAssistantHandler(options) {
1317
1348
  max: 2e4,
1318
1349
  cache: `stable`
1319
1350
  } } : {},
1320
- ...skillsRegistry && skillsRegistry.catalog.size > 0 ? { skills_catalog: {
1321
- content: () => skillsRegistry.renderCatalog(2e3),
1322
- max: 2e3,
1323
- cache: `stable`
1324
- } } : {}
1351
+ ...skillsRegistry && skillsRegistry.catalog.size > 0 ? loadedSkills.sources : {}
1325
1352
  }
1326
1353
  });
1327
1354
  else if (skillsRegistry && skillsRegistry.catalog.size > 0) ctx.useContext({
1328
- sourceBudget: 1e5,
1355
+ sourceBudget,
1329
1356
  sources: {
1330
- skills_catalog: {
1331
- content: () => skillsRegistry.renderCatalog(2e3),
1332
- max: 2e3,
1333
- cache: `stable`
1334
- },
1357
+ ...loadedSkills.sources,
1335
1358
  conversation: {
1336
1359
  content: () => ctx.timelineMessages(),
1337
1360
  cache: `volatile`
@@ -1344,7 +1367,7 @@ function createAssistantHandler(options) {
1344
1367
  }
1345
1368
  });
1346
1369
  else if (agentsMd) ctx.useContext({
1347
- sourceBudget: 1e5,
1370
+ sourceBudget,
1348
1371
  sources: {
1349
1372
  conversation: {
1350
1373
  content: () => ctx.timelineMessages(),
@@ -1401,6 +1424,16 @@ function registerHorton(registry, options) {
1401
1424
  registry.define(`horton`, {
1402
1425
  description: `Friendly capable assistant — chat, code, research, dispatch`,
1403
1426
  creationSchema: hortonCreationSchema,
1427
+ permissionGrants: [{
1428
+ subject_kind: `principal_kind`,
1429
+ subject_value: `user`,
1430
+ permission: `spawn`
1431
+ }, {
1432
+ subject_kind: `principal_kind`,
1433
+ subject_value: `user`,
1434
+ permission: `manage`
1435
+ }],
1436
+ slashCommands: (0, __electric_ax_agents_runtime.buildSkillSlashCommands)(skillsRegistry),
1404
1437
  handler: assistantHandler
1405
1438
  });
1406
1439
  return [`horton`];
@@ -1442,7 +1475,7 @@ function parseWorkerArgs(value) {
1442
1475
  if (typeof value.reasoningEffort === `string` && REASONING_EFFORT_VALUES.includes(value.reasoningEffort)) args.reasoningEffort = value.reasoningEffort;
1443
1476
  return args;
1444
1477
  }
1445
- function buildToolsForWorker(tools, sandbox, ctx, readSet) {
1478
+ function buildToolsForWorker(tools, sandbox, ctx, readSet, opts) {
1446
1479
  const out = [];
1447
1480
  for (const name of tools) switch (name) {
1448
1481
  case `bash`:
@@ -1461,7 +1494,10 @@ function buildToolsForWorker(tools, sandbox, ctx, readSet) {
1461
1494
  out.push(__electric_ax_agents_runtime_tools.braveSearchTool);
1462
1495
  break;
1463
1496
  case `fetch_url`:
1464
- out.push((0, __electric_ax_agents_runtime_tools.createFetchUrlTool)(sandbox));
1497
+ out.push((0, __electric_ax_agents_runtime_tools.createFetchUrlTool)(sandbox, {
1498
+ catalog: opts.modelCatalog,
1499
+ modelConfig: opts.modelConfig
1500
+ }));
1465
1501
  break;
1466
1502
  case `spawn_worker`:
1467
1503
  out.push(createSpawnWorkerTool(ctx));
@@ -1572,11 +1608,23 @@ function registerWorker(registry, options) {
1572
1608
  const { streamFn, modelCatalog } = options;
1573
1609
  registry.define(`worker`, {
1574
1610
  description: `Internal — generic worker spawned by other agents. Configure via spawn args (systemPrompt + tools + optional sharedDb).`,
1611
+ permissionGrants: [{
1612
+ subject_kind: `principal_kind`,
1613
+ subject_value: `user`,
1614
+ permission: `spawn`
1615
+ }, {
1616
+ subject_kind: `principal_kind`,
1617
+ subject_value: `user`,
1618
+ permission: `manage`
1619
+ }],
1575
1620
  async handler(ctx) {
1576
1621
  const args = parseWorkerArgs(ctx.args);
1577
1622
  const readSet = new Set();
1578
- const builtinTools = buildToolsForWorker(args.tools, ctx.sandbox, ctx, readSet);
1579
1623
  const modelConfig = resolveBuiltinModelConfig(modelCatalog, args);
1624
+ const builtinTools = buildToolsForWorker(args.tools, ctx.sandbox, ctx, readSet, {
1625
+ modelCatalog,
1626
+ modelConfig
1627
+ });
1580
1628
  const sharedStateTools = [];
1581
1629
  if (args.sharedDb) {
1582
1630
  const shared = await ctx.observe((0, __electric_ax_agents_runtime.db)(args.sharedDb.id, args.sharedDb.schema));
@@ -1770,6 +1818,18 @@ function resolveCwd(args, fallback) {
1770
1818
  return readWorkingDirectoryArg(args) ?? fallback;
1771
1819
  }
1772
1820
 
1821
+ //#endregion
1822
+ //#region src/durable-streams-cache.ts
1823
+ const MEMORY_CACHE_SIZE_BYTES = 100 * 1024 * 1024;
1824
+ function installDurableStreamsFetchCache(options = {}) {
1825
+ if (options === false) return;
1826
+ const store = options.store === `sqlite` || options.sqliteLocation ? new undici.cacheStores.SqliteCacheStore({
1827
+ location: options.sqliteLocation,
1828
+ maxCount: options.maxCount
1829
+ }) : new undici.cacheStores.MemoryCacheStore({ maxSize: MEMORY_CACHE_SIZE_BYTES });
1830
+ (0, undici.setGlobalDispatcher)(new undici.Agent().compose(undici.interceptors.cache({ store })));
1831
+ }
1832
+
1773
1833
  //#endregion
1774
1834
  //#region src/server.ts
1775
1835
  var BuiltinAgentsServer = class {
@@ -1779,6 +1839,8 @@ var BuiltinAgentsServer = class {
1779
1839
  mcpToolProviderName = null;
1780
1840
  mcpApplyInFlight = new Set();
1781
1841
  mcpStopping = false;
1842
+ mcpExtras = [];
1843
+ mcpLastJsonConfig = null;
1782
1844
  pullWakeRunner = null;
1783
1845
  options;
1784
1846
  constructor(options) {
@@ -1788,8 +1850,70 @@ var BuiltinAgentsServer = class {
1788
1850
  get mcpRegistry() {
1789
1851
  return this._mcpRegistry;
1790
1852
  }
1853
+ /**
1854
+ * Replace the in-memory `extras` list and re-apply the merged config
1855
+ * against the last-known workspace `mcp.json` state. Workspace
1856
+ * `mcp.json` still wins on name collision. No-op once `stop()` has
1857
+ * latched `mcpStopping`.
1858
+ */
1859
+ async setExtraMcpServers(extras) {
1860
+ if (!this._mcpRegistry || this.mcpStopping) return;
1861
+ this.mcpExtras = extras;
1862
+ await this.applyMerged(this.mcpLastJsonConfig);
1863
+ }
1864
+ async wirePersistence(cfg) {
1865
+ const servers = [];
1866
+ for (const s of cfg.servers) if (s.transport === `http` && s.auth?.mode === `authorizationCode`) {
1867
+ const persist = await (0, __electric_ax_agents_mcp.keychainPersistence)({ server: s.name });
1868
+ servers.push({
1869
+ ...s,
1870
+ auth: {
1871
+ ...s.auth,
1872
+ ...persist
1873
+ }
1874
+ });
1875
+ } else servers.push(s);
1876
+ return {
1877
+ ...cfg,
1878
+ servers
1879
+ };
1880
+ }
1881
+ mergeMcp(jsonCfg) {
1882
+ const jsonServers = jsonCfg?.servers ?? [];
1883
+ const jsonNames = new Set(jsonServers.map((s) => s.name));
1884
+ const filteredExtras = this.mcpExtras.filter((s) => !jsonNames.has(s.name));
1885
+ return {
1886
+ servers: [...filteredExtras, ...jsonServers],
1887
+ raw: jsonCfg?.raw
1888
+ };
1889
+ }
1890
+ async runApply(jsonCfg) {
1891
+ if (this.mcpStopping) return;
1892
+ const registry = this._mcpRegistry;
1893
+ if (!registry) return;
1894
+ try {
1895
+ const wired = await this.wirePersistence(this.mergeMcp(jsonCfg));
1896
+ if (this.mcpStopping) return;
1897
+ await registry.applyConfig(wired);
1898
+ } catch (e) {
1899
+ serverLog.error(`[mcp] applyConfig:`, e);
1900
+ try {
1901
+ this.options.onConfigError?.(e);
1902
+ } catch (cbErr) {
1903
+ serverLog.error(`[mcp] onConfigError callback failed:`, cbErr);
1904
+ }
1905
+ }
1906
+ }
1907
+ applyMerged(jsonCfg) {
1908
+ this.mcpLastJsonConfig = jsonCfg;
1909
+ const p = this.runApply(jsonCfg);
1910
+ this.mcpApplyInFlight.add(p);
1911
+ p.finally(() => this.mcpApplyInFlight.delete(p));
1912
+ return p;
1913
+ }
1791
1914
  async start() {
1792
1915
  if (this.bootstrap || this.pullWakeRunner) throw new Error(`Builtin agents runtime already started`);
1916
+ installDurableStreamsFetchCache(this.options.durableStreamsFetchCache);
1793
1917
  const pullWake = this.options.pullWake;
1794
1918
  if (!pullWake?.runnerId) throw new Error(`Builtin agents require a pull-wake runner id`);
1795
1919
  try {
@@ -1800,76 +1924,28 @@ var BuiltinAgentsServer = class {
1800
1924
  });
1801
1925
  this._mcpRegistry = mcpRegistry;
1802
1926
  const mcpConfigPath = this.options.loadProjectMcpConfig ? node_path.default.resolve(this.options.workingDirectory ?? process.cwd(), `mcp.json`) : null;
1803
- const extras = this.options.extraMcpServers ?? [];
1804
- const wirePersistence = async (cfg) => {
1805
- const servers = [];
1806
- for (const s of cfg.servers) if (s.transport === `http` && s.auth?.mode === `authorizationCode`) {
1807
- const persist = await (0, __electric_ax_agents_mcp.keychainPersistence)({ server: s.name });
1808
- servers.push({
1809
- ...s,
1810
- auth: {
1811
- ...s.auth,
1812
- ...persist
1813
- }
1814
- });
1815
- } else servers.push(s);
1816
- return {
1817
- ...cfg,
1818
- servers
1819
- };
1820
- };
1821
- const merge = (jsonCfg) => {
1822
- const jsonServers = jsonCfg?.servers ?? [];
1823
- const jsonNames = new Set(jsonServers.map((s) => s.name));
1824
- const filteredExtras = extras.filter((s) => !jsonNames.has(s.name));
1825
- return {
1826
- servers: [...filteredExtras, ...jsonServers],
1827
- raw: jsonCfg?.raw
1828
- };
1829
- };
1830
- const onConfigError = this.options.onConfigError;
1831
- const runApply = async (jsonCfg) => {
1832
- if (this.mcpStopping) return;
1833
- try {
1834
- const wired = await wirePersistence(merge(jsonCfg));
1835
- if (this.mcpStopping) return;
1836
- await mcpRegistry.applyConfig(wired);
1837
- } catch (e) {
1838
- serverLog.error(`[mcp] applyConfig:`, e);
1839
- try {
1840
- onConfigError?.(e);
1841
- } catch (cbErr) {
1842
- serverLog.error(`[mcp] onConfigError callback failed:`, cbErr);
1843
- }
1844
- }
1845
- };
1846
- const applyMerged = (jsonCfg) => {
1847
- const p = runApply(jsonCfg);
1848
- this.mcpApplyInFlight.add(p);
1849
- p.finally(() => this.mcpApplyInFlight.delete(p));
1850
- return p;
1851
- };
1927
+ this.mcpExtras = this.options.extraMcpServers ?? [];
1852
1928
  if (mcpConfigPath) {
1853
1929
  try {
1854
1930
  const cfg = await (0, __electric_ax_agents_mcp.loadConfig)(mcpConfigPath, process.env);
1855
- applyMerged(cfg);
1931
+ this.applyMerged(cfg);
1856
1932
  } catch (err) {
1857
1933
  if (err.code !== `ENOENT`) throw err;
1858
- if (extras.length === 0) serverLog.info(`[mcp] no ${mcpConfigPath} — starting with no servers`);
1859
- else serverLog.info(`[mcp] no ${mcpConfigPath} — starting with ${extras.length} server(s) from extras`);
1860
- applyMerged(null);
1934
+ if (this.mcpExtras.length === 0) serverLog.info(`[mcp] no ${mcpConfigPath} — starting with no servers`);
1935
+ else serverLog.info(`[mcp] no ${mcpConfigPath} — starting with ${this.mcpExtras.length} server(s) from extras`);
1936
+ this.applyMerged(null);
1861
1937
  }
1862
1938
  try {
1863
1939
  this.mcpWatcherCloser = await (0, __electric_ax_agents_mcp.watchConfig)(mcpConfigPath, {
1864
- onChange: (cfg) => void applyMerged(cfg),
1940
+ onChange: (cfg) => void this.applyMerged(cfg),
1865
1941
  onError: (e) => serverLog.error(`[mcp] config error:`, e)
1866
1942
  });
1867
1943
  } catch (e) {
1868
1944
  serverLog.error(`[mcp] config watcher failed to start:`, e);
1869
1945
  }
1870
1946
  } else {
1871
- if (extras.length > 0) serverLog.info(`[mcp] starting with ${extras.length} server(s) from extras`);
1872
- applyMerged(null);
1947
+ if (this.mcpExtras.length > 0) serverLog.info(`[mcp] starting with ${this.mcpExtras.length} server(s) from extras`);
1948
+ this.applyMerged(null);
1873
1949
  }
1874
1950
  this.mcpToolProviderName = `mcp`;
1875
1951
  (0, __electric_ax_agents_runtime.registerToolProvider)({
package/dist/index.d.cts CHANGED
@@ -36,12 +36,26 @@ declare function createAgentHandler(agentServerUrl: string, workingDirectory?: s
36
36
  declare function registerBuiltinAgentTypes(bootstrap: AgentHandlerResult): Promise<void>;
37
37
  declare const registerAgentTypes: typeof registerBuiltinAgentTypes;
38
38
 
39
+ //#endregion
40
+ //#region src/durable-streams-cache.d.ts
41
+ type DurableStreamsFetchCacheOptions = false | {
42
+ store?: `memory` | `sqlite`;
43
+ sqliteLocation?: string;
44
+ maxCount?: number;
45
+ };
46
+
39
47
  //#endregion
40
48
  //#region src/server.d.ts
41
49
  interface BuiltinAgentsServerOptions {
42
50
  agentServerUrl: string;
43
51
  workingDirectory?: string;
44
52
  mockStreamFn?: StreamFn;
53
+ /**
54
+ * Configure the process-wide HTTP cache used by Undici-backed fetch calls.
55
+ * Defaults to a 100 MiB in-memory cache. Pass `false` to leave the global
56
+ * dispatcher unchanged.
57
+ */
58
+ durableStreamsFetchCache?: DurableStreamsFetchCacheOptions;
45
59
  /** Pull-wake runner configuration for built-in agents. */
46
60
  pullWake: {
47
61
  runnerId: string;
@@ -92,11 +106,24 @@ declare class BuiltinAgentsServer {
92
106
  private mcpToolProviderName;
93
107
  private mcpApplyInFlight;
94
108
  private mcpStopping;
109
+ private mcpExtras;
110
+ private mcpLastJsonConfig;
95
111
  private pullWakeRunner;
96
112
  readonly options: BuiltinAgentsServerOptions;
97
113
  constructor(options: BuiltinAgentsServerOptions);
98
114
  /** Embedded MCP registry. `null` until `start()` has run. */
99
115
  get mcpRegistry(): Registry | null;
116
+ /**
117
+ * Replace the in-memory `extras` list and re-apply the merged config
118
+ * against the last-known workspace `mcp.json` state. Workspace
119
+ * `mcp.json` still wins on name collision. No-op once `stop()` has
120
+ * latched `mcpStopping`.
121
+ */
122
+ setExtraMcpServers(extras: ReadonlyArray<McpServerConfig$1>): Promise<void>;
123
+ private wirePersistence;
124
+ private mergeMcp;
125
+ private runApply;
126
+ private applyMerged;
100
127
  start(): Promise<string>;
101
128
  stop(): Promise<void>;
102
129
  private registerPullWakeRunner;
package/dist/index.d.ts CHANGED
@@ -36,12 +36,26 @@ declare function createAgentHandler(agentServerUrl: string, workingDirectory?: s
36
36
  declare function registerBuiltinAgentTypes(bootstrap: AgentHandlerResult): Promise<void>;
37
37
  declare const registerAgentTypes: typeof registerBuiltinAgentTypes;
38
38
 
39
+ //#endregion
40
+ //#region src/durable-streams-cache.d.ts
41
+ type DurableStreamsFetchCacheOptions = false | {
42
+ store?: `memory` | `sqlite`;
43
+ sqliteLocation?: string;
44
+ maxCount?: number;
45
+ };
46
+
39
47
  //#endregion
40
48
  //#region src/server.d.ts
41
49
  interface BuiltinAgentsServerOptions {
42
50
  agentServerUrl: string;
43
51
  workingDirectory?: string;
44
52
  mockStreamFn?: StreamFn;
53
+ /**
54
+ * Configure the process-wide HTTP cache used by Undici-backed fetch calls.
55
+ * Defaults to a 100 MiB in-memory cache. Pass `false` to leave the global
56
+ * dispatcher unchanged.
57
+ */
58
+ durableStreamsFetchCache?: DurableStreamsFetchCacheOptions;
45
59
  /** Pull-wake runner configuration for built-in agents. */
46
60
  pullWake: {
47
61
  runnerId: string;
@@ -92,11 +106,24 @@ declare class BuiltinAgentsServer {
92
106
  private mcpToolProviderName;
93
107
  private mcpApplyInFlight;
94
108
  private mcpStopping;
109
+ private mcpExtras;
110
+ private mcpLastJsonConfig;
95
111
  private pullWakeRunner;
96
112
  readonly options: BuiltinAgentsServerOptions;
97
113
  constructor(options: BuiltinAgentsServerOptions);
98
114
  /** Embedded MCP registry. `null` until `start()` has run. */
99
115
  get mcpRegistry(): Registry | null;
116
+ /**
117
+ * Replace the in-memory `extras` list and re-apply the merged config
118
+ * against the last-known workspace `mcp.json` state. Workspace
119
+ * `mcp.json` still wins on name collision. No-op once `stop()` has
120
+ * latched `mcpStopping`.
121
+ */
122
+ setExtraMcpServers(extras: ReadonlyArray<McpServerConfig$1>): Promise<void>;
123
+ private wirePersistence;
124
+ private mergeMcp;
125
+ private runApply;
126
+ private applyMerged;
100
127
  start(): Promise<string>;
101
128
  stop(): Promise<void>;
102
129
  private registerPullWakeRunner;