@band-ai/sdk 0.1.2 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{CodexAdapter-A1k_LMdZ.d.ts → ClaudeSDKAdapter-BHOkjN3X.d.ts} +222 -222
  2. package/dist/{CodexAdapter-BbZD-nBd.d.cts → ClaudeSDKAdapter-CRq4R-WB.d.cts} +222 -222
  3. package/dist/adapters.cjs +375 -275
  4. package/dist/adapters.d.cts +21 -21
  5. package/dist/adapters.d.ts +21 -21
  6. package/dist/adapters.js +1512 -13
  7. package/dist/{backends-C4n6cKOf.d.ts → backends-CzDbiQar.d.ts} +1 -1
  8. package/dist/{backends-BnOLsG7w.d.cts → backends-SVMT-7l4.d.cts} +1 -1
  9. package/dist/chunk-FYVLUGW7.js +59 -0
  10. package/dist/{chunk-6AJA2OPC.js → chunk-I5EZG52P.js} +11 -4
  11. package/dist/{chunk-NIAQBANR.js → chunk-MSL6CWHY.js} +1 -1
  12. package/dist/{chunk-A3TDK6GP.js → chunk-RHVH2GZR.js} +4589 -5993
  13. package/dist/{chunk-FUODYQRE.js → chunk-W5NDZSYE.js} +2 -59
  14. package/dist/converters.d.cts +1 -1
  15. package/dist/converters.d.ts +1 -1
  16. package/dist/converters.js +5 -3
  17. package/dist/index.cjs +7161 -7116
  18. package/dist/index.d.cts +3 -3
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +4 -6
  21. package/dist/mcp-claude.cjs +4 -6
  22. package/dist/mcp-claude.d.cts +1 -1
  23. package/dist/mcp-claude.d.ts +1 -1
  24. package/dist/mcp-claude.js +47 -5
  25. package/dist/mcp.d.cts +3 -3
  26. package/dist/mcp.d.ts +3 -3
  27. package/dist/mcp.js +1 -1
  28. package/dist/runtime.cjs +11 -4
  29. package/dist/runtime.js +1 -1
  30. package/package.json +2 -2
  31. package/dist/chunk-5CXIMAH2.js +0 -52
  32. package/dist/chunk-LY55KYVI.js +0 -0
  33. package/dist/sdk-HJUVSSWA.js +0 -10
  34. package/dist/{history-ByessXNq.d.ts → acp-server-B1Da7L6u.d.ts} +4 -4
  35. package/dist/{history-i6yN7neC.d.cts → acp-server-BdRz9_UN.d.cts} +4 -4
  36. /package/dist/{claude-CcnQ5OUC.d.ts → sdk-CcnQ5OUC.d.ts} +0 -0
  37. /package/dist/{claude-CwTAxhwI.d.cts → sdk-CwTAxhwI.d.cts} +0 -0
package/dist/adapters.cjs CHANGED
@@ -30,6 +30,35 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // src/contracts/protocols.ts
34
+ function isToolExecutorError(value) {
35
+ if (!value || typeof value !== "object") {
36
+ return false;
37
+ }
38
+ const candidate = value;
39
+ return candidate.ok === false && typeof candidate.errorType === "string" && TOOL_EXECUTOR_ERROR_TYPES.includes(candidate.errorType) && typeof candidate.toolName === "string" && typeof candidate.message === "string" && typeof candidate.legacyMessage === "string";
40
+ }
41
+ function toLegacyToolExecutorErrorMessage(value) {
42
+ if (typeof value === "string") {
43
+ return value;
44
+ }
45
+ if (!isToolExecutorError(value)) {
46
+ return null;
47
+ }
48
+ return value.legacyMessage;
49
+ }
50
+ var TOOL_EXECUTOR_ERROR_TYPES;
51
+ var init_protocols = __esm({
52
+ "src/contracts/protocols.ts"() {
53
+ "use strict";
54
+ TOOL_EXECUTOR_ERROR_TYPES = [
55
+ "ToolArgumentsValidationError",
56
+ "ToolNotFoundError",
57
+ "ToolExecutionError"
58
+ ];
59
+ }
60
+ });
61
+
33
62
  // src/core/errors.ts
34
63
  var ThenvoiSdkError, UnsupportedFeatureError, ValidationError, RuntimeStateError;
35
64
  var init_errors = __esm({
@@ -420,35 +449,6 @@ var init_schemas = __esm({
420
449
  }
421
450
  });
422
451
 
423
- // src/contracts/protocols.ts
424
- function isToolExecutorError(value) {
425
- if (!value || typeof value !== "object") {
426
- return false;
427
- }
428
- const candidate = value;
429
- return candidate.ok === false && typeof candidate.errorType === "string" && TOOL_EXECUTOR_ERROR_TYPES.includes(candidate.errorType) && typeof candidate.toolName === "string" && typeof candidate.message === "string" && typeof candidate.legacyMessage === "string";
430
- }
431
- function toLegacyToolExecutorErrorMessage(value) {
432
- if (typeof value === "string") {
433
- return value;
434
- }
435
- if (!isToolExecutorError(value)) {
436
- return null;
437
- }
438
- return value.legacyMessage;
439
- }
440
- var TOOL_EXECUTOR_ERROR_TYPES;
441
- var init_protocols = __esm({
442
- "src/contracts/protocols.ts"() {
443
- "use strict";
444
- TOOL_EXECUTOR_ERROR_TYPES = [
445
- "ToolArgumentsValidationError",
446
- "ToolNotFoundError",
447
- "ToolExecutionError"
448
- ];
449
- }
450
- });
451
-
452
452
  // src/mcp/registrations.ts
453
453
  function buildRoomScopedRegistrations(resolver, options = {}) {
454
454
  const toolNames = resolveToolNames(options);
@@ -576,42 +576,42 @@ var init_registrations = __esm({
576
576
  });
577
577
 
578
578
  // src/mcp/zod.ts
579
- function buildZodShape(z3, properties, required) {
579
+ function buildZodShape(z4, properties, required) {
580
580
  const shape = {};
581
581
  for (const [name, schema] of Object.entries(properties)) {
582
- const validator = jsonSchemaToZod(z3, schema);
582
+ const validator = jsonSchemaToZod(z4, schema);
583
583
  shape[name] = required.has(name) ? validator : validator.optional();
584
584
  }
585
585
  return shape;
586
586
  }
587
- function jsonSchemaToZod(z3, schema) {
587
+ function jsonSchemaToZod(z4, schema) {
588
588
  const type = schema.type;
589
589
  if (type === "string") {
590
590
  if (Array.isArray(schema.enum) && schema.enum.every((v) => typeof v === "string")) {
591
591
  const values = schema.enum;
592
592
  if (values.length > 0) {
593
- return z3.enum(values);
593
+ return z4.enum(values);
594
594
  }
595
595
  }
596
- return z3.string();
596
+ return z4.string();
597
597
  }
598
598
  if (type === "integer" || type === "number") {
599
- return z3.number();
599
+ return z4.number();
600
600
  }
601
601
  if (type === "boolean") {
602
- return z3.boolean();
602
+ return z4.boolean();
603
603
  }
604
604
  if (type === "array") {
605
605
  const itemSchema = schema.items;
606
606
  if (itemSchema && typeof itemSchema === "object") {
607
- return z3.array(jsonSchemaToZod(z3, itemSchema));
607
+ return z4.array(jsonSchemaToZod(z4, itemSchema));
608
608
  }
609
- return z3.array(z3.unknown());
609
+ return z4.array(z4.unknown());
610
610
  }
611
611
  if (type === "object") {
612
- return z3.record(z3.string(), z3.unknown());
612
+ return z4.record(z4.string(), z4.unknown());
613
613
  }
614
- return z3.unknown();
614
+ return z4.unknown();
615
615
  }
616
616
  var init_zod = __esm({
617
617
  "src/mcp/zod.ts"() {
@@ -647,7 +647,7 @@ function createThenvoiSdkMcpServer(options) {
647
647
  }
648
648
  function toSdkToolDefinition(registration) {
649
649
  const shape = buildZodShape(
650
- import_zod4.z,
650
+ import_zod5.z,
651
651
  registration.inputSchema.properties,
652
652
  new Set(registration.inputSchema.required)
653
653
  );
@@ -658,12 +658,12 @@ function toSdkToolDefinition(registration) {
658
658
  async (args) => registration.execute(args)
659
659
  );
660
660
  }
661
- var import_claude_agent_sdk, import_zod4;
661
+ var import_claude_agent_sdk, import_zod5;
662
662
  var init_sdk = __esm({
663
663
  "src/mcp/sdk.ts"() {
664
664
  "use strict";
665
665
  import_claude_agent_sdk = require("@anthropic-ai/claude-agent-sdk");
666
- import_zod4 = require("zod");
666
+ import_zod5 = require("zod");
667
667
  init_schemas();
668
668
  init_registrations();
669
669
  init_zod();
@@ -774,7 +774,6 @@ var GenericAdapter = class extends SimpleAdapter {
774
774
  // src/adapters/acp/ACPClientAdapter.ts
775
775
  var import_node_child_process = require("child_process");
776
776
  var import_node_stream = require("stream");
777
- var import_sdk = require("@agentclientprotocol/sdk");
778
777
 
779
778
  // src/converters/acp-client.ts
780
779
  var ACPClientHistoryConverter = class {
@@ -894,72 +893,6 @@ ${customSection}`.trim();
894
893
  return templateString.replaceAll("{agent_name}", agentName).replaceAll("{agent_description}", agentDescription).replaceAll("{custom_section}", customSection);
895
894
  }
896
895
 
897
- // src/mcp/backends.ts
898
- init_schemas();
899
- init_registrations();
900
-
901
- // src/mcp/stdio.ts
902
- init_registrations();
903
- init_zod();
904
- var ThenvoiMcpStdioServer = class {
905
- options;
906
- registrations;
907
- mcpServer = null;
908
- transport = null;
909
- constructor(options) {
910
- this.options = options;
911
- const regOptions = {
912
- enableMemoryTools: options.enableMemoryTools,
913
- enableContactTools: options.enableContactTools,
914
- additionalTools: options.additionalTools
915
- };
916
- if (typeof options.tools === "function") {
917
- this.registrations = buildRoomScopedRegistrations(options.tools, regOptions);
918
- } else {
919
- this.registrations = buildSingleContextRegistrations(options.tools, regOptions);
920
- }
921
- }
922
- get toolNames() {
923
- return this.registrations.map((r) => r.name);
924
- }
925
- async start() {
926
- if (this.transport) {
927
- return;
928
- }
929
- const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
930
- const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
931
- const { z: z3 } = await import("zod");
932
- const mcpServer = new McpServer({
933
- name: this.options.name ?? "thenvoi",
934
- version: "1.0.0"
935
- });
936
- registerTools(mcpServer, z3, this.registrations);
937
- const transport = new StdioServerTransport(this.options.stdin, this.options.stdout);
938
- await mcpServer.connect(transport);
939
- this.mcpServer = mcpServer;
940
- this.transport = transport;
941
- }
942
- async stop() {
943
- await this.transport?.close();
944
- this.transport = null;
945
- this.mcpServer = null;
946
- }
947
- };
948
- function registerTools(mcpServer, z3, registrations) {
949
- for (const reg of registrations) {
950
- const zodShape = buildZodShape(z3, reg.inputSchema.properties, new Set(reg.inputSchema.required));
951
- mcpServer.registerTool(
952
- reg.name,
953
- {
954
- description: reg.description,
955
- inputSchema: z3.object(zodShape)
956
- },
957
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK handler signature is complex; our McpToolResult is compatible
958
- async (args) => reg.execute(args)
959
- );
960
- }
961
- }
962
-
963
896
  // src/mcp/server.ts
964
897
  init_registrations();
965
898
  init_zod();
@@ -1011,7 +944,7 @@ var ThenvoiMcpServer = class {
1011
944
  const express = expressModule.default ?? expressModule;
1012
945
  const http = await import("http");
1013
946
  const { randomUUID: randomUUID7 } = await import("crypto");
1014
- const { z: z3 } = await import("zod");
947
+ const { z: z4 } = await import("zod");
1015
948
  const serverName = this.options.name ?? "thenvoi";
1016
949
  const app = express();
1017
950
  app.use(express.json());
@@ -1032,7 +965,7 @@ var ThenvoiMcpServer = class {
1032
965
  StreamableHTTPServerTransport,
1033
966
  serverName,
1034
967
  sessionIdGenerator: randomUUID7,
1035
- z: z3
968
+ z: z4
1036
969
  });
1037
970
  }
1038
971
  session.lastSeenAt = Date.now();
@@ -1089,7 +1022,7 @@ var ThenvoiMcpServer = class {
1089
1022
  async createSession(input) {
1090
1023
  const createdAt = Date.now();
1091
1024
  const mcpServer = new input.McpServer({ name: input.serverName, version: MCP_SERVER_VERSION });
1092
- registerTools2(mcpServer, input.z, this.registrations);
1025
+ registerTools(mcpServer, input.z, this.registrations);
1093
1026
  let record = null;
1094
1027
  const transport = new input.StreamableHTTPServerTransport({
1095
1028
  sessionIdGenerator: input.sessionIdGenerator,
@@ -1158,14 +1091,14 @@ function sendMcpError(res, status, message) {
1158
1091
  id: null
1159
1092
  });
1160
1093
  }
1161
- function registerTools2(mcpServer, z3, registrations) {
1094
+ function registerTools(mcpServer, z4, registrations) {
1162
1095
  for (const reg of registrations) {
1163
- const zodShape = buildZodShape(z3, reg.inputSchema.properties, new Set(reg.inputSchema.required));
1096
+ const zodShape = buildZodShape(z4, reg.inputSchema.properties, new Set(reg.inputSchema.required));
1164
1097
  mcpServer.registerTool(
1165
1098
  reg.name,
1166
1099
  {
1167
1100
  description: reg.description,
1168
- inputSchema: z3.object(zodShape)
1101
+ inputSchema: z4.object(zodShape)
1169
1102
  },
1170
1103
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK handler signature is complex; our McpToolResult is compatible
1171
1104
  async (args) => reg.execute(args)
@@ -1240,7 +1173,7 @@ var ThenvoiMcpSseServer = class {
1240
1173
  const expressModule = await import("express");
1241
1174
  const express = expressModule.default ?? expressModule;
1242
1175
  const http = await import("http");
1243
- const { z: z3 } = await import("zod");
1176
+ const { z: z4 } = await import("zod");
1244
1177
  const app = express();
1245
1178
  app.use(express.json());
1246
1179
  app.get("/healthz", (_req, res) => {
@@ -1252,7 +1185,7 @@ var ThenvoiMcpSseServer = class {
1252
1185
  name: this.options.name ?? "thenvoi",
1253
1186
  version: "1.0.0"
1254
1187
  });
1255
- registerTools3(mcpServer, z3, this.registrations);
1188
+ registerTools2(mcpServer, z4, this.registrations);
1256
1189
  await mcpServer.connect(transport);
1257
1190
  const sessionId = transport.sessionId;
1258
1191
  this.sessions.set(sessionId, {
@@ -1344,10 +1277,10 @@ var ThenvoiMcpSseServer = class {
1344
1277
  }
1345
1278
  }
1346
1279
  };
1347
- function registerTools3(mcpServer, z3, registrations) {
1280
+ function registerTools2(mcpServer, z4, registrations) {
1348
1281
  for (const registration of registrations) {
1349
1282
  const zodShape = buildZodShape(
1350
- z3,
1283
+ z4,
1351
1284
  registration.inputSchema.properties,
1352
1285
  new Set(registration.inputSchema.required)
1353
1286
  );
@@ -1355,7 +1288,7 @@ function registerTools3(mcpServer, z3, registrations) {
1355
1288
  registration.name,
1356
1289
  {
1357
1290
  description: registration.description,
1358
- inputSchema: z3.object(zodShape)
1291
+ inputSchema: z4.object(zodShape)
1359
1292
  },
1360
1293
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK handler signature is complex; our McpToolResult is compatible
1361
1294
  async (args) => registration.execute(args)
@@ -1383,85 +1316,6 @@ function checkPort2(http, port) {
1383
1316
  });
1384
1317
  }
1385
1318
 
1386
- // src/mcp/backends.ts
1387
- async function createThenvoiMcpBackend(options) {
1388
- const registrations = buildRoomScopedRegistrations(
1389
- options.getToolsForRoom,
1390
- {
1391
- enableMemoryTools: options.enableMemoryTools,
1392
- enableContactTools: true,
1393
- additionalTools: options.additionalTools
1394
- }
1395
- );
1396
- const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
1397
- if (options.kind === "sdk") {
1398
- const { createThenvoiSdkMcpServer: createThenvoiSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
1399
- const server2 = createThenvoiSdkMcpServer2({
1400
- enableMemoryTools: options.enableMemoryTools,
1401
- getToolsForRoom: options.getToolsForRoom,
1402
- additionalTools: options.additionalTools
1403
- });
1404
- return {
1405
- kind: "sdk",
1406
- server: server2,
1407
- allowedTools: server2.allowedTools,
1408
- stop: async () => void 0
1409
- };
1410
- }
1411
- if (options.kind === "stdio") {
1412
- const server2 = new ThenvoiMcpStdioServer({
1413
- tools: options.getToolsForRoom,
1414
- enableMemoryTools: options.enableMemoryTools,
1415
- enableContactTools: true,
1416
- additionalTools: options.additionalTools
1417
- });
1418
- await server2.start();
1419
- return {
1420
- kind: "stdio",
1421
- server: server2,
1422
- allowedTools,
1423
- stop: async () => {
1424
- await server2.stop();
1425
- }
1426
- };
1427
- }
1428
- if (options.kind === "sse") {
1429
- const server2 = new ThenvoiMcpSseServer({
1430
- tools: options.getToolsForRoom,
1431
- enableMemoryTools: options.enableMemoryTools,
1432
- enableContactTools: true,
1433
- additionalTools: options.additionalTools
1434
- });
1435
- await server2.start();
1436
- return {
1437
- kind: "sse",
1438
- server: server2,
1439
- allowedTools,
1440
- stop: async () => {
1441
- await server2.stop();
1442
- }
1443
- };
1444
- }
1445
- const server = new ThenvoiMcpServer({
1446
- tools: options.getToolsForRoom,
1447
- enableMemoryTools: options.enableMemoryTools,
1448
- enableContactTools: true,
1449
- additionalTools: options.additionalTools
1450
- });
1451
- await server.start();
1452
- return {
1453
- kind: "http",
1454
- server,
1455
- allowedTools,
1456
- stop: async () => {
1457
- await server.stop();
1458
- }
1459
- };
1460
- }
1461
-
1462
- // src/mcp/index.ts
1463
- init_registrations();
1464
-
1465
1319
  // src/adapters/acp/types.ts
1466
1320
  var DEFAULT_ACP_SERVER_MODES = [
1467
1321
  {
@@ -1722,6 +1576,67 @@ function toOptionalString(value) {
1722
1576
  return typeof value === "string" && value.length > 0 ? value : null;
1723
1577
  }
1724
1578
 
1579
+ // src/adapters/acp/loader.ts
1580
+ init_errors();
1581
+
1582
+ // src/adapters/shared/lazyAsyncValue.ts
1583
+ var DEFAULT_RETRY_BACKOFF_MS = 1e3;
1584
+ var LazyAsyncValue = class {
1585
+ load;
1586
+ onRejected;
1587
+ retryBackoffMs;
1588
+ value = null;
1589
+ pending = null;
1590
+ lastFailureAt = 0;
1591
+ constructor(options) {
1592
+ this.load = options.load;
1593
+ this.onRejected = options.onRejected;
1594
+ this.retryBackoffMs = options.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS;
1595
+ }
1596
+ get current() {
1597
+ return this.value;
1598
+ }
1599
+ async get() {
1600
+ if (this.value) {
1601
+ return this.value;
1602
+ }
1603
+ if (!this.pending) {
1604
+ if (this.lastFailureAt > 0 && Date.now() - this.lastFailureAt < this.retryBackoffMs) {
1605
+ throw new Error(
1606
+ `LazyAsyncValue load failed recently; retrying after ${this.retryBackoffMs}ms backoff.`
1607
+ );
1608
+ }
1609
+ this.pending = this.load().then((value) => {
1610
+ this.value = value;
1611
+ this.lastFailureAt = 0;
1612
+ return value;
1613
+ }).catch((error) => {
1614
+ this.pending = null;
1615
+ this.lastFailureAt = Date.now();
1616
+ this.onRejected?.(error);
1617
+ throw error;
1618
+ });
1619
+ }
1620
+ return this.pending;
1621
+ }
1622
+ clear() {
1623
+ this.value = null;
1624
+ this.pending = null;
1625
+ this.lastFailureAt = 0;
1626
+ }
1627
+ };
1628
+
1629
+ // src/adapters/acp/loader.ts
1630
+ var acpModule = new LazyAsyncValue({
1631
+ load: async () => {
1632
+ return await import("@agentclientprotocol/sdk").catch((error) => {
1633
+ throw new UnsupportedFeatureError(
1634
+ `ACP adapters require optional dependency "@agentclientprotocol/sdk". Install it with "pnpm add @agentclientprotocol/sdk". (${error instanceof Error ? error.message : String(error)})`
1635
+ );
1636
+ });
1637
+ }
1638
+ });
1639
+
1725
1640
  // src/adapters/acp/ACPClientAdapter.ts
1726
1641
  var ACPClientAdapter = class extends SimpleAdapter {
1727
1642
  command;
@@ -1878,6 +1793,7 @@ ${message.content}`;
1878
1793
  }
1879
1794
  }
1880
1795
  async spawnConnection() {
1796
+ const acp = await acpModule.get();
1881
1797
  const client = new ThenvoiACPClient();
1882
1798
  const handle = await this.connectionFactory(client, {
1883
1799
  command: this.command,
@@ -1886,7 +1802,7 @@ ${message.content}`;
1886
1802
  });
1887
1803
  const connection = handle.connection;
1888
1804
  const initializeResult = await connection.initialize({
1889
- protocolVersion: import_sdk.PROTOCOL_VERSION,
1805
+ protocolVersion: acp.PROTOCOL_VERSION,
1890
1806
  clientCapabilities: this.clientCapabilities ?? {}
1891
1807
  });
1892
1808
  if (this.authMethod) {
@@ -1985,19 +1901,44 @@ ${message.content}`;
1985
1901
  });
1986
1902
  return mcpServers;
1987
1903
  }
1988
- throw new Error(`Unsupported MCP backend for ACP client injection: ${backend.kind}`);
1904
+ return mcpServers;
1989
1905
  }
1990
1906
  async getOrCreateBackend() {
1991
1907
  if (this.backend) {
1992
1908
  return this.backend;
1993
1909
  }
1994
1910
  const transport = this.connectionState?.agentCapabilities?.mcpCapabilities?.http ? "http" : this.connectionState?.agentCapabilities?.mcpCapabilities?.sse ? "sse" : "http";
1995
- this.backend = await createThenvoiMcpBackend({
1996
- kind: transport,
1911
+ if (transport === "sse") {
1912
+ const server2 = new ThenvoiMcpSseServer({
1913
+ tools: (roomId) => this.roomTools.get(roomId),
1914
+ enableMemoryTools: this.enableMemoryTools,
1915
+ enableContactTools: true,
1916
+ additionalTools: this.additionalMcpTools
1917
+ });
1918
+ await server2.start();
1919
+ this.backend = {
1920
+ kind: "sse",
1921
+ server: server2,
1922
+ stop: async () => {
1923
+ await server2.stop();
1924
+ }
1925
+ };
1926
+ return this.backend;
1927
+ }
1928
+ const server = new ThenvoiMcpServer({
1929
+ tools: (roomId) => this.roomTools.get(roomId),
1997
1930
  enableMemoryTools: this.enableMemoryTools,
1998
- getToolsForRoom: (roomId) => this.roomTools.get(roomId),
1931
+ enableContactTools: true,
1999
1932
  additionalTools: this.additionalMcpTools
2000
1933
  });
1934
+ await server.start();
1935
+ this.backend = {
1936
+ kind: "http",
1937
+ server,
1938
+ stop: async () => {
1939
+ await server.stop();
1940
+ }
1941
+ };
2001
1942
  return this.backend;
2002
1943
  }
2003
1944
  buildSystemContext(roomId, message) {
@@ -2067,6 +2008,7 @@ ${message.content}`;
2067
2008
  }
2068
2009
  };
2069
2010
  async function createSubprocessConnection(client, options) {
2011
+ const acp = await acpModule.get();
2070
2012
  const child = (0, import_node_child_process.spawn)(options.command[0], options.command.slice(1), {
2071
2013
  cwd: options.cwd,
2072
2014
  env: {
@@ -2078,11 +2020,11 @@ async function createSubprocessConnection(client, options) {
2078
2020
  if (!child.stdin || !child.stdout) {
2079
2021
  throw new Error("ACP subprocess did not expose stdio pipes");
2080
2022
  }
2081
- const stream = (0, import_sdk.ndJsonStream)(
2023
+ const stream = acp.ndJsonStream(
2082
2024
  import_node_stream.Writable.toWeb(child.stdin),
2083
2025
  import_node_stream.Readable.toWeb(child.stdout)
2084
2026
  );
2085
- const connection = new import_sdk.ClientSideConnection(() => client, stream);
2027
+ const connection = new acp.ClientSideConnection(() => client, stream);
2086
2028
  return {
2087
2029
  connection,
2088
2030
  stop: async () => {
@@ -2122,7 +2064,6 @@ function toErrorMessage(error) {
2122
2064
 
2123
2065
  // src/adapters/acp/ACPServer.ts
2124
2066
  var import_node_stream2 = require("stream");
2125
- var import_sdk2 = require("@agentclientprotocol/sdk");
2126
2067
 
2127
2068
  // src/adapters/acp/ThenvoiACPServerAdapter.ts
2128
2069
  var import_node_crypto = require("crypto");
@@ -2791,11 +2732,12 @@ var ACPServer = class {
2791
2732
  this.agentInfo = options?.agentInfo ?? {};
2792
2733
  this.extensionHandler = options?.extensionHandler ?? new CursorExtensionHandler();
2793
2734
  }
2794
- connectStream(stream) {
2735
+ async connectStream(stream) {
2795
2736
  if (this.connection && !this.connection.signal.aborted) {
2796
2737
  return this.connection;
2797
2738
  }
2798
- this.connection = new import_sdk2.AgentSideConnection((connection) => {
2739
+ const acp = await acpModule.get();
2740
+ this.connection = new acp.AgentSideConnection((connection) => {
2799
2741
  this.adapter.bindConnection(connection);
2800
2742
  return this;
2801
2743
  }, stream);
@@ -2809,19 +2751,20 @@ var ACPServer = class {
2809
2751
  connectStdio(options) {
2810
2752
  const stdin = options?.stdin ?? process.stdin;
2811
2753
  const stdout = options?.stdout ?? process.stdout;
2812
- return this.connectStream(
2813
- (0, import_sdk2.ndJsonStream)(
2754
+ return acpModule.get().then((acp) => this.connectStream(
2755
+ acp.ndJsonStream(
2814
2756
  import_node_stream2.Writable.toWeb(stdout),
2815
2757
  import_node_stream2.Readable.toWeb(stdin)
2816
2758
  )
2817
- );
2759
+ ));
2818
2760
  }
2819
2761
  get closed() {
2820
2762
  return this.connection?.closed ?? Promise.resolve();
2821
2763
  }
2822
2764
  async initialize(params) {
2765
+ const acp = await acpModule.get();
2823
2766
  return {
2824
- protocolVersion: params.protocolVersion === import_sdk2.PROTOCOL_VERSION ? params.protocolVersion : import_sdk2.PROTOCOL_VERSION,
2767
+ protocolVersion: params.protocolVersion === acp.PROTOCOL_VERSION ? params.protocolVersion : acp.PROTOCOL_VERSION,
2825
2768
  agentCapabilities: {
2826
2769
  loadSession: true,
2827
2770
  promptCapabilities: {
@@ -2856,7 +2799,8 @@ var ACPServer = class {
2856
2799
  }
2857
2800
  async loadSession(params) {
2858
2801
  if (!this.adapter.hasSession(params.sessionId)) {
2859
- throw import_sdk2.RequestError.resourceNotFound(params.sessionId);
2802
+ const acp = await acpModule.get();
2803
+ throw acp.RequestError.resourceNotFound(params.sessionId);
2860
2804
  }
2861
2805
  this.adapter.updateSessionContext(params.sessionId, {
2862
2806
  cwd: params.cwd,
@@ -2875,7 +2819,8 @@ var ACPServer = class {
2875
2819
  }
2876
2820
  async unstable_forkSession(params) {
2877
2821
  if (!this.adapter.hasSession(params.sessionId)) {
2878
- throw import_sdk2.RequestError.resourceNotFound(params.sessionId);
2822
+ const acp = await acpModule.get();
2823
+ throw acp.RequestError.resourceNotFound(params.sessionId);
2879
2824
  }
2880
2825
  const sessionId = await this.adapter.createSession({
2881
2826
  cwd: params.cwd,
@@ -2887,7 +2832,8 @@ var ACPServer = class {
2887
2832
  }
2888
2833
  async unstable_resumeSession(params) {
2889
2834
  if (!this.adapter.hasSession(params.sessionId)) {
2890
- throw import_sdk2.RequestError.resourceNotFound(params.sessionId);
2835
+ const acp = await acpModule.get();
2836
+ throw acp.RequestError.resourceNotFound(params.sessionId);
2891
2837
  }
2892
2838
  this.adapter.updateSessionContext(params.sessionId, {
2893
2839
  cwd: params.cwd,
@@ -2903,14 +2849,16 @@ var ACPServer = class {
2903
2849
  }
2904
2850
  async setSessionMode(params) {
2905
2851
  if (!this.adapter.hasSession(params.sessionId)) {
2906
- throw import_sdk2.RequestError.resourceNotFound(params.sessionId);
2852
+ const acp = await acpModule.get();
2853
+ throw acp.RequestError.resourceNotFound(params.sessionId);
2907
2854
  }
2908
2855
  this.adapter.setSessionMode(params.sessionId, params.modeId);
2909
2856
  return {};
2910
2857
  }
2911
2858
  async unstable_setSessionModel(params) {
2912
2859
  if (!this.adapter.hasSession(params.sessionId)) {
2913
- throw import_sdk2.RequestError.resourceNotFound(params.sessionId);
2860
+ const acp = await acpModule.get();
2861
+ throw acp.RequestError.resourceNotFound(params.sessionId);
2914
2862
  }
2915
2863
  this.adapter.setSessionModel(params.sessionId, params.modelId);
2916
2864
  return {};
@@ -2922,11 +2870,13 @@ var ACPServer = class {
2922
2870
  }
2923
2871
  async authenticate(params) {
2924
2872
  if (params.methodId !== "api_key" && params.methodId !== "cursor_login") {
2925
- throw import_sdk2.RequestError.authRequired(void 0, `Unsupported auth method: ${params.methodId}`);
2873
+ const acp = await acpModule.get();
2874
+ throw acp.RequestError.authRequired(void 0, `Unsupported auth method: ${params.methodId}`);
2926
2875
  }
2927
2876
  const ok = await this.adapter.verifyCredentials();
2928
2877
  if (!ok) {
2929
- throw import_sdk2.RequestError.authRequired(void 0, "Authentication failed");
2878
+ const acp = await acpModule.get();
2879
+ throw acp.RequestError.authRequired(void 0, "Authentication failed");
2930
2880
  }
2931
2881
  return {};
2932
2882
  }
@@ -3046,7 +2996,7 @@ function formatHistoryForLlm(messages, options) {
3046
2996
  }
3047
2997
 
3048
2998
  // src/runtime/tools/customTools.ts
3049
- var import_zod6 = require("zod");
2999
+ var import_zod3 = require("zod");
3050
3000
  var import_zod_to_json_schema = require("zod-to-json-schema");
3051
3001
  var CustomToolDefinitionError = class extends Error {
3052
3002
  constructor(message) {
@@ -3344,53 +3294,6 @@ function runSingleToolRound(model, request) {
3344
3294
  // src/adapters/vercel-ai-sdk/model.ts
3345
3295
  init_errors();
3346
3296
 
3347
- // src/adapters/shared/lazyAsyncValue.ts
3348
- var DEFAULT_RETRY_BACKOFF_MS = 1e3;
3349
- var LazyAsyncValue = class {
3350
- load;
3351
- onRejected;
3352
- retryBackoffMs;
3353
- value = null;
3354
- pending = null;
3355
- lastFailureAt = 0;
3356
- constructor(options) {
3357
- this.load = options.load;
3358
- this.onRejected = options.onRejected;
3359
- this.retryBackoffMs = options.retryBackoffMs ?? DEFAULT_RETRY_BACKOFF_MS;
3360
- }
3361
- get current() {
3362
- return this.value;
3363
- }
3364
- async get() {
3365
- if (this.value) {
3366
- return this.value;
3367
- }
3368
- if (!this.pending) {
3369
- if (this.lastFailureAt > 0 && Date.now() - this.lastFailureAt < this.retryBackoffMs) {
3370
- throw new Error(
3371
- `LazyAsyncValue load failed recently; retrying after ${this.retryBackoffMs}ms backoff.`
3372
- );
3373
- }
3374
- this.pending = this.load().then((value) => {
3375
- this.value = value;
3376
- this.lastFailureAt = 0;
3377
- return value;
3378
- }).catch((error) => {
3379
- this.pending = null;
3380
- this.lastFailureAt = Date.now();
3381
- this.onRejected?.(error);
3382
- throw error;
3383
- });
3384
- }
3385
- return this.pending;
3386
- }
3387
- clear() {
3388
- this.value = null;
3389
- this.pending = null;
3390
- this.lastFailureAt = 0;
3391
- }
3392
- };
3393
-
3394
3297
  // src/adapters/shared/coercion.ts
3395
3298
  init_protocols();
3396
3299
  function asOptionalRecord(value) {
@@ -7833,6 +7736,148 @@ async function loadLettaClientFactory(config) {
7833
7736
  });
7834
7737
  }
7835
7738
 
7739
+ // src/mcp/backends.ts
7740
+ init_schemas();
7741
+ init_registrations();
7742
+
7743
+ // src/mcp/stdio.ts
7744
+ init_registrations();
7745
+ init_zod();
7746
+ var ThenvoiMcpStdioServer = class {
7747
+ options;
7748
+ registrations;
7749
+ mcpServer = null;
7750
+ transport = null;
7751
+ constructor(options) {
7752
+ this.options = options;
7753
+ const regOptions = {
7754
+ enableMemoryTools: options.enableMemoryTools,
7755
+ enableContactTools: options.enableContactTools,
7756
+ additionalTools: options.additionalTools
7757
+ };
7758
+ if (typeof options.tools === "function") {
7759
+ this.registrations = buildRoomScopedRegistrations(options.tools, regOptions);
7760
+ } else {
7761
+ this.registrations = buildSingleContextRegistrations(options.tools, regOptions);
7762
+ }
7763
+ }
7764
+ get toolNames() {
7765
+ return this.registrations.map((r) => r.name);
7766
+ }
7767
+ async start() {
7768
+ if (this.transport) {
7769
+ return;
7770
+ }
7771
+ const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
7772
+ const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
7773
+ const { z: z4 } = await import("zod");
7774
+ const mcpServer = new McpServer({
7775
+ name: this.options.name ?? "thenvoi",
7776
+ version: "1.0.0"
7777
+ });
7778
+ registerTools3(mcpServer, z4, this.registrations);
7779
+ const transport = new StdioServerTransport(this.options.stdin, this.options.stdout);
7780
+ await mcpServer.connect(transport);
7781
+ this.mcpServer = mcpServer;
7782
+ this.transport = transport;
7783
+ }
7784
+ async stop() {
7785
+ await this.transport?.close();
7786
+ this.transport = null;
7787
+ this.mcpServer = null;
7788
+ }
7789
+ };
7790
+ function registerTools3(mcpServer, z4, registrations) {
7791
+ for (const reg of registrations) {
7792
+ const zodShape = buildZodShape(z4, reg.inputSchema.properties, new Set(reg.inputSchema.required));
7793
+ mcpServer.registerTool(
7794
+ reg.name,
7795
+ {
7796
+ description: reg.description,
7797
+ inputSchema: z4.object(zodShape)
7798
+ },
7799
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK handler signature is complex; our McpToolResult is compatible
7800
+ async (args) => reg.execute(args)
7801
+ );
7802
+ }
7803
+ }
7804
+
7805
+ // src/mcp/backends.ts
7806
+ async function createThenvoiMcpBackend(options) {
7807
+ const registrations = buildRoomScopedRegistrations(
7808
+ options.getToolsForRoom,
7809
+ {
7810
+ enableMemoryTools: options.enableMemoryTools,
7811
+ enableContactTools: true,
7812
+ additionalTools: options.additionalTools
7813
+ }
7814
+ );
7815
+ const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
7816
+ if (options.kind === "sdk") {
7817
+ const { createThenvoiSdkMcpServer: createThenvoiSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
7818
+ const server2 = createThenvoiSdkMcpServer2({
7819
+ enableMemoryTools: options.enableMemoryTools,
7820
+ getToolsForRoom: options.getToolsForRoom,
7821
+ additionalTools: options.additionalTools
7822
+ });
7823
+ return {
7824
+ kind: "sdk",
7825
+ server: server2,
7826
+ allowedTools: server2.allowedTools,
7827
+ stop: async () => void 0
7828
+ };
7829
+ }
7830
+ if (options.kind === "stdio") {
7831
+ const server2 = new ThenvoiMcpStdioServer({
7832
+ tools: options.getToolsForRoom,
7833
+ enableMemoryTools: options.enableMemoryTools,
7834
+ enableContactTools: true,
7835
+ additionalTools: options.additionalTools
7836
+ });
7837
+ await server2.start();
7838
+ return {
7839
+ kind: "stdio",
7840
+ server: server2,
7841
+ allowedTools,
7842
+ stop: async () => {
7843
+ await server2.stop();
7844
+ }
7845
+ };
7846
+ }
7847
+ if (options.kind === "sse") {
7848
+ const server2 = new ThenvoiMcpSseServer({
7849
+ tools: options.getToolsForRoom,
7850
+ enableMemoryTools: options.enableMemoryTools,
7851
+ enableContactTools: true,
7852
+ additionalTools: options.additionalTools
7853
+ });
7854
+ await server2.start();
7855
+ return {
7856
+ kind: "sse",
7857
+ server: server2,
7858
+ allowedTools,
7859
+ stop: async () => {
7860
+ await server2.stop();
7861
+ }
7862
+ };
7863
+ }
7864
+ const server = new ThenvoiMcpServer({
7865
+ tools: options.getToolsForRoom,
7866
+ enableMemoryTools: options.enableMemoryTools,
7867
+ enableContactTools: true,
7868
+ additionalTools: options.additionalTools
7869
+ });
7870
+ await server.start();
7871
+ return {
7872
+ kind: "http",
7873
+ server,
7874
+ allowedTools,
7875
+ stop: async () => {
7876
+ await server.stop();
7877
+ }
7878
+ };
7879
+ }
7880
+
7836
7881
  // src/adapters/opencode/OpencodeAdapter.ts
7837
7882
  init_registrations();
7838
7883
 
@@ -8997,6 +9042,10 @@ function delay(ms) {
8997
9042
  });
8998
9043
  }
8999
9044
 
9045
+ // src/adapters/claude-sdk/ClaudeSDKAdapter.ts
9046
+ init_errors();
9047
+ init_schemas();
9048
+
9000
9049
  // src/adapters/shared/conversationPrompt.ts
9001
9050
  function buildConversationPrompt(options) {
9002
9051
  const parts = [];
@@ -9030,11 +9079,57 @@ function extractClaudeSessionId(raw) {
9030
9079
  return typeof sessionId === "string" && sessionId.length > 0 ? sessionId : null;
9031
9080
  }
9032
9081
 
9033
- // src/mcp/claude.ts
9034
- init_sdk();
9035
-
9036
9082
  // src/adapters/claude-sdk/ClaudeSDKAdapter.ts
9083
+ init_registrations();
9084
+ init_zod();
9085
+ var import_zod8 = require("zod");
9037
9086
  var DEFAULT_MODEL2 = "claude-sonnet-4-6";
9087
+ var thenvoiMcpBridgeFactory = new LazyAsyncValue({
9088
+ load: async () => {
9089
+ const module2 = await import("@anthropic-ai/claude-agent-sdk").catch((error) => {
9090
+ throw new UnsupportedFeatureError(
9091
+ `ClaudeSDKAdapter requires optional dependency "@anthropic-ai/claude-agent-sdk" when MCP tools are enabled. Install it with "pnpm add @anthropic-ai/claude-agent-sdk". (${error instanceof Error ? error.message : String(error)})`
9092
+ );
9093
+ });
9094
+ if (typeof module2.createSdkMcpServer !== "function" || typeof module2.tool !== "function") {
9095
+ throw new UnsupportedFeatureError(
9096
+ 'ClaudeSDKAdapter requires optional dependency "@anthropic-ai/claude-agent-sdk" when MCP tools are enabled. Install it with "pnpm add @anthropic-ai/claude-agent-sdk".'
9097
+ );
9098
+ }
9099
+ const createSdkMcpServer2 = module2.createSdkMcpServer;
9100
+ const defineTool = module2.tool;
9101
+ return (input) => {
9102
+ const registrations = buildRoomScopedRegistrations(
9103
+ input.getToolsForRoom,
9104
+ {
9105
+ enableMemoryTools: input.enableMemoryTools,
9106
+ enableContactTools: true,
9107
+ additionalTools: input.additionalTools
9108
+ }
9109
+ );
9110
+ const toolDefinitions = registrations.map((registration) => {
9111
+ const shape = buildZodShape(
9112
+ import_zod8.z,
9113
+ registration.inputSchema.properties,
9114
+ new Set(registration.inputSchema.required)
9115
+ );
9116
+ return defineTool(
9117
+ registration.name,
9118
+ registration.description,
9119
+ shape,
9120
+ async (args) => registration.execute(args)
9121
+ );
9122
+ });
9123
+ return {
9124
+ serverConfig: createSdkMcpServer2({
9125
+ name: "thenvoi",
9126
+ tools: toolDefinitions
9127
+ }),
9128
+ allowedTools: mcpToolNames(new Set(registrations.map((registration) => registration.name)))
9129
+ };
9130
+ };
9131
+ }
9132
+ });
9038
9133
  var ClaudeSDKAdapter = class extends SimpleAdapter {
9039
9134
  model;
9040
9135
  customSection;
@@ -9077,7 +9172,8 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
9077
9172
  includeBaseInstructions: this.includeBaseInstructions
9078
9173
  });
9079
9174
  if (this.enableMcpTools) {
9080
- this.mcpBridge = createThenvoiSdkMcpServer({
9175
+ const createThenvoiMcpBridge = await thenvoiMcpBridgeFactory.get();
9176
+ this.mcpBridge = createThenvoiMcpBridge({
9081
9177
  enableMemoryTools: this.enableMemoryTools,
9082
9178
  getToolsForRoom: (roomId) => this.roomTools.get(roomId),
9083
9179
  additionalTools: this.additionalMcpTools.length > 0 ? this.additionalMcpTools : void 0
@@ -9201,9 +9297,13 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
9201
9297
  }
9202
9298
  };
9203
9299
  async function loadClaudeQuery() {
9204
- const module2 = await import("@anthropic-ai/claude-agent-sdk");
9300
+ const module2 = await import("@anthropic-ai/claude-agent-sdk").catch((error) => {
9301
+ throw new UnsupportedFeatureError(
9302
+ `ClaudeSDKAdapter requires optional dependency "@anthropic-ai/claude-agent-sdk". Install it with "pnpm add @anthropic-ai/claude-agent-sdk". (${error instanceof Error ? error.message : String(error)})`
9303
+ );
9304
+ });
9205
9305
  if (!module2.query) {
9206
- throw new Error("@anthropic-ai/claude-agent-sdk did not export query()");
9306
+ throw new UnsupportedFeatureError("@anthropic-ai/claude-agent-sdk did not export query()");
9207
9307
  }
9208
9308
  return module2.query;
9209
9309
  }