@band-ai/sdk 0.1.10 → 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 (81) hide show
  1. package/README.md +54 -54
  2. package/dist/{ClaudeSDKAdapter-DfjaI5ke.d.cts → ClaudeSDKAdapter-BY4zEbCl.d.cts} +12 -10
  3. package/dist/{ClaudeSDKAdapter-DonPGJ43.d.ts → ClaudeSDKAdapter-Cna5P1dR.d.ts} +12 -10
  4. package/dist/{acp-server-NZAeg-WO.d.ts → acp-server-CiUqN3G3.d.ts} +2 -2
  5. package/dist/{acp-server-CUBXIiG6.d.cts → acp-server-Dlj7D563.d.cts} +2 -2
  6. package/dist/adapters.cjs +250 -183
  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-2BHHR6YW.js → chunk-4IAXZBXX.js} +62 -23
  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-RDM4TE4B.js → chunk-LBWKISBS.js} +19 -1
  16. package/dist/{chunk-FP237EAG.js → chunk-N2QTUMGO.js} +112 -195
  17. package/dist/{chunk-J3M3PFFY.js → chunk-NMZLX7TP.js} +35 -31
  18. package/dist/{chunk-6RXWL6TC.js → chunk-NT7TBFX2.js} +1 -1
  19. package/dist/{chunk-MLROFDKR.js → chunk-RV76SKFT.js} +39 -33
  20. package/dist/{chunk-XA4N2JPH.js → chunk-TLBCKDQO.js} +23 -23
  21. package/dist/{chunk-IZPV6QS6.js → chunk-WL2HNJZ6.js} +38 -11
  22. package/dist/{chunk-DNPVCR3S.js → chunk-WLCM2OXG.js} +31 -31
  23. package/dist/config.cjs +40 -13
  24. package/dist/config.d.cts +7 -1
  25. package/dist/config.d.ts +7 -1
  26. package/dist/config.js +2 -2
  27. package/dist/converters.cjs +61 -61
  28. package/dist/converters.d.cts +5 -5
  29. package/dist/converters.d.ts +5 -5
  30. package/dist/converters.js +4 -4
  31. package/dist/core.cjs +8 -8
  32. package/dist/core.d.cts +9 -9
  33. package/dist/core.d.ts +9 -9
  34. package/dist/core.js +3 -3
  35. package/dist/{dtos-Dd_fTfLn.d.cts → dtos-B8KU_q4d.d.cts} +2 -2
  36. package/dist/{dtos-Dd_fTfLn.d.ts → dtos-B8KU_q4d.d.ts} +2 -2
  37. package/dist/index.cjs +459 -504
  38. package/dist/index.d.cts +16 -15
  39. package/dist/index.d.ts +16 -15
  40. package/dist/index.js +15 -13
  41. package/dist/linear.cjs +74 -74
  42. package/dist/linear.d.cts +14 -14
  43. package/dist/linear.d.ts +14 -14
  44. package/dist/linear.js +72 -72
  45. package/dist/mcp-claude.cjs +37 -36
  46. package/dist/mcp-claude.d.cts +3 -3
  47. package/dist/mcp-claude.d.ts +3 -3
  48. package/dist/mcp-claude.js +7 -6
  49. package/dist/mcp.cjs +103 -62
  50. package/dist/mcp.d.cts +29 -16
  51. package/dist/mcp.d.ts +29 -16
  52. package/dist/mcp.js +14 -14
  53. package/dist/{opencode--iA5-KYk.d.cts → opencode-2YdscIc1.d.cts} +5 -5
  54. package/dist/{opencode-YNacv-eJ.d.ts → opencode-Bld62x5t.d.ts} +5 -5
  55. package/dist/{pagination-BBLsYLhT.d.ts → pagination-BgEx-HeL.d.ts} +2 -2
  56. package/dist/{pagination-CqidD-L_.d.cts → pagination-DqdkQArT.d.cts} +2 -2
  57. package/dist/{protocols-BF6jamIl.d.ts → protocols-Bwwcql0h.d.ts} +1 -1
  58. package/dist/{protocols-D2bTrQ_t.d.cts → protocols-Bz1rxcUg.d.cts} +1 -1
  59. package/dist/rest.cjs +41 -97
  60. package/dist/rest.d.cts +7 -7
  61. package/dist/rest.d.ts +7 -7
  62. package/dist/rest.js +2 -2
  63. package/dist/runtime.cjs +293 -464
  64. package/dist/runtime.d.cts +16 -28
  65. package/dist/runtime.d.ts +16 -28
  66. package/dist/runtime.js +12 -63
  67. package/dist/{schemas-CI0qgcp_.d.cts → schemas-BotL3ZLH.d.cts} +40 -54
  68. package/dist/{schemas-B1Fd3oUM.d.ts → schemas-DBsC4J1g.d.ts} +40 -54
  69. package/dist/{sdk-D2rTDU_o.d.cts → sdk-BTciSLRQ.d.cts} +5 -5
  70. package/dist/{sdk-CyqN1W5g.d.ts → sdk-qKJtMma_.d.ts} +5 -5
  71. package/dist/{simpleAdapter-qQt-tSz4.d.ts → simpleAdapter--wznuoOw.d.ts} +1 -1
  72. package/dist/{simpleAdapter-C_f-01Cu.d.cts → simpleAdapter-BpT4XbZC.d.cts} +1 -1
  73. package/dist/testing.d.cts +3 -3
  74. package/dist/testing.d.ts +3 -3
  75. package/dist/{types-DNySTI_8.d.ts → types-BTN_ZETM.d.ts} +2 -2
  76. package/dist/{types-D3AsUnd0.d.ts → types-BgYFd_Yw.d.cts} +5 -5
  77. package/dist/{types-DtMms5Fi.d.cts → types-BivGO7I9.d.ts} +5 -5
  78. package/dist/{types-CKqrhGB1.d.cts → types-D958TC71.d.cts} +2 -2
  79. package/package.json +6 -5
  80. package/dist/backends-DYtEhCZG.d.cts +0 -25
  81. package/dist/backends-oYAb7EU-.d.ts +0 -25
package/dist/index.cjs CHANGED
@@ -31,35 +31,35 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
33
  // src/core/errors.ts
34
- var ThenvoiSdkError, UnsupportedFeatureError, ValidationError, TransportError, RuntimeStateError;
34
+ var BandSdkError, UnsupportedFeatureError, ValidationError, TransportError, RuntimeStateError;
35
35
  var init_errors = __esm({
36
36
  "src/core/errors.ts"() {
37
37
  "use strict";
38
- ThenvoiSdkError = class extends Error {
38
+ BandSdkError = class extends Error {
39
39
  constructor(message, cause) {
40
40
  super(message, cause !== void 0 ? { cause } : void 0);
41
- this.name = "ThenvoiSdkError";
41
+ this.name = "BandSdkError";
42
42
  }
43
43
  };
44
- UnsupportedFeatureError = class extends ThenvoiSdkError {
44
+ UnsupportedFeatureError = class extends BandSdkError {
45
45
  constructor(message) {
46
46
  super(message);
47
47
  this.name = "UnsupportedFeatureError";
48
48
  }
49
49
  };
50
- ValidationError = class extends ThenvoiSdkError {
50
+ ValidationError = class extends BandSdkError {
51
51
  constructor(message, cause) {
52
52
  super(message, cause);
53
53
  this.name = "ValidationError";
54
54
  }
55
55
  };
56
- TransportError = class extends ThenvoiSdkError {
56
+ TransportError = class extends BandSdkError {
57
57
  constructor(message, cause) {
58
58
  super(message, cause);
59
59
  this.name = "TransportError";
60
60
  }
61
61
  };
62
- RuntimeStateError = class extends ThenvoiSdkError {
62
+ RuntimeStateError = class extends BandSdkError {
63
63
  constructor(message) {
64
64
  super(message);
65
65
  this.name = "RuntimeStateError";
@@ -228,9 +228,9 @@ var init_memory = __esm({
228
228
  "active",
229
229
  // Normal, visible memories
230
230
  "superseded",
231
- // Outdated; soft-deleted via thenvoi_supersede_memory
231
+ // Outdated; soft-deleted via band_supersede_memory
232
232
  "archived",
233
- // Hidden but preserved via thenvoi_archive_memory
233
+ // Hidden but preserved via band_archive_memory
234
234
  "all"
235
235
  // Any status (no filter)
236
236
  ];
@@ -249,14 +249,14 @@ function getToolDescription(name) {
249
249
  const model = TOOL_MODELS[name];
250
250
  return model?.description ?? `Execute ${name}`;
251
251
  }
252
- var TOOL_MODELS, ALL_TOOL_NAMES, MEMORY_TOOL_NAMES, CONTACT_TOOL_NAMES, BASE_TOOL_NAMES, CHAT_TOOL_NAMES, MCP_TOOL_PREFIX;
252
+ var TOOL_MODELS, ALL_TOOL_NAMES, MEMORY_TOOL_NAMES, CONTACT_TOOL_NAMES, BASE_TOOL_NAMES, CHAT_TOOL_NAMES, MCP_TOOL_PREFIX, MCP_SERVER_NAME, SEND_MESSAGE_TOOL_NAME, SEND_EVENT_TOOL_NAME;
253
253
  var init_schemas = __esm({
254
254
  "src/runtime/tools/schemas.ts"() {
255
255
  "use strict";
256
256
  init_chatEvents();
257
257
  init_memory();
258
258
  TOOL_MODELS = {
259
- thenvoi_send_message: {
259
+ band_send_message: {
260
260
  description: "Send a message to the chat room. Use this to respond to users or other agents. Messages require at least one @mention in the mentions array. You MUST use this tool to communicate \u2014 plain text responses won't reach users. When delegating, send the full task context in this message instead of assuming hidden state.",
261
261
  properties: {
262
262
  content: {
@@ -272,7 +272,7 @@ var init_schemas = __esm({
272
272
  },
273
273
  required: ["content", "mentions"]
274
274
  },
275
- thenvoi_send_event: {
275
+ band_send_event: {
276
276
  description: "Send an event to the chat room. No mentions required. 'thought': Share your reasoning or plan BEFORE taking actions. Explain what you're about to do and why. 'error': Report an error or problem that occurred. 'task': Report task progress or completion status. Always send a thought before complex actions to keep users informed.",
277
277
  properties: {
278
278
  content: {
@@ -291,12 +291,12 @@ var init_schemas = __esm({
291
291
  },
292
292
  required: ["content", "message_type"]
293
293
  },
294
- thenvoi_add_participant: {
295
- description: "Add a participant (agent or user) to the chat room by name. IMPORTANT: Use thenvoi_lookup_peers() first to find available agents. Pass the exact peer name from thenvoi_lookup_peers, not the handle. For normal delegation, omit role or use 'member'.",
294
+ band_add_participant: {
295
+ description: "Add a participant (agent or user) to the chat room by name. IMPORTANT: Use band_lookup_peers() first to find available agents. Pass the exact peer name from band_lookup_peers, not the handle. For normal delegation, omit role or use 'member'.",
296
296
  properties: {
297
297
  name: {
298
298
  type: "string",
299
- description: "Name of participant to add (must match a name from thenvoi_lookup_peers)."
299
+ description: "Name of participant to add (must match a name from band_lookup_peers)."
300
300
  },
301
301
  role: {
302
302
  type: "string",
@@ -306,7 +306,7 @@ var init_schemas = __esm({
306
306
  },
307
307
  required: ["name"]
308
308
  },
309
- thenvoi_remove_participant: {
309
+ band_remove_participant: {
310
310
  description: "Remove a participant from the chat room by name.",
311
311
  properties: {
312
312
  name: {
@@ -316,12 +316,12 @@ var init_schemas = __esm({
316
316
  },
317
317
  required: ["name"]
318
318
  },
319
- thenvoi_get_participants: {
319
+ band_get_participants: {
320
320
  description: "Get a list of all participants in the current chat room.",
321
321
  properties: {},
322
322
  required: []
323
323
  },
324
- thenvoi_lookup_peers: {
324
+ band_lookup_peers: {
325
325
  description: "List available peers (agents and users) that can be added to this room. Automatically excludes peers already in the room. Returns dict with 'peers' list and 'metadata' (page, page_size, total_count, total_pages). Use this to find specialized agents (e.g., Weather Agent) when you cannot answer a question directly.",
326
326
  properties: {
327
327
  page: {
@@ -336,7 +336,7 @@ var init_schemas = __esm({
336
336
  },
337
337
  required: []
338
338
  },
339
- thenvoi_create_chatroom: {
339
+ band_create_chatroom: {
340
340
  description: "Create a new chat room for a specific task or conversation.",
341
341
  properties: {
342
342
  task_id: {
@@ -346,7 +346,7 @@ var init_schemas = __esm({
346
346
  },
347
347
  required: []
348
348
  },
349
- thenvoi_list_contacts: {
349
+ band_list_contacts: {
350
350
  description: "List agent's contacts with pagination.",
351
351
  properties: {
352
352
  page: {
@@ -363,7 +363,7 @@ var init_schemas = __esm({
363
363
  },
364
364
  required: []
365
365
  },
366
- thenvoi_add_contact: {
366
+ band_add_contact: {
367
367
  description: "Send a contact request to add someone as a contact. Returns 'pending' when request is created. Returns 'approved' when inverse request existed and was auto-accepted.",
368
368
  properties: {
369
369
  handle: {
@@ -377,7 +377,7 @@ var init_schemas = __esm({
377
377
  },
378
378
  required: ["handle"]
379
379
  },
380
- thenvoi_remove_contact: {
380
+ band_remove_contact: {
381
381
  description: "Remove an existing contact by handle or ID.",
382
382
  properties: {
383
383
  handle: {
@@ -391,7 +391,7 @@ var init_schemas = __esm({
391
391
  },
392
392
  required: []
393
393
  },
394
- thenvoi_list_contact_requests: {
394
+ band_list_contact_requests: {
395
395
  description: "List both received and sent contact requests. Received requests are always filtered to pending status. Sent requests can be filtered by status.",
396
396
  properties: {
397
397
  page: {
@@ -413,7 +413,7 @@ var init_schemas = __esm({
413
413
  },
414
414
  required: []
415
415
  },
416
- thenvoi_respond_contact_request: {
416
+ band_respond_contact_request: {
417
417
  description: "Respond to a contact request. 'approve'/'reject': For requests you RECEIVED (handle = requester's handle). 'cancel': For requests you SENT (handle = recipient's handle).",
418
418
  properties: {
419
419
  action: {
@@ -432,7 +432,7 @@ var init_schemas = __esm({
432
432
  },
433
433
  required: ["action"]
434
434
  },
435
- thenvoi_list_memories: {
435
+ band_list_memories: {
436
436
  description: "List memories accessible to the agent. Returns memories about the specified subject (cross-agent sharing) and organization-wide shared memories.",
437
437
  properties: {
438
438
  subject_id: {
@@ -477,7 +477,7 @@ var init_schemas = __esm({
477
477
  },
478
478
  required: []
479
479
  },
480
- thenvoi_store_memory: {
480
+ band_store_memory: {
481
481
  description: "Store a new memory entry. The memory will be associated with the authenticated agent as the source. For subject-scoped memories, provide a subject_id. For organization-scoped memories, omit subject_id.",
482
482
  properties: {
483
483
  content: {
@@ -519,7 +519,7 @@ var init_schemas = __esm({
519
519
  },
520
520
  required: ["content", "system", "type", "segment", "thought"]
521
521
  },
522
- thenvoi_get_memory: {
522
+ band_get_memory: {
523
523
  description: "Retrieve a specific memory by ID.",
524
524
  properties: {
525
525
  memory_id: {
@@ -529,7 +529,7 @@ var init_schemas = __esm({
529
529
  },
530
530
  required: ["memory_id"]
531
531
  },
532
- thenvoi_supersede_memory: {
532
+ band_supersede_memory: {
533
533
  description: "Mark a memory as superseded (soft delete). Use when information is outdated or incorrect. The memory remains for audit trail but won't appear in normal queries. Only the source agent can supersede.",
534
534
  properties: {
535
535
  memory_id: {
@@ -539,7 +539,7 @@ var init_schemas = __esm({
539
539
  },
540
540
  required: ["memory_id"]
541
541
  },
542
- thenvoi_archive_memory: {
542
+ band_archive_memory: {
543
543
  description: "Archive a memory (hide but preserve). Use when memory is valid but not currently needed. Archived memories can be restored later by humans. Only the source agent can archive.",
544
544
  properties: {
545
545
  memory_id: {
@@ -552,18 +552,18 @@ var init_schemas = __esm({
552
552
  };
553
553
  ALL_TOOL_NAMES = new Set(Object.keys(TOOL_MODELS));
554
554
  MEMORY_TOOL_NAMES = /* @__PURE__ */ new Set([
555
- "thenvoi_list_memories",
556
- "thenvoi_store_memory",
557
- "thenvoi_get_memory",
558
- "thenvoi_supersede_memory",
559
- "thenvoi_archive_memory"
555
+ "band_list_memories",
556
+ "band_store_memory",
557
+ "band_get_memory",
558
+ "band_supersede_memory",
559
+ "band_archive_memory"
560
560
  ]);
561
561
  CONTACT_TOOL_NAMES = /* @__PURE__ */ new Set([
562
- "thenvoi_list_contacts",
563
- "thenvoi_add_contact",
564
- "thenvoi_remove_contact",
565
- "thenvoi_list_contact_requests",
566
- "thenvoi_respond_contact_request"
562
+ "band_list_contacts",
563
+ "band_add_contact",
564
+ "band_remove_contact",
565
+ "band_list_contact_requests",
566
+ "band_respond_contact_request"
567
567
  ]);
568
568
  BASE_TOOL_NAMES = new Set(
569
569
  [...ALL_TOOL_NAMES].filter((name) => !MEMORY_TOOL_NAMES.has(name))
@@ -571,7 +571,10 @@ var init_schemas = __esm({
571
571
  CHAT_TOOL_NAMES = new Set(
572
572
  [...BASE_TOOL_NAMES].filter((name) => !CONTACT_TOOL_NAMES.has(name))
573
573
  );
574
- MCP_TOOL_PREFIX = "mcp__thenvoi__";
574
+ MCP_TOOL_PREFIX = "mcp__band__";
575
+ MCP_SERVER_NAME = "band";
576
+ SEND_MESSAGE_TOOL_NAME = "band_send_message";
577
+ SEND_EVENT_TOOL_NAME = "band_send_event";
575
578
  }
576
579
  });
577
580
 
@@ -755,9 +758,9 @@ var init_zod = __esm({
755
758
  // src/mcp/sdk.ts
756
759
  var sdk_exports = {};
757
760
  __export(sdk_exports, {
758
- createThenvoiSdkMcpServer: () => createThenvoiSdkMcpServer
761
+ createBandSdkMcpServer: () => createBandSdkMcpServer
759
762
  });
760
- function createThenvoiSdkMcpServer(options) {
763
+ function createBandSdkMcpServer(options) {
761
764
  const registrationOptions = {
762
765
  enableMemoryTools: options.enableMemoryTools,
763
766
  enableContactTools: true,
@@ -769,7 +772,7 @@ function createThenvoiSdkMcpServer(options) {
769
772
  const contextCache = /* @__PURE__ */ new Map();
770
773
  const MAX_CONTEXT_CACHE_ENTRIES = 100;
771
774
  const serverConfig = (0, import_claude_agent_sdk.createSdkMcpServer)({
772
- name: "thenvoi",
775
+ name: MCP_SERVER_NAME,
773
776
  tools: toolDefinitions
774
777
  });
775
778
  return {
@@ -1007,6 +1010,7 @@ __export(src_exports, {
1007
1010
  Agent: () => Agent,
1008
1011
  AgentRuntime: () => AgentRuntime,
1009
1012
  AnthropicAdapter: () => AnthropicAdapter,
1013
+ BandLink: () => BandLink,
1010
1014
  CODEX_REASONING_EFFORTS: () => CODEX_REASONING_EFFORTS,
1011
1015
  CODEX_REASONING_SUMMARIES: () => CODEX_REASONING_SUMMARIES,
1012
1016
  CODEX_WEB_SEARCH_MODES: () => CODEX_WEB_SEARCH_MODES,
@@ -1018,6 +1022,7 @@ __export(src_exports, {
1018
1022
  GoogleADKAdapter: () => GoogleADKAdapter,
1019
1023
  LangGraphAdapter: () => LangGraphAdapter,
1020
1024
  LettaAdapter: () => LettaAdapter,
1025
+ MCP_SERVER_NAME: () => MCP_SERVER_NAME,
1021
1026
  MCP_TOOL_PREFIX: () => MCP_TOOL_PREFIX,
1022
1027
  OpenAIAdapter: () => OpenAIAdapter,
1023
1028
  OpencodeAdapter: () => OpencodeAdapter,
@@ -1025,7 +1030,6 @@ __export(src_exports, {
1025
1030
  PlatformRuntime: () => PlatformRuntime,
1026
1031
  SimpleAdapter: () => SimpleAdapter,
1027
1032
  TOOL_MODELS: () => TOOL_MODELS,
1028
- ThenvoiLink: () => ThenvoiLink,
1029
1033
  VercelAISDKAdapter: () => VercelAISDKAdapter,
1030
1034
  WebSocketDisconnectError: () => WebSocketDisconnectError,
1031
1035
  deriveDefaultRestUrl: () => deriveDefaultRestUrl,
@@ -1324,56 +1328,19 @@ init_errors();
1324
1328
  var DEFAULT_REQUEST_OPTIONS = {
1325
1329
  maxRetries: 3
1326
1330
  };
1331
+ var MESSAGE_SEND_MAX_RETRIES = 2;
1327
1332
 
1328
1333
  // src/client/rest/FernRestAdapter.ts
1329
- function mergeOptions(options) {
1334
+ function mergeOptions(options, maxRetries) {
1330
1335
  return {
1331
1336
  ...DEFAULT_REQUEST_OPTIONS,
1337
+ ...maxRetries !== void 0 ? { maxRetries } : {},
1332
1338
  ...options
1333
1339
  };
1334
1340
  }
1335
- var AGENT_ME_RETRY_LIMIT = 4;
1336
- var AGENT_ME_RETRY_BASE_DELAY_MS = 2e3;
1337
- var MESSAGE_SEND_RETRY_LIMIT = 3;
1338
- var MESSAGE_SEND_RETRY_BASE_DELAY_MS = 500;
1339
1341
  function asMetadataMap2(value) {
1340
1342
  return asOptionalRecord(value);
1341
1343
  }
1342
- function extractHttpStatus(error) {
1343
- const record = asOptionalRecord(error);
1344
- if (!record) {
1345
- return void 0;
1346
- }
1347
- const response = asOptionalRecord(record.response);
1348
- const status = record.statusCode ?? record.status ?? response?.statusCode ?? response?.status;
1349
- return typeof status === "number" ? status : void 0;
1350
- }
1351
- function isFernRateLimitError(error) {
1352
- return extractHttpStatus(error) === 429;
1353
- }
1354
- async function sleep(ms) {
1355
- await new Promise((resolveDelay) => setTimeout(resolveDelay, ms));
1356
- }
1357
- function computeRetryDelayMs(baseDelayMs, attempt) {
1358
- const backoff = baseDelayMs * 2 ** (attempt - 1);
1359
- const jitter = Math.floor(Math.random() * Math.max(1, Math.floor(backoff / 4)));
1360
- return backoff + jitter;
1361
- }
1362
- async function withRateLimitRetry(operation, options) {
1363
- let lastError;
1364
- for (let attempt = 1; attempt <= options.retryLimit; attempt += 1) {
1365
- try {
1366
- return await operation();
1367
- } catch (error) {
1368
- lastError = error;
1369
- if (!isFernRateLimitError(error) || attempt === options.retryLimit) {
1370
- throw error;
1371
- }
1372
- await sleep(computeRetryDelayMs(options.baseDelayMs, attempt));
1373
- }
1374
- }
1375
- throw lastError instanceof Error ? lastError : new Error("Rate-limit retry exhausted without a terminal error.");
1376
- }
1377
1344
  function requireNonEmptyStringField(value, field, source) {
1378
1345
  if (typeof value !== "string" || value.trim().length === 0) {
1379
1346
  throw new Error(`Invalid ${source} response: expected non-empty string AgentIdentity.${field}`);
@@ -1581,28 +1548,21 @@ var FernRestAdapter = class {
1581
1548
  this.client = client;
1582
1549
  }
1583
1550
  async getAgentMe(options) {
1584
- return withRateLimitRetry(
1585
- async () => {
1586
- if (this.client.agentApiIdentity?.getAgentMe) {
1587
- const response = await this.client.agentApiIdentity.getAgentMe(mergeOptions(options));
1588
- return normalizeAgentIdentityEnvelope(response, "agentApiIdentity.getAgentMe");
1589
- }
1590
- const profileClient = this.client.myProfile ?? this.client.humanApiProfile;
1591
- if (!profileClient?.getMyProfile) {
1592
- throw new UnsupportedFeatureError(
1593
- "Fern client missing agentApiIdentity.getAgentMe or humanApiProfile.getMyProfile"
1594
- );
1595
- }
1596
- const profile = await profileClient.getMyProfile(mergeOptions(options));
1597
- return normalizeLegacyProfileIdentity(
1598
- normalizeLegacyProfileEnvelope(profile),
1599
- "profile.getMyProfile"
1600
- );
1601
- },
1602
- {
1603
- retryLimit: AGENT_ME_RETRY_LIMIT,
1604
- baseDelayMs: AGENT_ME_RETRY_BASE_DELAY_MS
1605
- }
1551
+ const requestOptions = mergeOptions(options);
1552
+ if (this.client.agentApiIdentity?.getAgentMe) {
1553
+ const response = await this.client.agentApiIdentity.getAgentMe(requestOptions);
1554
+ return normalizeAgentIdentityEnvelope(response, "agentApiIdentity.getAgentMe");
1555
+ }
1556
+ const profileClient = this.client.myProfile ?? this.client.humanApiProfile;
1557
+ if (!profileClient?.getMyProfile) {
1558
+ throw new UnsupportedFeatureError(
1559
+ "Fern client missing agentApiIdentity.getAgentMe or humanApiProfile.getMyProfile"
1560
+ );
1561
+ }
1562
+ const profile = await profileClient.getMyProfile(requestOptions);
1563
+ return normalizeLegacyProfileIdentity(
1564
+ normalizeLegacyProfileEnvelope(profile),
1565
+ "profile.getMyProfile"
1606
1566
  );
1607
1567
  }
1608
1568
  async createChatMessage(chatId, message, options) {
@@ -1610,45 +1570,33 @@ var FernRestAdapter = class {
1610
1570
  if (!api) {
1611
1571
  throw new UnsupportedFeatureError("Fern client missing chat message creation endpoint");
1612
1572
  }
1613
- const response = await withRateLimitRetry(
1614
- async () => await api(
1615
- chatId,
1616
- {
1617
- message: {
1618
- content: message.content,
1619
- message_type: message.messageType,
1620
- metadata: message.metadata,
1621
- mentions: message.mentions
1622
- }
1623
- },
1624
- mergeOptions(options)
1625
- ),
1573
+ const response = await api(
1574
+ chatId,
1626
1575
  {
1627
- retryLimit: MESSAGE_SEND_RETRY_LIMIT,
1628
- baseDelayMs: MESSAGE_SEND_RETRY_BASE_DELAY_MS
1629
- }
1576
+ message: {
1577
+ content: message.content,
1578
+ message_type: message.messageType,
1579
+ metadata: message.metadata,
1580
+ mentions: message.mentions
1581
+ }
1582
+ },
1583
+ mergeOptions(options, MESSAGE_SEND_MAX_RETRIES)
1630
1584
  );
1631
1585
  return normalizeToolOperationResult(response);
1632
1586
  }
1633
1587
  async createChatEvent(chatId, event, options) {
1634
1588
  const createAgentChatEvent = this.client.agentApiEvents?.createAgentChatEvent?.bind(this.client.agentApiEvents);
1635
1589
  if (createAgentChatEvent) {
1636
- const response = await withRateLimitRetry(
1637
- async () => await createAgentChatEvent(
1638
- chatId,
1639
- {
1640
- event: {
1641
- content: event.content,
1642
- message_type: event.messageType,
1643
- metadata: event.metadata
1644
- }
1645
- },
1646
- mergeOptions(options)
1647
- ),
1590
+ const response = await createAgentChatEvent(
1591
+ chatId,
1648
1592
  {
1649
- retryLimit: MESSAGE_SEND_RETRY_LIMIT,
1650
- baseDelayMs: MESSAGE_SEND_RETRY_BASE_DELAY_MS
1651
- }
1593
+ event: {
1594
+ content: event.content,
1595
+ message_type: event.messageType,
1596
+ metadata: event.metadata
1597
+ }
1598
+ },
1599
+ mergeOptions(options, MESSAGE_SEND_MAX_RETRIES)
1652
1600
  );
1653
1601
  return normalizeToolOperationResult(response);
1654
1602
  }
@@ -1944,7 +1892,7 @@ var FernRestAdapter = class {
1944
1892
  }
1945
1893
  };
1946
1894
 
1947
- // src/platform/ThenvoiLink.ts
1895
+ // src/platform/BandLink.ts
1948
1896
  init_errors();
1949
1897
 
1950
1898
  // src/contracts/capabilities.ts
@@ -2188,7 +2136,7 @@ function retryAfterFromHeaders(headers) {
2188
2136
  var import_ws = require("ws");
2189
2137
  function createNodeWebSocketFactory(headers) {
2190
2138
  const Constructor = import_ws.WebSocket;
2191
- class ThenvoiNodeWebSocket {
2139
+ class BandNodeWebSocket {
2192
2140
  constructor(address, protocols) {
2193
2141
  const socket = new Constructor(address, protocols, headers ? { headers } : void 0);
2194
2142
  socket.once("unexpected-response", (request, response) => {
@@ -2197,7 +2145,7 @@ function createNodeWebSocketFactory(headers) {
2197
2145
  return socket;
2198
2146
  }
2199
2147
  }
2200
- return ThenvoiNodeWebSocket;
2148
+ return BandNodeWebSocket;
2201
2149
  }
2202
2150
  async function emitUpgradeError(websocket, request, response) {
2203
2151
  const body = await readResponseBody(response);
@@ -2585,10 +2533,10 @@ function getSocketChannelCount(socket) {
2585
2533
  return candidate.channels.length;
2586
2534
  }
2587
2535
 
2588
- // src/platform/ThenvoiLink.ts
2536
+ // src/platform/BandLink.ts
2589
2537
  init_protocols();
2590
- var import_rest_client = require("@thenvoi/rest-client");
2591
- var DEFAULT_WS_URL = "wss://app.thenvoi.com/api/v1/socket";
2538
+ var import_rest_client = require("@band-ai/rest-client");
2539
+ var DEFAULT_WS_URL = "wss://app.band.ai/api/v1/socket";
2592
2540
  function deriveDefaultRestUrl(wsUrl) {
2593
2541
  const parsed = new URL(wsUrl);
2594
2542
  const protocol = parsed.protocol === "ws:" ? "http:" : "https:";
@@ -2613,7 +2561,7 @@ function toPlatformMessage(roomId, message) {
2613
2561
  createdAt: new Date(message.inserted_at)
2614
2562
  };
2615
2563
  }
2616
- var ThenvoiLink = class {
2564
+ var BandLink = class {
2617
2565
  agentId;
2618
2566
  apiKey;
2619
2567
  wsUrl;
@@ -2639,7 +2587,7 @@ var ThenvoiLink = class {
2639
2587
  ...options.capabilities
2640
2588
  };
2641
2589
  const restApi = options.restApi ?? new FernRestAdapter(
2642
- new import_rest_client.ThenvoiClient({
2590
+ new import_rest_client.BandClient({
2643
2591
  apiKey: this.apiKey,
2644
2592
  baseUrl: this.restUrl
2645
2593
  })
@@ -3258,6 +3206,104 @@ init_errors();
3258
3206
 
3259
3207
  // src/runtime/tools/AgentTools.ts
3260
3208
  init_errors();
3209
+ var import_band_sdk_core = require("@band-ai/band-sdk-core");
3210
+
3211
+ // src/runtime/types.ts
3212
+ var HistoryProvider = class {
3213
+ raw;
3214
+ constructor(raw) {
3215
+ this.raw = raw;
3216
+ }
3217
+ convert(converter) {
3218
+ return converter.convert(this.raw);
3219
+ }
3220
+ get length() {
3221
+ return this.raw.length;
3222
+ }
3223
+ };
3224
+ var SYNTHETIC_SENDER_TYPE = "System";
3225
+ var SYNTHETIC_CONTACT_EVENTS_SENDER_ID = "contact-events";
3226
+ var SYNTHETIC_CONTACT_EVENTS_SENDER_NAME = "Contact Events";
3227
+ function ensureHandlePrefix(handle) {
3228
+ if (!handle) {
3229
+ return null;
3230
+ }
3231
+ return handle.startsWith("@") ? handle : `@${handle}`;
3232
+ }
3233
+
3234
+ // src/runtime/formatters.ts
3235
+ function isMetadataMap(value) {
3236
+ return value !== null && typeof value === "object" && !Array.isArray(value);
3237
+ }
3238
+ function replaceUuidMentions(content, participants) {
3239
+ if (!content || participants.length === 0) {
3240
+ return content;
3241
+ }
3242
+ let next = content;
3243
+ for (const participant of participants) {
3244
+ const participantId = participant.id;
3245
+ const handle = participant.handle;
3246
+ if (typeof participantId === "string" && typeof handle === "string") {
3247
+ next = next.replaceAll(`@[[${participantId}]]`, ensureHandlePrefix(handle) ?? "");
3248
+ }
3249
+ }
3250
+ return next;
3251
+ }
3252
+ function formatMessageForLlm(message, participants) {
3253
+ const senderType = String(message.sender_type ?? "");
3254
+ const senderName = String(message.sender_name ?? message.name ?? senderType);
3255
+ const content = participants ? replaceUuidMentions(String(message.content ?? ""), participants) : String(message.content ?? "");
3256
+ return {
3257
+ role: senderType === "Agent" ? "assistant" : "user",
3258
+ content,
3259
+ sender_name: senderName,
3260
+ sender_type: senderType,
3261
+ message_type: String(message.message_type ?? "text"),
3262
+ metadata: isMetadataMap(message.metadata) ? message.metadata : {}
3263
+ };
3264
+ }
3265
+ function formatHistoryForLlm(messages, options) {
3266
+ const excludeId = options?.excludeId;
3267
+ const participants = options?.participants;
3268
+ return messages.filter((message) => String(message.id ?? "") !== excludeId).map((message) => formatMessageForLlm(message, participants));
3269
+ }
3270
+ function toParticipantRecord(fields) {
3271
+ return {
3272
+ id: fields.id,
3273
+ name: fields.name ?? "unknown",
3274
+ type: fields.type ?? "unknown",
3275
+ handle: fields.handle ?? null
3276
+ };
3277
+ }
3278
+ function toParticipantRecordFromRest(participant) {
3279
+ return {
3280
+ id: participant.id,
3281
+ name: participant.name,
3282
+ type: participant.type,
3283
+ handle: participant.handle ?? null
3284
+ };
3285
+ }
3286
+ function buildParticipantsMessage(participants) {
3287
+ if (participants.length === 0) {
3288
+ return "## Current Participants\nNo other participants in this room.";
3289
+ }
3290
+ const lines = ["## Current Participants"];
3291
+ for (const participant of participants) {
3292
+ const participantType = String(participant.type ?? "Unknown");
3293
+ const participantName = String(participant.name ?? "Unknown");
3294
+ const participantHandle = String(participant.handle ?? "Unknown");
3295
+ lines.push(
3296
+ `- ${ensureHandlePrefix(participantHandle) ?? ""} \u2014 ${participantName} (${participantType})`
3297
+ );
3298
+ }
3299
+ lines.push("");
3300
+ lines.push(
3301
+ "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."
3302
+ );
3303
+ return lines.join("\n");
3304
+ }
3305
+
3306
+ // src/runtime/tools/AgentTools.ts
3261
3307
  init_chatEvents();
3262
3308
  init_protocols();
3263
3309
  init_schemas();
@@ -3300,13 +3346,13 @@ var AgentTools = class {
3300
3346
  roomId;
3301
3347
  capabilities;
3302
3348
  rest;
3303
- participants;
3349
+ roster;
3304
3350
  adapterTools;
3305
3351
  toolHandlers;
3306
3352
  constructor(options) {
3307
3353
  this.roomId = options.roomId;
3308
3354
  this.rest = options.rest;
3309
- this.participants = options.participants ?? [];
3355
+ this.roster = options.roster ?? new import_band_sdk_core.ParticipantRoster();
3310
3356
  this.capabilities = {
3311
3357
  ...DEFAULT_AGENT_TOOLS_CAPABILITIES,
3312
3358
  ...options.capabilities
@@ -3318,17 +3364,20 @@ var AgentTools = class {
3318
3364
  return this.adapterTools;
3319
3365
  }
3320
3366
  async sendMessage(content, mentions = []) {
3321
- if (mentions.length > 0 && typeof mentions[0] === "string" && this.participants.length === 0) {
3322
- await this.syncParticipants();
3367
+ let participants;
3368
+ if (mentions.length > 0 && typeof mentions[0] === "string") {
3369
+ participants = this.roster.list();
3370
+ if (participants.length === 0) {
3371
+ participants = await this.syncParticipants();
3372
+ }
3323
3373
  }
3324
- const resolvedMentions = this.resolveMentions(mentions);
3374
+ const resolvedMentions = this.resolveMentions(mentions, participants);
3325
3375
  return this.rest.createChatMessage(
3326
3376
  this.roomId,
3327
3377
  {
3328
3378
  content,
3329
3379
  mentions: resolvedMentions
3330
- },
3331
- DEFAULT_REQUEST_OPTIONS
3380
+ }
3332
3381
  );
3333
3382
  }
3334
3383
  async sendEvent(content, messageType, metadata) {
@@ -3339,8 +3388,7 @@ var AgentTools = class {
3339
3388
  content,
3340
3389
  messageType,
3341
3390
  metadata
3342
- },
3343
- DEFAULT_REQUEST_OPTIONS
3391
+ }
3344
3392
  );
3345
3393
  }
3346
3394
  async createChatroom(taskId) {
@@ -3379,7 +3427,7 @@ var AgentTools = class {
3379
3427
  type: String(peer.type ?? "Agent"),
3380
3428
  handle: typeof peer.handle === "string" ? peer.handle : null
3381
3429
  };
3382
- this.participants.push(participantRecord);
3430
+ this.roster.add(participantRecord);
3383
3431
  return {
3384
3432
  ...participantRecord,
3385
3433
  status: "added"
@@ -3394,7 +3442,7 @@ var AgentTools = class {
3394
3442
  throw new ValidationError(`Participant '${name}' not found in room`);
3395
3443
  }
3396
3444
  await this.rest.removeChatParticipant(this.roomId, String(participant.id), DEFAULT_REQUEST_OPTIONS);
3397
- this.replaceParticipants(this.participants.filter((entry) => entry.id !== participant.id));
3445
+ this.roster.remove(participant.id);
3398
3446
  return {
3399
3447
  id: participant.id,
3400
3448
  name,
@@ -3422,17 +3470,12 @@ var AgentTools = class {
3422
3470
  }
3423
3471
  async fetchParticipants() {
3424
3472
  const participants = await this.rest.listChatParticipants(this.roomId, DEFAULT_REQUEST_OPTIONS);
3425
- return participants.map((participant) => ({
3426
- id: participant.id,
3427
- name: participant.name,
3428
- type: participant.type,
3429
- handle: participant.handle ?? null
3430
- }));
3473
+ return participants.map(toParticipantRecordFromRest);
3431
3474
  }
3432
3475
  async syncParticipants() {
3433
3476
  const participants = await this.fetchParticipants();
3434
- this.replaceParticipants(participants);
3435
- return [...this.participants];
3477
+ this.roster.setAll(participants);
3478
+ return this.roster.list().map(toParticipantRecord);
3436
3479
  }
3437
3480
  async executeToolCall(toolName, arguments_) {
3438
3481
  const validationError = validateToolArgs(toolName, arguments_);
@@ -3480,7 +3523,7 @@ var AgentTools = class {
3480
3523
  if (!CHAT_TOOL_NAMES.has(name) && !this.capabilities.contacts) {
3481
3524
  return false;
3482
3525
  }
3483
- if (name === "thenvoi_lookup_peers" && !this.capabilities.peers) {
3526
+ if (name === "band_lookup_peers" && !this.capabilities.peers) {
3484
3527
  return false;
3485
3528
  }
3486
3529
  return true;
@@ -3675,7 +3718,7 @@ var AgentTools = class {
3675
3718
  }
3676
3719
  return this.rest.archiveMemory(normalizedMemoryId, DEFAULT_REQUEST_OPTIONS);
3677
3720
  }
3678
- resolveMentions(mentions) {
3721
+ resolveMentions(mentions, participants) {
3679
3722
  if (mentions.length === 0) {
3680
3723
  return [];
3681
3724
  }
@@ -3688,7 +3731,7 @@ var AgentTools = class {
3688
3731
  const participantsByHandle = /* @__PURE__ */ new Map();
3689
3732
  const participantsById = /* @__PURE__ */ new Map();
3690
3733
  const participantsByName = /* @__PURE__ */ new Map();
3691
- for (const participant of this.participants) {
3734
+ for (const participant of participants ?? []) {
3692
3735
  const ref = {
3693
3736
  id: String(participant.id),
3694
3737
  handle: typeof participant.handle === "string" ? participant.handle : void 0
@@ -3744,9 +3787,6 @@ var AgentTools = class {
3744
3787
  normalizeMentionHandle(handle) {
3745
3788
  return handle.trim().replace(/^@+/, "").toLowerCase();
3746
3789
  }
3747
- replaceParticipants(participants) {
3748
- this.participants.splice(0, this.participants.length, ...participants);
3749
- }
3750
3790
  buildAdapterTools() {
3751
3791
  const tools = {
3752
3792
  capabilities: this.capabilities
@@ -3777,51 +3817,51 @@ var AgentTools = class {
3777
3817
  }
3778
3818
  buildMessagingToolHandlers() {
3779
3819
  return {
3780
- thenvoi_send_message: async (arguments_) => this.sendMessage(
3820
+ band_send_message: async (arguments_) => this.sendMessage(
3781
3821
  String(arguments_.content ?? ""),
3782
3822
  this.normalizeMentionInput(arguments_.mentions)
3783
3823
  ),
3784
- thenvoi_send_event: async (arguments_) => this.sendEvent(
3824
+ band_send_event: async (arguments_) => this.sendEvent(
3785
3825
  String(arguments_.content ?? ""),
3786
3826
  String(arguments_.message_type ?? "task"),
3787
3827
  this.normalizeOptionalMetadata(arguments_.metadata)
3788
3828
  ),
3789
- thenvoi_add_participant: async (arguments_) => this.addParticipant(String(arguments_.name ?? ""), String(arguments_.role ?? "member")),
3790
- thenvoi_remove_participant: async (arguments_) => this.removeParticipant(String(arguments_.name ?? "")),
3791
- thenvoi_lookup_peers: async (arguments_) => this.lookupPeers(
3829
+ band_add_participant: async (arguments_) => this.addParticipant(String(arguments_.name ?? ""), String(arguments_.role ?? "member")),
3830
+ band_remove_participant: async (arguments_) => this.removeParticipant(String(arguments_.name ?? "")),
3831
+ band_lookup_peers: async (arguments_) => this.lookupPeers(
3792
3832
  coercePositiveInt(arguments_.page, 1),
3793
3833
  coercePositiveInt(arguments_.page_size, 50)
3794
3834
  ),
3795
- thenvoi_get_participants: async () => this.getParticipants(),
3796
- thenvoi_create_chatroom: async (arguments_) => this.createChatroom(this.normalizeOptionalString(arguments_.task_id))
3835
+ band_get_participants: async () => this.getParticipants(),
3836
+ band_create_chatroom: async (arguments_) => this.createChatroom(this.normalizeOptionalString(arguments_.task_id))
3797
3837
  };
3798
3838
  }
3799
3839
  buildContactToolHandlers() {
3800
3840
  return {
3801
- thenvoi_list_contacts: async (arguments_) => this.listContacts({
3841
+ band_list_contacts: async (arguments_) => this.listContacts({
3802
3842
  page: coercePositiveInt(arguments_.page, 1),
3803
3843
  pageSize: coercePositiveInt(arguments_.page_size, 50)
3804
3844
  }),
3805
- thenvoi_add_contact: async (arguments_) => this.addContact({
3845
+ band_add_contact: async (arguments_) => this.addContact({
3806
3846
  handle: String(arguments_.handle ?? ""),
3807
3847
  ...typeof arguments_.message === "string" ? { message: arguments_.message } : {}
3808
3848
  }),
3809
- thenvoi_remove_contact: async (arguments_) => this.removeContact(this.toRemoveContactArgs(arguments_)),
3810
- thenvoi_list_contact_requests: async (arguments_) => this.listContactRequests({
3849
+ band_remove_contact: async (arguments_) => this.removeContact(this.toRemoveContactArgs(arguments_)),
3850
+ band_list_contact_requests: async (arguments_) => this.listContactRequests({
3811
3851
  page: coercePositiveInt(arguments_.page, 1),
3812
3852
  pageSize: coercePositiveInt(arguments_.page_size, 50),
3813
3853
  sentStatus: String(arguments_.sent_status ?? "pending")
3814
3854
  }),
3815
- thenvoi_respond_contact_request: async (arguments_) => this.respondContactRequest(this.toRespondContactRequestArgs(arguments_))
3855
+ band_respond_contact_request: async (arguments_) => this.respondContactRequest(this.toRespondContactRequestArgs(arguments_))
3816
3856
  };
3817
3857
  }
3818
3858
  buildMemoryToolHandlers() {
3819
3859
  return {
3820
- thenvoi_list_memories: async (arguments_) => this.listMemories(this.toListMemoriesArgs(arguments_)),
3821
- thenvoi_store_memory: async (arguments_) => this.storeMemory(this.toStoreMemoryArgs(arguments_)),
3822
- thenvoi_get_memory: async (arguments_) => this.getMemory(String(arguments_.memory_id ?? "")),
3823
- thenvoi_supersede_memory: async (arguments_) => this.supersedeMemory(String(arguments_.memory_id ?? "")),
3824
- thenvoi_archive_memory: async (arguments_) => this.archiveMemory(String(arguments_.memory_id ?? ""))
3860
+ band_list_memories: async (arguments_) => this.listMemories(this.toListMemoriesArgs(arguments_)),
3861
+ band_store_memory: async (arguments_) => this.storeMemory(this.toStoreMemoryArgs(arguments_)),
3862
+ band_get_memory: async (arguments_) => this.getMemory(String(arguments_.memory_id ?? "")),
3863
+ band_supersede_memory: async (arguments_) => this.supersedeMemory(String(arguments_.memory_id ?? "")),
3864
+ band_archive_memory: async (arguments_) => this.archiveMemory(String(arguments_.memory_id ?? ""))
3825
3865
  };
3826
3866
  }
3827
3867
  toRemoveContactArgs(arguments_) {
@@ -4065,13 +4105,13 @@ function validateToolArgs(toolName, args) {
4065
4105
  errors.push(`${field}: Field required`);
4066
4106
  }
4067
4107
  }
4068
- if (toolName === "thenvoi_send_message") {
4108
+ if (toolName === "band_send_message") {
4069
4109
  const mentions = args.mentions;
4070
4110
  if (Array.isArray(mentions) && mentions.length === 0) {
4071
4111
  errors.push("mentions: At least one mention is required");
4072
4112
  }
4073
4113
  }
4074
- if (toolName === "thenvoi_send_event") {
4114
+ if (toolName === "band_send_event") {
4075
4115
  const messageType = args.message_type;
4076
4116
  if (typeof messageType === "string" && !CHAT_EVENT_TYPES.includes(messageType)) {
4077
4117
  errors.push(
@@ -4079,7 +4119,7 @@ function validateToolArgs(toolName, args) {
4079
4119
  );
4080
4120
  }
4081
4121
  }
4082
- if (toolName === "thenvoi_respond_contact_request") {
4122
+ if (toolName === "band_respond_contact_request") {
4083
4123
  const action = args.action;
4084
4124
  const validActions = ["approve", "reject", "cancel"];
4085
4125
  if (typeof action === "string" && !validActions.includes(action)) {
@@ -4088,7 +4128,7 @@ function validateToolArgs(toolName, args) {
4088
4128
  );
4089
4129
  }
4090
4130
  }
4091
- if (toolName === "thenvoi_store_memory") {
4131
+ if (toolName === "band_store_memory") {
4092
4132
  if (typeof args.system === "string" && !isMemorySystem(args.system)) {
4093
4133
  errors.push(`system: Invalid value '${args.system}'. Expected one of: ${expectedList(MEMORY_SYSTEMS)}`);
4094
4134
  }
@@ -4117,137 +4157,8 @@ function validateToolArgs(toolName, args) {
4117
4157
  return null;
4118
4158
  }
4119
4159
 
4120
- // src/runtime/retryTracker.ts
4121
- var DEFAULT_MAX_TRACKED = 1e4;
4122
- var MessageRetryTracker = class {
4123
- maxRetriesValue;
4124
- maxTracked;
4125
- attempts = /* @__PURE__ */ new Map();
4126
- failed = /* @__PURE__ */ new Set();
4127
- constructor(maxRetries = 1, maxTracked = DEFAULT_MAX_TRACKED) {
4128
- this.maxRetriesValue = maxRetries;
4129
- this.maxTracked = maxTracked;
4130
- }
4131
- get maxRetries() {
4132
- return this.maxRetriesValue;
4133
- }
4134
- isPermanentlyFailed(messageId) {
4135
- return this.failed.has(messageId);
4136
- }
4137
- recordAttempt(messageId) {
4138
- const attempts = (this.attempts.get(messageId) ?? 0) + 1;
4139
- this.attempts.set(messageId, attempts);
4140
- const exceeded = attempts > this.maxRetriesValue;
4141
- if (exceeded) {
4142
- this.evictSetIfNeeded(this.failed);
4143
- this.failed.add(messageId);
4144
- }
4145
- this.evictMapIfNeeded(this.attempts);
4146
- return [attempts, exceeded];
4147
- }
4148
- markSuccess(messageId) {
4149
- this.attempts.delete(messageId);
4150
- }
4151
- markPermanentlyFailed(messageId) {
4152
- this.evictSetIfNeeded(this.failed);
4153
- this.failed.add(messageId);
4154
- }
4155
- evictMapIfNeeded(map) {
4156
- while (map.size >= this.maxTracked) {
4157
- const first = map.keys().next();
4158
- if (first.done) break;
4159
- map.delete(first.value);
4160
- }
4161
- }
4162
- evictSetIfNeeded(set) {
4163
- while (set.size >= this.maxTracked) {
4164
- const first = set.values().next();
4165
- if (first.done) break;
4166
- set.delete(first.value);
4167
- }
4168
- }
4169
- };
4170
-
4171
- // src/runtime/types.ts
4172
- var HistoryProvider = class {
4173
- raw;
4174
- constructor(raw) {
4175
- this.raw = raw;
4176
- }
4177
- convert(converter) {
4178
- return converter.convert(this.raw);
4179
- }
4180
- get length() {
4181
- return this.raw.length;
4182
- }
4183
- };
4184
- var SYNTHETIC_SENDER_TYPE = "System";
4185
- var SYNTHETIC_CONTACT_EVENTS_SENDER_ID = "contact-events";
4186
- var SYNTHETIC_CONTACT_EVENTS_SENDER_NAME = "Contact Events";
4187
- function ensureHandlePrefix(handle) {
4188
- if (!handle) {
4189
- return null;
4190
- }
4191
- return handle.startsWith("@") ? handle : `@${handle}`;
4192
- }
4193
-
4194
- // src/runtime/formatters.ts
4195
- function isMetadataMap(value) {
4196
- return value !== null && typeof value === "object" && !Array.isArray(value);
4197
- }
4198
- function replaceUuidMentions(content, participants) {
4199
- if (!content || participants.length === 0) {
4200
- return content;
4201
- }
4202
- let next = content;
4203
- for (const participant of participants) {
4204
- const participantId = participant.id;
4205
- const handle = participant.handle;
4206
- if (typeof participantId === "string" && typeof handle === "string") {
4207
- next = next.replaceAll(`@[[${participantId}]]`, ensureHandlePrefix(handle) ?? "");
4208
- }
4209
- }
4210
- return next;
4211
- }
4212
- function formatMessageForLlm(message, participants) {
4213
- const senderType = String(message.sender_type ?? "");
4214
- const senderName = String(message.sender_name ?? message.name ?? senderType);
4215
- const content = participants ? replaceUuidMentions(String(message.content ?? ""), participants) : String(message.content ?? "");
4216
- return {
4217
- role: senderType === "Agent" ? "assistant" : "user",
4218
- content,
4219
- sender_name: senderName,
4220
- sender_type: senderType,
4221
- message_type: String(message.message_type ?? "text"),
4222
- metadata: isMetadataMap(message.metadata) ? message.metadata : {}
4223
- };
4224
- }
4225
- function formatHistoryForLlm(messages, options) {
4226
- const excludeId = options?.excludeId;
4227
- const participants = options?.participants;
4228
- return messages.filter((message) => String(message.id ?? "") !== excludeId).map((message) => formatMessageForLlm(message, participants));
4229
- }
4230
- function buildParticipantsMessage(participants) {
4231
- if (participants.length === 0) {
4232
- return "## Current Participants\nNo other participants in this room.";
4233
- }
4234
- const lines = ["## Current Participants"];
4235
- for (const participant of participants) {
4236
- const participantType = String(participant.type ?? "Unknown");
4237
- const participantName = String(participant.name ?? "Unknown");
4238
- const participantHandle = String(participant.handle ?? "Unknown");
4239
- lines.push(
4240
- `- ${ensureHandlePrefix(participantHandle) ?? ""} \u2014 ${participantName} (${participantType})`
4241
- );
4242
- }
4243
- lines.push("");
4244
- lines.push(
4245
- "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."
4246
- );
4247
- return lines.join("\n");
4248
- }
4249
-
4250
4160
  // src/runtime/ExecutionContext.ts
4161
+ var import_band_sdk_core2 = require("@band-ai/band-sdk-core");
4251
4162
  var DEDUP_CACHE_MAX = 500;
4252
4163
  var ExecutionContext = class {
4253
4164
  roomId;
@@ -4259,11 +4170,10 @@ var ExecutionContext = class {
4259
4170
  history = [];
4260
4171
  messageIds = /* @__PURE__ */ new Set();
4261
4172
  dedupCache = /* @__PURE__ */ new Map();
4262
- participants = [];
4173
+ roster = new import_band_sdk_core2.ParticipantRoster();
4263
4174
  tools;
4264
4175
  adapterTools;
4265
4176
  participantsMessage = null;
4266
- lastSentParticipantIds = null;
4267
4177
  contactsMessage = null;
4268
4178
  contextCache = null;
4269
4179
  contextCacheExpiresAt = 0;
@@ -4278,11 +4188,11 @@ var ExecutionContext = class {
4278
4188
  this.enableContextCache = options.enableContextCache ?? true;
4279
4189
  this.contextCacheTtlMs = Math.max(0, (options.contextCacheTtlSeconds ?? 300) * 1e3);
4280
4190
  this.enableContextHydration = options.enableContextHydration ?? true;
4281
- this.retryTrackerInstance = new MessageRetryTracker(options.maxMessageRetries ?? 1);
4191
+ this.retryTrackerInstance = new import_band_sdk_core2.RetryTracker(options.maxMessageRetries ?? 1);
4282
4192
  this.tools = new AgentTools({
4283
4193
  roomId: this.roomId,
4284
4194
  rest: this.link.rest,
4285
- participants: this.participants,
4195
+ roster: this.roster,
4286
4196
  capabilities: this.link.capabilities
4287
4197
  });
4288
4198
  this.adapterTools = this.tools.getAdapterTools();
@@ -4350,23 +4260,20 @@ var ExecutionContext = class {
4350
4260
  }));
4351
4261
  }
4352
4262
  setParticipants(participants) {
4353
- this.replaceParticipants(participants);
4263
+ this.roster.setAll(participants);
4354
4264
  this.updateCachedParticipants();
4355
4265
  }
4356
4266
  addParticipant(participant) {
4357
- const existingIndex = this.participants.findIndex((entry) => entry.id === participant.id);
4358
- if (existingIndex >= 0) {
4359
- this.participants.splice(existingIndex, 1);
4267
+ const isNew = this.roster.add(participant);
4268
+ if (isNew) {
4269
+ const name = String(participant.name ?? "unknown");
4270
+ this.participantsMessage = `${name} joined the room.`;
4360
4271
  }
4361
- this.participants.push(participant);
4362
- const name = String(participant.name ?? "unknown");
4363
- this.participantsMessage = `${name} joined the room.`;
4364
4272
  this.updateCachedParticipants();
4365
4273
  }
4366
4274
  removeParticipant(participantId) {
4367
- const removed = this.participants.find((entry) => String(entry.id) === participantId);
4368
- const next = this.participants.filter((entry) => String(entry.id) !== participantId);
4369
- this.replaceParticipants(next);
4275
+ const removed = this.roster.list().find((entry) => entry.id === participantId);
4276
+ this.roster.remove(participantId);
4370
4277
  if (removed) {
4371
4278
  this.participantsMessage = `${String(removed.name ?? participantId)} left the room.`;
4372
4279
  }
@@ -4376,16 +4283,7 @@ var ExecutionContext = class {
4376
4283
  this.contactsMessage = message;
4377
4284
  }
4378
4285
  consumeParticipantsMessage() {
4379
- const currentIds = new Set(this.participants.map((p) => String(p.id)));
4380
- let changed = !this.lastSentParticipantIds || currentIds.size !== this.lastSentParticipantIds.size;
4381
- if (!changed) {
4382
- for (const id of currentIds) {
4383
- if (!this.lastSentParticipantIds.has(id)) {
4384
- changed = true;
4385
- break;
4386
- }
4387
- }
4388
- }
4286
+ const changed = this.roster.changed();
4389
4287
  if (!changed && !this.participantsMessage) {
4390
4288
  return null;
4391
4289
  }
@@ -4395,15 +4293,9 @@ var ExecutionContext = class {
4395
4293
  this.participantsMessage = null;
4396
4294
  }
4397
4295
  if (changed) {
4398
- const asRecords = this.participants.map((p) => ({
4399
- id: p.id,
4400
- name: p.name,
4401
- type: p.type,
4402
- handle: p.handle ?? null
4403
- }));
4404
- parts.push(buildParticipantsMessage(asRecords));
4296
+ parts.push(buildParticipantsMessage(this.roster.list().map((p) => ({ ...toParticipantRecord(p) }))));
4405
4297
  }
4406
- this.lastSentParticipantIds = currentIds;
4298
+ this.roster.markSent();
4407
4299
  return parts.length > 0 ? parts.join("\n") : null;
4408
4300
  }
4409
4301
  consumeContactsMessage() {
@@ -4454,27 +4346,19 @@ var ExecutionContext = class {
4454
4346
  return fallback;
4455
4347
  }
4456
4348
  }
4457
- replaceParticipants(participants) {
4458
- this.participants.splice(0, this.participants.length, ...participants);
4459
- }
4460
4349
  buildLocalContext() {
4461
4350
  return {
4462
4351
  roomId: this.roomId,
4463
4352
  messages: this.getRawHistory(),
4464
- participants: [...this.participants],
4353
+ participants: this.roster.list().map(toParticipantRecord),
4465
4354
  hydratedAt: /* @__PURE__ */ new Date()
4466
4355
  };
4467
4356
  }
4468
4357
  async loadParticipants() {
4469
4358
  const participants = await this.link.rest.listChatParticipants(this.roomId, DEFAULT_REQUEST_OPTIONS);
4470
- const normalized = participants.map((participant) => ({
4471
- id: participant.id,
4472
- name: participant.name,
4473
- type: participant.type,
4474
- handle: participant.handle ?? null
4475
- }));
4476
- this.replaceParticipants(normalized);
4477
- return [...this.participants];
4359
+ const normalized = participants.map(toParticipantRecordFromRest);
4360
+ this.roster.setAll(normalized);
4361
+ return this.roster.list().map(toParticipantRecord);
4478
4362
  }
4479
4363
  async loadHydratedMessages() {
4480
4364
  const messages = [];
@@ -4516,7 +4400,7 @@ var ExecutionContext = class {
4516
4400
  if (!this.contextCache) {
4517
4401
  return;
4518
4402
  }
4519
- this.contextCache.participants = [...this.participants];
4403
+ this.contextCache.participants = this.roster.list().map(toParticipantRecord);
4520
4404
  this.contextCache.hydratedAt = /* @__PURE__ */ new Date();
4521
4405
  this.contextCacheExpiresAt = this.nextCacheExpiry();
4522
4406
  }
@@ -5162,14 +5046,6 @@ var ContactToolsImpl = class {
5162
5046
  };
5163
5047
 
5164
5048
  // src/runtime/tools/ContactCallbackTools.ts
5165
- function toParticipantRecord(participant) {
5166
- return {
5167
- id: participant.id,
5168
- name: participant.name,
5169
- type: participant.type,
5170
- handle: participant.handle ?? null
5171
- };
5172
- }
5173
5049
  function normalizePage(value, fallback) {
5174
5050
  return Number.isInteger(value) && value && value > 0 ? value : fallback;
5175
5051
  }
@@ -5213,8 +5089,7 @@ var ContactCallbackTools = class {
5213
5089
  {
5214
5090
  content,
5215
5091
  ...normalizedMentions ? { mentions: normalizedMentions } : {}
5216
- },
5217
- DEFAULT_REQUEST_OPTIONS
5092
+ }
5218
5093
  );
5219
5094
  }
5220
5095
  async sendEvent(content, messageType, metadata) {
@@ -5228,8 +5103,7 @@ var ContactCallbackTools = class {
5228
5103
  content,
5229
5104
  messageType,
5230
5105
  ...metadata ? { metadata } : {}
5231
- },
5232
- DEFAULT_REQUEST_OPTIONS
5106
+ }
5233
5107
  );
5234
5108
  }
5235
5109
  async addParticipant() {
@@ -5243,7 +5117,7 @@ var ContactCallbackTools = class {
5243
5117
  if (!this.rest.listChatParticipants) {
5244
5118
  throw new UnsupportedFeatureError("Participant listing is not available in current REST adapter");
5245
5119
  }
5246
- return (await this.rest.listChatParticipants(roomId, DEFAULT_REQUEST_OPTIONS)).map(toParticipantRecord);
5120
+ return (await this.rest.listChatParticipants(roomId, DEFAULT_REQUEST_OPTIONS)).map(toParticipantRecordFromRest);
5247
5121
  }
5248
5122
  async createChatroom(taskId) {
5249
5123
  const chat = await this.rest.createChat(taskId, DEFAULT_REQUEST_OPTIONS);
@@ -5333,48 +5207,48 @@ var ContactCallbackTools = class {
5333
5207
  }
5334
5208
  async executeToolCall(toolName, toolArgs) {
5335
5209
  switch (toolName) {
5336
- case "thenvoi_send_message":
5210
+ case "band_send_message":
5337
5211
  return this.sendMessage(
5338
5212
  String(toolArgs.content ?? ""),
5339
5213
  toolArgs.mentions
5340
5214
  );
5341
- case "thenvoi_send_event":
5215
+ case "band_send_event":
5342
5216
  return this.sendEvent(
5343
5217
  String(toolArgs.content ?? ""),
5344
5218
  String(toolArgs.message_type ?? "task"),
5345
5219
  toolArgs.metadata
5346
5220
  );
5347
- case "thenvoi_get_participants":
5221
+ case "band_get_participants":
5348
5222
  return this.getParticipants();
5349
- case "thenvoi_create_chatroom":
5223
+ case "band_create_chatroom":
5350
5224
  return this.createChatroom(typeof toolArgs.task_id === "string" ? toolArgs.task_id : void 0);
5351
- case "thenvoi_lookup_peers":
5225
+ case "band_lookup_peers":
5352
5226
  return this.lookupPeers(
5353
5227
  typeof toolArgs.page === "number" ? toolArgs.page : void 0,
5354
5228
  typeof toolArgs.page_size === "number" ? toolArgs.page_size : void 0
5355
5229
  );
5356
- case "thenvoi_list_contacts":
5230
+ case "band_list_contacts":
5357
5231
  return this.listContacts({
5358
5232
  page: typeof toolArgs.page === "number" ? toolArgs.page : void 0,
5359
5233
  pageSize: typeof toolArgs.page_size === "number" ? toolArgs.page_size : void 0
5360
5234
  });
5361
- case "thenvoi_add_contact":
5235
+ case "band_add_contact":
5362
5236
  return this.addContact({
5363
5237
  handle: String(toolArgs.handle ?? ""),
5364
5238
  ...typeof toolArgs.message === "string" ? { message: toolArgs.message } : {}
5365
5239
  });
5366
- case "thenvoi_remove_contact":
5240
+ case "band_remove_contact":
5367
5241
  if (typeof toolArgs.contact_id === "string") {
5368
5242
  return this.removeContact({ target: "contactId", contactId: toolArgs.contact_id });
5369
5243
  }
5370
5244
  return this.removeContact({ target: "handle", handle: String(toolArgs.handle ?? "") });
5371
- case "thenvoi_list_contact_requests":
5245
+ case "band_list_contact_requests":
5372
5246
  return this.listContactRequests({
5373
5247
  page: typeof toolArgs.page === "number" ? toolArgs.page : void 0,
5374
5248
  pageSize: typeof toolArgs.page_size === "number" ? toolArgs.page_size : void 0,
5375
5249
  sentStatus: typeof toolArgs.sent_status === "string" ? toolArgs.sent_status : void 0
5376
5250
  });
5377
- case "thenvoi_respond_contact_request":
5251
+ case "band_respond_contact_request":
5378
5252
  if (typeof toolArgs.request_id === "string") {
5379
5253
  return this.respondContactRequest({
5380
5254
  action: String(toolArgs.action ?? "approve"),
@@ -5387,15 +5261,15 @@ var ContactCallbackTools = class {
5387
5261
  target: "handle",
5388
5262
  handle: String(toolArgs.handle ?? "")
5389
5263
  });
5390
- case "thenvoi_list_memories":
5264
+ case "band_list_memories":
5391
5265
  return this.listMemories(toolArgs);
5392
- case "thenvoi_store_memory":
5266
+ case "band_store_memory":
5393
5267
  return this.storeMemory(toolArgs);
5394
- case "thenvoi_get_memory":
5268
+ case "band_get_memory":
5395
5269
  return this.getMemory(String(toolArgs.memory_id ?? ""));
5396
- case "thenvoi_supersede_memory":
5270
+ case "band_supersede_memory":
5397
5271
  return this.supersedeMemory(String(toolArgs.memory_id ?? ""));
5398
- case "thenvoi_archive_memory":
5272
+ case "band_archive_memory":
5399
5273
  return this.archiveMemory(String(toolArgs.memory_id ?? ""));
5400
5274
  default:
5401
5275
  throw new UnsupportedFeatureError(`Unsupported tool call for contact callback: ${toolName}`);
@@ -5409,14 +5283,14 @@ var HUB_ROOM_SYSTEM_PROMPT = `## OVERRIDE: Contact Management Mode
5409
5283
 
5410
5284
  This is your CONTACTS HUB - a dedicated room for managing contact requests.
5411
5285
 
5412
- **IMPORTANT: Do NOT delegate or add participants here.** You handle contact events DIRECTLY using the contact tools below. Do NOT call thenvoi_lookup_peers() or thenvoi_add_participant() in this room.
5286
+ **IMPORTANT: Do NOT delegate or add participants here.** You handle contact events DIRECTLY using the contact tools below. Do NOT call band_lookup_peers() or band_add_participant() in this room.
5413
5287
 
5414
5288
  ## Your Role
5415
5289
 
5416
5290
  1. **Review incoming contact requests** - When you see a [Contact Request] message, evaluate it
5417
5291
  2. **Take action** - Use the contact tools to respond:
5418
- - \`thenvoi_respond_contact_request(action="approve", request_id="...")\` to accept
5419
- - \`thenvoi_respond_contact_request(action="reject", request_id="...")\` to decline
5292
+ - \`band_respond_contact_request(action="approve", request_id="...")\` to accept
5293
+ - \`band_respond_contact_request(action="reject", request_id="...")\` to decline
5420
5294
  3. **Report your decision** - Send a thought event explaining what you did
5421
5295
 
5422
5296
  ## Example
@@ -5425,14 +5299,14 @@ This is your CONTACTS HUB - a dedicated room for managing contact requests.
5425
5299
  Request ID: abc-123
5426
5300
 
5427
5301
  Your response:
5428
- 1. thenvoi_send_event("Received contact request from Alice. Approving.", message_type="thought")
5429
- 2. thenvoi_respond_contact_request(action="approve", request_id="abc-123")
5430
- 3. thenvoi_send_event("Approved contact request from Alice (@alice)", message_type="thought")
5302
+ 1. band_send_event("Received contact request from Alice. Approving.", message_type="thought")
5303
+ 2. band_respond_contact_request(action="approve", request_id="abc-123")
5304
+ 3. band_send_event("Approved contact request from Alice (@alice)", message_type="thought")
5431
5305
 
5432
5306
  ## Contact Tools (use these, NOT participant tools)
5433
- - \`thenvoi_respond_contact_request(action, request_id)\` - Approve/reject requests
5434
- - \`thenvoi_list_contact_requests()\` - List pending requests
5435
- - \`thenvoi_list_contacts()\` - List current contacts`;
5307
+ - \`band_respond_contact_request(action, request_id)\` - Approve/reject requests
5308
+ - \`band_list_contact_requests()\` - List pending requests
5309
+ - \`band_list_contacts()\` - List current contacts`;
5436
5310
  var ContactEventHandlerError = class extends Error {
5437
5311
  retryable;
5438
5312
  stage;
@@ -5760,6 +5634,8 @@ function normalizeHandle(handle) {
5760
5634
  }
5761
5635
 
5762
5636
  // src/runtime/PlatformRuntime.ts
5637
+ var MAX_MESSAGE_RETRIES = 4294967295;
5638
+ var isValidRetryCount = (value) => Number.isInteger(value) && value >= 0 && value <= MAX_MESSAGE_RETRIES;
5763
5639
  var PlatformRuntime = class {
5764
5640
  _agentId;
5765
5641
  _apiKey;
@@ -5796,6 +5672,12 @@ var PlatformRuntime = class {
5796
5672
  "apiKey is required and must be a non-empty string. Use loadAgentConfig() to load credentials from agent_config.yaml."
5797
5673
  );
5798
5674
  }
5675
+ const maxMessageRetries = options.sessionConfig?.maxMessageRetries;
5676
+ if (maxMessageRetries !== void 0 && !isValidRetryCount(maxMessageRetries)) {
5677
+ throw new ValidationError(
5678
+ `sessionConfig.maxMessageRetries must be an integer between 0 and ${MAX_MESSAGE_RETRIES}, got ${maxMessageRetries}.`
5679
+ );
5680
+ }
5799
5681
  this._agentId = options.agentId;
5800
5682
  this._apiKey = options.apiKey;
5801
5683
  this._wsUrl = options.wsUrl;
@@ -5848,7 +5730,7 @@ var PlatformRuntime = class {
5848
5730
  }
5849
5731
  async doInitialize() {
5850
5732
  if (!this.linkInstance) {
5851
- this.linkInstance = new ThenvoiLink({
5733
+ this.linkInstance = new BandLink({
5852
5734
  ...this.linkOptions,
5853
5735
  agentId: this._agentId,
5854
5736
  apiKey: this._apiKey,
@@ -6183,7 +6065,21 @@ var import_node_fs = require("fs");
6183
6065
  var import_js_yaml = __toESM(require("js-yaml"), 1);
6184
6066
  init_errors();
6185
6067
  var DEFAULT_CONFIG_PATH = "./agent_config.yaml";
6186
- var DEFAULT_ENV_PREFIX = "THENVOI_";
6068
+ var DEFAULT_ENV_PREFIX = "BAND_";
6069
+ var LEGACY_ENV_PREFIX = "THENVOI_";
6070
+ var _warnedLegacyEnvVars = /* @__PURE__ */ new Set();
6071
+ function readBandFirstEnv(env, field) {
6072
+ const bandVar = `${DEFAULT_ENV_PREFIX}${field}`;
6073
+ const bandValue = env[bandVar];
6074
+ if (bandValue !== void 0) return bandValue;
6075
+ const legacyVar = `${LEGACY_ENV_PREFIX}${field}`;
6076
+ const legacyValue = env[legacyVar];
6077
+ if (legacyValue !== void 0 && !_warnedLegacyEnvVars.has(legacyVar)) {
6078
+ _warnedLegacyEnvVars.add(legacyVar);
6079
+ console.warn(`[band] ${legacyVar} is deprecated; use ${bandVar} instead`);
6080
+ }
6081
+ return legacyValue;
6082
+ }
6187
6083
  var REQUIRED_FIELDS = ["agent_id", "api_key"];
6188
6084
  var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype", "toString", "valueOf"]);
6189
6085
  function toSnakeCase(key) {
@@ -6267,19 +6163,32 @@ function loadAgentConfig(agentKey, configPath) {
6267
6163
  }
6268
6164
  function loadAgentConfigFromEnv(options) {
6269
6165
  const env = options?.env ?? process.env;
6270
- const prefix = options?.prefix === void 0 ? DEFAULT_ENV_PREFIX : options.prefix === "" || options.prefix.endsWith("_") ? options.prefix : `${options.prefix}_`;
6271
- const section = normalizeKeys({
6272
- agent_id: env[`${prefix}AGENT_ID`],
6273
- api_key: env[`${prefix}API_KEY`],
6274
- ws_url: env[`${prefix}WS_URL`],
6275
- rest_url: env[`${prefix}REST_URL`]
6276
- });
6166
+ let section;
6167
+ let requiredHint;
6168
+ if (options?.prefix === void 0) {
6169
+ section = normalizeKeys({
6170
+ agent_id: readBandFirstEnv(env, "AGENT_ID"),
6171
+ api_key: readBandFirstEnv(env, "API_KEY"),
6172
+ ws_url: readBandFirstEnv(env, "WS_URL"),
6173
+ rest_url: readBandFirstEnv(env, "REST_URL")
6174
+ });
6175
+ requiredHint = `${DEFAULT_ENV_PREFIX}AGENT_ID and ${DEFAULT_ENV_PREFIX}API_KEY (legacy ${LEGACY_ENV_PREFIX}* still accepted)`;
6176
+ } else {
6177
+ const prefix = options.prefix === "" || options.prefix.endsWith("_") ? options.prefix : `${options.prefix}_`;
6178
+ section = normalizeKeys({
6179
+ agent_id: env[`${prefix}AGENT_ID`],
6180
+ api_key: env[`${prefix}API_KEY`],
6181
+ ws_url: env[`${prefix}WS_URL`],
6182
+ rest_url: env[`${prefix}REST_URL`]
6183
+ });
6184
+ requiredHint = `${prefix}AGENT_ID and ${prefix}API_KEY`;
6185
+ }
6277
6186
  try {
6278
- return toAgentConfigResult(section, `environment variables (${prefix}AGENT_ID, ${prefix}API_KEY)`);
6187
+ return toAgentConfigResult(section, `environment variables (${requiredHint})`);
6279
6188
  } catch (error) {
6280
6189
  if (error instanceof ValidationError) {
6281
6190
  throw new ValidationError(
6282
- `${error.message}. Set ${prefix}AGENT_ID and ${prefix}API_KEY, or use loadAgentConfig() for agent_config.yaml.`
6191
+ `${error.message}. Set ${requiredHint}, or use loadAgentConfig() for agent_config.yaml.`
6283
6192
  );
6284
6193
  }
6285
6194
  throw error;
@@ -6363,19 +6272,19 @@ var ENVIRONMENT_SECTION = `
6363
6272
 
6364
6273
  Multi-participant chat. Messages show sender: [Name]: content.
6365
6274
  Messages prefixed with [System]: are platform updates (participant changes, contact updates, etc.) \u2014 not messages from users.
6366
- Use \`thenvoi_send_message(content, mentions)\` to respond. Plain text output is not delivered.
6275
+ Use \`band_send_message(content, mentions)\` to respond. Plain text output is not delivered.
6367
6276
  Mentions use handles: @<username> for users, @<username>/<agent-name> for agents.`;
6368
6277
  var MULTI_AGENT_RULES_SECTION = `## CRITICAL: Delegate When You Cannot Help Directly
6369
6278
 
6370
6279
  You have NO internet access and NO real-time data. When asked about weather, news, stock prices,
6371
6280
  or any current information you cannot answer directly:
6372
6281
 
6373
- 1. Call \`thenvoi_lookup_peers()\` to find available specialized agents
6374
- 2. If a relevant agent exists, call \`thenvoi_add_participant(name)\` to add them
6375
- 3. Ask that agent using \`thenvoi_send_message(question, mentions=[agent_handle])\`
6282
+ 1. Call \`band_lookup_peers()\` to find available specialized agents
6283
+ 2. If a relevant agent exists, call \`band_add_participant(name)\` to add them
6284
+ 3. Ask that agent using \`band_send_message(question, mentions=[agent_handle])\`
6376
6285
  4. Wait for their response and relay it back to the user
6377
6286
 
6378
- NEVER say "I can't do that" without first checking if another agent can help via \`thenvoi_lookup_peers()\`.
6287
+ NEVER say "I can't do that" without first checking if another agent can help via \`band_lookup_peers()\`.
6379
6288
 
6380
6289
  ## CRITICAL: Do NOT Remove Agents Automatically
6381
6290
 
@@ -6394,42 +6303,42 @@ When someone asks you to get information from another agent:
6394
6303
  3. Do NOT just thank the helper agent - the requester is waiting for their answer!`;
6395
6304
  var THINKING_SECTION = `## IMPORTANT: Always Share Your Thinking
6396
6305
 
6397
- You MUST call \`thenvoi_send_event(content, message_type="thought")\` BEFORE every action.
6306
+ You MUST call \`band_send_event(content, message_type="thought")\` BEFORE every action.
6398
6307
  This is required so users can see your reasoning process.`;
6399
6308
  var EXAMPLES_SECTION = `## Examples
6400
6309
 
6401
6310
  ### Simple question - answer directly
6402
6311
  [John Doe]: What's 2+2?
6403
- -> thenvoi_send_event("Simple arithmetic, answering directly.", message_type="thought")
6404
- -> thenvoi_send_message("4", mentions=["@john"])
6312
+ -> band_send_event("Simple arithmetic, answering directly.", message_type="thought")
6313
+ -> band_send_message("4", mentions=["@john"])
6405
6314
 
6406
6315
  ### User asks about weather (you cannot answer directly)
6407
6316
  [John Doe]: What's the weather in Tokyo?
6408
- -> thenvoi_send_event("I can't check weather directly. Looking for a Weather Agent.", message_type="thought")
6409
- -> thenvoi_lookup_peers()
6410
- -> thenvoi_send_event("Found Weather Agent. Adding to room.", message_type="thought")
6411
- -> thenvoi_add_participant("Weather Agent")
6412
- -> thenvoi_send_message("What's the weather in Tokyo?", mentions=["@john/weather-agent"])
6317
+ -> band_send_event("I can't check weather directly. Looking for a Weather Agent.", message_type="thought")
6318
+ -> band_lookup_peers()
6319
+ -> band_send_event("Found Weather Agent. Adding to room.", message_type="thought")
6320
+ -> band_add_participant("Weather Agent")
6321
+ -> band_send_message("What's the weather in Tokyo?", mentions=["@john/weather-agent"])
6413
6322
 
6414
6323
  [Weather Agent]: Tokyo is 15\xB0C and cloudy.
6415
- -> thenvoi_send_event("Got weather response. Relaying back to John Doe.", message_type="thought")
6416
- -> thenvoi_send_message("The weather in Tokyo is 15\xB0C and cloudy.", mentions=["@john"])
6324
+ -> band_send_event("Got weather response. Relaying back to John Doe.", message_type="thought")
6325
+ -> band_send_message("The weather in Tokyo is 15\xB0C and cloudy.", mentions=["@john"])
6417
6326
 
6418
6327
  ### No suitable agent available
6419
6328
  [John Doe]: What's the stock price of AAPL?
6420
- -> thenvoi_send_event("I can't check stock prices. Looking for a Stock Agent.", message_type="thought")
6421
- -> thenvoi_lookup_peers()
6422
- -> thenvoi_send_event("No stock agent available. Must inform user.", message_type="thought")
6423
- -> thenvoi_send_message("I don't have access to stock prices, and there's no specialized agent available to help with that.", mentions=["@john"])
6329
+ -> band_send_event("I can't check stock prices. Looking for a Stock Agent.", message_type="thought")
6330
+ -> band_lookup_peers()
6331
+ -> band_send_event("No stock agent available. Must inform user.", message_type="thought")
6332
+ -> band_send_message("I don't have access to stock prices, and there's no specialized agent available to help with that.", mentions=["@john"])
6424
6333
 
6425
6334
  ### Follow-up question in same conversation
6426
6335
  [John Doe]: What about London?
6427
- -> thenvoi_send_event("Follow-up weather question. Asking Weather Agent.", message_type="thought")
6428
- -> thenvoi_send_message("What's the weather in London?", mentions=["@john/weather-agent"])
6336
+ -> band_send_event("Follow-up weather question. Asking Weather Agent.", message_type="thought")
6337
+ -> band_send_message("What's the weather in London?", mentions=["@john/weather-agent"])
6429
6338
 
6430
6339
  [Weather Agent]: London is 8\xB0C and rainy.
6431
- -> thenvoi_send_event("Got London weather. Relaying to John Doe.", message_type="thought")
6432
- -> thenvoi_send_message("London is 8\xB0C and rainy.", mentions=["@john"])`;
6340
+ -> band_send_event("Got London weather. Relaying to John Doe.", message_type="thought")
6341
+ -> band_send_message("London is 8\xB0C and rainy.", mentions=["@john"])`;
6433
6342
  var BASE_INSTRUCTIONS = [
6434
6343
  ENVIRONMENT_SECTION,
6435
6344
  MULTI_AGENT_RULES_SECTION,
@@ -6443,10 +6352,10 @@ init_schemas();
6443
6352
  var MEMORY_INTRO = `## Memory Tools
6444
6353
 
6445
6354
  You have access to memory tools for storing and retrieving information
6446
- across conversations. Use \`thenvoi_store_memory\` to persist important
6447
- information and \`thenvoi_list_memories\` / \`thenvoi_get_memory\` to recall it.
6448
- Use \`thenvoi_supersede_memory\` to mark outdated memories and
6449
- \`thenvoi_archive_memory\` to hide memories that should be preserved.`;
6355
+ across conversations. Use \`band_store_memory\` to persist important
6356
+ information and \`band_list_memories\` / \`band_get_memory\` to recall it.
6357
+ Use \`band_supersede_memory\` to mark outdated memories and
6358
+ \`band_archive_memory\` to hide memories that should be preserved.`;
6450
6359
  function longTermPattern(label, type, segment, scope) {
6451
6360
  return {
6452
6361
  label,
@@ -6471,7 +6380,7 @@ var MEMORY_COMMON_PATTERNS = [
6471
6380
  ].join("\n");
6472
6381
  var MEMORY_SCOPE_GUIDANCE = `Prefer \`scope="${MEMORY_STORE_SCOPE.subject}"\` whenever the memory is about a specific person or agent, so it
6473
6382
  stays attached to that subject rather than leaking org-wide. Storing with \`scope="${MEMORY_STORE_SCOPE.subject}"\` requires a
6474
- real \`subject_id\` UUID, so resolve it first via \`thenvoi_lookup_peers\` or the participant list.
6383
+ real \`subject_id\` UUID, so resolve it first via \`band_lookup_peers\` or the participant list.
6475
6384
  Reserve \`scope="${MEMORY_STORE_SCOPE.organization}"\` for knowledge that is genuinely shared across the whole organization and
6476
6385
  is not about any one subject.`;
6477
6386
  function quoteChoices(values) {
@@ -6481,11 +6390,11 @@ function memoryTypeLines() {
6481
6390
  return Object.entries(MEMORY_SYSTEM_TYPES).map(([system, types]) => ` - ${system}: ${quoteChoices(types)}`).join("\n");
6482
6391
  }
6483
6392
  function buildMemorySection() {
6484
- const storeMemoryProps = TOOL_MODELS.thenvoi_store_memory.properties;
6393
+ const storeMemoryProps = TOOL_MODELS.band_store_memory.properties;
6485
6394
  const systems = storeMemoryProps.system.enum;
6486
6395
  const segments = storeMemoryProps.segment.enum;
6487
6396
  const scopes = storeMemoryProps.scope.enum;
6488
- const fieldRules = `When calling \`thenvoi_store_memory\`, the \`system\`, \`type\`, \`segment\`, and \`scope\` fields
6397
+ const fieldRules = `When calling \`band_store_memory\`, the \`system\`, \`type\`, \`segment\`, and \`scope\` fields
6489
6398
  must use these exact values (case-sensitive):
6490
6399
 
6491
6400
  - **system**: ${quoteChoices(systems)}
@@ -6525,6 +6434,9 @@ ${customSection}`.trim();
6525
6434
  return parts.join("\n\n");
6526
6435
  }
6527
6436
 
6437
+ // src/adapters/codex/CodexAdapter.ts
6438
+ init_schemas();
6439
+
6528
6440
  // src/runtime/tools/customTools.ts
6529
6441
  var import_zod3 = require("zod");
6530
6442
  var import_zod_to_json_schema = require("zod-to-json-schema");
@@ -6948,8 +6860,8 @@ var CODEX_WEB_SEARCH_MODES = ["disabled", "cached", "live"];
6948
6860
  var CODEX_REASONING_SUMMARIES = ["auto", "concise", "detailed", "none"];
6949
6861
  var CODEX_REASONING_EFFORTS = ["low", "medium", "high", "xhigh"];
6950
6862
  var SILENT_REPORTING_TOOLS = /* @__PURE__ */ new Set([
6951
- "thenvoi_send_message",
6952
- "thenvoi_send_event"
6863
+ SEND_MESSAGE_TOOL_NAME,
6864
+ SEND_EVENT_TOOL_NAME
6953
6865
  ]);
6954
6866
  var CodexAdapter = class extends SimpleAdapter {
6955
6867
  baseConfig;
@@ -6979,8 +6891,8 @@ var CodexAdapter = class extends SimpleAdapter {
6979
6891
  includeBaseInstructions: true,
6980
6892
  experimentalApi: true,
6981
6893
  fallbackSendAgentText: true,
6982
- clientName: "thenvoi_codex_adapter",
6983
- clientTitle: "Thenvoi Codex Adapter",
6894
+ clientName: "band_codex_adapter",
6895
+ clientTitle: "Band Codex Adapter",
6984
6896
  clientVersion: "0.1.0",
6985
6897
  turnTimeoutMs: 18e4,
6986
6898
  ...options?.config
@@ -7246,8 +7158,8 @@ var CodexAdapter = class extends SimpleAdapter {
7246
7158
  await client.connect();
7247
7159
  await client.initialize({
7248
7160
  clientInfo: {
7249
- name: this.baseConfig.clientName ?? "thenvoi_codex_adapter",
7250
- title: this.baseConfig.clientTitle ?? "Thenvoi Codex Adapter",
7161
+ name: this.baseConfig.clientName ?? "band_codex_adapter",
7162
+ title: this.baseConfig.clientTitle ?? "Band Codex Adapter",
7251
7163
  version: this.baseConfig.clientVersion ?? "0.1.0"
7252
7164
  },
7253
7165
  capabilities: {
@@ -7520,7 +7432,7 @@ var CodexAdapter = class extends SimpleAdapter {
7520
7432
  tool_call_id: callId
7521
7433
  }), "tool_result");
7522
7434
  }
7523
- return !isError && toolName === "thenvoi_send_message";
7435
+ return !isError && toolName === SEND_MESSAGE_TOOL_NAME;
7524
7436
  } catch (error) {
7525
7437
  const output = {
7526
7438
  ok: false,
@@ -9245,7 +9157,7 @@ var GoogleADKHistoryConverter = class {
9245
9157
  };
9246
9158
 
9247
9159
  // src/adapters/google-adk/GoogleADKAdapter.ts
9248
- var APP_NAME = "thenvoi";
9160
+ var APP_NAME = "band";
9249
9161
  var DEFAULT_MAX_HISTORY_MESSAGES = 50;
9250
9162
  var DEFAULT_MAX_TRANSCRIPT_CHARS = 1e5;
9251
9163
  var MAX_TOOL_OUTPUT_PREVIEW = 200;
@@ -9419,7 +9331,7 @@ var GoogleADKAdapter = class extends SimpleAdapter {
9419
9331
  }
9420
9332
  buildAgent(sdk, tools) {
9421
9333
  return sdk.createAgent({
9422
- name: this.agentName || "thenvoi_agent",
9334
+ name: this.agentName || "band_agent",
9423
9335
  model: this.model,
9424
9336
  instruction: this.systemPrompt,
9425
9337
  tools: this.buildTools(sdk, tools)
@@ -10782,7 +10694,7 @@ function buildAgentCard(peer, gatewayUrl) {
10782
10694
  id: "default",
10783
10695
  name: peer.name,
10784
10696
  description: peer.description,
10785
- tags: ["thenvoi", "gateway"]
10697
+ tags: ["band", "gateway"]
10786
10698
  }
10787
10699
  ],
10788
10700
  defaultInputModes: ["text/plain"],
@@ -10964,7 +10876,7 @@ var DEFAULT_RESPONSE_TIMEOUT_MS = 12e4;
10964
10876
  var DEFAULT_PEER_PAGE_SIZE = 100;
10965
10877
  var DEFAULT_MAX_PEER_PAGES = 25;
10966
10878
  var A2AGatewayAdapter = class extends SimpleAdapter {
10967
- thenvoiRest;
10879
+ bandRest;
10968
10880
  gatewayUrl;
10969
10881
  host;
10970
10882
  port;
@@ -10985,7 +10897,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
10985
10897
  super({
10986
10898
  historyConverter: new GatewayHistoryConverter()
10987
10899
  });
10988
- this.thenvoiRest = options.thenvoiRest;
10900
+ this.bandRest = options.bandRest;
10989
10901
  this.gatewayUrl = options.gatewayUrl ?? DEFAULT_GATEWAY_URL;
10990
10902
  this.host = options.host ?? DEFAULT_HOST;
10991
10903
  this.port = options.port ?? DEFAULT_PORT;
@@ -11065,13 +10977,13 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
11065
10977
  async refreshPeers() {
11066
10978
  this.peersBySlug.clear();
11067
10979
  this.peersById.clear();
11068
- if (!this.thenvoiRest.listPeers) {
10980
+ if (!this.bandRest.listPeers) {
11069
10981
  throw new UnsupportedFeatureError(
11070
10982
  "Peer listing is not available in current REST adapter"
11071
10983
  );
11072
10984
  }
11073
10985
  for (let page = 1; page <= this.maxPeerPages; page += 1) {
11074
- const response = await this.thenvoiRest.listPeers({
10986
+ const response = await this.bandRest.listPeers({
11075
10987
  page,
11076
10988
  pageSize: this.peerPageSize,
11077
10989
  notInChat: ""
@@ -11141,7 +11053,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
11141
11053
  try {
11142
11054
  await this.emitContextEvent(roomId, contextId);
11143
11055
  const content = extractMessageText2(request.message) ?? "";
11144
- await this.thenvoiRest.createChatMessage(roomId, {
11056
+ await this.bandRest.createChatMessage(roomId, {
11145
11057
  content: buildMentionedContent(peer.name, content),
11146
11058
  mentions: buildMentions(peer),
11147
11059
  metadata: {
@@ -11172,7 +11084,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
11172
11084
  contextId: pending.contextId,
11173
11085
  state: "failed",
11174
11086
  final: true,
11175
- text: "Timed out waiting for a Thenvoi peer response."
11087
+ text: "Timed out waiting for a Band peer response."
11176
11088
  });
11177
11089
  return;
11178
11090
  }
@@ -11259,7 +11171,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
11259
11171
  if (existingRoom) {
11260
11172
  const participants = this.roomParticipants.get(existingRoom) ?? /* @__PURE__ */ new Set();
11261
11173
  if (!participants.has(targetPeerId)) {
11262
- await this.thenvoiRest.addChatParticipant(existingRoom, {
11174
+ await this.bandRest.addChatParticipant(existingRoom, {
11263
11175
  participantId: targetPeerId,
11264
11176
  role: "member"
11265
11177
  });
@@ -11269,11 +11181,11 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
11269
11181
  return [existingRoom, contextId];
11270
11182
  }
11271
11183
  const normalizedContextId = contextId && contextId.length > 0 ? contextId : (0, import_node_crypto5.randomUUID)();
11272
- const created = await this.thenvoiRest.createChat(
11184
+ const created = await this.bandRest.createChat(
11273
11185
  `a2a:gateway:${normalizedContextId}`
11274
11186
  );
11275
11187
  const roomId = created.id;
11276
- await this.thenvoiRest.addChatParticipant(roomId, {
11188
+ await this.bandRest.addChatParticipant(roomId, {
11277
11189
  participantId: targetPeerId,
11278
11190
  role: "member"
11279
11191
  });
@@ -11282,7 +11194,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
11282
11194
  return [roomId, normalizedContextId];
11283
11195
  }
11284
11196
  async emitContextEvent(roomId, contextId) {
11285
- await this.thenvoiRest.createChatEvent(roomId, {
11197
+ await this.bandRest.createChatEvent(roomId, {
11286
11198
  content: "A2A gateway context",
11287
11199
  messageType: "task",
11288
11200
  metadata: {
@@ -11460,10 +11372,10 @@ function toStatusUpdateEvent(message, taskId, contextId) {
11460
11372
  final,
11461
11373
  text: message.content,
11462
11374
  metadata: {
11463
- thenvoi_message_id: message.id,
11464
- thenvoi_message_type: message.messageType,
11465
- thenvoi_sender_id: message.senderId,
11466
- thenvoi_room_id: message.roomId
11375
+ band_message_id: message.id,
11376
+ band_message_type: message.messageType,
11377
+ band_sender_id: message.senderId,
11378
+ band_room_id: message.roomId
11467
11379
  }
11468
11380
  });
11469
11381
  }
@@ -11633,8 +11545,8 @@ var ParlantAdapter = class extends SimpleAdapter {
11633
11545
  message: userMessage,
11634
11546
  moderation: "none",
11635
11547
  metadata: {
11636
- thenvoi_source: "thenvoi-sdk-typescript",
11637
- thenvoi_room_id: context.roomId
11548
+ band_source: "band-sdk-typescript",
11549
+ band_room_id: context.roomId
11638
11550
  }
11639
11551
  },
11640
11552
  this.requestOptions()
@@ -11709,9 +11621,9 @@ var ParlantAdapter = class extends SimpleAdapter {
11709
11621
  {
11710
11622
  agentId: this.agentId,
11711
11623
  customerId,
11712
- title: `Thenvoi Room ${roomId.slice(0, 8)}`,
11624
+ title: `Band Room ${roomId.slice(0, 8)}`,
11713
11625
  metadata: {
11714
- thenvoi_room_id: roomId
11626
+ band_room_id: roomId
11715
11627
  }
11716
11628
  },
11717
11629
  this.requestOptions()
@@ -11724,7 +11636,7 @@ var ParlantAdapter = class extends SimpleAdapter {
11724
11636
  source: "system",
11725
11637
  message: this.systemPrompt,
11726
11638
  metadata: {
11727
- thenvoi_system_prompt: true
11639
+ band_system_prompt: true
11728
11640
  }
11729
11641
  },
11730
11642
  this.requestOptions()
@@ -11778,7 +11690,7 @@ var ParlantAdapter = class extends SimpleAdapter {
11778
11690
  {
11779
11691
  name: customerName,
11780
11692
  metadata: {
11781
- thenvoi_room_id: roomId
11693
+ band_room_id: roomId
11782
11694
  }
11783
11695
  },
11784
11696
  this.requestOptions()
@@ -12328,7 +12240,7 @@ var LettaAdapter = class extends SimpleAdapter {
12328
12240
  const agent = await this.raceTimeout(
12329
12241
  (s) => client.agents.create(
12330
12242
  {
12331
- name: `thenvoi-room-${roomId.slice(0, 16)}`,
12243
+ name: `band-room-${roomId.slice(0, 16)}`,
12332
12244
  model: this.model,
12333
12245
  ...this.embedding ? { embedding: this.embedding } : {},
12334
12246
  system: this.systemPrompt || void 0,
@@ -12742,10 +12654,31 @@ async function loadLettaClientFactory(config) {
12742
12654
  init_schemas();
12743
12655
  init_registrations();
12744
12656
 
12657
+ // src/mcp/auth.ts
12658
+ var import_node_crypto6 = require("crypto");
12659
+ function generateAuthToken() {
12660
+ return (0, import_node_crypto6.randomBytes)(32).toString("hex");
12661
+ }
12662
+ function isAuthorizedRequest(authorizationHeader, authToken) {
12663
+ if (!authToken) {
12664
+ return true;
12665
+ }
12666
+ if (!authorizationHeader) {
12667
+ return false;
12668
+ }
12669
+ const expected = Buffer.from(`Bearer ${authToken}`);
12670
+ const actual = Buffer.from(authorizationHeader);
12671
+ if (expected.length !== actual.length) {
12672
+ return false;
12673
+ }
12674
+ return (0, import_node_crypto6.timingSafeEqual)(expected, actual);
12675
+ }
12676
+
12745
12677
  // src/mcp/stdio.ts
12746
12678
  init_registrations();
12747
12679
  init_zod();
12748
- var ThenvoiMcpStdioServer = class {
12680
+ init_schemas();
12681
+ var BandMcpStdioServer = class {
12749
12682
  options;
12750
12683
  registrations;
12751
12684
  mcpServer = null;
@@ -12774,7 +12707,7 @@ var ThenvoiMcpStdioServer = class {
12774
12707
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
12775
12708
  const { z: z6 } = await import("zod");
12776
12709
  const mcpServer = new McpServer({
12777
- name: this.options.name ?? "thenvoi",
12710
+ name: this.options.name ?? MCP_SERVER_NAME,
12778
12711
  version: "1.0.0"
12779
12712
  });
12780
12713
  registerTools(mcpServer, z6, this.registrations);
@@ -12807,12 +12740,13 @@ function registerTools(mcpServer, z6, registrations) {
12807
12740
  // src/mcp/server.ts
12808
12741
  init_registrations();
12809
12742
  init_zod();
12743
+ init_schemas();
12810
12744
  var PORT_RANGE_START = 5e4;
12811
12745
  var PORT_RANGE_END = 6e4;
12812
12746
  var MCP_SERVER_VERSION = "1.0.0";
12813
12747
  var SESSION_IDLE_TTL_MS = 15 * 60 * 1e3;
12814
12748
  var SESSION_SWEEP_INTERVAL_MS = 60 * 1e3;
12815
- var ThenvoiMcpServer = class {
12749
+ var BandMcpServer = class {
12816
12750
  options;
12817
12751
  registrations;
12818
12752
  httpServer = null;
@@ -12856,7 +12790,7 @@ var ThenvoiMcpServer = class {
12856
12790
  const http = await import("http");
12857
12791
  const { randomUUID: randomUUID6 } = await import("crypto");
12858
12792
  const { z: z6 } = await import("zod");
12859
- const serverName = this.options.name ?? "thenvoi";
12793
+ const serverName = this.options.name ?? MCP_SERVER_NAME;
12860
12794
  const app = express();
12861
12795
  app.use(express.json());
12862
12796
  app.get("/healthz", (_req, res) => {
@@ -12864,6 +12798,10 @@ var ThenvoiMcpServer = class {
12864
12798
  });
12865
12799
  const handleMcpRequest = async (req, res) => {
12866
12800
  try {
12801
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
12802
+ sendMcpError(res, 401, "Unauthorized");
12803
+ return;
12804
+ }
12867
12805
  const sessionId = getSessionIdHeader(req.headers["mcp-session-id"]);
12868
12806
  let session = sessionId ? this.sessions.get(sessionId) : void 0;
12869
12807
  if (!session) {
@@ -13039,11 +12977,12 @@ function checkPort(http, port) {
13039
12977
  // src/mcp/sse.ts
13040
12978
  init_registrations();
13041
12979
  init_zod();
12980
+ init_schemas();
13042
12981
  var PORT_RANGE_START2 = 5e4;
13043
12982
  var PORT_RANGE_END2 = 6e4;
13044
12983
  var SESSION_IDLE_TTL_MS2 = 15 * 60 * 1e3;
13045
12984
  var SESSION_SWEEP_INTERVAL_MS2 = 60 * 1e3;
13046
- var ThenvoiMcpSseServer = class {
12985
+ var BandMcpSseServer = class {
13047
12986
  options;
13048
12987
  registrations;
13049
12988
  httpServer = null;
@@ -13090,10 +13029,14 @@ var ThenvoiMcpSseServer = class {
13090
13029
  app.get("/healthz", (_req, res) => {
13091
13030
  res.json({ status: "ok" });
13092
13031
  });
13093
- app.get("/sse", async (_req, res) => {
13032
+ app.get("/sse", async (req, res) => {
13033
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
13034
+ res.status(401).send("Unauthorized");
13035
+ return;
13036
+ }
13094
13037
  const transport = new SSEServerTransport("/messages", res);
13095
13038
  const mcpServer = new McpServer({
13096
- name: this.options.name ?? "thenvoi",
13039
+ name: this.options.name ?? MCP_SERVER_NAME,
13097
13040
  version: "1.0.0"
13098
13041
  });
13099
13042
  registerTools3(mcpServer, z6, this.registrations);
@@ -13115,6 +13058,10 @@ var ThenvoiMcpSseServer = class {
13115
13058
  });
13116
13059
  });
13117
13060
  app.post("/messages", async (req, res) => {
13061
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
13062
+ res.status(401).send("Unauthorized");
13063
+ return;
13064
+ }
13118
13065
  const sessionId = typeof req.query.sessionId === "string" ? req.query.sessionId : null;
13119
13066
  if (!sessionId) {
13120
13067
  res.status(400).send("Missing sessionId");
@@ -13228,15 +13175,15 @@ function checkPort2(http, port) {
13228
13175
  }
13229
13176
 
13230
13177
  // src/mcp/backends.ts
13231
- async function createThenvoiMcpBackend(options) {
13178
+ async function createBandMcpBackend(options) {
13232
13179
  const registrationOptions = {
13233
13180
  enableMemoryTools: options.enableMemoryTools,
13234
13181
  enableContactTools: true,
13235
13182
  additionalTools: options.additionalTools
13236
13183
  };
13237
13184
  if (options.kind === "sdk") {
13238
- const { createThenvoiSdkMcpServer: createThenvoiSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
13239
- const server2 = createThenvoiSdkMcpServer2({
13185
+ const { createBandSdkMcpServer: createBandSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
13186
+ const server2 = createBandSdkMcpServer2({
13240
13187
  getToolsForRoom: options.getToolsForRoom,
13241
13188
  multiRoom: options.multiRoom,
13242
13189
  enableMemoryTools: options.enableMemoryTools,
@@ -13253,7 +13200,7 @@ async function createThenvoiMcpBackend(options) {
13253
13200
  const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolvedTools, registrationOptions) : buildRoomScopedRegistrations(resolvedTools, registrationOptions);
13254
13201
  const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
13255
13202
  if (options.kind === "stdio") {
13256
- const server2 = new ThenvoiMcpStdioServer({
13203
+ const server2 = new BandMcpStdioServer({
13257
13204
  tools: resolvedTools,
13258
13205
  enableMemoryTools: options.enableMemoryTools,
13259
13206
  enableContactTools: true,
@@ -13269,34 +13216,39 @@ async function createThenvoiMcpBackend(options) {
13269
13216
  }
13270
13217
  };
13271
13218
  }
13219
+ const authToken = generateAuthToken();
13272
13220
  if (options.kind === "sse") {
13273
- const server2 = new ThenvoiMcpSseServer({
13221
+ const server2 = new BandMcpSseServer({
13274
13222
  tools: resolvedTools,
13275
13223
  enableMemoryTools: options.enableMemoryTools,
13276
13224
  enableContactTools: true,
13277
- additionalTools: options.additionalTools
13225
+ additionalTools: options.additionalTools,
13226
+ authToken
13278
13227
  });
13279
13228
  await server2.start();
13280
13229
  return {
13281
13230
  kind: "sse",
13282
13231
  server: server2,
13283
13232
  allowedTools,
13233
+ authToken,
13284
13234
  stop: async () => {
13285
13235
  await server2.stop();
13286
13236
  }
13287
13237
  };
13288
13238
  }
13289
- const server = new ThenvoiMcpServer({
13239
+ const server = new BandMcpServer({
13290
13240
  tools: resolvedTools,
13291
13241
  enableMemoryTools: options.enableMemoryTools,
13292
13242
  enableContactTools: true,
13293
- additionalTools: options.additionalTools
13243
+ additionalTools: options.additionalTools,
13244
+ authToken
13294
13245
  });
13295
13246
  await server.start();
13296
13247
  return {
13297
13248
  kind: "http",
13298
13249
  server,
13299
13250
  allowedTools,
13251
+ authToken,
13300
13252
  stop: async () => {
13301
13253
  await server.stop();
13302
13254
  }
@@ -13305,6 +13257,7 @@ async function createThenvoiMcpBackend(options) {
13305
13257
 
13306
13258
  // src/adapters/opencode/OpencodeAdapter.ts
13307
13259
  init_registrations();
13260
+ init_schemas();
13308
13261
 
13309
13262
  // src/converters/opencode.ts
13310
13263
  var OpencodeHistoryConverter = class {
@@ -13438,7 +13391,7 @@ var SdkOpencodeClientBase = class {
13438
13391
  const result = await runtime.client.mcp.add({
13439
13392
  ...this.scope(),
13440
13393
  name: input.name,
13441
- config: { type: "remote", url: input.url }
13394
+ config: { type: "remote", url: input.url, headers: input.headers }
13442
13395
  });
13443
13396
  return expectRecord(result);
13444
13397
  }
@@ -13629,8 +13582,8 @@ async function readResponseBody2(response) {
13629
13582
 
13630
13583
  // src/adapters/opencode/OpencodeAdapter.ts
13631
13584
  var OPENCODE_SYSTEM_NOTE = [
13632
- "Responses are relayed back into the Thenvoi room by the adapter.",
13633
- "Use the thenvoi_ prefixed tools (for example thenvoi_send_message) for Thenvoi platform actions when available.",
13585
+ "Responses are relayed back into the Band room by the adapter.",
13586
+ "Use the band_ prefixed tools (for example band_send_message) for Band platform actions when available.",
13634
13587
  "When you need approval or clarification, ask clearly and wait for the user's next room message."
13635
13588
  ].join("\n");
13636
13589
  function createDeferred() {
@@ -13661,8 +13614,8 @@ function withDefaults(config) {
13661
13614
  approvalTimeoutReply: "reject",
13662
13615
  questionMode: "manual",
13663
13616
  questionWaitTimeoutMs: 3e5,
13664
- sessionTitlePrefix: "Thenvoi",
13665
- mcpServerName: "thenvoi",
13617
+ sessionTitlePrefix: "Band",
13618
+ mcpServerName: MCP_SERVER_NAME,
13666
13619
  ...config
13667
13620
  };
13668
13621
  }
@@ -13718,7 +13671,7 @@ var OpencodeAdapter = class extends SimpleAdapter {
13718
13671
  directory: config.directory || void 0,
13719
13672
  workspace: config.workspace || void 0
13720
13673
  }));
13721
- this.mcpBackendFactory = options.mcpBackendFactory ?? createThenvoiMcpBackend;
13674
+ this.mcpBackendFactory = options.mcpBackendFactory ?? createBandMcpBackend;
13722
13675
  this.logger = options.logger ?? new NoopLogger();
13723
13676
  }
13724
13677
  async onStarted(agentName, agentDescription) {
@@ -13872,7 +13825,8 @@ ${OPENCODE_SYSTEM_NOTE}`.trim();
13872
13825
  }
13873
13826
  await client.registerMcpServer({
13874
13827
  name: this.config.mcpServerName,
13875
- url: server.url
13828
+ url: server.url,
13829
+ headers: backend.authToken ? { Authorization: `Bearer ${backend.authToken}` } : void 0
13876
13830
  });
13877
13831
  } catch (error) {
13878
13832
  this.logger.warn("Failed to register OpenCode MCP backend", { error });
@@ -14510,7 +14464,7 @@ init_registrations();
14510
14464
  init_zod();
14511
14465
  var import_zod10 = require("zod");
14512
14466
  var DEFAULT_MODEL2 = "claude-sonnet-4-6";
14513
- var thenvoiMcpBridgeFactory = new LazyAsyncValue({
14467
+ var bandMcpBridgeFactory = new LazyAsyncValue({
14514
14468
  load: async () => {
14515
14469
  const module2 = await import("@anthropic-ai/claude-agent-sdk").catch((error) => {
14516
14470
  throw new UnsupportedFeatureError(
@@ -14548,7 +14502,7 @@ var thenvoiMcpBridgeFactory = new LazyAsyncValue({
14548
14502
  });
14549
14503
  return {
14550
14504
  serverConfig: createSdkMcpServer2({
14551
- name: "thenvoi",
14505
+ name: MCP_SERVER_NAME,
14552
14506
  tools: toolDefinitions
14553
14507
  }),
14554
14508
  allowedTools: mcpToolNames(new Set(registrations.map((registration) => registration.name)))
@@ -14599,8 +14553,8 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
14599
14553
  capabilities: { memory: this.enableMemoryTools }
14600
14554
  });
14601
14555
  if (this.enableMcpTools) {
14602
- const createThenvoiMcpBridge = await thenvoiMcpBridgeFactory.get();
14603
- this.mcpBridge = createThenvoiMcpBridge({
14556
+ const createBandMcpBridge = await bandMcpBridgeFactory.get();
14557
+ this.mcpBridge = createBandMcpBridge({
14604
14558
  enableMemoryTools: this.enableMemoryTools,
14605
14559
  getToolsForRoom: (roomId) => this.roomTools.get(roomId),
14606
14560
  additionalTools: this.additionalMcpTools.length > 0 ? this.additionalMcpTools : void 0
@@ -14648,14 +14602,14 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
14648
14602
  }
14649
14603
  if (this.mcpBridge && this.enableMcpTools) {
14650
14604
  options.mcpServers = {
14651
- thenvoi: this.mcpBridge.serverConfig
14605
+ [MCP_SERVER_NAME]: this.mcpBridge.serverConfig
14652
14606
  };
14653
14607
  options.allowedTools = this.mcpBridge.allowedTools;
14654
14608
  this.roomTools.set(context.roomId, tools);
14655
14609
  }
14656
14610
  const roomToolHint = this.enableMcpTools ? `
14657
14611
 
14658
- [Tooling note]: For any mcp__thenvoi__* tool call, pass room_id="${context.roomId}".` : "";
14612
+ [Tooling note]: For any mcp__band__* tool call, pass room_id="${context.roomId}".` : "";
14659
14613
  const query = queryFn({
14660
14614
  prompt: buildConversationPrompt({
14661
14615
  history,
@@ -14751,6 +14705,7 @@ init_schemas();
14751
14705
  Agent,
14752
14706
  AgentRuntime,
14753
14707
  AnthropicAdapter,
14708
+ BandLink,
14754
14709
  CODEX_REASONING_EFFORTS,
14755
14710
  CODEX_REASONING_SUMMARIES,
14756
14711
  CODEX_WEB_SEARCH_MODES,
@@ -14762,6 +14717,7 @@ init_schemas();
14762
14717
  GoogleADKAdapter,
14763
14718
  LangGraphAdapter,
14764
14719
  LettaAdapter,
14720
+ MCP_SERVER_NAME,
14765
14721
  MCP_TOOL_PREFIX,
14766
14722
  OpenAIAdapter,
14767
14723
  OpencodeAdapter,
@@ -14769,7 +14725,6 @@ init_schemas();
14769
14725
  PlatformRuntime,
14770
14726
  SimpleAdapter,
14771
14727
  TOOL_MODELS,
14772
- ThenvoiLink,
14773
14728
  VercelAISDKAdapter,
14774
14729
  WebSocketDisconnectError,
14775
14730
  deriveDefaultRestUrl,