@band-ai/sdk 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +372 -0
  2. package/dist/{ClaudeSDKAdapter-CRq4R-WB.d.cts → ClaudeSDKAdapter-BY4zEbCl.d.cts} +14 -10
  3. package/dist/{ClaudeSDKAdapter-BHOkjN3X.d.ts → ClaudeSDKAdapter-Cna5P1dR.d.ts} +14 -10
  4. package/dist/{acp-server-B1Da7L6u.d.ts → acp-server-CiUqN3G3.d.ts} +2 -2
  5. package/dist/{acp-server-BdRz9_UN.d.cts → acp-server-Dlj7D563.d.cts} +2 -2
  6. package/dist/adapters.cjs +734 -279
  7. package/dist/adapters.d.cts +21 -19
  8. package/dist/adapters.d.ts +21 -19
  9. package/dist/adapters.js +65 -44
  10. package/dist/backends-D-dBdDm-.d.ts +27 -0
  11. package/dist/backends-ZLxmQrTZ.d.cts +27 -0
  12. package/dist/{chunk-MSL6CWHY.js → chunk-4IAXZBXX.js} +77 -37
  13. package/dist/{chunk-SG4WLD2H.js → chunk-EAI2M3WM.js} +38 -94
  14. package/dist/{chunk-YR3BOQNW.js → chunk-JY75VSQK.js} +7 -7
  15. package/dist/{chunk-INA6YZTZ.js → chunk-LBWKISBS.js} +51 -31
  16. package/dist/{chunk-I5EZG52P.js → chunk-N2QTUMGO.js} +532 -327
  17. package/dist/{chunk-RHVH2GZR.js → chunk-NMZLX7TP.js} +110 -56
  18. package/dist/{chunk-EDPKUUJL.js → chunk-NT7TBFX2.js} +9 -1
  19. package/dist/{chunk-GVEQ3RAH.js → chunk-RV76SKFT.js} +169 -54
  20. package/dist/{chunk-W5NDZSYE.js → chunk-TLBCKDQO.js} +23 -23
  21. package/dist/chunk-US226AS4.js +130 -0
  22. package/dist/{chunk-IZPV6QS6.js → chunk-WL2HNJZ6.js} +38 -11
  23. package/dist/chunk-WLCM2OXG.js +181 -0
  24. package/dist/config.cjs +40 -13
  25. package/dist/config.d.cts +7 -1
  26. package/dist/config.d.ts +7 -1
  27. package/dist/config.js +2 -2
  28. package/dist/converters.cjs +491 -35
  29. package/dist/converters.d.cts +5 -5
  30. package/dist/converters.d.ts +5 -5
  31. package/dist/converters.js +4 -3
  32. package/dist/core.cjs +53 -10
  33. package/dist/core.d.cts +10 -9
  34. package/dist/core.d.ts +10 -9
  35. package/dist/core.js +8 -4
  36. package/dist/disconnectReason-IuADl6TH.d.cts +34 -0
  37. package/dist/disconnectReason-IuADl6TH.d.ts +34 -0
  38. package/dist/{dtos-DUpbIu8k.d.ts → dtos-B8KU_q4d.d.cts} +26 -6
  39. package/dist/{dtos-DUpbIu8k.d.cts → dtos-B8KU_q4d.d.ts} +26 -6
  40. package/dist/index.cjs +1510 -735
  41. package/dist/index.d.cts +18 -16
  42. package/dist/index.d.ts +18 -16
  43. package/dist/index.js +21 -13
  44. package/dist/linear.cjs +1044 -112
  45. package/dist/linear.d.cts +146 -16
  46. package/dist/linear.d.ts +146 -16
  47. package/dist/linear.js +1031 -110
  48. package/dist/mcp-claude.cjs +338 -66
  49. package/dist/mcp-claude.d.cts +3 -3
  50. package/dist/mcp-claude.d.ts +3 -3
  51. package/dist/mcp-claude.js +215 -16
  52. package/dist/mcp.cjs +414 -105
  53. package/dist/mcp.d.cts +29 -16
  54. package/dist/mcp.d.ts +29 -16
  55. package/dist/mcp.js +14 -14
  56. package/dist/{opencode-BBcDchcN.d.cts → opencode-2YdscIc1.d.cts} +5 -5
  57. package/dist/{opencode-DthQQUsZ.d.ts → opencode-Bld62x5t.d.ts} +5 -5
  58. package/dist/{pagination-CcDkVFxK.d.ts → pagination-BgEx-HeL.d.ts} +2 -2
  59. package/dist/{pagination-BPiys10t.d.cts → pagination-DqdkQArT.d.cts} +2 -2
  60. package/dist/{protocols-DrhzOH6K.d.ts → protocols-Bwwcql0h.d.ts} +1 -1
  61. package/dist/{protocols-CInhtFpA.d.cts → protocols-Bz1rxcUg.d.cts} +1 -1
  62. package/dist/rest.cjs +41 -97
  63. package/dist/rest.d.cts +7 -7
  64. package/dist/rest.d.ts +7 -7
  65. package/dist/rest.js +2 -2
  66. package/dist/runtime.cjs +998 -620
  67. package/dist/runtime.d.cts +22 -29
  68. package/dist/runtime.d.ts +22 -29
  69. package/dist/runtime.js +19 -67
  70. package/dist/{schemas-BpEBkq5V.d.cts → schemas-BotL3ZLH.d.cts} +51 -56
  71. package/dist/{schemas-vos1AaBc.d.ts → schemas-DBsC4J1g.d.ts} +51 -56
  72. package/dist/{sdk-CwTAxhwI.d.cts → sdk-BTciSLRQ.d.cts} +35 -5
  73. package/dist/{sdk-CcnQ5OUC.d.ts → sdk-qKJtMma_.d.ts} +35 -5
  74. package/dist/{simpleAdapter-9OE_p6QW.d.ts → simpleAdapter--wznuoOw.d.ts} +1 -1
  75. package/dist/{simpleAdapter-DqhvjsGr.d.cts → simpleAdapter-BpT4XbZC.d.cts} +1 -1
  76. package/dist/testing.d.cts +3 -3
  77. package/dist/testing.d.ts +3 -3
  78. package/dist/{types-7jVzOeOP.d.ts → types-BTN_ZETM.d.ts} +2 -2
  79. package/dist/{types-CxII3XkA.d.ts → types-BgYFd_Yw.d.cts} +5 -5
  80. package/dist/{types-CSHFipIc.d.cts → types-BivGO7I9.d.ts} +5 -5
  81. package/dist/{types-CovcHpYf.d.cts → types-D958TC71.d.cts} +2 -2
  82. package/package.json +25 -23
  83. package/dist/backends-CzDbiQar.d.ts +0 -20
  84. package/dist/backends-SVMT-7l4.d.cts +0 -20
  85. package/dist/chunk-SFVKOEQH.js +0 -103
package/dist/adapters.cjs CHANGED
@@ -30,59 +30,108 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // src/contracts/protocols.ts
34
- function isToolExecutorError(value) {
35
- if (!value || typeof value !== "object") {
36
- return false;
37
- }
38
- const candidate = value;
39
- return candidate.ok === false && typeof candidate.errorType === "string" && TOOL_EXECUTOR_ERROR_TYPES.includes(candidate.errorType) && typeof candidate.toolName === "string" && typeof candidate.message === "string" && typeof candidate.legacyMessage === "string";
33
+ // src/contracts/memory.ts
34
+ function namedValues(values) {
35
+ return Object.fromEntries(values.map((value) => [value, value]));
40
36
  }
41
- function toLegacyToolExecutorErrorMessage(value) {
42
- if (typeof value === "string") {
43
- return value;
44
- }
45
- if (!isToolExecutorError(value)) {
46
- return null;
47
- }
48
- return value.legacyMessage;
49
- }
50
- var TOOL_EXECUTOR_ERROR_TYPES;
51
- var init_protocols = __esm({
52
- "src/contracts/protocols.ts"() {
37
+ var SENSORY_MEMORY_TYPES, COGNITIVE_MEMORY_TYPES, MEMORY_SYSTEM_TYPES, MEMORY_SYSTEMS, MEMORY_TYPES, MEMORY_SEGMENTS, MEMORY_STORE_SCOPES, MEMORY_LIST_SCOPES, MEMORY_STATUSES, MEMORY_SYSTEM, MEMORY_TYPE, MEMORY_SEGMENT, MEMORY_STORE_SCOPE;
38
+ var init_memory = __esm({
39
+ "src/contracts/memory.ts"() {
53
40
  "use strict";
54
- TOOL_EXECUTOR_ERROR_TYPES = [
55
- "ToolArgumentsValidationError",
56
- "ToolNotFoundError",
57
- "ToolExecutionError"
41
+ SENSORY_MEMORY_TYPES = [
42
+ "iconic",
43
+ // Visual input
44
+ "echoic",
45
+ // Auditory input
46
+ "haptic"
47
+ // Tactile input
48
+ ];
49
+ COGNITIVE_MEMORY_TYPES = [
50
+ "episodic",
51
+ // Events that occurred
52
+ "semantic",
53
+ // Facts, preferences, learned knowledge
54
+ "procedural"
55
+ // How to perform tasks
56
+ ];
57
+ MEMORY_SYSTEM_TYPES = {
58
+ sensory: SENSORY_MEMORY_TYPES,
59
+ // Brief sensory inputs
60
+ working: COGNITIVE_MEMORY_TYPES,
61
+ // Short-term session context
62
+ long_term: COGNITIVE_MEMORY_TYPES
63
+ // Persistent cross-conversation memory
64
+ };
65
+ MEMORY_SYSTEMS = Object.keys(MEMORY_SYSTEM_TYPES);
66
+ MEMORY_TYPES = [
67
+ ...SENSORY_MEMORY_TYPES,
68
+ ...COGNITIVE_MEMORY_TYPES
69
+ ];
70
+ MEMORY_SEGMENTS = [
71
+ "user",
72
+ // User preferences or profile info
73
+ "agent",
74
+ // Facts or events about agents/entities
75
+ "tool",
76
+ // Tool usage or task procedures
77
+ "guideline"
78
+ // Behavioral rules or policies
79
+ ];
80
+ MEMORY_STORE_SCOPES = [
81
+ "subject",
82
+ // About one person/agent; requires subject_id
83
+ "organization"
84
+ // Shared org-wide
85
+ ];
86
+ MEMORY_LIST_SCOPES = [
87
+ "subject",
88
+ // Subject-scoped memories only
89
+ "organization",
90
+ // Organization-scoped memories only
91
+ "all"
92
+ // Both scopes (no scope filter)
58
93
  ];
94
+ MEMORY_STATUSES = [
95
+ "active",
96
+ // Normal, visible memories
97
+ "superseded",
98
+ // Outdated; soft-deleted via band_supersede_memory
99
+ "archived",
100
+ // Hidden but preserved via band_archive_memory
101
+ "all"
102
+ // Any status (no filter)
103
+ ];
104
+ MEMORY_SYSTEM = namedValues(MEMORY_SYSTEMS);
105
+ MEMORY_TYPE = namedValues(MEMORY_TYPES);
106
+ MEMORY_SEGMENT = namedValues(MEMORY_SEGMENTS);
107
+ MEMORY_STORE_SCOPE = namedValues(MEMORY_STORE_SCOPES);
59
108
  }
60
109
  });
61
110
 
62
111
  // src/core/errors.ts
63
- var ThenvoiSdkError, UnsupportedFeatureError, ValidationError, RuntimeStateError;
112
+ var BandSdkError, UnsupportedFeatureError, ValidationError, RuntimeStateError;
64
113
  var init_errors = __esm({
65
114
  "src/core/errors.ts"() {
66
115
  "use strict";
67
- ThenvoiSdkError = class extends Error {
116
+ BandSdkError = class extends Error {
68
117
  constructor(message, cause) {
69
118
  super(message, cause !== void 0 ? { cause } : void 0);
70
- this.name = "ThenvoiSdkError";
119
+ this.name = "BandSdkError";
71
120
  }
72
121
  };
73
- UnsupportedFeatureError = class extends ThenvoiSdkError {
122
+ UnsupportedFeatureError = class extends BandSdkError {
74
123
  constructor(message) {
75
124
  super(message);
76
125
  this.name = "UnsupportedFeatureError";
77
126
  }
78
127
  };
79
- ValidationError = class extends ThenvoiSdkError {
128
+ ValidationError = class extends BandSdkError {
80
129
  constructor(message, cause) {
81
130
  super(message, cause);
82
131
  this.name = "ValidationError";
83
132
  }
84
133
  };
85
- RuntimeStateError = class extends ThenvoiSdkError {
134
+ RuntimeStateError = class extends BandSdkError {
86
135
  constructor(message) {
87
136
  super(message);
88
137
  this.name = "RuntimeStateError";
@@ -110,13 +159,14 @@ function getToolDescription(name) {
110
159
  const model = TOOL_MODELS[name];
111
160
  return model?.description ?? `Execute ${name}`;
112
161
  }
113
- var TOOL_MODELS, ALL_TOOL_NAMES, MEMORY_TOOL_NAMES, CONTACT_TOOL_NAMES, BASE_TOOL_NAMES, CHAT_TOOL_NAMES, MCP_TOOL_PREFIX;
162
+ 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;
114
163
  var init_schemas = __esm({
115
164
  "src/runtime/tools/schemas.ts"() {
116
165
  "use strict";
117
166
  init_chatEvents();
167
+ init_memory();
118
168
  TOOL_MODELS = {
119
- thenvoi_send_message: {
169
+ band_send_message: {
120
170
  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.",
121
171
  properties: {
122
172
  content: {
@@ -132,7 +182,7 @@ var init_schemas = __esm({
132
182
  },
133
183
  required: ["content", "mentions"]
134
184
  },
135
- thenvoi_send_event: {
185
+ band_send_event: {
136
186
  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.",
137
187
  properties: {
138
188
  content: {
@@ -151,12 +201,12 @@ var init_schemas = __esm({
151
201
  },
152
202
  required: ["content", "message_type"]
153
203
  },
154
- thenvoi_add_participant: {
155
- 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'.",
204
+ band_add_participant: {
205
+ 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'.",
156
206
  properties: {
157
207
  name: {
158
208
  type: "string",
159
- description: "Name of participant to add (must match a name from thenvoi_lookup_peers)."
209
+ description: "Name of participant to add (must match a name from band_lookup_peers)."
160
210
  },
161
211
  role: {
162
212
  type: "string",
@@ -166,7 +216,7 @@ var init_schemas = __esm({
166
216
  },
167
217
  required: ["name"]
168
218
  },
169
- thenvoi_remove_participant: {
219
+ band_remove_participant: {
170
220
  description: "Remove a participant from the chat room by name.",
171
221
  properties: {
172
222
  name: {
@@ -176,12 +226,12 @@ var init_schemas = __esm({
176
226
  },
177
227
  required: ["name"]
178
228
  },
179
- thenvoi_get_participants: {
229
+ band_get_participants: {
180
230
  description: "Get a list of all participants in the current chat room.",
181
231
  properties: {},
182
232
  required: []
183
233
  },
184
- thenvoi_lookup_peers: {
234
+ band_lookup_peers: {
185
235
  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.",
186
236
  properties: {
187
237
  page: {
@@ -196,7 +246,7 @@ var init_schemas = __esm({
196
246
  },
197
247
  required: []
198
248
  },
199
- thenvoi_create_chatroom: {
249
+ band_create_chatroom: {
200
250
  description: "Create a new chat room for a specific task or conversation.",
201
251
  properties: {
202
252
  task_id: {
@@ -206,7 +256,7 @@ var init_schemas = __esm({
206
256
  },
207
257
  required: []
208
258
  },
209
- thenvoi_list_contacts: {
259
+ band_list_contacts: {
210
260
  description: "List agent's contacts with pagination.",
211
261
  properties: {
212
262
  page: {
@@ -223,7 +273,7 @@ var init_schemas = __esm({
223
273
  },
224
274
  required: []
225
275
  },
226
- thenvoi_add_contact: {
276
+ band_add_contact: {
227
277
  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.",
228
278
  properties: {
229
279
  handle: {
@@ -237,7 +287,7 @@ var init_schemas = __esm({
237
287
  },
238
288
  required: ["handle"]
239
289
  },
240
- thenvoi_remove_contact: {
290
+ band_remove_contact: {
241
291
  description: "Remove an existing contact by handle or ID.",
242
292
  properties: {
243
293
  handle: {
@@ -251,7 +301,7 @@ var init_schemas = __esm({
251
301
  },
252
302
  required: []
253
303
  },
254
- thenvoi_list_contact_requests: {
304
+ band_list_contact_requests: {
255
305
  description: "List both received and sent contact requests. Received requests are always filtered to pending status. Sent requests can be filtered by status.",
256
306
  properties: {
257
307
  page: {
@@ -273,7 +323,7 @@ var init_schemas = __esm({
273
323
  },
274
324
  required: []
275
325
  },
276
- thenvoi_respond_contact_request: {
326
+ band_respond_contact_request: {
277
327
  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).",
278
328
  properties: {
279
329
  action: {
@@ -292,7 +342,7 @@ var init_schemas = __esm({
292
342
  },
293
343
  required: ["action"]
294
344
  },
295
- thenvoi_list_memories: {
345
+ band_list_memories: {
296
346
  description: "List memories accessible to the agent. Returns memories about the specified subject (cross-agent sharing) and organization-wide shared memories.",
297
347
  properties: {
298
348
  subject_id: {
@@ -301,29 +351,22 @@ var init_schemas = __esm({
301
351
  },
302
352
  scope: {
303
353
  type: "string",
304
- enum: ["subject", "organization", "all"],
354
+ enum: [...MEMORY_LIST_SCOPES],
305
355
  description: "Filter by scope."
306
356
  },
307
357
  system: {
308
358
  type: "string",
309
- enum: ["sensory", "working", "long_term"],
359
+ enum: [...MEMORY_SYSTEMS],
310
360
  description: "Filter by memory system."
311
361
  },
312
362
  type: {
313
363
  type: "string",
314
- enum: [
315
- "iconic",
316
- "echoic",
317
- "haptic",
318
- "episodic",
319
- "semantic",
320
- "procedural"
321
- ],
364
+ enum: [...MEMORY_TYPES],
322
365
  description: "Filter by memory type."
323
366
  },
324
367
  segment: {
325
368
  type: "string",
326
- enum: ["user", "agent", "tool", "guideline"],
369
+ enum: [...MEMORY_SEGMENTS],
327
370
  description: "Filter by segment."
328
371
  },
329
372
  content_query: {
@@ -338,13 +381,13 @@ var init_schemas = __esm({
338
381
  },
339
382
  status: {
340
383
  type: "string",
341
- enum: ["active", "superseded", "archived", "all"],
384
+ enum: [...MEMORY_STATUSES],
342
385
  description: "Filter by status."
343
386
  }
344
387
  },
345
388
  required: []
346
389
  },
347
- thenvoi_store_memory: {
390
+ band_store_memory: {
348
391
  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.",
349
392
  properties: {
350
393
  content: {
@@ -353,24 +396,17 @@ var init_schemas = __esm({
353
396
  },
354
397
  system: {
355
398
  type: "string",
356
- enum: ["sensory", "working", "long_term"],
399
+ enum: [...MEMORY_SYSTEMS],
357
400
  description: "Memory system tier."
358
401
  },
359
402
  type: {
360
403
  type: "string",
361
- enum: [
362
- "iconic",
363
- "echoic",
364
- "haptic",
365
- "episodic",
366
- "semantic",
367
- "procedural"
368
- ],
404
+ enum: [...MEMORY_TYPES],
369
405
  description: "Memory type (must be valid for selected system)."
370
406
  },
371
407
  segment: {
372
408
  type: "string",
373
- enum: ["user", "agent", "tool", "guideline"],
409
+ enum: [...MEMORY_SEGMENTS],
374
410
  description: "Logical segment."
375
411
  },
376
412
  thought: {
@@ -379,7 +415,7 @@ var init_schemas = __esm({
379
415
  },
380
416
  scope: {
381
417
  type: "string",
382
- enum: ["subject", "organization"],
418
+ enum: [...MEMORY_STORE_SCOPES],
383
419
  description: "Visibility scope."
384
420
  },
385
421
  subject_id: {
@@ -393,7 +429,7 @@ var init_schemas = __esm({
393
429
  },
394
430
  required: ["content", "system", "type", "segment", "thought"]
395
431
  },
396
- thenvoi_get_memory: {
432
+ band_get_memory: {
397
433
  description: "Retrieve a specific memory by ID.",
398
434
  properties: {
399
435
  memory_id: {
@@ -403,7 +439,7 @@ var init_schemas = __esm({
403
439
  },
404
440
  required: ["memory_id"]
405
441
  },
406
- thenvoi_supersede_memory: {
442
+ band_supersede_memory: {
407
443
  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.",
408
444
  properties: {
409
445
  memory_id: {
@@ -413,7 +449,7 @@ var init_schemas = __esm({
413
449
  },
414
450
  required: ["memory_id"]
415
451
  },
416
- thenvoi_archive_memory: {
452
+ band_archive_memory: {
417
453
  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.",
418
454
  properties: {
419
455
  memory_id: {
@@ -426,18 +462,18 @@ var init_schemas = __esm({
426
462
  };
427
463
  ALL_TOOL_NAMES = new Set(Object.keys(TOOL_MODELS));
428
464
  MEMORY_TOOL_NAMES = /* @__PURE__ */ new Set([
429
- "thenvoi_list_memories",
430
- "thenvoi_store_memory",
431
- "thenvoi_get_memory",
432
- "thenvoi_supersede_memory",
433
- "thenvoi_archive_memory"
465
+ "band_list_memories",
466
+ "band_store_memory",
467
+ "band_get_memory",
468
+ "band_supersede_memory",
469
+ "band_archive_memory"
434
470
  ]);
435
471
  CONTACT_TOOL_NAMES = /* @__PURE__ */ new Set([
436
- "thenvoi_list_contacts",
437
- "thenvoi_add_contact",
438
- "thenvoi_remove_contact",
439
- "thenvoi_list_contact_requests",
440
- "thenvoi_respond_contact_request"
472
+ "band_list_contacts",
473
+ "band_add_contact",
474
+ "band_remove_contact",
475
+ "band_list_contact_requests",
476
+ "band_respond_contact_request"
441
477
  ]);
442
478
  BASE_TOOL_NAMES = new Set(
443
479
  [...ALL_TOOL_NAMES].filter((name) => !MEMORY_TOOL_NAMES.has(name))
@@ -445,7 +481,39 @@ var init_schemas = __esm({
445
481
  CHAT_TOOL_NAMES = new Set(
446
482
  [...BASE_TOOL_NAMES].filter((name) => !CONTACT_TOOL_NAMES.has(name))
447
483
  );
448
- MCP_TOOL_PREFIX = "mcp__thenvoi__";
484
+ MCP_TOOL_PREFIX = "mcp__band__";
485
+ MCP_SERVER_NAME = "band";
486
+ SEND_MESSAGE_TOOL_NAME = "band_send_message";
487
+ SEND_EVENT_TOOL_NAME = "band_send_event";
488
+ }
489
+ });
490
+
491
+ // src/contracts/protocols.ts
492
+ function isToolExecutorError(value) {
493
+ if (!value || typeof value !== "object") {
494
+ return false;
495
+ }
496
+ const candidate = value;
497
+ return candidate.ok === false && typeof candidate.errorType === "string" && TOOL_EXECUTOR_ERROR_TYPES.includes(candidate.errorType) && typeof candidate.toolName === "string" && typeof candidate.message === "string" && typeof candidate.legacyMessage === "string";
498
+ }
499
+ function toLegacyToolExecutorErrorMessage(value) {
500
+ if (typeof value === "string") {
501
+ return value;
502
+ }
503
+ if (!isToolExecutorError(value)) {
504
+ return null;
505
+ }
506
+ return value.legacyMessage;
507
+ }
508
+ var TOOL_EXECUTOR_ERROR_TYPES;
509
+ var init_protocols = __esm({
510
+ "src/contracts/protocols.ts"() {
511
+ "use strict";
512
+ TOOL_EXECUTOR_ERROR_TYPES = [
513
+ "ToolArgumentsValidationError",
514
+ "ToolNotFoundError",
515
+ "ToolExecutionError"
516
+ ];
449
517
  }
450
518
  });
451
519
 
@@ -567,6 +635,13 @@ function serializeValue(value) {
567
635
  return String(value);
568
636
  }
569
637
  }
638
+ function resolveSingleRoomTools(getToolsForRoom) {
639
+ const tools = getToolsForRoom("");
640
+ if (!tools) {
641
+ throw new Error('Single-room mode requires getToolsForRoom("") to return a tools instance');
642
+ }
643
+ return tools;
644
+ }
570
645
  var init_registrations = __esm({
571
646
  "src/mcp/registrations.ts"() {
572
647
  "use strict";
@@ -622,29 +697,225 @@ var init_zod = __esm({
622
697
  // src/mcp/sdk.ts
623
698
  var sdk_exports = {};
624
699
  __export(sdk_exports, {
625
- createThenvoiSdkMcpServer: () => createThenvoiSdkMcpServer
700
+ createBandSdkMcpServer: () => createBandSdkMcpServer
626
701
  });
627
- function createThenvoiSdkMcpServer(options) {
628
- const registrations = buildRoomScopedRegistrations(
629
- options.getToolsForRoom,
630
- {
631
- enableMemoryTools: options.enableMemoryTools,
632
- enableContactTools: true,
633
- additionalTools: options.additionalTools
634
- }
635
- );
702
+ function createBandSdkMcpServer(options) {
703
+ const registrationOptions = {
704
+ enableMemoryTools: options.enableMemoryTools,
705
+ enableContactTools: true,
706
+ additionalTools: options.additionalTools
707
+ };
708
+ const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolveSingleRoomTools(options.getToolsForRoom), registrationOptions) : buildRoomScopedRegistrations(options.getToolsForRoom, registrationOptions);
636
709
  const toolDefinitions = registrations.map(toSdkToolDefinition);
637
710
  const toolNames = new Set(registrations.map((r) => r.name));
711
+ const contextCache = /* @__PURE__ */ new Map();
712
+ const MAX_CONTEXT_CACHE_ENTRIES = 100;
638
713
  const serverConfig = (0, import_claude_agent_sdk.createSdkMcpServer)({
639
- name: "thenvoi",
714
+ name: MCP_SERVER_NAME,
640
715
  tools: toolDefinitions
641
716
  });
642
717
  return {
643
718
  serverConfig,
644
719
  allowedTools: mcpToolNames(toolNames),
645
- toolDefinitions
720
+ toolDefinitions,
721
+ getSystemPromptContext: async (roomId, contextOptions) => {
722
+ const context = await getOrBuildSystemPromptContext(
723
+ roomId,
724
+ contextOptions,
725
+ options.getToolsForRoom,
726
+ contextCache,
727
+ MAX_CONTEXT_CACHE_ENTRIES
728
+ );
729
+ return context.markdown;
730
+ },
731
+ getSystemPromptContextData: (roomId, contextOptions) => {
732
+ return getOrBuildSystemPromptContext(
733
+ roomId,
734
+ contextOptions,
735
+ options.getToolsForRoom,
736
+ contextCache,
737
+ MAX_CONTEXT_CACHE_ENTRIES
738
+ );
739
+ }
740
+ };
741
+ }
742
+ async function getOrBuildSystemPromptContext(roomId, contextOptions, getToolsForRoom, contextCache, maxEntries) {
743
+ const ttlMs = contextOptions?.ttlMs ?? 3e4;
744
+ const now = Date.now();
745
+ const cached = contextCache.get(roomId);
746
+ if (cached && cached.expiresAt > now) {
747
+ cached.lastAccessedAt = now;
748
+ return cached.value;
749
+ }
750
+ if (cached) {
751
+ contextCache.delete(roomId);
752
+ }
753
+ const tools = getToolsForRoom(roomId);
754
+ if (!tools) {
755
+ return buildUnavailableSystemPromptContext(roomId);
756
+ }
757
+ const context = await buildSystemPromptContext(roomId, tools);
758
+ contextCache.set(roomId, {
759
+ value: context,
760
+ expiresAt: now + ttlMs,
761
+ lastAccessedAt: now
762
+ });
763
+ evictLeastRecentlyUsedContext(contextCache, maxEntries);
764
+ return context;
765
+ }
766
+ async function buildSystemPromptContext(roomId, tools) {
767
+ const participants = await tools.getParticipants();
768
+ const warnings = [];
769
+ const agentResolution = await resolveAgentIdentity(tools);
770
+ if (agentResolution.warning) {
771
+ warnings.push(agentResolution.warning);
772
+ }
773
+ const roomResolution = await resolveRoomTitle(tools, roomId);
774
+ if (roomResolution.warning) {
775
+ warnings.push(roomResolution.warning);
776
+ }
777
+ const agentIdentity = agentResolution.value;
778
+ const roomTitle = roomResolution.value;
779
+ const normalizedParticipants = participants.map((participant) => ({
780
+ id: String(participant.id),
781
+ name: String(participant.name ?? "Unknown"),
782
+ type: String(participant.type ?? "Unknown"),
783
+ handle: normalizeHandle(participant.handle),
784
+ isSelf: participant.id === agentIdentity?.id
785
+ }));
786
+ const selfHandle = normalizeHandle(agentIdentity?.handle);
787
+ const selfName = agentIdentity?.name ?? "Agent";
788
+ const mentionHandles = normalizedParticipants.filter((participant) => !participant.isSelf).map((participant) => participant.handle).filter((handle) => Boolean(handle));
789
+ const mentionFormat = mentionHandles.length > 0 ? mentionHandles.join(", ") : "No participant handles available";
790
+ const roomLabel = roomTitle ? `"${roomTitle}"` : "this room";
791
+ const agentLabel = selfHandle ? `${selfName} (${selfHandle})` : selfName;
792
+ const participantLines = normalizedParticipants.length > 0 ? normalizedParticipants.map((participant) => {
793
+ const suffix = participant.isSelf ? " (you)" : "";
794
+ const handle = participant.handle ? ` (${participant.handle})` : "";
795
+ return `- **${participant.name}**${handle} -- ${participant.type}${suffix}`;
796
+ }).join("\n") : "- No participants found";
797
+ const markdown = [
798
+ "## Room Context",
799
+ "",
800
+ `You are **${agentLabel}** in room ${roomLabel} (id: ${roomId}).`,
801
+ "",
802
+ "### Participants",
803
+ participantLines,
804
+ "",
805
+ "### Mention Format",
806
+ `To address someone, use their exact handle: ${mentionFormat}`,
807
+ ...warnings.length > 0 ? ["", "### Warnings", ...warnings.map((warning) => `- ${warning}`)] : []
808
+ ].join("\n");
809
+ return {
810
+ roomId,
811
+ roomTitle,
812
+ agent: {
813
+ id: agentIdentity?.id ?? "unknown-agent",
814
+ name: selfName,
815
+ handle: selfHandle,
816
+ description: agentIdentity?.description ?? null
817
+ },
818
+ participants: normalizedParticipants,
819
+ mentionFormat,
820
+ warnings,
821
+ markdown
822
+ };
823
+ }
824
+ async function resolveAgentIdentity(tools) {
825
+ const maybeTools = tools;
826
+ try {
827
+ if (maybeTools.getAgentIdentity) {
828
+ return { value: await maybeTools.getAgentIdentity(), warning: null };
829
+ }
830
+ if (maybeTools.rest?.getAgentMe) {
831
+ return { value: await maybeTools.rest.getAgentMe(), warning: null };
832
+ }
833
+ } catch (error) {
834
+ return {
835
+ value: null,
836
+ warning: `Unable to resolve agent identity: ${error instanceof Error ? error.message : String(error)}`
837
+ };
838
+ }
839
+ return { value: null, warning: null };
840
+ }
841
+ async function resolveRoomTitle(tools, roomId) {
842
+ const maybeTools = tools;
843
+ const rest = maybeTools.rest;
844
+ if (!rest?.listChats) {
845
+ return { value: null, warning: null };
846
+ }
847
+ try {
848
+ let page = 1;
849
+ const pageSize = 100;
850
+ while (true) {
851
+ const response = await rest.listChats({ page, pageSize });
852
+ const room = response?.data?.find((entry) => entry.id === roomId);
853
+ if (typeof room?.title === "string" && room.title.length > 0) {
854
+ return { value: room.title, warning: null };
855
+ }
856
+ const totalPages = response?.metadata?.totalPages ?? page;
857
+ if (page >= totalPages) {
858
+ return { value: null, warning: null };
859
+ }
860
+ page += 1;
861
+ }
862
+ } catch (error) {
863
+ return {
864
+ value: null,
865
+ warning: `Unable to resolve room title: ${error instanceof Error ? error.message : String(error)}`
866
+ };
867
+ }
868
+ }
869
+ function buildUnavailableSystemPromptContext(roomId) {
870
+ const warnings = [`No tool context found for room_id ${roomId}`];
871
+ const markdown = [
872
+ "## Room Context",
873
+ "",
874
+ `You are **Agent** in this room (id: ${roomId}).`,
875
+ "",
876
+ "### Participants",
877
+ "- No participants found",
878
+ "",
879
+ "### Mention Format",
880
+ "No participant handles available",
881
+ "",
882
+ "### Warnings",
883
+ ...warnings.map((warning) => `- ${warning}`)
884
+ ].join("\n");
885
+ return {
886
+ roomId,
887
+ roomTitle: null,
888
+ agent: {
889
+ id: "unknown-agent",
890
+ name: "Agent",
891
+ handle: null,
892
+ description: null
893
+ },
894
+ participants: [],
895
+ mentionFormat: "No participant handles available",
896
+ warnings,
897
+ markdown
646
898
  };
647
899
  }
900
+ function evictLeastRecentlyUsedContext(contextCache, maxEntries) {
901
+ if (contextCache.size <= maxEntries) {
902
+ return;
903
+ }
904
+ let oldestKey = null;
905
+ let oldestAccessedAt = Number.POSITIVE_INFINITY;
906
+ for (const [key, entry] of contextCache.entries()) {
907
+ if (entry.lastAccessedAt < oldestAccessedAt) {
908
+ oldestAccessedAt = entry.lastAccessedAt;
909
+ oldestKey = key;
910
+ }
911
+ }
912
+ if (oldestKey) {
913
+ contextCache.delete(oldestKey);
914
+ }
915
+ }
916
+ function normalizeHandle(handle) {
917
+ return typeof handle === "string" && handle.trim().length > 0 ? handle.trim() : null;
918
+ }
648
919
  function toSdkToolDefinition(registration) {
649
920
  const shape = buildZodShape(
650
921
  import_zod5.z,
@@ -680,6 +951,7 @@ __export(adapters_exports, {
680
951
  ACPServer: () => ACPServer,
681
952
  AnthropicAdapter: () => AnthropicAdapter,
682
953
  AnthropicToolCallingModel: () => AnthropicToolCallingModel,
954
+ BandACPServerAdapter: () => BandACPServerAdapter,
683
955
  CODEX_REASONING_EFFORTS: () => CODEX_REASONING_EFFORTS,
684
956
  CODEX_REASONING_SUMMARIES: () => CODEX_REASONING_SUMMARIES,
685
957
  CODEX_WEB_SEARCH_MODES: () => CODEX_WEB_SEARCH_MODES,
@@ -703,7 +975,6 @@ __export(adapters_exports, {
703
975
  OpencodeAdapter: () => OpencodeAdapter,
704
976
  ParlantAdapter: () => ParlantAdapter,
705
977
  ParlantHistoryConverter: () => ParlantHistoryConverter,
706
- ThenvoiACPServerAdapter: () => ThenvoiACPServerAdapter,
707
978
  ToolCallingAdapter: () => ToolCallingAdapter,
708
979
  VercelAISDKAdapter: () => VercelAISDKAdapter,
709
980
  VercelAISDKToolCallingModel: () => VercelAISDKToolCallingModel,
@@ -795,26 +1066,25 @@ var ACPClientHistoryConverter = class {
795
1066
  }
796
1067
  };
797
1068
 
798
- // src/runtime/prompts.ts
799
- var BASE_INSTRUCTIONS = `
1069
+ // src/runtime/prompts/base.ts
1070
+ var ENVIRONMENT_SECTION = `
800
1071
  ## Environment
801
1072
 
802
1073
  Multi-participant chat. Messages show sender: [Name]: content.
803
1074
  Messages prefixed with [System]: are platform updates (participant changes, contact updates, etc.) \u2014 not messages from users.
804
- Use \`thenvoi_send_message(content, mentions)\` to respond. Plain text output is not delivered.
805
- Mentions use handles: @<username> for users, @<username>/<agent-name> for agents.
806
-
807
- ## CRITICAL: Delegate When You Cannot Help Directly
1075
+ Use \`band_send_message(content, mentions)\` to respond. Plain text output is not delivered.
1076
+ Mentions use handles: @<username> for users, @<username>/<agent-name> for agents.`;
1077
+ var MULTI_AGENT_RULES_SECTION = `## CRITICAL: Delegate When You Cannot Help Directly
808
1078
 
809
1079
  You have NO internet access and NO real-time data. When asked about weather, news, stock prices,
810
1080
  or any current information you cannot answer directly:
811
1081
 
812
- 1. Call \`thenvoi_lookup_peers()\` to find available specialized agents
813
- 2. If a relevant agent exists, call \`thenvoi_add_participant(name)\` to add them
814
- 3. Ask that agent using \`thenvoi_send_message(question, mentions=[agent_handle])\`
1082
+ 1. Call \`band_lookup_peers()\` to find available specialized agents
1083
+ 2. If a relevant agent exists, call \`band_add_participant(name)\` to add them
1084
+ 3. Ask that agent using \`band_send_message(question, mentions=[agent_handle])\`
815
1085
  4. Wait for their response and relay it back to the user
816
1086
 
817
- NEVER say "I can't do that" without first checking if another agent can help via \`thenvoi_lookup_peers()\`.
1087
+ NEVER say "I can't do that" without first checking if another agent can help via \`band_lookup_peers()\`.
818
1088
 
819
1089
  ## CRITICAL: Do NOT Remove Agents Automatically
820
1090
 
@@ -830,48 +1100,113 @@ Only remove agents if the user explicitly requests it.
830
1100
  When someone asks you to get information from another agent:
831
1101
  1. Ask the other agent for the information
832
1102
  2. When you receive the response, IMMEDIATELY relay it back to the ORIGINAL REQUESTER
833
- 3. Do NOT just thank the helper agent - the requester is waiting for their answer!
1103
+ 3. Do NOT just thank the helper agent - the requester is waiting for their answer!`;
1104
+ var THINKING_SECTION = `## IMPORTANT: Always Share Your Thinking
834
1105
 
835
- ## IMPORTANT: Always Share Your Thinking
836
-
837
- You MUST call \`thenvoi_send_event(content, message_type="thought")\` BEFORE every action.
838
- This is required so users can see your reasoning process.
839
-
840
- ## Examples
1106
+ You MUST call \`band_send_event(content, message_type="thought")\` BEFORE every action.
1107
+ This is required so users can see your reasoning process.`;
1108
+ var EXAMPLES_SECTION = `## Examples
841
1109
 
842
1110
  ### Simple question - answer directly
843
1111
  [John Doe]: What's 2+2?
844
- -> thenvoi_send_event("Simple arithmetic, answering directly.", message_type="thought")
845
- -> thenvoi_send_message("4", mentions=["@john"])
1112
+ -> band_send_event("Simple arithmetic, answering directly.", message_type="thought")
1113
+ -> band_send_message("4", mentions=["@john"])
846
1114
 
847
1115
  ### User asks about weather (you cannot answer directly)
848
1116
  [John Doe]: What's the weather in Tokyo?
849
- -> thenvoi_send_event("I can't check weather directly. Looking for a Weather Agent.", message_type="thought")
850
- -> thenvoi_lookup_peers()
851
- -> thenvoi_send_event("Found Weather Agent. Adding to room.", message_type="thought")
852
- -> thenvoi_add_participant("Weather Agent")
853
- -> thenvoi_send_message("What's the weather in Tokyo?", mentions=["@john/weather-agent"])
1117
+ -> band_send_event("I can't check weather directly. Looking for a Weather Agent.", message_type="thought")
1118
+ -> band_lookup_peers()
1119
+ -> band_send_event("Found Weather Agent. Adding to room.", message_type="thought")
1120
+ -> band_add_participant("Weather Agent")
1121
+ -> band_send_message("What's the weather in Tokyo?", mentions=["@john/weather-agent"])
854
1122
 
855
1123
  [Weather Agent]: Tokyo is 15\xB0C and cloudy.
856
- -> thenvoi_send_event("Got weather response. Relaying back to John Doe.", message_type="thought")
857
- -> thenvoi_send_message("The weather in Tokyo is 15\xB0C and cloudy.", mentions=["@john"])
1124
+ -> band_send_event("Got weather response. Relaying back to John Doe.", message_type="thought")
1125
+ -> band_send_message("The weather in Tokyo is 15\xB0C and cloudy.", mentions=["@john"])
858
1126
 
859
1127
  ### No suitable agent available
860
1128
  [John Doe]: What's the stock price of AAPL?
861
- -> thenvoi_send_event("I can't check stock prices. Looking for a Stock Agent.", message_type="thought")
862
- -> thenvoi_lookup_peers()
863
- -> thenvoi_send_event("No stock agent available. Must inform user.", message_type="thought")
864
- -> thenvoi_send_message("I don't have access to stock prices, and there's no specialized agent available to help with that.", mentions=["@john"])
1129
+ -> band_send_event("I can't check stock prices. Looking for a Stock Agent.", message_type="thought")
1130
+ -> band_lookup_peers()
1131
+ -> band_send_event("No stock agent available. Must inform user.", message_type="thought")
1132
+ -> band_send_message("I don't have access to stock prices, and there's no specialized agent available to help with that.", mentions=["@john"])
865
1133
 
866
1134
  ### Follow-up question in same conversation
867
1135
  [John Doe]: What about London?
868
- -> thenvoi_send_event("Follow-up weather question. Asking Weather Agent.", message_type="thought")
869
- -> thenvoi_send_message("What's the weather in London?", mentions=["@john/weather-agent"])
1136
+ -> band_send_event("Follow-up weather question. Asking Weather Agent.", message_type="thought")
1137
+ -> band_send_message("What's the weather in London?", mentions=["@john/weather-agent"])
870
1138
 
871
1139
  [Weather Agent]: London is 8\xB0C and rainy.
872
- -> thenvoi_send_event("Got London weather. Relaying to John Doe.", message_type="thought")
873
- -> thenvoi_send_message("London is 8\xB0C and rainy.", mentions=["@john"])
874
- `;
1140
+ -> band_send_event("Got London weather. Relaying to John Doe.", message_type="thought")
1141
+ -> band_send_message("London is 8\xB0C and rainy.", mentions=["@john"])`;
1142
+ var BASE_INSTRUCTIONS = [
1143
+ ENVIRONMENT_SECTION,
1144
+ MULTI_AGENT_RULES_SECTION,
1145
+ THINKING_SECTION,
1146
+ EXAMPLES_SECTION
1147
+ ].join("\n\n") + "\n";
1148
+
1149
+ // src/runtime/prompts/memory.ts
1150
+ init_memory();
1151
+ init_schemas();
1152
+ var MEMORY_INTRO = `## Memory Tools
1153
+
1154
+ You have access to memory tools for storing and retrieving information
1155
+ across conversations. Use \`band_store_memory\` to persist important
1156
+ information and \`band_list_memories\` / \`band_get_memory\` to recall it.
1157
+ Use \`band_supersede_memory\` to mark outdated memories and
1158
+ \`band_archive_memory\` to hide memories that should be preserved.`;
1159
+ function longTermPattern(label, type, segment, scope) {
1160
+ return {
1161
+ label,
1162
+ system: MEMORY_SYSTEM.long_term,
1163
+ type,
1164
+ segment,
1165
+ scope
1166
+ };
1167
+ }
1168
+ var COMMON_MEMORY_PATTERNS = [
1169
+ longTermPattern("Facts learned about a specific agent/entity", MEMORY_TYPE.semantic, MEMORY_SEGMENT.agent, MEMORY_STORE_SCOPE.subject),
1170
+ longTermPattern("Events involving a specific person/agent", MEMORY_TYPE.episodic, MEMORY_SEGMENT.agent, MEMORY_STORE_SCOPE.subject),
1171
+ longTermPattern("A user's preferences or profile info", MEMORY_TYPE.semantic, MEMORY_SEGMENT.user, MEMORY_STORE_SCOPE.subject),
1172
+ longTermPattern("Org-wide knowledge or how to perform a task", MEMORY_TYPE.procedural, MEMORY_SEGMENT.tool, MEMORY_STORE_SCOPE.organization)
1173
+ ];
1174
+ function renderMemoryPattern(pattern) {
1175
+ return `- ${pattern.label}: \`system="${pattern.system}"\`, \`type="${pattern.type}"\`, \`segment="${pattern.segment}"\`, \`scope="${pattern.scope}"\``;
1176
+ }
1177
+ var MEMORY_COMMON_PATTERNS = [
1178
+ "Common patterns:",
1179
+ ...COMMON_MEMORY_PATTERNS.map(renderMemoryPattern)
1180
+ ].join("\n");
1181
+ var MEMORY_SCOPE_GUIDANCE = `Prefer \`scope="${MEMORY_STORE_SCOPE.subject}"\` whenever the memory is about a specific person or agent, so it
1182
+ stays attached to that subject rather than leaking org-wide. Storing with \`scope="${MEMORY_STORE_SCOPE.subject}"\` requires a
1183
+ real \`subject_id\` UUID, so resolve it first via \`band_lookup_peers\` or the participant list.
1184
+ Reserve \`scope="${MEMORY_STORE_SCOPE.organization}"\` for knowledge that is genuinely shared across the whole organization and
1185
+ is not about any one subject.`;
1186
+ function quoteChoices(values) {
1187
+ return values.map((value) => `\`"${value}"\``).join(" | ");
1188
+ }
1189
+ function memoryTypeLines() {
1190
+ return Object.entries(MEMORY_SYSTEM_TYPES).map(([system, types]) => ` - ${system}: ${quoteChoices(types)}`).join("\n");
1191
+ }
1192
+ function buildMemorySection() {
1193
+ const storeMemoryProps = TOOL_MODELS.band_store_memory.properties;
1194
+ const systems = storeMemoryProps.system.enum;
1195
+ const segments = storeMemoryProps.segment.enum;
1196
+ const scopes = storeMemoryProps.scope.enum;
1197
+ const fieldRules = `When calling \`band_store_memory\`, the \`system\`, \`type\`, \`segment\`, and \`scope\` fields
1198
+ must use these exact values (case-sensitive):
1199
+
1200
+ - **system**: ${quoteChoices(systems)}
1201
+ - **type** (must match the chosen system):
1202
+ ${memoryTypeLines()}
1203
+ - **segment**: ${quoteChoices(segments)}
1204
+ - **scope**: ${quoteChoices(scopes)}`;
1205
+ return [MEMORY_INTRO, fieldRules, MEMORY_COMMON_PATTERNS, MEMORY_SCOPE_GUIDANCE].join("\n\n");
1206
+ }
1207
+ var MEMORY_SECTION = buildMemorySection();
1208
+
1209
+ // src/runtime/prompts/templates.ts
875
1210
  var TEMPLATES = {
876
1211
  default: `You are {agent_name}, {agent_description}.
877
1212
 
@@ -890,18 +1225,48 @@ ${customSection}`.trim();
890
1225
  }
891
1226
  const template = options?.template ?? "default";
892
1227
  const templateString = TEMPLATES[template] ?? TEMPLATES.default;
893
- return templateString.replaceAll("{agent_name}", agentName).replaceAll("{agent_description}", agentDescription).replaceAll("{custom_section}", customSection);
1228
+ const parts = [
1229
+ templateString.replaceAll("{agent_name}", agentName).replaceAll("{agent_description}", agentDescription).replaceAll("{custom_section}", customSection)
1230
+ ];
1231
+ if (options?.capabilities?.memory) {
1232
+ parts.push(MEMORY_SECTION);
1233
+ }
1234
+ return parts.join("\n\n");
1235
+ }
1236
+
1237
+ // src/adapters/acp/ACPClientAdapter.ts
1238
+ init_schemas();
1239
+
1240
+ // src/mcp/auth.ts
1241
+ var import_node_crypto = require("crypto");
1242
+ function generateAuthToken() {
1243
+ return (0, import_node_crypto.randomBytes)(32).toString("hex");
1244
+ }
1245
+ function isAuthorizedRequest(authorizationHeader, authToken) {
1246
+ if (!authToken) {
1247
+ return true;
1248
+ }
1249
+ if (!authorizationHeader) {
1250
+ return false;
1251
+ }
1252
+ const expected = Buffer.from(`Bearer ${authToken}`);
1253
+ const actual = Buffer.from(authorizationHeader);
1254
+ if (expected.length !== actual.length) {
1255
+ return false;
1256
+ }
1257
+ return (0, import_node_crypto.timingSafeEqual)(expected, actual);
894
1258
  }
895
1259
 
896
1260
  // src/mcp/server.ts
897
1261
  init_registrations();
898
1262
  init_zod();
1263
+ init_schemas();
899
1264
  var PORT_RANGE_START = 5e4;
900
1265
  var PORT_RANGE_END = 6e4;
901
1266
  var MCP_SERVER_VERSION = "1.0.0";
902
1267
  var SESSION_IDLE_TTL_MS = 15 * 60 * 1e3;
903
1268
  var SESSION_SWEEP_INTERVAL_MS = 60 * 1e3;
904
- var ThenvoiMcpServer = class {
1269
+ var BandMcpServer = class {
905
1270
  options;
906
1271
  registrations;
907
1272
  httpServer = null;
@@ -945,7 +1310,7 @@ var ThenvoiMcpServer = class {
945
1310
  const http = await import("http");
946
1311
  const { randomUUID: randomUUID7 } = await import("crypto");
947
1312
  const { z: z4 } = await import("zod");
948
- const serverName = this.options.name ?? "thenvoi";
1313
+ const serverName = this.options.name ?? MCP_SERVER_NAME;
949
1314
  const app = express();
950
1315
  app.use(express.json());
951
1316
  app.get("/healthz", (_req, res) => {
@@ -953,6 +1318,10 @@ var ThenvoiMcpServer = class {
953
1318
  });
954
1319
  const handleMcpRequest = async (req, res) => {
955
1320
  try {
1321
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
1322
+ sendMcpError(res, 401, "Unauthorized");
1323
+ return;
1324
+ }
956
1325
  const sessionId = getSessionIdHeader(req.headers["mcp-session-id"]);
957
1326
  let session = sessionId ? this.sessions.get(sessionId) : void 0;
958
1327
  if (!session) {
@@ -1128,11 +1497,12 @@ function checkPort(http, port) {
1128
1497
  // src/mcp/sse.ts
1129
1498
  init_registrations();
1130
1499
  init_zod();
1500
+ init_schemas();
1131
1501
  var PORT_RANGE_START2 = 5e4;
1132
1502
  var PORT_RANGE_END2 = 6e4;
1133
1503
  var SESSION_IDLE_TTL_MS2 = 15 * 60 * 1e3;
1134
1504
  var SESSION_SWEEP_INTERVAL_MS2 = 60 * 1e3;
1135
- var ThenvoiMcpSseServer = class {
1505
+ var BandMcpSseServer = class {
1136
1506
  options;
1137
1507
  registrations;
1138
1508
  httpServer = null;
@@ -1179,10 +1549,14 @@ var ThenvoiMcpSseServer = class {
1179
1549
  app.get("/healthz", (_req, res) => {
1180
1550
  res.json({ status: "ok" });
1181
1551
  });
1182
- app.get("/sse", async (_req, res) => {
1552
+ app.get("/sse", async (req, res) => {
1553
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
1554
+ res.status(401).send("Unauthorized");
1555
+ return;
1556
+ }
1183
1557
  const transport = new SSEServerTransport("/messages", res);
1184
1558
  const mcpServer = new McpServer({
1185
- name: this.options.name ?? "thenvoi",
1559
+ name: this.options.name ?? MCP_SERVER_NAME,
1186
1560
  version: "1.0.0"
1187
1561
  });
1188
1562
  registerTools2(mcpServer, z4, this.registrations);
@@ -1204,6 +1578,10 @@ var ThenvoiMcpSseServer = class {
1204
1578
  });
1205
1579
  });
1206
1580
  app.post("/messages", async (req, res) => {
1581
+ if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
1582
+ res.status(401).send("Unauthorized");
1583
+ return;
1584
+ }
1207
1585
  const sessionId = typeof req.query.sessionId === "string" ? req.query.sessionId : null;
1208
1586
  if (!sessionId) {
1209
1587
  res.status(400).send("Missing sessionId");
@@ -1376,7 +1754,7 @@ function normalizeMcpServers(mcpServers) {
1376
1754
  }
1377
1755
 
1378
1756
  // src/adapters/acp/client.ts
1379
- var ThenvoiACPClient = class {
1757
+ var BandACPClient = class {
1380
1758
  sessionChunks = /* @__PURE__ */ new Map();
1381
1759
  permissionHandlers = /* @__PURE__ */ new Map();
1382
1760
  async sessionUpdate(params) {
@@ -1654,6 +2032,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
1654
2032
  activeSessions = /* @__PURE__ */ new Set();
1655
2033
  bootstrappedSessions = /* @__PURE__ */ new Set();
1656
2034
  backend = null;
2035
+ backendPromise = null;
1657
2036
  client = null;
1658
2037
  connectionHandle = null;
1659
2038
  connection = null;
@@ -1794,7 +2173,7 @@ ${message.content}`;
1794
2173
  }
1795
2174
  async spawnConnection() {
1796
2175
  const acp = await acpModule.get();
1797
- const client = new ThenvoiACPClient();
2176
+ const client = new BandACPClient();
1798
2177
  const handle = await this.connectionFactory(client, {
1799
2178
  command: this.command,
1800
2179
  cwd: this.cwd,
@@ -1826,11 +2205,11 @@ ${message.content}`;
1826
2205
  }
1827
2206
  async getOrCreateSession(roomId, connection) {
1828
2207
  const existingSessionId = this.roomToSession.get(roomId);
2208
+ if (existingSessionId && this.activeSessions.has(existingSessionId)) {
2209
+ return existingSessionId;
2210
+ }
1829
2211
  const mcpServers = await this.buildSessionMcpServers();
1830
2212
  if (existingSessionId) {
1831
- if (this.activeSessions.has(existingSessionId)) {
1832
- return existingSessionId;
1833
- }
1834
2213
  const restored = await this.tryRestoreSession(connection, existingSessionId, mcpServers);
1835
2214
  if (restored) {
1836
2215
  this.activeSessions.add(existingSessionId);
@@ -1878,26 +2257,26 @@ ${message.content}`;
1878
2257
  if (backend.kind === "http") {
1879
2258
  const url = backend.server.url;
1880
2259
  if (!url) {
1881
- throw new Error("Thenvoi MCP HTTP backend did not expose a URL");
2260
+ throw new Error("Band MCP HTTP backend did not expose a URL");
1882
2261
  }
1883
2262
  mcpServers.push({
1884
2263
  type: "http",
1885
- name: "thenvoi",
2264
+ name: MCP_SERVER_NAME,
1886
2265
  url,
1887
- headers: []
2266
+ headers: [{ name: "Authorization", value: `Bearer ${backend.authToken}` }]
1888
2267
  });
1889
2268
  return mcpServers;
1890
2269
  }
1891
2270
  if (backend.kind === "sse") {
1892
2271
  const url = backend.server.sseUrl;
1893
2272
  if (!url) {
1894
- throw new Error("Thenvoi MCP SSE backend did not expose a URL");
2273
+ throw new Error("Band MCP SSE backend did not expose a URL");
1895
2274
  }
1896
2275
  mcpServers.push({
1897
2276
  type: "sse",
1898
- name: "thenvoi",
2277
+ name: MCP_SERVER_NAME,
1899
2278
  url,
1900
- headers: []
2279
+ headers: [{ name: "Authorization", value: `Bearer ${backend.authToken}` }]
1901
2280
  });
1902
2281
  return mcpServers;
1903
2282
  }
@@ -1907,34 +2286,51 @@ ${message.content}`;
1907
2286
  if (this.backend) {
1908
2287
  return this.backend;
1909
2288
  }
1910
- const transport = this.connectionState?.agentCapabilities?.mcpCapabilities?.http ? "http" : this.connectionState?.agentCapabilities?.mcpCapabilities?.sse ? "sse" : "http";
2289
+ this.backendPromise ??= this.createBackend().finally(() => {
2290
+ this.backendPromise = null;
2291
+ });
2292
+ return this.backendPromise;
2293
+ }
2294
+ async createBackend() {
2295
+ const mcpCapabilities = this.connectionState?.agentCapabilities?.mcpCapabilities;
2296
+ const transport = mcpCapabilities?.http ? "http" : mcpCapabilities?.sse ? "sse" : null;
2297
+ if (transport === null) {
2298
+ throw new Error(
2299
+ "ACP agent does not advertise MCP transport support: its initialize response has mcpCapabilities.http and .sse both false or missing, so Band tools cannot be exposed to it over MCP."
2300
+ );
2301
+ }
2302
+ const authToken = generateAuthToken();
1911
2303
  if (transport === "sse") {
1912
- const server2 = new ThenvoiMcpSseServer({
2304
+ const server2 = new BandMcpSseServer({
1913
2305
  tools: (roomId) => this.roomTools.get(roomId),
1914
2306
  enableMemoryTools: this.enableMemoryTools,
1915
2307
  enableContactTools: true,
1916
- additionalTools: this.additionalMcpTools
2308
+ additionalTools: this.additionalMcpTools,
2309
+ authToken
1917
2310
  });
1918
2311
  await server2.start();
1919
2312
  this.backend = {
1920
2313
  kind: "sse",
1921
2314
  server: server2,
2315
+ authToken,
1922
2316
  stop: async () => {
1923
2317
  await server2.stop();
1924
2318
  }
1925
2319
  };
1926
2320
  return this.backend;
1927
2321
  }
1928
- const server = new ThenvoiMcpServer({
2322
+ const server = new BandMcpServer({
1929
2323
  tools: (roomId) => this.roomTools.get(roomId),
1930
2324
  enableMemoryTools: this.enableMemoryTools,
1931
2325
  enableContactTools: true,
1932
- additionalTools: this.additionalMcpTools
2326
+ additionalTools: this.additionalMcpTools,
2327
+ authToken
1933
2328
  });
1934
2329
  await server.start();
1935
2330
  this.backend = {
1936
2331
  kind: "http",
1937
2332
  server,
2333
+ authToken,
1938
2334
  stop: async () => {
1939
2335
  await server.stop();
1940
2336
  }
@@ -1949,14 +2345,14 @@ ${message.content}`;
1949
2345
  this.systemPrompt,
1950
2346
  "",
1951
2347
  "## Room Context",
1952
- "You are connected to Thenvoi using Thenvoi MCP tools.",
1953
- "Use the Thenvoi tools for any visible room action. Plain text output is not posted back to the room.",
2348
+ "You are connected to Band using Band MCP tools.",
2349
+ "Use the Band tools for any visible room action. Plain text output is not posted back to the room.",
1954
2350
  "",
1955
2351
  `Current room_id: ${roomId}`,
1956
2352
  `Current requester name: ${requesterName}`,
1957
2353
  `Current requester id: ${requesterId}`,
1958
2354
  "",
1959
- "All Thenvoi MCP tool calls must include room_id."
2355
+ "All Band MCP tool calls must include room_id."
1960
2356
  ].join("\n");
1961
2357
  }
1962
2358
  async handlePermissionRequest(tools, roomId, params) {
@@ -2065,8 +2461,8 @@ function toErrorMessage(error) {
2065
2461
  // src/adapters/acp/ACPServer.ts
2066
2462
  var import_node_stream2 = require("stream");
2067
2463
 
2068
- // src/adapters/acp/ThenvoiACPServerAdapter.ts
2069
- var import_node_crypto = require("crypto");
2464
+ // src/adapters/acp/BandACPServerAdapter.ts
2465
+ var import_node_crypto2 = require("crypto");
2070
2466
 
2071
2467
  // src/converters/acp-server.ts
2072
2468
  var ACPServerHistoryConverter = class {
@@ -2317,12 +2713,12 @@ var AgentRouter = class {
2317
2713
  }
2318
2714
  };
2319
2715
 
2320
- // src/adapters/acp/ThenvoiACPServerAdapter.ts
2716
+ // src/adapters/acp/BandACPServerAdapter.ts
2321
2717
  var DEFAULT_MAX_SESSIONS = 100;
2322
2718
  var DEFAULT_PROMPT_TIMEOUT_MS = 3e5;
2323
2719
  var DEFAULT_PROMPT_COMPLETION_GRACE_MS = 250;
2324
- var ThenvoiACPServerAdapter = class extends SimpleAdapter {
2325
- thenvoiRest;
2720
+ var BandACPServerAdapter = class extends SimpleAdapter {
2721
+ bandRest;
2326
2722
  maxSessions;
2327
2723
  responseTimeoutMs;
2328
2724
  promptCompletionGraceMs;
@@ -2343,7 +2739,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
2343
2739
  super({
2344
2740
  historyConverter: new ACPServerHistoryConverter()
2345
2741
  });
2346
- this.thenvoiRest = options.thenvoiRest;
2742
+ this.bandRest = options.bandRest;
2347
2743
  this.maxSessions = options.maxSessions ?? DEFAULT_MAX_SESSIONS;
2348
2744
  this.responseTimeoutMs = options.responseTimeoutMs ?? DEFAULT_PROMPT_TIMEOUT_MS;
2349
2745
  this.promptCompletionGraceMs = options.promptCompletionGraceMs ?? DEFAULT_PROMPT_COMPLETION_GRACE_MS;
@@ -2405,7 +2801,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
2405
2801
  }
2406
2802
  async verifyCredentials() {
2407
2803
  try {
2408
- await this.thenvoiRest.getAgentMe();
2804
+ await this.bandRest.getAgentMe();
2409
2805
  return true;
2410
2806
  } catch {
2411
2807
  return false;
@@ -2414,7 +2810,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
2414
2810
  async onStarted(agentName, agentDescription) {
2415
2811
  await super.onStarted(agentName, agentDescription);
2416
2812
  try {
2417
- const identity = await this.thenvoiRest.getAgentMe();
2813
+ const identity = await this.bandRest.getAgentMe();
2418
2814
  this.agentId = identity.id;
2419
2815
  } catch {
2420
2816
  this.agentId = null;
@@ -2428,8 +2824,8 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
2428
2824
  throw new Error(`Maximum ACP sessions (${this.maxSessions}) reached`);
2429
2825
  }
2430
2826
  try {
2431
- const room = await this.thenvoiRest.createChat();
2432
- const sessionId = (0, import_node_crypto.randomUUID)();
2827
+ const room = await this.bandRest.createChat();
2828
+ const sessionId = (0, import_node_crypto2.randomUUID)();
2433
2829
  const normalizedMcpServers = normalizeMcpServers(input.mcpServers);
2434
2830
  this.sessionToRoom.set(sessionId, room.id);
2435
2831
  this.roomToSession.set(room.id, sessionId);
@@ -2438,7 +2834,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
2438
2834
  this.sessionMcpServers.set(sessionId, normalizedMcpServers);
2439
2835
  }
2440
2836
  try {
2441
- await this.thenvoiRest.createChatEvent(room.id, {
2837
+ await this.bandRest.createChatEvent(room.id, {
2442
2838
  content: "ACP session context",
2443
2839
  messageType: "task",
2444
2840
  metadata: {
@@ -2471,10 +2867,10 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
2471
2867
  this.pendingPrompts.set(roomId, pending);
2472
2868
  const resolved = this.router.resolve(text, this.sessionModeIds.get(sessionId));
2473
2869
  const promptText = this.prependSessionContext(sessionId, resolved.text);
2474
- const participants = await this.thenvoiRest.listChatParticipants(roomId);
2870
+ const participants = await this.bandRest.listChatParticipants(roomId);
2475
2871
  const mentions = this.resolveMentions(participants, resolved.targetPeer);
2476
2872
  try {
2477
- await this.thenvoiRest.createChatMessage(roomId, {
2873
+ await this.bandRest.createChatMessage(roomId, {
2478
2874
  content: promptText,
2479
2875
  mentions
2480
2876
  });
@@ -2727,7 +3123,7 @@ var ACPServer = class {
2727
3123
  this.authMethods = options?.authMethods ?? [{
2728
3124
  id: "api_key",
2729
3125
  name: "API Key",
2730
- description: "Authenticate with THENVOI_API_KEY."
3126
+ description: "Authenticate with BAND_API_KEY (legacy THENVOI_API_KEY)."
2731
3127
  }];
2732
3128
  this.agentInfo = options?.agentInfo ?? {};
2733
3129
  this.extensionHandler = options?.extensionHandler ?? new CursorExtensionHandler();
@@ -2780,8 +3176,8 @@ var ACPServer = class {
2780
3176
  }
2781
3177
  },
2782
3178
  agentInfo: {
2783
- name: this.agentInfo.name ?? "thenvoi-agent",
2784
- title: this.agentInfo.title ?? this.adapter.displayName ?? "Thenvoi Agent",
3179
+ name: this.agentInfo.name ?? "band-agent",
3180
+ title: this.agentInfo.title ?? this.adapter.displayName ?? "Band Agent",
2785
3181
  version: this.agentInfo.version ?? "0.1.0"
2786
3182
  },
2787
3183
  authMethods: this.authMethods
@@ -2971,7 +3367,7 @@ function replaceUuidMentions(content, participants) {
2971
3367
  const participantId = participant.id;
2972
3368
  const handle = participant.handle;
2973
3369
  if (typeof participantId === "string" && typeof handle === "string") {
2974
- next = next.replaceAll(`@[[${participantId}]]`, `@${handle}`);
3370
+ next = next.replaceAll(`@[[${participantId}]]`, ensureHandlePrefix(handle) ?? "");
2975
3371
  }
2976
3372
  }
2977
3373
  return next;
@@ -4133,7 +4529,7 @@ var GeminiAdapter = class extends ToolCallingAdapter {
4133
4529
  };
4134
4530
 
4135
4531
  // src/adapters/google-adk/GoogleADKAdapter.ts
4136
- var import_node_crypto2 = require("crypto");
4532
+ var import_node_crypto3 = require("crypto");
4137
4533
 
4138
4534
  // src/adapters/shared/history.ts
4139
4535
  function findLatestTaskMetadata(raw, predicate) {
@@ -4290,7 +4686,7 @@ var GoogleADKHistoryConverter = class {
4290
4686
  };
4291
4687
 
4292
4688
  // src/adapters/google-adk/GoogleADKAdapter.ts
4293
- var APP_NAME = "thenvoi";
4689
+ var APP_NAME = "band";
4294
4690
  var DEFAULT_MAX_HISTORY_MESSAGES = 50;
4295
4691
  var DEFAULT_MAX_TRANSCRIPT_CHARS = 1e5;
4296
4692
  var MAX_TOOL_OUTPUT_PREVIEW = 200;
@@ -4390,7 +4786,8 @@ var GoogleADKAdapter = class extends SimpleAdapter {
4390
4786
  this.systemPrompt = this.systemPromptOverride ?? renderSystemPrompt({
4391
4787
  agentName,
4392
4788
  agentDescription,
4393
- customSection: this.customSection
4789
+ customSection: this.customSection,
4790
+ capabilities: { memory: this.enableMemoryTools }
4394
4791
  });
4395
4792
  }
4396
4793
  async onMessage(message, tools, history, participantsMessage, contactsMessage, context) {
@@ -4404,7 +4801,7 @@ var GoogleADKAdapter = class extends SimpleAdapter {
4404
4801
  agent: this.buildAgent(sdk, tools),
4405
4802
  appName: APP_NAME
4406
4803
  });
4407
- const sessionId = (0, import_node_crypto2.randomUUID)();
4804
+ const sessionId = (0, import_node_crypto3.randomUUID)();
4408
4805
  this.roomSessions.set(context.roomId, sessionId);
4409
4806
  await runner.sessionService.createSession({
4410
4807
  appName: APP_NAME,
@@ -4463,7 +4860,7 @@ var GoogleADKAdapter = class extends SimpleAdapter {
4463
4860
  }
4464
4861
  buildAgent(sdk, tools) {
4465
4862
  return sdk.createAgent({
4466
- name: this.agentName || "thenvoi_agent",
4863
+ name: this.agentName || "band_agent",
4467
4864
  model: this.model,
4468
4865
  instruction: this.systemPrompt,
4469
4866
  tools: this.buildTools(sdk, tools)
@@ -4630,7 +5027,8 @@ var LangGraphAdapter = class extends SimpleAdapter {
4630
5027
  this.renderedSystemPrompt = this.systemPromptOverride ?? renderSystemPrompt({
4631
5028
  agentName,
4632
5029
  agentDescription,
4633
- customSection: this.customSection
5030
+ customSection: this.customSection,
5031
+ capabilities: { memory: this.includeMemoryTools }
4634
5032
  });
4635
5033
  }
4636
5034
  async onMessage(message, tools, history, participantsMessage, contactsMessage, context) {
@@ -4649,14 +5047,17 @@ var LangGraphAdapter = class extends SimpleAdapter {
4649
5047
  ];
4650
5048
  }
4651
5049
  const graph = await this.resolveGraph(sdk, langGraphTools);
4652
- const messages = this.buildMessages(
4653
- history,
4654
- message,
4655
- participantsMessage,
4656
- contactsMessage,
4657
- context.isSessionBootstrap,
4658
- context.roomId
4659
- );
5050
+ const usesCheckpointer = Boolean(this.checkpointer);
5051
+ const isFirstBootstrap = context.isSessionBootstrap && !this.bootstrappedRooms.has(context.roomId);
5052
+ const replayHistory = !usesCheckpointer || isFirstBootstrap;
5053
+ const includeSystemPrompt = this.usesCustomGraph && (!usesCheckpointer || isFirstBootstrap);
5054
+ if (context.isSessionBootstrap) {
5055
+ this.bootstrappedRooms.add(context.roomId);
5056
+ }
5057
+ const messages = this.buildMessages(history, message, participantsMessage, contactsMessage, {
5058
+ replayHistory,
5059
+ includeSystemPrompt
5060
+ });
4660
5061
  const input = { messages };
4661
5062
  const graphConfig = {
4662
5063
  configurable: {
@@ -4683,6 +5084,10 @@ var LangGraphAdapter = class extends SimpleAdapter {
4683
5084
  async onCleanup(roomId) {
4684
5085
  this.bootstrappedRooms.delete(roomId);
4685
5086
  }
5087
+ /** A caller-supplied graph rather than the built-in createReactAgent. */
5088
+ get usesCustomGraph() {
5089
+ return Boolean(this.graph || this.graphFactory);
5090
+ }
4686
5091
  resolveGraph(sdk, langGraphTools) {
4687
5092
  if (this.graphFactory) {
4688
5093
  return Promise.resolve(this.graphFactory(langGraphTools));
@@ -4703,14 +5108,13 @@ var LangGraphAdapter = class extends SimpleAdapter {
4703
5108
  prompt: this.renderedSystemPrompt
4704
5109
  }));
4705
5110
  }
4706
- buildMessages(history, message, participantsMessage, contactsMessage, isSessionBootstrap, roomId) {
5111
+ buildMessages(history, message, participantsMessage, contactsMessage, options) {
4707
5112
  const messages = [];
4708
- if (isSessionBootstrap && !this.bootstrappedRooms.has(roomId)) {
5113
+ if (options.includeSystemPrompt) {
4709
5114
  messages.push(["system", this.renderedSystemPrompt]);
4710
- this.bootstrappedRooms.add(roomId);
4711
5115
  }
4712
- if (isSessionBootstrap && history.length > 0) {
4713
- const historical = history.raw.slice(-this.maxHistoryMessages);
5116
+ if (options.replayHistory && history.length > 0) {
5117
+ const historical = history.raw.filter((item) => item.id !== message.id).slice(-this.maxHistoryMessages);
4714
5118
  for (const item of historical) {
4715
5119
  const role = String(item.sender_type ?? "") === "Agent" ? "assistant" : "user";
4716
5120
  const content = String(item.content ?? "");
@@ -4729,7 +5133,7 @@ var LangGraphAdapter = class extends SimpleAdapter {
4729
5133
  return messages;
4730
5134
  }
4731
5135
  async forwardStreamEvents(graph, input, config, tools) {
4732
- const stream = graph.streamEvents?.(input, config, { version: "v2" });
5136
+ const stream = graph.streamEvents?.(input, { ...config, version: "v2" });
4733
5137
  if (!stream) {
4734
5138
  return null;
4735
5139
  }
@@ -4756,6 +5160,10 @@ var LangGraphAdapter = class extends SimpleAdapter {
4756
5160
  );
4757
5161
  }
4758
5162
  if (eventType === "on_chain_end") {
5163
+ const chainName = String(data.name ?? "");
5164
+ if (!this.usesCustomGraph && chainName !== "LangGraph" && chainName !== "agent") {
5165
+ continue;
5166
+ }
4759
5167
  const output = asOptionalRecord(data.data) ?? {};
4760
5168
  const text = extractAssistantText(output.output);
4761
5169
  if (text) {
@@ -4817,18 +5225,25 @@ function stringifyToolResult2(value, logger, toolName) {
4817
5225
  });
4818
5226
  }
4819
5227
  function extractAssistantText(result) {
4820
- if (typeof result === "string" && result.trim().length > 0) {
4821
- return result.trim();
5228
+ if (typeof result === "string") {
5229
+ const trimmed = result.trim();
5230
+ return trimmed.length > 0 && !isInternalLangGraphMarker(trimmed) ? trimmed : null;
4822
5231
  }
4823
5232
  const record = asOptionalRecord(result) ?? {};
5233
+ if (isLangChainAssistantMessage(record)) {
5234
+ const text = asLangChainMessageContent(record);
5235
+ if (text && !isInternalLangGraphMarker(text)) {
5236
+ return text;
5237
+ }
5238
+ }
4824
5239
  const directContent = asMessageContent(record.content);
4825
- if (directContent) {
5240
+ if (directContent && !isInternalLangGraphMarker(directContent)) {
4826
5241
  return directContent;
4827
5242
  }
4828
5243
  const messages = Array.isArray(record.messages) ? record.messages : [];
4829
5244
  for (let index = messages.length - 1; index >= 0; index -= 1) {
4830
5245
  const text = asMessageText(messages[index]);
4831
- if (text) {
5246
+ if (text && !isInternalLangGraphMarker(text)) {
4832
5247
  return text;
4833
5248
  }
4834
5249
  }
@@ -4845,12 +5260,40 @@ function asMessageText(value) {
4845
5260
  if (!record) {
4846
5261
  return null;
4847
5262
  }
5263
+ if (isLangChainAssistantMessage(record)) {
5264
+ return asLangChainMessageContent(record);
5265
+ }
4848
5266
  const role = String(record.role ?? "");
4849
5267
  if (role !== "assistant") {
4850
5268
  return null;
4851
5269
  }
4852
5270
  return asMessageContent(record.content);
4853
5271
  }
5272
+ function isLangChainAssistantMessage(record) {
5273
+ const id = record.id;
5274
+ if (Array.isArray(id)) {
5275
+ const typeName = String(id[id.length - 1] ?? "");
5276
+ if (typeName === "AIMessage" || typeName === "AIMessageChunk") {
5277
+ return true;
5278
+ }
5279
+ }
5280
+ const getType = record.getType;
5281
+ if (typeof getType === "function") {
5282
+ try {
5283
+ return getType.call(record) === "ai";
5284
+ } catch {
5285
+ return false;
5286
+ }
5287
+ }
5288
+ return false;
5289
+ }
5290
+ function asLangChainMessageContent(record) {
5291
+ const kwargs = asOptionalRecord(record.kwargs);
5292
+ return asMessageContent(kwargs?.content ?? record.content);
5293
+ }
5294
+ function isInternalLangGraphMarker(text) {
5295
+ return text === "__end__" || text === "__start__";
5296
+ }
4854
5297
  function asMessageContent(value) {
4855
5298
  if (typeof value === "string" && value.trim().length > 0) {
4856
5299
  return value.trim();
@@ -4910,7 +5353,7 @@ function stringifyJsonWithFallback(value, logger, context) {
4910
5353
  }
4911
5354
 
4912
5355
  // src/adapters/a2a/A2AAdapter.ts
4913
- var import_node_crypto3 = require("crypto");
5356
+ var import_node_crypto4 = require("crypto");
4914
5357
  init_errors();
4915
5358
 
4916
5359
  // src/adapters/a2a/types.ts
@@ -5169,7 +5612,7 @@ var A2AAdapter = class extends SimpleAdapter {
5169
5612
  return {
5170
5613
  message: {
5171
5614
  kind: "message",
5172
- messageId: (0, import_node_crypto3.randomUUID)(),
5615
+ messageId: (0, import_node_crypto4.randomUUID)(),
5173
5616
  role: "user",
5174
5617
  parts: [{ kind: "text", text: message.content }],
5175
5618
  ...contextId ? { contextId } : {},
@@ -5463,7 +5906,7 @@ function createAuthFetch(authHeaders) {
5463
5906
  }
5464
5907
 
5465
5908
  // src/adapters/a2a-gateway/A2AGatewayAdapter.ts
5466
- var import_node_crypto6 = require("crypto");
5909
+ var import_node_crypto7 = require("crypto");
5467
5910
  init_errors();
5468
5911
 
5469
5912
  // src/adapters/a2a-gateway/history.ts
@@ -5502,10 +5945,10 @@ var GatewayHistoryConverter = class {
5502
5945
  };
5503
5946
 
5504
5947
  // src/adapters/a2a-gateway/server.ts
5505
- var import_node_crypto5 = require("crypto");
5948
+ var import_node_crypto6 = require("crypto");
5506
5949
 
5507
5950
  // src/adapters/a2a-gateway/statusEvent.ts
5508
- var import_node_crypto4 = require("crypto");
5951
+ var import_node_crypto5 = require("crypto");
5509
5952
  function buildStatusEvent(input) {
5510
5953
  return {
5511
5954
  kind: "status-update",
@@ -5517,7 +5960,7 @@ function buildStatusEvent(input) {
5517
5960
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5518
5961
  message: {
5519
5962
  kind: "message",
5520
- messageId: (0, import_node_crypto4.randomUUID)(),
5963
+ messageId: (0, import_node_crypto5.randomUUID)(),
5521
5964
  role: "agent",
5522
5965
  taskId: input.taskId,
5523
5966
  contextId: input.contextId,
@@ -5544,8 +5987,8 @@ var GatewayPeerExecutor = class {
5544
5987
  this.onCancel = options.onCancel;
5545
5988
  }
5546
5989
  async execute(requestContext, eventBus) {
5547
- const taskId = asNonEmptyString2(requestContext.taskId) ?? (0, import_node_crypto5.randomUUID)();
5548
- const contextId = asNonEmptyString2(requestContext.contextId) ?? (0, import_node_crypto5.randomUUID)();
5990
+ const taskId = asNonEmptyString2(requestContext.taskId) ?? (0, import_node_crypto6.randomUUID)();
5991
+ const contextId = asNonEmptyString2(requestContext.contextId) ?? (0, import_node_crypto6.randomUUID)();
5549
5992
  const message = asA2AMessage(requestContext.userMessage, contextId, taskId);
5550
5993
  try {
5551
5994
  for await (const event of this.onRequest({
@@ -5585,7 +6028,7 @@ var GatewayPeerExecutor = class {
5585
6028
  eventBus.publish(
5586
6029
  buildStatusEvent({
5587
6030
  taskId,
5588
- contextId: (0, import_node_crypto5.randomUUID)(),
6031
+ contextId: (0, import_node_crypto6.randomUUID)(),
5589
6032
  state: "canceled",
5590
6033
  final: true,
5591
6034
  text: "Task canceled."
@@ -5780,7 +6223,7 @@ function buildAgentCard(peer, gatewayUrl) {
5780
6223
  id: "default",
5781
6224
  name: peer.name,
5782
6225
  description: peer.description,
5783
- tags: ["thenvoi", "gateway"]
6226
+ tags: ["band", "gateway"]
5784
6227
  }
5785
6228
  ],
5786
6229
  defaultInputModes: ["text/plain"],
@@ -5791,7 +6234,7 @@ function asA2AMessage(value, fallbackContextId, fallbackTaskId) {
5791
6234
  if (!value || typeof value !== "object") {
5792
6235
  return {
5793
6236
  kind: "message",
5794
- messageId: (0, import_node_crypto5.randomUUID)(),
6237
+ messageId: (0, import_node_crypto6.randomUUID)(),
5795
6238
  role: "user",
5796
6239
  contextId: fallbackContextId,
5797
6240
  taskId: fallbackTaskId,
@@ -5816,7 +6259,7 @@ function asA2AMessage(value, fallbackContextId, fallbackTaskId) {
5816
6259
  }
5817
6260
  return {
5818
6261
  kind: "message",
5819
- messageId: asNonEmptyString2(raw.messageId) ?? (0, import_node_crypto5.randomUUID)(),
6262
+ messageId: asNonEmptyString2(raw.messageId) ?? (0, import_node_crypto6.randomUUID)(),
5820
6263
  role: asNonEmptyString2(raw.role) === "agent" ? "agent" : "user",
5821
6264
  contextId: asNonEmptyString2(raw.contextId) ?? fallbackContextId,
5822
6265
  taskId: asNonEmptyString2(raw.taskId) ?? fallbackTaskId,
@@ -5951,7 +6394,7 @@ function safeHeaderEquals(left, right) {
5951
6394
  if (leftBuffer.length !== rightBuffer.length) {
5952
6395
  return false;
5953
6396
  }
5954
- return (0, import_node_crypto5.timingSafeEqual)(leftBuffer, rightBuffer);
6397
+ return (0, import_node_crypto6.timingSafeEqual)(leftBuffer, rightBuffer);
5955
6398
  }
5956
6399
 
5957
6400
  // src/adapters/a2a-gateway/A2AGatewayAdapter.ts
@@ -5962,7 +6405,7 @@ var DEFAULT_RESPONSE_TIMEOUT_MS = 12e4;
5962
6405
  var DEFAULT_PEER_PAGE_SIZE = 100;
5963
6406
  var DEFAULT_MAX_PEER_PAGES = 25;
5964
6407
  var A2AGatewayAdapter = class extends SimpleAdapter {
5965
- thenvoiRest;
6408
+ bandRest;
5966
6409
  gatewayUrl;
5967
6410
  host;
5968
6411
  port;
@@ -5983,7 +6426,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
5983
6426
  super({
5984
6427
  historyConverter: new GatewayHistoryConverter()
5985
6428
  });
5986
- this.thenvoiRest = options.thenvoiRest;
6429
+ this.bandRest = options.bandRest;
5987
6430
  this.gatewayUrl = options.gatewayUrl ?? DEFAULT_GATEWAY_URL;
5988
6431
  this.host = options.host ?? DEFAULT_HOST;
5989
6432
  this.port = options.port ?? DEFAULT_PORT;
@@ -6063,13 +6506,13 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
6063
6506
  async refreshPeers() {
6064
6507
  this.peersBySlug.clear();
6065
6508
  this.peersById.clear();
6066
- if (!this.thenvoiRest.listPeers) {
6509
+ if (!this.bandRest.listPeers) {
6067
6510
  throw new UnsupportedFeatureError(
6068
6511
  "Peer listing is not available in current REST adapter"
6069
6512
  );
6070
6513
  }
6071
6514
  for (let page = 1; page <= this.maxPeerPages; page += 1) {
6072
- const response = await this.thenvoiRest.listPeers({
6515
+ const response = await this.bandRest.listPeers({
6073
6516
  page,
6074
6517
  pageSize: this.peerPageSize,
6075
6518
  notInChat: ""
@@ -6139,7 +6582,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
6139
6582
  try {
6140
6583
  await this.emitContextEvent(roomId, contextId);
6141
6584
  const content = extractMessageText2(request.message) ?? "";
6142
- await this.thenvoiRest.createChatMessage(roomId, {
6585
+ await this.bandRest.createChatMessage(roomId, {
6143
6586
  content: buildMentionedContent(peer.name, content),
6144
6587
  mentions: buildMentions(peer),
6145
6588
  metadata: {
@@ -6170,7 +6613,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
6170
6613
  contextId: pending.contextId,
6171
6614
  state: "failed",
6172
6615
  final: true,
6173
- text: "Timed out waiting for a Thenvoi peer response."
6616
+ text: "Timed out waiting for a Band peer response."
6174
6617
  });
6175
6618
  return;
6176
6619
  }
@@ -6257,7 +6700,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
6257
6700
  if (existingRoom) {
6258
6701
  const participants = this.roomParticipants.get(existingRoom) ?? /* @__PURE__ */ new Set();
6259
6702
  if (!participants.has(targetPeerId)) {
6260
- await this.thenvoiRest.addChatParticipant(existingRoom, {
6703
+ await this.bandRest.addChatParticipant(existingRoom, {
6261
6704
  participantId: targetPeerId,
6262
6705
  role: "member"
6263
6706
  });
@@ -6266,12 +6709,12 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
6266
6709
  }
6267
6710
  return [existingRoom, contextId];
6268
6711
  }
6269
- const normalizedContextId = contextId && contextId.length > 0 ? contextId : (0, import_node_crypto6.randomUUID)();
6270
- const created = await this.thenvoiRest.createChat(
6712
+ const normalizedContextId = contextId && contextId.length > 0 ? contextId : (0, import_node_crypto7.randomUUID)();
6713
+ const created = await this.bandRest.createChat(
6271
6714
  `a2a:gateway:${normalizedContextId}`
6272
6715
  );
6273
6716
  const roomId = created.id;
6274
- await this.thenvoiRest.addChatParticipant(roomId, {
6717
+ await this.bandRest.addChatParticipant(roomId, {
6275
6718
  participantId: targetPeerId,
6276
6719
  role: "member"
6277
6720
  });
@@ -6280,7 +6723,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
6280
6723
  return [roomId, normalizedContextId];
6281
6724
  }
6282
6725
  async emitContextEvent(roomId, contextId) {
6283
- await this.thenvoiRest.createChatEvent(roomId, {
6726
+ await this.bandRest.createChatEvent(roomId, {
6284
6727
  content: "A2A gateway context",
6285
6728
  messageType: "task",
6286
6729
  metadata: {
@@ -6458,10 +6901,10 @@ function toStatusUpdateEvent(message, taskId, contextId) {
6458
6901
  final,
6459
6902
  text: message.content,
6460
6903
  metadata: {
6461
- thenvoi_message_id: message.id,
6462
- thenvoi_message_type: message.messageType,
6463
- thenvoi_sender_id: message.senderId,
6464
- thenvoi_room_id: message.roomId
6904
+ band_message_id: message.id,
6905
+ band_message_type: message.messageType,
6906
+ band_sender_id: message.senderId,
6907
+ band_room_id: message.roomId
6465
6908
  }
6466
6909
  });
6467
6910
  }
@@ -6631,8 +7074,8 @@ var ParlantAdapter = class extends SimpleAdapter {
6631
7074
  message: userMessage,
6632
7075
  moderation: "none",
6633
7076
  metadata: {
6634
- thenvoi_source: "thenvoi-sdk-typescript",
6635
- thenvoi_room_id: context.roomId
7077
+ band_source: "band-sdk-typescript",
7078
+ band_room_id: context.roomId
6636
7079
  }
6637
7080
  },
6638
7081
  this.requestOptions()
@@ -6707,9 +7150,9 @@ var ParlantAdapter = class extends SimpleAdapter {
6707
7150
  {
6708
7151
  agentId: this.agentId,
6709
7152
  customerId,
6710
- title: `Thenvoi Room ${roomId.slice(0, 8)}`,
7153
+ title: `Band Room ${roomId.slice(0, 8)}`,
6711
7154
  metadata: {
6712
- thenvoi_room_id: roomId
7155
+ band_room_id: roomId
6713
7156
  }
6714
7157
  },
6715
7158
  this.requestOptions()
@@ -6722,7 +7165,7 @@ var ParlantAdapter = class extends SimpleAdapter {
6722
7165
  source: "system",
6723
7166
  message: this.systemPrompt,
6724
7167
  metadata: {
6725
- thenvoi_system_prompt: true
7168
+ band_system_prompt: true
6726
7169
  }
6727
7170
  },
6728
7171
  this.requestOptions()
@@ -6776,7 +7219,7 @@ var ParlantAdapter = class extends SimpleAdapter {
6776
7219
  {
6777
7220
  name: customerName,
6778
7221
  metadata: {
6779
- thenvoi_room_id: roomId
7222
+ band_room_id: roomId
6780
7223
  }
6781
7224
  },
6782
7225
  this.requestOptions()
@@ -7326,7 +7769,7 @@ var LettaAdapter = class extends SimpleAdapter {
7326
7769
  const agent = await this.raceTimeout(
7327
7770
  (s) => client.agents.create(
7328
7771
  {
7329
- name: `thenvoi-room-${roomId.slice(0, 16)}`,
7772
+ name: `band-room-${roomId.slice(0, 16)}`,
7330
7773
  model: this.model,
7331
7774
  ...this.embedding ? { embedding: this.embedding } : {},
7332
7775
  system: this.systemPrompt || void 0,
@@ -7743,7 +8186,8 @@ init_registrations();
7743
8186
  // src/mcp/stdio.ts
7744
8187
  init_registrations();
7745
8188
  init_zod();
7746
- var ThenvoiMcpStdioServer = class {
8189
+ init_schemas();
8190
+ var BandMcpStdioServer = class {
7747
8191
  options;
7748
8192
  registrations;
7749
8193
  mcpServer = null;
@@ -7772,7 +8216,7 @@ var ThenvoiMcpStdioServer = class {
7772
8216
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
7773
8217
  const { z: z4 } = await import("zod");
7774
8218
  const mcpServer = new McpServer({
7775
- name: this.options.name ?? "thenvoi",
8219
+ name: this.options.name ?? MCP_SERVER_NAME,
7776
8220
  version: "1.0.0"
7777
8221
  });
7778
8222
  registerTools3(mcpServer, z4, this.registrations);
@@ -7803,21 +8247,18 @@ function registerTools3(mcpServer, z4, registrations) {
7803
8247
  }
7804
8248
 
7805
8249
  // src/mcp/backends.ts
7806
- async function createThenvoiMcpBackend(options) {
7807
- const registrations = buildRoomScopedRegistrations(
7808
- options.getToolsForRoom,
7809
- {
7810
- enableMemoryTools: options.enableMemoryTools,
7811
- enableContactTools: true,
7812
- additionalTools: options.additionalTools
7813
- }
7814
- );
7815
- const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
8250
+ async function createBandMcpBackend(options) {
8251
+ const registrationOptions = {
8252
+ enableMemoryTools: options.enableMemoryTools,
8253
+ enableContactTools: true,
8254
+ additionalTools: options.additionalTools
8255
+ };
7816
8256
  if (options.kind === "sdk") {
7817
- const { createThenvoiSdkMcpServer: createThenvoiSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
7818
- const server2 = createThenvoiSdkMcpServer2({
7819
- enableMemoryTools: options.enableMemoryTools,
8257
+ const { createBandSdkMcpServer: createBandSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
8258
+ const server2 = createBandSdkMcpServer2({
7820
8259
  getToolsForRoom: options.getToolsForRoom,
8260
+ multiRoom: options.multiRoom,
8261
+ enableMemoryTools: options.enableMemoryTools,
7821
8262
  additionalTools: options.additionalTools
7822
8263
  });
7823
8264
  return {
@@ -7827,9 +8268,12 @@ async function createThenvoiMcpBackend(options) {
7827
8268
  stop: async () => void 0
7828
8269
  };
7829
8270
  }
8271
+ const resolvedTools = options.multiRoom === false ? resolveSingleRoomTools(options.getToolsForRoom) : options.getToolsForRoom;
8272
+ const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolvedTools, registrationOptions) : buildRoomScopedRegistrations(resolvedTools, registrationOptions);
8273
+ const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
7830
8274
  if (options.kind === "stdio") {
7831
- const server2 = new ThenvoiMcpStdioServer({
7832
- tools: options.getToolsForRoom,
8275
+ const server2 = new BandMcpStdioServer({
8276
+ tools: resolvedTools,
7833
8277
  enableMemoryTools: options.enableMemoryTools,
7834
8278
  enableContactTools: true,
7835
8279
  additionalTools: options.additionalTools
@@ -7844,34 +8288,39 @@ async function createThenvoiMcpBackend(options) {
7844
8288
  }
7845
8289
  };
7846
8290
  }
8291
+ const authToken = generateAuthToken();
7847
8292
  if (options.kind === "sse") {
7848
- const server2 = new ThenvoiMcpSseServer({
7849
- tools: options.getToolsForRoom,
8293
+ const server2 = new BandMcpSseServer({
8294
+ tools: resolvedTools,
7850
8295
  enableMemoryTools: options.enableMemoryTools,
7851
8296
  enableContactTools: true,
7852
- additionalTools: options.additionalTools
8297
+ additionalTools: options.additionalTools,
8298
+ authToken
7853
8299
  });
7854
8300
  await server2.start();
7855
8301
  return {
7856
8302
  kind: "sse",
7857
8303
  server: server2,
7858
8304
  allowedTools,
8305
+ authToken,
7859
8306
  stop: async () => {
7860
8307
  await server2.stop();
7861
8308
  }
7862
8309
  };
7863
8310
  }
7864
- const server = new ThenvoiMcpServer({
7865
- tools: options.getToolsForRoom,
8311
+ const server = new BandMcpServer({
8312
+ tools: resolvedTools,
7866
8313
  enableMemoryTools: options.enableMemoryTools,
7867
8314
  enableContactTools: true,
7868
- additionalTools: options.additionalTools
8315
+ additionalTools: options.additionalTools,
8316
+ authToken
7869
8317
  });
7870
8318
  await server.start();
7871
8319
  return {
7872
8320
  kind: "http",
7873
8321
  server,
7874
8322
  allowedTools,
8323
+ authToken,
7875
8324
  stop: async () => {
7876
8325
  await server.stop();
7877
8326
  }
@@ -7880,6 +8329,7 @@ async function createThenvoiMcpBackend(options) {
7880
8329
 
7881
8330
  // src/adapters/opencode/OpencodeAdapter.ts
7882
8331
  init_registrations();
8332
+ init_schemas();
7883
8333
 
7884
8334
  // src/converters/opencode.ts
7885
8335
  var OpencodeHistoryConverter = class {
@@ -8013,7 +8463,7 @@ var SdkOpencodeClientBase = class {
8013
8463
  const result = await runtime.client.mcp.add({
8014
8464
  ...this.scope(),
8015
8465
  name: input.name,
8016
- config: { type: "remote", url: input.url }
8466
+ config: { type: "remote", url: input.url, headers: input.headers }
8017
8467
  });
8018
8468
  return expectRecord(result);
8019
8469
  }
@@ -8204,8 +8654,8 @@ async function readResponseBody(response) {
8204
8654
 
8205
8655
  // src/adapters/opencode/OpencodeAdapter.ts
8206
8656
  var OPENCODE_SYSTEM_NOTE = [
8207
- "Responses are relayed back into the Thenvoi room by the adapter.",
8208
- "Use the thenvoi_ prefixed tools (for example thenvoi_send_message) for Thenvoi platform actions when available.",
8657
+ "Responses are relayed back into the Band room by the adapter.",
8658
+ "Use the band_ prefixed tools (for example band_send_message) for Band platform actions when available.",
8209
8659
  "When you need approval or clarification, ask clearly and wait for the user's next room message."
8210
8660
  ].join("\n");
8211
8661
  function createDeferred() {
@@ -8236,8 +8686,8 @@ function withDefaults(config) {
8236
8686
  approvalTimeoutReply: "reject",
8237
8687
  questionMode: "manual",
8238
8688
  questionWaitTimeoutMs: 3e5,
8239
- sessionTitlePrefix: "Thenvoi",
8240
- mcpServerName: "thenvoi",
8689
+ sessionTitlePrefix: "Band",
8690
+ mcpServerName: MCP_SERVER_NAME,
8241
8691
  ...config
8242
8692
  };
8243
8693
  }
@@ -8293,7 +8743,7 @@ var OpencodeAdapter = class extends SimpleAdapter {
8293
8743
  directory: config.directory || void 0,
8294
8744
  workspace: config.workspace || void 0
8295
8745
  }));
8296
- this.mcpBackendFactory = options.mcpBackendFactory ?? createThenvoiMcpBackend;
8746
+ this.mcpBackendFactory = options.mcpBackendFactory ?? createBandMcpBackend;
8297
8747
  this.logger = options.logger ?? new NoopLogger();
8298
8748
  }
8299
8749
  async onStarted(agentName, agentDescription) {
@@ -8302,7 +8752,8 @@ var OpencodeAdapter = class extends SimpleAdapter {
8302
8752
  agentName,
8303
8753
  agentDescription,
8304
8754
  customSection: this.config.customSection,
8305
- includeBaseInstructions: this.config.includeBaseInstructions
8755
+ includeBaseInstructions: this.config.includeBaseInstructions,
8756
+ capabilities: { memory: this.config.enableMemoryTools }
8306
8757
  }).trim();
8307
8758
  this.systemPrompt = `${systemPrompt}
8308
8759
 
@@ -8446,7 +8897,8 @@ ${OPENCODE_SYSTEM_NOTE}`.trim();
8446
8897
  }
8447
8898
  await client.registerMcpServer({
8448
8899
  name: this.config.mcpServerName,
8449
- url: server.url
8900
+ url: server.url,
8901
+ headers: backend.authToken ? { Authorization: `Bearer ${backend.authToken}` } : void 0
8450
8902
  });
8451
8903
  } catch (error) {
8452
8904
  this.logger.warn("Failed to register OpenCode MCP backend", { error });
@@ -9084,7 +9536,7 @@ init_registrations();
9084
9536
  init_zod();
9085
9537
  var import_zod8 = require("zod");
9086
9538
  var DEFAULT_MODEL2 = "claude-sonnet-4-6";
9087
- var thenvoiMcpBridgeFactory = new LazyAsyncValue({
9539
+ var bandMcpBridgeFactory = new LazyAsyncValue({
9088
9540
  load: async () => {
9089
9541
  const module2 = await import("@anthropic-ai/claude-agent-sdk").catch((error) => {
9090
9542
  throw new UnsupportedFeatureError(
@@ -9122,7 +9574,7 @@ var thenvoiMcpBridgeFactory = new LazyAsyncValue({
9122
9574
  });
9123
9575
  return {
9124
9576
  serverConfig: createSdkMcpServer2({
9125
- name: "thenvoi",
9577
+ name: MCP_SERVER_NAME,
9126
9578
  tools: toolDefinitions
9127
9579
  }),
9128
9580
  allowedTools: mcpToolNames(new Set(registrations.map((registration) => registration.name)))
@@ -9169,11 +9621,12 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
9169
9621
  agentName,
9170
9622
  agentDescription,
9171
9623
  customSection: this.customSection,
9172
- includeBaseInstructions: this.includeBaseInstructions
9624
+ includeBaseInstructions: this.includeBaseInstructions,
9625
+ capabilities: { memory: this.enableMemoryTools }
9173
9626
  });
9174
9627
  if (this.enableMcpTools) {
9175
- const createThenvoiMcpBridge = await thenvoiMcpBridgeFactory.get();
9176
- this.mcpBridge = createThenvoiMcpBridge({
9628
+ const createBandMcpBridge = await bandMcpBridgeFactory.get();
9629
+ this.mcpBridge = createBandMcpBridge({
9177
9630
  enableMemoryTools: this.enableMemoryTools,
9178
9631
  getToolsForRoom: (roomId) => this.roomTools.get(roomId),
9179
9632
  additionalTools: this.additionalMcpTools.length > 0 ? this.additionalMcpTools : void 0
@@ -9221,14 +9674,14 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
9221
9674
  }
9222
9675
  if (this.mcpBridge && this.enableMcpTools) {
9223
9676
  options.mcpServers = {
9224
- thenvoi: this.mcpBridge.serverConfig
9677
+ [MCP_SERVER_NAME]: this.mcpBridge.serverConfig
9225
9678
  };
9226
9679
  options.allowedTools = this.mcpBridge.allowedTools;
9227
9680
  this.roomTools.set(context.roomId, tools);
9228
9681
  }
9229
9682
  const roomToolHint = this.enableMcpTools ? `
9230
9683
 
9231
- [Tooling note]: For any mcp__thenvoi__* tool call, pass room_id="${context.roomId}".` : "";
9684
+ [Tooling note]: For any mcp__band__* tool call, pass room_id="${context.roomId}".` : "";
9232
9685
  const query = queryFn({
9233
9686
  prompt: buildConversationPrompt({
9234
9687
  history,
@@ -9317,6 +9770,7 @@ function extractAssistantText3(event) {
9317
9770
 
9318
9771
  // src/adapters/codex/CodexAdapter.ts
9319
9772
  init_protocols();
9773
+ init_schemas();
9320
9774
 
9321
9775
  // src/adapters/codex/appServerClient.ts
9322
9776
  var import_node_child_process2 = require("child_process");
@@ -9616,8 +10070,8 @@ var CODEX_WEB_SEARCH_MODES = ["disabled", "cached", "live"];
9616
10070
  var CODEX_REASONING_SUMMARIES = ["auto", "concise", "detailed", "none"];
9617
10071
  var CODEX_REASONING_EFFORTS = ["low", "medium", "high", "xhigh"];
9618
10072
  var SILENT_REPORTING_TOOLS = /* @__PURE__ */ new Set([
9619
- "thenvoi_send_message",
9620
- "thenvoi_send_event"
10073
+ SEND_MESSAGE_TOOL_NAME,
10074
+ SEND_EVENT_TOOL_NAME
9621
10075
  ]);
9622
10076
  var CodexAdapter = class extends SimpleAdapter {
9623
10077
  baseConfig;
@@ -9647,8 +10101,8 @@ var CodexAdapter = class extends SimpleAdapter {
9647
10101
  includeBaseInstructions: true,
9648
10102
  experimentalApi: true,
9649
10103
  fallbackSendAgentText: true,
9650
- clientName: "thenvoi_codex_adapter",
9651
- clientTitle: "Thenvoi Codex Adapter",
10104
+ clientName: "band_codex_adapter",
10105
+ clientTitle: "Band Codex Adapter",
9652
10106
  clientVersion: "0.1.0",
9653
10107
  turnTimeoutMs: 18e4,
9654
10108
  ...options?.config
@@ -9889,7 +10343,8 @@ var CodexAdapter = class extends SimpleAdapter {
9889
10343
  agentName: this.agentName,
9890
10344
  agentDescription: this.agentDescription,
9891
10345
  customSection,
9892
- includeBaseInstructions: this.baseConfig.includeBaseInstructions ?? true
10346
+ includeBaseInstructions: this.baseConfig.includeBaseInstructions ?? true,
10347
+ capabilities: { memory: this.includeMemoryTools }
9893
10348
  }).trim();
9894
10349
  this.systemPrompt = prompt.length > 0 ? prompt : null;
9895
10350
  }
@@ -9913,8 +10368,8 @@ var CodexAdapter = class extends SimpleAdapter {
9913
10368
  await client.connect();
9914
10369
  await client.initialize({
9915
10370
  clientInfo: {
9916
- name: this.baseConfig.clientName ?? "thenvoi_codex_adapter",
9917
- title: this.baseConfig.clientTitle ?? "Thenvoi Codex Adapter",
10371
+ name: this.baseConfig.clientName ?? "band_codex_adapter",
10372
+ title: this.baseConfig.clientTitle ?? "Band Codex Adapter",
9918
10373
  version: this.baseConfig.clientVersion ?? "0.1.0"
9919
10374
  },
9920
10375
  capabilities: {
@@ -10187,7 +10642,7 @@ var CodexAdapter = class extends SimpleAdapter {
10187
10642
  tool_call_id: callId
10188
10643
  }), "tool_result");
10189
10644
  }
10190
- return !isError && toolName === "thenvoi_send_message";
10645
+ return !isError && toolName === SEND_MESSAGE_TOOL_NAME;
10191
10646
  } catch (error) {
10192
10647
  const output = {
10193
10648
  ok: false,
@@ -10710,6 +11165,7 @@ function parseModelListResponse(value) {
10710
11165
  ACPServer,
10711
11166
  AnthropicAdapter,
10712
11167
  AnthropicToolCallingModel,
11168
+ BandACPServerAdapter,
10713
11169
  CODEX_REASONING_EFFORTS,
10714
11170
  CODEX_REASONING_SUMMARIES,
10715
11171
  CODEX_WEB_SEARCH_MODES,
@@ -10733,7 +11189,6 @@ function parseModelListResponse(value) {
10733
11189
  OpencodeAdapter,
10734
11190
  ParlantAdapter,
10735
11191
  ParlantHistoryConverter,
10736
- ThenvoiACPServerAdapter,
10737
11192
  ToolCallingAdapter,
10738
11193
  VercelAISDKAdapter,
10739
11194
  VercelAISDKToolCallingModel,