@band-ai/sdk 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +372 -0
  2. package/dist/{ClaudeSDKAdapter-CRq4R-WB.d.cts → ClaudeSDKAdapter-BY4zEbCl.d.cts} +14 -10
  3. package/dist/{ClaudeSDKAdapter-BHOkjN3X.d.ts → ClaudeSDKAdapter-Cna5P1dR.d.ts} +14 -10
  4. package/dist/{acp-server-B1Da7L6u.d.ts → acp-server-CiUqN3G3.d.ts} +2 -2
  5. package/dist/{acp-server-BdRz9_UN.d.cts → acp-server-Dlj7D563.d.cts} +2 -2
  6. package/dist/adapters.cjs +734 -279
  7. package/dist/adapters.d.cts +21 -19
  8. package/dist/adapters.d.ts +21 -19
  9. package/dist/adapters.js +65 -44
  10. package/dist/backends-D-dBdDm-.d.ts +27 -0
  11. package/dist/backends-ZLxmQrTZ.d.cts +27 -0
  12. package/dist/{chunk-MSL6CWHY.js → chunk-4IAXZBXX.js} +77 -37
  13. package/dist/{chunk-SG4WLD2H.js → chunk-EAI2M3WM.js} +38 -94
  14. package/dist/{chunk-YR3BOQNW.js → chunk-JY75VSQK.js} +7 -7
  15. package/dist/{chunk-INA6YZTZ.js → chunk-LBWKISBS.js} +51 -31
  16. package/dist/{chunk-I5EZG52P.js → chunk-N2QTUMGO.js} +532 -327
  17. package/dist/{chunk-RHVH2GZR.js → chunk-NMZLX7TP.js} +110 -56
  18. package/dist/{chunk-EDPKUUJL.js → chunk-NT7TBFX2.js} +9 -1
  19. package/dist/{chunk-GVEQ3RAH.js → chunk-RV76SKFT.js} +169 -54
  20. package/dist/{chunk-W5NDZSYE.js → chunk-TLBCKDQO.js} +23 -23
  21. package/dist/chunk-US226AS4.js +130 -0
  22. package/dist/{chunk-IZPV6QS6.js → chunk-WL2HNJZ6.js} +38 -11
  23. package/dist/chunk-WLCM2OXG.js +181 -0
  24. package/dist/config.cjs +40 -13
  25. package/dist/config.d.cts +7 -1
  26. package/dist/config.d.ts +7 -1
  27. package/dist/config.js +2 -2
  28. package/dist/converters.cjs +491 -35
  29. package/dist/converters.d.cts +5 -5
  30. package/dist/converters.d.ts +5 -5
  31. package/dist/converters.js +4 -3
  32. package/dist/core.cjs +53 -10
  33. package/dist/core.d.cts +10 -9
  34. package/dist/core.d.ts +10 -9
  35. package/dist/core.js +8 -4
  36. package/dist/disconnectReason-IuADl6TH.d.cts +34 -0
  37. package/dist/disconnectReason-IuADl6TH.d.ts +34 -0
  38. package/dist/{dtos-DUpbIu8k.d.ts → dtos-B8KU_q4d.d.cts} +26 -6
  39. package/dist/{dtos-DUpbIu8k.d.cts → dtos-B8KU_q4d.d.ts} +26 -6
  40. package/dist/index.cjs +1510 -735
  41. package/dist/index.d.cts +18 -16
  42. package/dist/index.d.ts +18 -16
  43. package/dist/index.js +21 -13
  44. package/dist/linear.cjs +1044 -112
  45. package/dist/linear.d.cts +146 -16
  46. package/dist/linear.d.ts +146 -16
  47. package/dist/linear.js +1031 -110
  48. package/dist/mcp-claude.cjs +338 -66
  49. package/dist/mcp-claude.d.cts +3 -3
  50. package/dist/mcp-claude.d.ts +3 -3
  51. package/dist/mcp-claude.js +215 -16
  52. package/dist/mcp.cjs +414 -105
  53. package/dist/mcp.d.cts +29 -16
  54. package/dist/mcp.d.ts +29 -16
  55. package/dist/mcp.js +14 -14
  56. package/dist/{opencode-BBcDchcN.d.cts → opencode-2YdscIc1.d.cts} +5 -5
  57. package/dist/{opencode-DthQQUsZ.d.ts → opencode-Bld62x5t.d.ts} +5 -5
  58. package/dist/{pagination-CcDkVFxK.d.ts → pagination-BgEx-HeL.d.ts} +2 -2
  59. package/dist/{pagination-BPiys10t.d.cts → pagination-DqdkQArT.d.cts} +2 -2
  60. package/dist/{protocols-DrhzOH6K.d.ts → protocols-Bwwcql0h.d.ts} +1 -1
  61. package/dist/{protocols-CInhtFpA.d.cts → protocols-Bz1rxcUg.d.cts} +1 -1
  62. package/dist/rest.cjs +41 -97
  63. package/dist/rest.d.cts +7 -7
  64. package/dist/rest.d.ts +7 -7
  65. package/dist/rest.js +2 -2
  66. package/dist/runtime.cjs +998 -620
  67. package/dist/runtime.d.cts +22 -29
  68. package/dist/runtime.d.ts +22 -29
  69. package/dist/runtime.js +19 -67
  70. package/dist/{schemas-BpEBkq5V.d.cts → schemas-BotL3ZLH.d.cts} +51 -56
  71. package/dist/{schemas-vos1AaBc.d.ts → schemas-DBsC4J1g.d.ts} +51 -56
  72. package/dist/{sdk-CwTAxhwI.d.cts → sdk-BTciSLRQ.d.cts} +35 -5
  73. package/dist/{sdk-CcnQ5OUC.d.ts → sdk-qKJtMma_.d.ts} +35 -5
  74. package/dist/{simpleAdapter-9OE_p6QW.d.ts → simpleAdapter--wznuoOw.d.ts} +1 -1
  75. package/dist/{simpleAdapter-DqhvjsGr.d.cts → simpleAdapter-BpT4XbZC.d.cts} +1 -1
  76. package/dist/testing.d.cts +3 -3
  77. package/dist/testing.d.ts +3 -3
  78. package/dist/{types-7jVzOeOP.d.ts → types-BTN_ZETM.d.ts} +2 -2
  79. package/dist/{types-CxII3XkA.d.ts → types-BgYFd_Yw.d.cts} +5 -5
  80. package/dist/{types-CSHFipIc.d.cts → types-BivGO7I9.d.ts} +5 -5
  81. package/dist/{types-CovcHpYf.d.cts → types-D958TC71.d.cts} +2 -2
  82. package/package.json +25 -23
  83. package/dist/backends-CzDbiQar.d.ts +0 -20
  84. package/dist/backends-SVMT-7l4.d.cts +0 -20
  85. package/dist/chunk-SFVKOEQH.js +0 -103
@@ -1,14 +1,16 @@
1
1
  import {
2
2
  buildRoomScopedRegistrations,
3
3
  buildSingleContextRegistrations,
4
- buildZodShape
5
- } from "./chunk-EDPKUUJL.js";
4
+ buildZodShape,
5
+ resolveSingleRoomTools
6
+ } from "./chunk-NT7TBFX2.js";
6
7
  import {
8
+ MCP_SERVER_NAME,
7
9
  mcpToolNames
8
- } from "./chunk-GVEQ3RAH.js";
10
+ } from "./chunk-RV76SKFT.js";
9
11
 
10
12
  // src/mcp/stdio.ts
11
- var ThenvoiMcpStdioServer = class {
13
+ var BandMcpStdioServer = class {
12
14
  options;
13
15
  registrations;
14
16
  mcpServer = null;
@@ -37,7 +39,7 @@ var ThenvoiMcpStdioServer = class {
37
39
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
38
40
  const { z } = await import("zod");
39
41
  const mcpServer = new McpServer({
40
- name: this.options.name ?? "thenvoi",
42
+ name: this.options.name ?? MCP_SERVER_NAME,
41
43
  version: "1.0.0"
42
44
  });
43
45
  registerTools(mcpServer, z, this.registrations);
@@ -67,13 +69,33 @@ function registerTools(mcpServer, z, registrations) {
67
69
  }
68
70
  }
69
71
 
72
+ // src/mcp/auth.ts
73
+ import { randomBytes, timingSafeEqual } from "crypto";
74
+ function generateAuthToken() {
75
+ return randomBytes(32).toString("hex");
76
+ }
77
+ function isAuthorizedRequest(authorizationHeader, authToken) {
78
+ if (!authToken) {
79
+ return true;
80
+ }
81
+ if (!authorizationHeader) {
82
+ return false;
83
+ }
84
+ const expected = Buffer.from(`Bearer ${authToken}`);
85
+ const actual = Buffer.from(authorizationHeader);
86
+ if (expected.length !== actual.length) {
87
+ return false;
88
+ }
89
+ return timingSafeEqual(expected, actual);
90
+ }
91
+
70
92
  // src/mcp/server.ts
71
93
  var PORT_RANGE_START = 5e4;
72
94
  var PORT_RANGE_END = 6e4;
73
95
  var MCP_SERVER_VERSION = "1.0.0";
74
96
  var SESSION_IDLE_TTL_MS = 15 * 60 * 1e3;
75
97
  var SESSION_SWEEP_INTERVAL_MS = 60 * 1e3;
76
- var ThenvoiMcpServer = class {
98
+ var BandMcpServer = class {
77
99
  options;
78
100
  registrations;
79
101
  httpServer = null;
@@ -117,7 +139,7 @@ var ThenvoiMcpServer = class {
117
139
  const http = await import("http");
118
140
  const { randomUUID } = await import("crypto");
119
141
  const { z } = await import("zod");
120
- const serverName = this.options.name ?? "thenvoi";
142
+ const serverName = this.options.name ?? MCP_SERVER_NAME;
121
143
  const app = express();
122
144
  app.use(express.json());
123
145
  app.get("/healthz", (_req, res) => {
@@ -125,6 +147,10 @@ var ThenvoiMcpServer = class {
125
147
  });
126
148
  const handleMcpRequest = async (req, res) => {
127
149
  try {
150
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
151
+ sendMcpError(res, 401, "Unauthorized");
152
+ return;
153
+ }
128
154
  const sessionId = getSessionIdHeader(req.headers["mcp-session-id"]);
129
155
  let session = sessionId ? this.sessions.get(sessionId) : void 0;
130
156
  if (!session) {
@@ -302,7 +328,7 @@ var PORT_RANGE_START2 = 5e4;
302
328
  var PORT_RANGE_END2 = 6e4;
303
329
  var SESSION_IDLE_TTL_MS2 = 15 * 60 * 1e3;
304
330
  var SESSION_SWEEP_INTERVAL_MS2 = 60 * 1e3;
305
- var ThenvoiMcpSseServer = class {
331
+ var BandMcpSseServer = class {
306
332
  options;
307
333
  registrations;
308
334
  httpServer = null;
@@ -349,10 +375,14 @@ var ThenvoiMcpSseServer = class {
349
375
  app.get("/healthz", (_req, res) => {
350
376
  res.json({ status: "ok" });
351
377
  });
352
- app.get("/sse", async (_req, res) => {
378
+ app.get("/sse", async (req, res) => {
379
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
380
+ res.status(401).send("Unauthorized");
381
+ return;
382
+ }
353
383
  const transport = new SSEServerTransport("/messages", res);
354
384
  const mcpServer = new McpServer({
355
- name: this.options.name ?? "thenvoi",
385
+ name: this.options.name ?? MCP_SERVER_NAME,
356
386
  version: "1.0.0"
357
387
  });
358
388
  registerTools3(mcpServer, z, this.registrations);
@@ -374,6 +404,10 @@ var ThenvoiMcpSseServer = class {
374
404
  });
375
405
  });
376
406
  app.post("/messages", async (req, res) => {
407
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
408
+ res.status(401).send("Unauthorized");
409
+ return;
410
+ }
377
411
  const sessionId = typeof req.query.sessionId === "string" ? req.query.sessionId : null;
378
412
  if (!sessionId) {
379
413
  res.status(400).send("Missing sessionId");
@@ -487,21 +521,18 @@ function checkPort2(http, port) {
487
521
  }
488
522
 
489
523
  // src/mcp/backends.ts
490
- async function createThenvoiMcpBackend(options) {
491
- const registrations = buildRoomScopedRegistrations(
492
- options.getToolsForRoom,
493
- {
494
- enableMemoryTools: options.enableMemoryTools,
495
- enableContactTools: true,
496
- additionalTools: options.additionalTools
497
- }
498
- );
499
- const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
524
+ async function createBandMcpBackend(options) {
525
+ const registrationOptions = {
526
+ enableMemoryTools: options.enableMemoryTools,
527
+ enableContactTools: true,
528
+ additionalTools: options.additionalTools
529
+ };
500
530
  if (options.kind === "sdk") {
501
- const { createThenvoiSdkMcpServer } = await import("./mcp-claude.js");
502
- const server2 = createThenvoiSdkMcpServer({
503
- enableMemoryTools: options.enableMemoryTools,
531
+ const { createBandSdkMcpServer } = await import("./mcp-claude.js");
532
+ const server2 = createBandSdkMcpServer({
504
533
  getToolsForRoom: options.getToolsForRoom,
534
+ multiRoom: options.multiRoom,
535
+ enableMemoryTools: options.enableMemoryTools,
505
536
  additionalTools: options.additionalTools
506
537
  });
507
538
  return {
@@ -511,9 +542,12 @@ async function createThenvoiMcpBackend(options) {
511
542
  stop: async () => void 0
512
543
  };
513
544
  }
545
+ const resolvedTools = options.multiRoom === false ? resolveSingleRoomTools(options.getToolsForRoom) : options.getToolsForRoom;
546
+ const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolvedTools, registrationOptions) : buildRoomScopedRegistrations(resolvedTools, registrationOptions);
547
+ const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
514
548
  if (options.kind === "stdio") {
515
- const server2 = new ThenvoiMcpStdioServer({
516
- tools: options.getToolsForRoom,
549
+ const server2 = new BandMcpStdioServer({
550
+ tools: resolvedTools,
517
551
  enableMemoryTools: options.enableMemoryTools,
518
552
  enableContactTools: true,
519
553
  additionalTools: options.additionalTools
@@ -528,40 +562,45 @@ async function createThenvoiMcpBackend(options) {
528
562
  }
529
563
  };
530
564
  }
565
+ const authToken = generateAuthToken();
531
566
  if (options.kind === "sse") {
532
- const server2 = new ThenvoiMcpSseServer({
533
- tools: options.getToolsForRoom,
567
+ const server2 = new BandMcpSseServer({
568
+ tools: resolvedTools,
534
569
  enableMemoryTools: options.enableMemoryTools,
535
570
  enableContactTools: true,
536
- additionalTools: options.additionalTools
571
+ additionalTools: options.additionalTools,
572
+ authToken
537
573
  });
538
574
  await server2.start();
539
575
  return {
540
576
  kind: "sse",
541
577
  server: server2,
542
578
  allowedTools,
579
+ authToken,
543
580
  stop: async () => {
544
581
  await server2.stop();
545
582
  }
546
583
  };
547
584
  }
548
- const server = new ThenvoiMcpServer({
549
- tools: options.getToolsForRoom,
585
+ const server = new BandMcpServer({
586
+ tools: resolvedTools,
550
587
  enableMemoryTools: options.enableMemoryTools,
551
588
  enableContactTools: true,
552
- additionalTools: options.additionalTools
589
+ additionalTools: options.additionalTools,
590
+ authToken
553
591
  });
554
592
  await server.start();
555
593
  return {
556
594
  kind: "http",
557
595
  server,
558
596
  allowedTools,
597
+ authToken,
559
598
  stop: async () => {
560
599
  await server.stop();
561
600
  }
562
601
  };
563
602
  }
564
- function getThenvoiSdkMcpServerConfig(backend) {
603
+ function getBandSdkMcpServerConfig(backend) {
565
604
  if (backend.kind !== "sdk") {
566
605
  throw new Error(`Expected sdk MCP backend, received ${backend.kind}`);
567
606
  }
@@ -569,9 +608,10 @@ function getThenvoiSdkMcpServerConfig(backend) {
569
608
  }
570
609
 
571
610
  export {
572
- ThenvoiMcpStdioServer,
573
- ThenvoiMcpServer,
574
- ThenvoiMcpSseServer,
575
- createThenvoiMcpBackend,
576
- getThenvoiSdkMcpServerConfig
611
+ generateAuthToken,
612
+ BandMcpStdioServer,
613
+ BandMcpServer,
614
+ BandMcpSseServer,
615
+ createBandMcpBackend,
616
+ getBandSdkMcpServerConfig
577
617
  };
@@ -9,7 +9,7 @@ import {
9
9
  import {
10
10
  UnsupportedFeatureError,
11
11
  ValidationError
12
- } from "./chunk-YR3BOQNW.js";
12
+ } from "./chunk-JY75VSQK.js";
13
13
 
14
14
  // src/client/rest/pagination.ts
15
15
  var DEFAULT_PAGE_SIZE = 100;
@@ -187,6 +187,7 @@ function toNonNegativeInteger(value) {
187
187
  var DEFAULT_REQUEST_OPTIONS = {
188
188
  maxRetries: 3
189
189
  };
190
+ var MESSAGE_SEND_MAX_RETRIES = 2;
190
191
 
191
192
  // src/client/rest/responseNormalization.ts
192
193
  function asMetadataMap(value) {
@@ -217,54 +218,16 @@ function normalizeContactRequestsResult(result) {
217
218
  }
218
219
 
219
220
  // src/client/rest/FernRestAdapter.ts
220
- function mergeOptions(options) {
221
+ function mergeOptions(options, maxRetries) {
221
222
  return {
222
223
  ...DEFAULT_REQUEST_OPTIONS,
224
+ ...maxRetries !== void 0 ? { maxRetries } : {},
223
225
  ...options
224
226
  };
225
227
  }
226
- var AGENT_ME_RETRY_LIMIT = 4;
227
- var AGENT_ME_RETRY_BASE_DELAY_MS = 2e3;
228
- var MESSAGE_SEND_RETRY_LIMIT = 3;
229
- var MESSAGE_SEND_RETRY_BASE_DELAY_MS = 500;
230
228
  function asMetadataMap2(value) {
231
229
  return asOptionalRecord(value);
232
230
  }
233
- function extractHttpStatus(error) {
234
- const record = asOptionalRecord(error);
235
- if (!record) {
236
- return void 0;
237
- }
238
- const response = asOptionalRecord(record.response);
239
- const status = record.statusCode ?? record.status ?? response?.statusCode ?? response?.status;
240
- return typeof status === "number" ? status : void 0;
241
- }
242
- function isFernRateLimitError(error) {
243
- return extractHttpStatus(error) === 429;
244
- }
245
- async function sleep(ms) {
246
- await new Promise((resolveDelay) => setTimeout(resolveDelay, ms));
247
- }
248
- function computeRetryDelayMs(baseDelayMs, attempt) {
249
- const backoff = baseDelayMs * 2 ** (attempt - 1);
250
- const jitter = Math.floor(Math.random() * Math.max(1, Math.floor(backoff / 4)));
251
- return backoff + jitter;
252
- }
253
- async function withRateLimitRetry(operation, options) {
254
- let lastError;
255
- for (let attempt = 1; attempt <= options.retryLimit; attempt += 1) {
256
- try {
257
- return await operation();
258
- } catch (error) {
259
- lastError = error;
260
- if (!isFernRateLimitError(error) || attempt === options.retryLimit) {
261
- throw error;
262
- }
263
- await sleep(computeRetryDelayMs(options.baseDelayMs, attempt));
264
- }
265
- }
266
- throw lastError instanceof Error ? lastError : new Error("Rate-limit retry exhausted without a terminal error.");
267
- }
268
231
  function requireNonEmptyStringField(value, field, source) {
269
232
  if (typeof value !== "string" || value.trim().length === 0) {
270
233
  throw new Error(`Invalid ${source} response: expected non-empty string AgentIdentity.${field}`);
@@ -472,28 +435,21 @@ var FernRestAdapter = class {
472
435
  this.client = client;
473
436
  }
474
437
  async getAgentMe(options) {
475
- return withRateLimitRetry(
476
- async () => {
477
- if (this.client.agentApiIdentity?.getAgentMe) {
478
- const response = await this.client.agentApiIdentity.getAgentMe(mergeOptions(options));
479
- return normalizeAgentIdentityEnvelope(response, "agentApiIdentity.getAgentMe");
480
- }
481
- const profileClient = this.client.myProfile ?? this.client.humanApiProfile;
482
- if (!profileClient?.getMyProfile) {
483
- throw new UnsupportedFeatureError(
484
- "Fern client missing agentApiIdentity.getAgentMe or humanApiProfile.getMyProfile"
485
- );
486
- }
487
- const profile = await profileClient.getMyProfile(mergeOptions(options));
488
- return normalizeLegacyProfileIdentity(
489
- normalizeLegacyProfileEnvelope(profile),
490
- "profile.getMyProfile"
491
- );
492
- },
493
- {
494
- retryLimit: AGENT_ME_RETRY_LIMIT,
495
- baseDelayMs: AGENT_ME_RETRY_BASE_DELAY_MS
496
- }
438
+ const requestOptions = mergeOptions(options);
439
+ if (this.client.agentApiIdentity?.getAgentMe) {
440
+ const response = await this.client.agentApiIdentity.getAgentMe(requestOptions);
441
+ return normalizeAgentIdentityEnvelope(response, "agentApiIdentity.getAgentMe");
442
+ }
443
+ const profileClient = this.client.myProfile ?? this.client.humanApiProfile;
444
+ if (!profileClient?.getMyProfile) {
445
+ throw new UnsupportedFeatureError(
446
+ "Fern client missing agentApiIdentity.getAgentMe or humanApiProfile.getMyProfile"
447
+ );
448
+ }
449
+ const profile = await profileClient.getMyProfile(requestOptions);
450
+ return normalizeLegacyProfileIdentity(
451
+ normalizeLegacyProfileEnvelope(profile),
452
+ "profile.getMyProfile"
497
453
  );
498
454
  }
499
455
  async createChatMessage(chatId, message, options) {
@@ -501,45 +457,33 @@ var FernRestAdapter = class {
501
457
  if (!api) {
502
458
  throw new UnsupportedFeatureError("Fern client missing chat message creation endpoint");
503
459
  }
504
- const response = await withRateLimitRetry(
505
- async () => await api(
506
- chatId,
507
- {
508
- message: {
509
- content: message.content,
510
- message_type: message.messageType,
511
- metadata: message.metadata,
512
- mentions: message.mentions
513
- }
514
- },
515
- mergeOptions(options)
516
- ),
460
+ const response = await api(
461
+ chatId,
517
462
  {
518
- retryLimit: MESSAGE_SEND_RETRY_LIMIT,
519
- baseDelayMs: MESSAGE_SEND_RETRY_BASE_DELAY_MS
520
- }
463
+ message: {
464
+ content: message.content,
465
+ message_type: message.messageType,
466
+ metadata: message.metadata,
467
+ mentions: message.mentions
468
+ }
469
+ },
470
+ mergeOptions(options, MESSAGE_SEND_MAX_RETRIES)
521
471
  );
522
472
  return normalizeToolOperationResult(response);
523
473
  }
524
474
  async createChatEvent(chatId, event, options) {
525
475
  const createAgentChatEvent = this.client.agentApiEvents?.createAgentChatEvent?.bind(this.client.agentApiEvents);
526
476
  if (createAgentChatEvent) {
527
- const response = await withRateLimitRetry(
528
- async () => await createAgentChatEvent(
529
- chatId,
530
- {
531
- event: {
532
- content: event.content,
533
- message_type: event.messageType,
534
- metadata: event.metadata
535
- }
536
- },
537
- mergeOptions(options)
538
- ),
477
+ const response = await createAgentChatEvent(
478
+ chatId,
539
479
  {
540
- retryLimit: MESSAGE_SEND_RETRY_LIMIT,
541
- baseDelayMs: MESSAGE_SEND_RETRY_BASE_DELAY_MS
542
- }
480
+ event: {
481
+ content: event.content,
482
+ message_type: event.messageType,
483
+ metadata: event.metadata
484
+ }
485
+ },
486
+ mergeOptions(options, MESSAGE_SEND_MAX_RETRIES)
543
487
  );
544
488
  return normalizeToolOperationResult(response);
545
489
  }
@@ -1,29 +1,29 @@
1
1
  // src/core/errors.ts
2
- var ThenvoiSdkError = class extends Error {
2
+ var BandSdkError = class extends Error {
3
3
  constructor(message, cause) {
4
4
  super(message, cause !== void 0 ? { cause } : void 0);
5
- this.name = "ThenvoiSdkError";
5
+ this.name = "BandSdkError";
6
6
  }
7
7
  };
8
- var UnsupportedFeatureError = class extends ThenvoiSdkError {
8
+ var UnsupportedFeatureError = class extends BandSdkError {
9
9
  constructor(message) {
10
10
  super(message);
11
11
  this.name = "UnsupportedFeatureError";
12
12
  }
13
13
  };
14
- var ValidationError = class extends ThenvoiSdkError {
14
+ var ValidationError = class extends BandSdkError {
15
15
  constructor(message, cause) {
16
16
  super(message, cause);
17
17
  this.name = "ValidationError";
18
18
  }
19
19
  };
20
- var TransportError = class extends ThenvoiSdkError {
20
+ var TransportError = class extends BandSdkError {
21
21
  constructor(message, cause) {
22
22
  super(message, cause);
23
23
  this.name = "TransportError";
24
24
  }
25
25
  };
26
- var RuntimeStateError = class extends ThenvoiSdkError {
26
+ var RuntimeStateError = class extends BandSdkError {
27
27
  constructor(message) {
28
28
  super(message);
29
29
  this.name = "RuntimeStateError";
@@ -31,7 +31,7 @@ var RuntimeStateError = class extends ThenvoiSdkError {
31
31
  };
32
32
 
33
33
  export {
34
- ThenvoiSdkError,
34
+ BandSdkError,
35
35
  UnsupportedFeatureError,
36
36
  ValidationError,
37
37
  TransportError,
@@ -1,3 +1,26 @@
1
+ // src/runtime/types.ts
2
+ var HistoryProvider = class {
3
+ raw;
4
+ constructor(raw) {
5
+ this.raw = raw;
6
+ }
7
+ convert(converter) {
8
+ return converter.convert(this.raw);
9
+ }
10
+ get length() {
11
+ return this.raw.length;
12
+ }
13
+ };
14
+ var SYNTHETIC_SENDER_TYPE = "System";
15
+ var SYNTHETIC_CONTACT_EVENTS_SENDER_ID = "contact-events";
16
+ var SYNTHETIC_CONTACT_EVENTS_SENDER_NAME = "Contact Events";
17
+ function ensureHandlePrefix(handle) {
18
+ if (!handle) {
19
+ return null;
20
+ }
21
+ return handle.startsWith("@") ? handle : `@${handle}`;
22
+ }
23
+
1
24
  // src/runtime/formatters.ts
2
25
  function isMetadataMap(value) {
3
26
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -11,7 +34,7 @@ function replaceUuidMentions(content, participants) {
11
34
  const participantId = participant.id;
12
35
  const handle = participant.handle;
13
36
  if (typeof participantId === "string" && typeof handle === "string") {
14
- next = next.replaceAll(`@[[${participantId}]]`, `@${handle}`);
37
+ next = next.replaceAll(`@[[${participantId}]]`, ensureHandlePrefix(handle) ?? "");
15
38
  }
16
39
  }
17
40
  return next;
@@ -34,6 +57,22 @@ function formatHistoryForLlm(messages, options) {
34
57
  const participants = options?.participants;
35
58
  return messages.filter((message) => String(message.id ?? "") !== excludeId).map((message) => formatMessageForLlm(message, participants));
36
59
  }
60
+ function toParticipantRecord(fields) {
61
+ return {
62
+ id: fields.id,
63
+ name: fields.name ?? "unknown",
64
+ type: fields.type ?? "unknown",
65
+ handle: fields.handle ?? null
66
+ };
67
+ }
68
+ function toParticipantRecordFromRest(participant) {
69
+ return {
70
+ id: participant.id,
71
+ name: participant.name,
72
+ type: participant.type,
73
+ handle: participant.handle ?? null
74
+ };
75
+ }
37
76
  function buildParticipantsMessage(participants) {
38
77
  if (participants.length === 0) {
39
78
  return "## Current Participants\nNo other participants in this room.";
@@ -43,46 +82,27 @@ function buildParticipantsMessage(participants) {
43
82
  const participantType = String(participant.type ?? "Unknown");
44
83
  const participantName = String(participant.name ?? "Unknown");
45
84
  const participantHandle = String(participant.handle ?? "Unknown");
46
- lines.push(`- @${participantHandle} \u2014 ${participantName} (${participantType})`);
85
+ lines.push(
86
+ `- ${ensureHandlePrefix(participantHandle) ?? ""} \u2014 ${participantName} (${participantType})`
87
+ );
47
88
  }
48
89
  lines.push("");
49
90
  lines.push(
50
- "IMPORTANT: In thenvoi_send_message mentions, always use the exact handle shown above (e.g. '@john' for users, '@john/weather-agent' for agents), NOT the display name. Handles are lowercase with no spaces."
91
+ "IMPORTANT: In band_send_message mentions, always use the exact handle shown above (e.g. '@john' for users, '@john/weather-agent' for agents), NOT the display name. Handles are lowercase with no spaces."
51
92
  );
52
93
  return lines.join("\n");
53
94
  }
54
95
 
55
- // src/runtime/types.ts
56
- var HistoryProvider = class {
57
- raw;
58
- constructor(raw) {
59
- this.raw = raw;
60
- }
61
- convert(converter) {
62
- return converter.convert(this.raw);
63
- }
64
- get length() {
65
- return this.raw.length;
66
- }
67
- };
68
- var SYNTHETIC_SENDER_TYPE = "System";
69
- var SYNTHETIC_CONTACT_EVENTS_SENDER_ID = "contact-events";
70
- var SYNTHETIC_CONTACT_EVENTS_SENDER_NAME = "Contact Events";
71
- function ensureHandlePrefix(handle) {
72
- if (!handle) {
73
- return null;
74
- }
75
- return handle.startsWith("@") ? handle : `@${handle}`;
76
- }
77
-
78
96
  export {
79
- replaceUuidMentions,
80
- formatMessageForLlm,
81
- formatHistoryForLlm,
82
- buildParticipantsMessage,
83
97
  HistoryProvider,
84
98
  SYNTHETIC_SENDER_TYPE,
85
99
  SYNTHETIC_CONTACT_EVENTS_SENDER_ID,
86
100
  SYNTHETIC_CONTACT_EVENTS_SENDER_NAME,
87
- ensureHandlePrefix
101
+ ensureHandlePrefix,
102
+ replaceUuidMentions,
103
+ formatMessageForLlm,
104
+ formatHistoryForLlm,
105
+ toParticipantRecord,
106
+ toParticipantRecordFromRest,
107
+ buildParticipantsMessage
88
108
  };