@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.
- package/README.md +54 -54
- package/dist/{ClaudeSDKAdapter-DfjaI5ke.d.cts → ClaudeSDKAdapter-BY4zEbCl.d.cts} +12 -10
- package/dist/{ClaudeSDKAdapter-DonPGJ43.d.ts → ClaudeSDKAdapter-Cna5P1dR.d.ts} +12 -10
- package/dist/{acp-server-NZAeg-WO.d.ts → acp-server-CiUqN3G3.d.ts} +2 -2
- package/dist/{acp-server-CUBXIiG6.d.cts → acp-server-Dlj7D563.d.cts} +2 -2
- package/dist/adapters.cjs +250 -183
- package/dist/adapters.d.cts +21 -19
- package/dist/adapters.d.ts +21 -19
- package/dist/adapters.js +65 -44
- package/dist/backends-D-dBdDm-.d.ts +27 -0
- package/dist/backends-ZLxmQrTZ.d.cts +27 -0
- package/dist/{chunk-2BHHR6YW.js → chunk-4IAXZBXX.js} +62 -23
- package/dist/{chunk-SG4WLD2H.js → chunk-EAI2M3WM.js} +38 -94
- package/dist/{chunk-YR3BOQNW.js → chunk-JY75VSQK.js} +7 -7
- package/dist/{chunk-RDM4TE4B.js → chunk-LBWKISBS.js} +19 -1
- package/dist/{chunk-FP237EAG.js → chunk-N2QTUMGO.js} +112 -195
- package/dist/{chunk-J3M3PFFY.js → chunk-NMZLX7TP.js} +35 -31
- package/dist/{chunk-6RXWL6TC.js → chunk-NT7TBFX2.js} +1 -1
- package/dist/{chunk-MLROFDKR.js → chunk-RV76SKFT.js} +39 -33
- package/dist/{chunk-XA4N2JPH.js → chunk-TLBCKDQO.js} +23 -23
- package/dist/{chunk-IZPV6QS6.js → chunk-WL2HNJZ6.js} +38 -11
- package/dist/{chunk-DNPVCR3S.js → chunk-WLCM2OXG.js} +31 -31
- package/dist/config.cjs +40 -13
- package/dist/config.d.cts +7 -1
- package/dist/config.d.ts +7 -1
- package/dist/config.js +2 -2
- package/dist/converters.cjs +61 -61
- package/dist/converters.d.cts +5 -5
- package/dist/converters.d.ts +5 -5
- package/dist/converters.js +4 -4
- package/dist/core.cjs +8 -8
- package/dist/core.d.cts +9 -9
- package/dist/core.d.ts +9 -9
- package/dist/core.js +3 -3
- package/dist/{dtos-Dd_fTfLn.d.cts → dtos-B8KU_q4d.d.cts} +2 -2
- package/dist/{dtos-Dd_fTfLn.d.ts → dtos-B8KU_q4d.d.ts} +2 -2
- package/dist/index.cjs +459 -504
- package/dist/index.d.cts +16 -15
- package/dist/index.d.ts +16 -15
- package/dist/index.js +15 -13
- package/dist/linear.cjs +74 -74
- package/dist/linear.d.cts +14 -14
- package/dist/linear.d.ts +14 -14
- package/dist/linear.js +72 -72
- package/dist/mcp-claude.cjs +37 -36
- package/dist/mcp-claude.d.cts +3 -3
- package/dist/mcp-claude.d.ts +3 -3
- package/dist/mcp-claude.js +7 -6
- package/dist/mcp.cjs +103 -62
- package/dist/mcp.d.cts +29 -16
- package/dist/mcp.d.ts +29 -16
- package/dist/mcp.js +14 -14
- package/dist/{opencode--iA5-KYk.d.cts → opencode-2YdscIc1.d.cts} +5 -5
- package/dist/{opencode-YNacv-eJ.d.ts → opencode-Bld62x5t.d.ts} +5 -5
- package/dist/{pagination-BBLsYLhT.d.ts → pagination-BgEx-HeL.d.ts} +2 -2
- package/dist/{pagination-CqidD-L_.d.cts → pagination-DqdkQArT.d.cts} +2 -2
- package/dist/{protocols-BF6jamIl.d.ts → protocols-Bwwcql0h.d.ts} +1 -1
- package/dist/{protocols-D2bTrQ_t.d.cts → protocols-Bz1rxcUg.d.cts} +1 -1
- package/dist/rest.cjs +41 -97
- package/dist/rest.d.cts +7 -7
- package/dist/rest.d.ts +7 -7
- package/dist/rest.js +2 -2
- package/dist/runtime.cjs +293 -464
- package/dist/runtime.d.cts +16 -28
- package/dist/runtime.d.ts +16 -28
- package/dist/runtime.js +12 -63
- package/dist/{schemas-CI0qgcp_.d.cts → schemas-BotL3ZLH.d.cts} +40 -54
- package/dist/{schemas-B1Fd3oUM.d.ts → schemas-DBsC4J1g.d.ts} +40 -54
- package/dist/{sdk-D2rTDU_o.d.cts → sdk-BTciSLRQ.d.cts} +5 -5
- package/dist/{sdk-CyqN1W5g.d.ts → sdk-qKJtMma_.d.ts} +5 -5
- package/dist/{simpleAdapter-qQt-tSz4.d.ts → simpleAdapter--wznuoOw.d.ts} +1 -1
- package/dist/{simpleAdapter-C_f-01Cu.d.cts → simpleAdapter-BpT4XbZC.d.cts} +1 -1
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/{types-DNySTI_8.d.ts → types-BTN_ZETM.d.ts} +2 -2
- package/dist/{types-D3AsUnd0.d.ts → types-BgYFd_Yw.d.cts} +5 -5
- package/dist/{types-DtMms5Fi.d.cts → types-BivGO7I9.d.ts} +5 -5
- package/dist/{types-CKqrhGB1.d.cts → types-D958TC71.d.cts} +2 -2
- package/package.json +6 -5
- package/dist/backends-DYtEhCZG.d.cts +0 -25
- package/dist/backends-oYAb7EU-.d.ts +0 -25
package/dist/adapters.cjs
CHANGED
|
@@ -95,9 +95,9 @@ var init_memory = __esm({
|
|
|
95
95
|
"active",
|
|
96
96
|
// Normal, visible memories
|
|
97
97
|
"superseded",
|
|
98
|
-
// Outdated; soft-deleted via
|
|
98
|
+
// Outdated; soft-deleted via band_supersede_memory
|
|
99
99
|
"archived",
|
|
100
|
-
// Hidden but preserved via
|
|
100
|
+
// Hidden but preserved via band_archive_memory
|
|
101
101
|
"all"
|
|
102
102
|
// Any status (no filter)
|
|
103
103
|
];
|
|
@@ -109,29 +109,29 @@ var init_memory = __esm({
|
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
// src/core/errors.ts
|
|
112
|
-
var
|
|
112
|
+
var BandSdkError, UnsupportedFeatureError, ValidationError, RuntimeStateError;
|
|
113
113
|
var init_errors = __esm({
|
|
114
114
|
"src/core/errors.ts"() {
|
|
115
115
|
"use strict";
|
|
116
|
-
|
|
116
|
+
BandSdkError = class extends Error {
|
|
117
117
|
constructor(message, cause) {
|
|
118
118
|
super(message, cause !== void 0 ? { cause } : void 0);
|
|
119
|
-
this.name = "
|
|
119
|
+
this.name = "BandSdkError";
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
|
-
UnsupportedFeatureError = class extends
|
|
122
|
+
UnsupportedFeatureError = class extends BandSdkError {
|
|
123
123
|
constructor(message) {
|
|
124
124
|
super(message);
|
|
125
125
|
this.name = "UnsupportedFeatureError";
|
|
126
126
|
}
|
|
127
127
|
};
|
|
128
|
-
ValidationError = class extends
|
|
128
|
+
ValidationError = class extends BandSdkError {
|
|
129
129
|
constructor(message, cause) {
|
|
130
130
|
super(message, cause);
|
|
131
131
|
this.name = "ValidationError";
|
|
132
132
|
}
|
|
133
133
|
};
|
|
134
|
-
RuntimeStateError = class extends
|
|
134
|
+
RuntimeStateError = class extends BandSdkError {
|
|
135
135
|
constructor(message) {
|
|
136
136
|
super(message);
|
|
137
137
|
this.name = "RuntimeStateError";
|
|
@@ -159,14 +159,14 @@ function getToolDescription(name) {
|
|
|
159
159
|
const model = TOOL_MODELS[name];
|
|
160
160
|
return model?.description ?? `Execute ${name}`;
|
|
161
161
|
}
|
|
162
|
-
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;
|
|
163
163
|
var init_schemas = __esm({
|
|
164
164
|
"src/runtime/tools/schemas.ts"() {
|
|
165
165
|
"use strict";
|
|
166
166
|
init_chatEvents();
|
|
167
167
|
init_memory();
|
|
168
168
|
TOOL_MODELS = {
|
|
169
|
-
|
|
169
|
+
band_send_message: {
|
|
170
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.",
|
|
171
171
|
properties: {
|
|
172
172
|
content: {
|
|
@@ -182,7 +182,7 @@ var init_schemas = __esm({
|
|
|
182
182
|
},
|
|
183
183
|
required: ["content", "mentions"]
|
|
184
184
|
},
|
|
185
|
-
|
|
185
|
+
band_send_event: {
|
|
186
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.",
|
|
187
187
|
properties: {
|
|
188
188
|
content: {
|
|
@@ -201,12 +201,12 @@ var init_schemas = __esm({
|
|
|
201
201
|
},
|
|
202
202
|
required: ["content", "message_type"]
|
|
203
203
|
},
|
|
204
|
-
|
|
205
|
-
description: "Add a participant (agent or user) to the chat room by name. IMPORTANT: Use
|
|
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'.",
|
|
206
206
|
properties: {
|
|
207
207
|
name: {
|
|
208
208
|
type: "string",
|
|
209
|
-
description: "Name of participant to add (must match a name from
|
|
209
|
+
description: "Name of participant to add (must match a name from band_lookup_peers)."
|
|
210
210
|
},
|
|
211
211
|
role: {
|
|
212
212
|
type: "string",
|
|
@@ -216,7 +216,7 @@ var init_schemas = __esm({
|
|
|
216
216
|
},
|
|
217
217
|
required: ["name"]
|
|
218
218
|
},
|
|
219
|
-
|
|
219
|
+
band_remove_participant: {
|
|
220
220
|
description: "Remove a participant from the chat room by name.",
|
|
221
221
|
properties: {
|
|
222
222
|
name: {
|
|
@@ -226,12 +226,12 @@ var init_schemas = __esm({
|
|
|
226
226
|
},
|
|
227
227
|
required: ["name"]
|
|
228
228
|
},
|
|
229
|
-
|
|
229
|
+
band_get_participants: {
|
|
230
230
|
description: "Get a list of all participants in the current chat room.",
|
|
231
231
|
properties: {},
|
|
232
232
|
required: []
|
|
233
233
|
},
|
|
234
|
-
|
|
234
|
+
band_lookup_peers: {
|
|
235
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.",
|
|
236
236
|
properties: {
|
|
237
237
|
page: {
|
|
@@ -246,7 +246,7 @@ var init_schemas = __esm({
|
|
|
246
246
|
},
|
|
247
247
|
required: []
|
|
248
248
|
},
|
|
249
|
-
|
|
249
|
+
band_create_chatroom: {
|
|
250
250
|
description: "Create a new chat room for a specific task or conversation.",
|
|
251
251
|
properties: {
|
|
252
252
|
task_id: {
|
|
@@ -256,7 +256,7 @@ var init_schemas = __esm({
|
|
|
256
256
|
},
|
|
257
257
|
required: []
|
|
258
258
|
},
|
|
259
|
-
|
|
259
|
+
band_list_contacts: {
|
|
260
260
|
description: "List agent's contacts with pagination.",
|
|
261
261
|
properties: {
|
|
262
262
|
page: {
|
|
@@ -273,7 +273,7 @@ var init_schemas = __esm({
|
|
|
273
273
|
},
|
|
274
274
|
required: []
|
|
275
275
|
},
|
|
276
|
-
|
|
276
|
+
band_add_contact: {
|
|
277
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.",
|
|
278
278
|
properties: {
|
|
279
279
|
handle: {
|
|
@@ -287,7 +287,7 @@ var init_schemas = __esm({
|
|
|
287
287
|
},
|
|
288
288
|
required: ["handle"]
|
|
289
289
|
},
|
|
290
|
-
|
|
290
|
+
band_remove_contact: {
|
|
291
291
|
description: "Remove an existing contact by handle or ID.",
|
|
292
292
|
properties: {
|
|
293
293
|
handle: {
|
|
@@ -301,7 +301,7 @@ var init_schemas = __esm({
|
|
|
301
301
|
},
|
|
302
302
|
required: []
|
|
303
303
|
},
|
|
304
|
-
|
|
304
|
+
band_list_contact_requests: {
|
|
305
305
|
description: "List both received and sent contact requests. Received requests are always filtered to pending status. Sent requests can be filtered by status.",
|
|
306
306
|
properties: {
|
|
307
307
|
page: {
|
|
@@ -323,7 +323,7 @@ var init_schemas = __esm({
|
|
|
323
323
|
},
|
|
324
324
|
required: []
|
|
325
325
|
},
|
|
326
|
-
|
|
326
|
+
band_respond_contact_request: {
|
|
327
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).",
|
|
328
328
|
properties: {
|
|
329
329
|
action: {
|
|
@@ -342,7 +342,7 @@ var init_schemas = __esm({
|
|
|
342
342
|
},
|
|
343
343
|
required: ["action"]
|
|
344
344
|
},
|
|
345
|
-
|
|
345
|
+
band_list_memories: {
|
|
346
346
|
description: "List memories accessible to the agent. Returns memories about the specified subject (cross-agent sharing) and organization-wide shared memories.",
|
|
347
347
|
properties: {
|
|
348
348
|
subject_id: {
|
|
@@ -387,7 +387,7 @@ var init_schemas = __esm({
|
|
|
387
387
|
},
|
|
388
388
|
required: []
|
|
389
389
|
},
|
|
390
|
-
|
|
390
|
+
band_store_memory: {
|
|
391
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.",
|
|
392
392
|
properties: {
|
|
393
393
|
content: {
|
|
@@ -429,7 +429,7 @@ var init_schemas = __esm({
|
|
|
429
429
|
},
|
|
430
430
|
required: ["content", "system", "type", "segment", "thought"]
|
|
431
431
|
},
|
|
432
|
-
|
|
432
|
+
band_get_memory: {
|
|
433
433
|
description: "Retrieve a specific memory by ID.",
|
|
434
434
|
properties: {
|
|
435
435
|
memory_id: {
|
|
@@ -439,7 +439,7 @@ var init_schemas = __esm({
|
|
|
439
439
|
},
|
|
440
440
|
required: ["memory_id"]
|
|
441
441
|
},
|
|
442
|
-
|
|
442
|
+
band_supersede_memory: {
|
|
443
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.",
|
|
444
444
|
properties: {
|
|
445
445
|
memory_id: {
|
|
@@ -449,7 +449,7 @@ var init_schemas = __esm({
|
|
|
449
449
|
},
|
|
450
450
|
required: ["memory_id"]
|
|
451
451
|
},
|
|
452
|
-
|
|
452
|
+
band_archive_memory: {
|
|
453
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.",
|
|
454
454
|
properties: {
|
|
455
455
|
memory_id: {
|
|
@@ -462,18 +462,18 @@ var init_schemas = __esm({
|
|
|
462
462
|
};
|
|
463
463
|
ALL_TOOL_NAMES = new Set(Object.keys(TOOL_MODELS));
|
|
464
464
|
MEMORY_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
465
|
-
"
|
|
466
|
-
"
|
|
467
|
-
"
|
|
468
|
-
"
|
|
469
|
-
"
|
|
465
|
+
"band_list_memories",
|
|
466
|
+
"band_store_memory",
|
|
467
|
+
"band_get_memory",
|
|
468
|
+
"band_supersede_memory",
|
|
469
|
+
"band_archive_memory"
|
|
470
470
|
]);
|
|
471
471
|
CONTACT_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
472
|
-
"
|
|
473
|
-
"
|
|
474
|
-
"
|
|
475
|
-
"
|
|
476
|
-
"
|
|
472
|
+
"band_list_contacts",
|
|
473
|
+
"band_add_contact",
|
|
474
|
+
"band_remove_contact",
|
|
475
|
+
"band_list_contact_requests",
|
|
476
|
+
"band_respond_contact_request"
|
|
477
477
|
]);
|
|
478
478
|
BASE_TOOL_NAMES = new Set(
|
|
479
479
|
[...ALL_TOOL_NAMES].filter((name) => !MEMORY_TOOL_NAMES.has(name))
|
|
@@ -481,7 +481,10 @@ var init_schemas = __esm({
|
|
|
481
481
|
CHAT_TOOL_NAMES = new Set(
|
|
482
482
|
[...BASE_TOOL_NAMES].filter((name) => !CONTACT_TOOL_NAMES.has(name))
|
|
483
483
|
);
|
|
484
|
-
MCP_TOOL_PREFIX = "
|
|
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";
|
|
485
488
|
}
|
|
486
489
|
});
|
|
487
490
|
|
|
@@ -694,9 +697,9 @@ var init_zod = __esm({
|
|
|
694
697
|
// src/mcp/sdk.ts
|
|
695
698
|
var sdk_exports = {};
|
|
696
699
|
__export(sdk_exports, {
|
|
697
|
-
|
|
700
|
+
createBandSdkMcpServer: () => createBandSdkMcpServer
|
|
698
701
|
});
|
|
699
|
-
function
|
|
702
|
+
function createBandSdkMcpServer(options) {
|
|
700
703
|
const registrationOptions = {
|
|
701
704
|
enableMemoryTools: options.enableMemoryTools,
|
|
702
705
|
enableContactTools: true,
|
|
@@ -708,7 +711,7 @@ function createThenvoiSdkMcpServer(options) {
|
|
|
708
711
|
const contextCache = /* @__PURE__ */ new Map();
|
|
709
712
|
const MAX_CONTEXT_CACHE_ENTRIES = 100;
|
|
710
713
|
const serverConfig = (0, import_claude_agent_sdk.createSdkMcpServer)({
|
|
711
|
-
name:
|
|
714
|
+
name: MCP_SERVER_NAME,
|
|
712
715
|
tools: toolDefinitions
|
|
713
716
|
});
|
|
714
717
|
return {
|
|
@@ -948,6 +951,7 @@ __export(adapters_exports, {
|
|
|
948
951
|
ACPServer: () => ACPServer,
|
|
949
952
|
AnthropicAdapter: () => AnthropicAdapter,
|
|
950
953
|
AnthropicToolCallingModel: () => AnthropicToolCallingModel,
|
|
954
|
+
BandACPServerAdapter: () => BandACPServerAdapter,
|
|
951
955
|
CODEX_REASONING_EFFORTS: () => CODEX_REASONING_EFFORTS,
|
|
952
956
|
CODEX_REASONING_SUMMARIES: () => CODEX_REASONING_SUMMARIES,
|
|
953
957
|
CODEX_WEB_SEARCH_MODES: () => CODEX_WEB_SEARCH_MODES,
|
|
@@ -971,7 +975,6 @@ __export(adapters_exports, {
|
|
|
971
975
|
OpencodeAdapter: () => OpencodeAdapter,
|
|
972
976
|
ParlantAdapter: () => ParlantAdapter,
|
|
973
977
|
ParlantHistoryConverter: () => ParlantHistoryConverter,
|
|
974
|
-
ThenvoiACPServerAdapter: () => ThenvoiACPServerAdapter,
|
|
975
978
|
ToolCallingAdapter: () => ToolCallingAdapter,
|
|
976
979
|
VercelAISDKAdapter: () => VercelAISDKAdapter,
|
|
977
980
|
VercelAISDKToolCallingModel: () => VercelAISDKToolCallingModel,
|
|
@@ -1069,19 +1072,19 @@ var ENVIRONMENT_SECTION = `
|
|
|
1069
1072
|
|
|
1070
1073
|
Multi-participant chat. Messages show sender: [Name]: content.
|
|
1071
1074
|
Messages prefixed with [System]: are platform updates (participant changes, contact updates, etc.) \u2014 not messages from users.
|
|
1072
|
-
Use \`
|
|
1075
|
+
Use \`band_send_message(content, mentions)\` to respond. Plain text output is not delivered.
|
|
1073
1076
|
Mentions use handles: @<username> for users, @<username>/<agent-name> for agents.`;
|
|
1074
1077
|
var MULTI_AGENT_RULES_SECTION = `## CRITICAL: Delegate When You Cannot Help Directly
|
|
1075
1078
|
|
|
1076
1079
|
You have NO internet access and NO real-time data. When asked about weather, news, stock prices,
|
|
1077
1080
|
or any current information you cannot answer directly:
|
|
1078
1081
|
|
|
1079
|
-
1. Call \`
|
|
1080
|
-
2. If a relevant agent exists, call \`
|
|
1081
|
-
3. Ask that agent using \`
|
|
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])\`
|
|
1082
1085
|
4. Wait for their response and relay it back to the user
|
|
1083
1086
|
|
|
1084
|
-
NEVER say "I can't do that" without first checking if another agent can help via \`
|
|
1087
|
+
NEVER say "I can't do that" without first checking if another agent can help via \`band_lookup_peers()\`.
|
|
1085
1088
|
|
|
1086
1089
|
## CRITICAL: Do NOT Remove Agents Automatically
|
|
1087
1090
|
|
|
@@ -1100,42 +1103,42 @@ When someone asks you to get information from another agent:
|
|
|
1100
1103
|
3. Do NOT just thank the helper agent - the requester is waiting for their answer!`;
|
|
1101
1104
|
var THINKING_SECTION = `## IMPORTANT: Always Share Your Thinking
|
|
1102
1105
|
|
|
1103
|
-
You MUST call \`
|
|
1106
|
+
You MUST call \`band_send_event(content, message_type="thought")\` BEFORE every action.
|
|
1104
1107
|
This is required so users can see your reasoning process.`;
|
|
1105
1108
|
var EXAMPLES_SECTION = `## Examples
|
|
1106
1109
|
|
|
1107
1110
|
### Simple question - answer directly
|
|
1108
1111
|
[John Doe]: What's 2+2?
|
|
1109
|
-
->
|
|
1110
|
-
->
|
|
1112
|
+
-> band_send_event("Simple arithmetic, answering directly.", message_type="thought")
|
|
1113
|
+
-> band_send_message("4", mentions=["@john"])
|
|
1111
1114
|
|
|
1112
1115
|
### User asks about weather (you cannot answer directly)
|
|
1113
1116
|
[John Doe]: What's the weather in Tokyo?
|
|
1114
|
-
->
|
|
1115
|
-
->
|
|
1116
|
-
->
|
|
1117
|
-
->
|
|
1118
|
-
->
|
|
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"])
|
|
1119
1122
|
|
|
1120
1123
|
[Weather Agent]: Tokyo is 15\xB0C and cloudy.
|
|
1121
|
-
->
|
|
1122
|
-
->
|
|
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"])
|
|
1123
1126
|
|
|
1124
1127
|
### No suitable agent available
|
|
1125
1128
|
[John Doe]: What's the stock price of AAPL?
|
|
1126
|
-
->
|
|
1127
|
-
->
|
|
1128
|
-
->
|
|
1129
|
-
->
|
|
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"])
|
|
1130
1133
|
|
|
1131
1134
|
### Follow-up question in same conversation
|
|
1132
1135
|
[John Doe]: What about London?
|
|
1133
|
-
->
|
|
1134
|
-
->
|
|
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"])
|
|
1135
1138
|
|
|
1136
1139
|
[Weather Agent]: London is 8\xB0C and rainy.
|
|
1137
|
-
->
|
|
1138
|
-
->
|
|
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"])`;
|
|
1139
1142
|
var BASE_INSTRUCTIONS = [
|
|
1140
1143
|
ENVIRONMENT_SECTION,
|
|
1141
1144
|
MULTI_AGENT_RULES_SECTION,
|
|
@@ -1149,10 +1152,10 @@ init_schemas();
|
|
|
1149
1152
|
var MEMORY_INTRO = `## Memory Tools
|
|
1150
1153
|
|
|
1151
1154
|
You have access to memory tools for storing and retrieving information
|
|
1152
|
-
across conversations. Use \`
|
|
1153
|
-
information and \`
|
|
1154
|
-
Use \`
|
|
1155
|
-
\`
|
|
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.`;
|
|
1156
1159
|
function longTermPattern(label, type, segment, scope) {
|
|
1157
1160
|
return {
|
|
1158
1161
|
label,
|
|
@@ -1177,7 +1180,7 @@ var MEMORY_COMMON_PATTERNS = [
|
|
|
1177
1180
|
].join("\n");
|
|
1178
1181
|
var MEMORY_SCOPE_GUIDANCE = `Prefer \`scope="${MEMORY_STORE_SCOPE.subject}"\` whenever the memory is about a specific person or agent, so it
|
|
1179
1182
|
stays attached to that subject rather than leaking org-wide. Storing with \`scope="${MEMORY_STORE_SCOPE.subject}"\` requires a
|
|
1180
|
-
real \`subject_id\` UUID, so resolve it first via \`
|
|
1183
|
+
real \`subject_id\` UUID, so resolve it first via \`band_lookup_peers\` or the participant list.
|
|
1181
1184
|
Reserve \`scope="${MEMORY_STORE_SCOPE.organization}"\` for knowledge that is genuinely shared across the whole organization and
|
|
1182
1185
|
is not about any one subject.`;
|
|
1183
1186
|
function quoteChoices(values) {
|
|
@@ -1187,11 +1190,11 @@ function memoryTypeLines() {
|
|
|
1187
1190
|
return Object.entries(MEMORY_SYSTEM_TYPES).map(([system, types]) => ` - ${system}: ${quoteChoices(types)}`).join("\n");
|
|
1188
1191
|
}
|
|
1189
1192
|
function buildMemorySection() {
|
|
1190
|
-
const storeMemoryProps = TOOL_MODELS.
|
|
1193
|
+
const storeMemoryProps = TOOL_MODELS.band_store_memory.properties;
|
|
1191
1194
|
const systems = storeMemoryProps.system.enum;
|
|
1192
1195
|
const segments = storeMemoryProps.segment.enum;
|
|
1193
1196
|
const scopes = storeMemoryProps.scope.enum;
|
|
1194
|
-
const fieldRules = `When calling \`
|
|
1197
|
+
const fieldRules = `When calling \`band_store_memory\`, the \`system\`, \`type\`, \`segment\`, and \`scope\` fields
|
|
1195
1198
|
must use these exact values (case-sensitive):
|
|
1196
1199
|
|
|
1197
1200
|
- **system**: ${quoteChoices(systems)}
|
|
@@ -1231,15 +1234,39 @@ ${customSection}`.trim();
|
|
|
1231
1234
|
return parts.join("\n\n");
|
|
1232
1235
|
}
|
|
1233
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);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1234
1260
|
// src/mcp/server.ts
|
|
1235
1261
|
init_registrations();
|
|
1236
1262
|
init_zod();
|
|
1263
|
+
init_schemas();
|
|
1237
1264
|
var PORT_RANGE_START = 5e4;
|
|
1238
1265
|
var PORT_RANGE_END = 6e4;
|
|
1239
1266
|
var MCP_SERVER_VERSION = "1.0.0";
|
|
1240
1267
|
var SESSION_IDLE_TTL_MS = 15 * 60 * 1e3;
|
|
1241
1268
|
var SESSION_SWEEP_INTERVAL_MS = 60 * 1e3;
|
|
1242
|
-
var
|
|
1269
|
+
var BandMcpServer = class {
|
|
1243
1270
|
options;
|
|
1244
1271
|
registrations;
|
|
1245
1272
|
httpServer = null;
|
|
@@ -1283,7 +1310,7 @@ var ThenvoiMcpServer = class {
|
|
|
1283
1310
|
const http = await import("http");
|
|
1284
1311
|
const { randomUUID: randomUUID7 } = await import("crypto");
|
|
1285
1312
|
const { z: z4 } = await import("zod");
|
|
1286
|
-
const serverName = this.options.name ??
|
|
1313
|
+
const serverName = this.options.name ?? MCP_SERVER_NAME;
|
|
1287
1314
|
const app = express();
|
|
1288
1315
|
app.use(express.json());
|
|
1289
1316
|
app.get("/healthz", (_req, res) => {
|
|
@@ -1291,6 +1318,10 @@ var ThenvoiMcpServer = class {
|
|
|
1291
1318
|
});
|
|
1292
1319
|
const handleMcpRequest = async (req, res) => {
|
|
1293
1320
|
try {
|
|
1321
|
+
if (!isAuthorizedRequest(req.headers.authorization, this.options.authToken)) {
|
|
1322
|
+
sendMcpError(res, 401, "Unauthorized");
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1294
1325
|
const sessionId = getSessionIdHeader(req.headers["mcp-session-id"]);
|
|
1295
1326
|
let session = sessionId ? this.sessions.get(sessionId) : void 0;
|
|
1296
1327
|
if (!session) {
|
|
@@ -1466,11 +1497,12 @@ function checkPort(http, port) {
|
|
|
1466
1497
|
// src/mcp/sse.ts
|
|
1467
1498
|
init_registrations();
|
|
1468
1499
|
init_zod();
|
|
1500
|
+
init_schemas();
|
|
1469
1501
|
var PORT_RANGE_START2 = 5e4;
|
|
1470
1502
|
var PORT_RANGE_END2 = 6e4;
|
|
1471
1503
|
var SESSION_IDLE_TTL_MS2 = 15 * 60 * 1e3;
|
|
1472
1504
|
var SESSION_SWEEP_INTERVAL_MS2 = 60 * 1e3;
|
|
1473
|
-
var
|
|
1505
|
+
var BandMcpSseServer = class {
|
|
1474
1506
|
options;
|
|
1475
1507
|
registrations;
|
|
1476
1508
|
httpServer = null;
|
|
@@ -1517,10 +1549,14 @@ var ThenvoiMcpSseServer = class {
|
|
|
1517
1549
|
app.get("/healthz", (_req, res) => {
|
|
1518
1550
|
res.json({ status: "ok" });
|
|
1519
1551
|
});
|
|
1520
|
-
app.get("/sse", async (
|
|
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
|
+
}
|
|
1521
1557
|
const transport = new SSEServerTransport("/messages", res);
|
|
1522
1558
|
const mcpServer = new McpServer({
|
|
1523
|
-
name: this.options.name ??
|
|
1559
|
+
name: this.options.name ?? MCP_SERVER_NAME,
|
|
1524
1560
|
version: "1.0.0"
|
|
1525
1561
|
});
|
|
1526
1562
|
registerTools2(mcpServer, z4, this.registrations);
|
|
@@ -1542,6 +1578,10 @@ var ThenvoiMcpSseServer = class {
|
|
|
1542
1578
|
});
|
|
1543
1579
|
});
|
|
1544
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
|
+
}
|
|
1545
1585
|
const sessionId = typeof req.query.sessionId === "string" ? req.query.sessionId : null;
|
|
1546
1586
|
if (!sessionId) {
|
|
1547
1587
|
res.status(400).send("Missing sessionId");
|
|
@@ -1714,7 +1754,7 @@ function normalizeMcpServers(mcpServers) {
|
|
|
1714
1754
|
}
|
|
1715
1755
|
|
|
1716
1756
|
// src/adapters/acp/client.ts
|
|
1717
|
-
var
|
|
1757
|
+
var BandACPClient = class {
|
|
1718
1758
|
sessionChunks = /* @__PURE__ */ new Map();
|
|
1719
1759
|
permissionHandlers = /* @__PURE__ */ new Map();
|
|
1720
1760
|
async sessionUpdate(params) {
|
|
@@ -1992,6 +2032,7 @@ var ACPClientAdapter = class extends SimpleAdapter {
|
|
|
1992
2032
|
activeSessions = /* @__PURE__ */ new Set();
|
|
1993
2033
|
bootstrappedSessions = /* @__PURE__ */ new Set();
|
|
1994
2034
|
backend = null;
|
|
2035
|
+
backendPromise = null;
|
|
1995
2036
|
client = null;
|
|
1996
2037
|
connectionHandle = null;
|
|
1997
2038
|
connection = null;
|
|
@@ -2132,7 +2173,7 @@ ${message.content}`;
|
|
|
2132
2173
|
}
|
|
2133
2174
|
async spawnConnection() {
|
|
2134
2175
|
const acp = await acpModule.get();
|
|
2135
|
-
const client = new
|
|
2176
|
+
const client = new BandACPClient();
|
|
2136
2177
|
const handle = await this.connectionFactory(client, {
|
|
2137
2178
|
command: this.command,
|
|
2138
2179
|
cwd: this.cwd,
|
|
@@ -2164,11 +2205,11 @@ ${message.content}`;
|
|
|
2164
2205
|
}
|
|
2165
2206
|
async getOrCreateSession(roomId, connection) {
|
|
2166
2207
|
const existingSessionId = this.roomToSession.get(roomId);
|
|
2208
|
+
if (existingSessionId && this.activeSessions.has(existingSessionId)) {
|
|
2209
|
+
return existingSessionId;
|
|
2210
|
+
}
|
|
2167
2211
|
const mcpServers = await this.buildSessionMcpServers();
|
|
2168
2212
|
if (existingSessionId) {
|
|
2169
|
-
if (this.activeSessions.has(existingSessionId)) {
|
|
2170
|
-
return existingSessionId;
|
|
2171
|
-
}
|
|
2172
2213
|
const restored = await this.tryRestoreSession(connection, existingSessionId, mcpServers);
|
|
2173
2214
|
if (restored) {
|
|
2174
2215
|
this.activeSessions.add(existingSessionId);
|
|
@@ -2216,26 +2257,26 @@ ${message.content}`;
|
|
|
2216
2257
|
if (backend.kind === "http") {
|
|
2217
2258
|
const url = backend.server.url;
|
|
2218
2259
|
if (!url) {
|
|
2219
|
-
throw new Error("
|
|
2260
|
+
throw new Error("Band MCP HTTP backend did not expose a URL");
|
|
2220
2261
|
}
|
|
2221
2262
|
mcpServers.push({
|
|
2222
2263
|
type: "http",
|
|
2223
|
-
name:
|
|
2264
|
+
name: MCP_SERVER_NAME,
|
|
2224
2265
|
url,
|
|
2225
|
-
headers: []
|
|
2266
|
+
headers: [{ name: "Authorization", value: `Bearer ${backend.authToken}` }]
|
|
2226
2267
|
});
|
|
2227
2268
|
return mcpServers;
|
|
2228
2269
|
}
|
|
2229
2270
|
if (backend.kind === "sse") {
|
|
2230
2271
|
const url = backend.server.sseUrl;
|
|
2231
2272
|
if (!url) {
|
|
2232
|
-
throw new Error("
|
|
2273
|
+
throw new Error("Band MCP SSE backend did not expose a URL");
|
|
2233
2274
|
}
|
|
2234
2275
|
mcpServers.push({
|
|
2235
2276
|
type: "sse",
|
|
2236
|
-
name:
|
|
2277
|
+
name: MCP_SERVER_NAME,
|
|
2237
2278
|
url,
|
|
2238
|
-
headers: []
|
|
2279
|
+
headers: [{ name: "Authorization", value: `Bearer ${backend.authToken}` }]
|
|
2239
2280
|
});
|
|
2240
2281
|
return mcpServers;
|
|
2241
2282
|
}
|
|
@@ -2245,34 +2286,51 @@ ${message.content}`;
|
|
|
2245
2286
|
if (this.backend) {
|
|
2246
2287
|
return this.backend;
|
|
2247
2288
|
}
|
|
2248
|
-
|
|
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();
|
|
2249
2303
|
if (transport === "sse") {
|
|
2250
|
-
const server2 = new
|
|
2304
|
+
const server2 = new BandMcpSseServer({
|
|
2251
2305
|
tools: (roomId) => this.roomTools.get(roomId),
|
|
2252
2306
|
enableMemoryTools: this.enableMemoryTools,
|
|
2253
2307
|
enableContactTools: true,
|
|
2254
|
-
additionalTools: this.additionalMcpTools
|
|
2308
|
+
additionalTools: this.additionalMcpTools,
|
|
2309
|
+
authToken
|
|
2255
2310
|
});
|
|
2256
2311
|
await server2.start();
|
|
2257
2312
|
this.backend = {
|
|
2258
2313
|
kind: "sse",
|
|
2259
2314
|
server: server2,
|
|
2315
|
+
authToken,
|
|
2260
2316
|
stop: async () => {
|
|
2261
2317
|
await server2.stop();
|
|
2262
2318
|
}
|
|
2263
2319
|
};
|
|
2264
2320
|
return this.backend;
|
|
2265
2321
|
}
|
|
2266
|
-
const server = new
|
|
2322
|
+
const server = new BandMcpServer({
|
|
2267
2323
|
tools: (roomId) => this.roomTools.get(roomId),
|
|
2268
2324
|
enableMemoryTools: this.enableMemoryTools,
|
|
2269
2325
|
enableContactTools: true,
|
|
2270
|
-
additionalTools: this.additionalMcpTools
|
|
2326
|
+
additionalTools: this.additionalMcpTools,
|
|
2327
|
+
authToken
|
|
2271
2328
|
});
|
|
2272
2329
|
await server.start();
|
|
2273
2330
|
this.backend = {
|
|
2274
2331
|
kind: "http",
|
|
2275
2332
|
server,
|
|
2333
|
+
authToken,
|
|
2276
2334
|
stop: async () => {
|
|
2277
2335
|
await server.stop();
|
|
2278
2336
|
}
|
|
@@ -2287,14 +2345,14 @@ ${message.content}`;
|
|
|
2287
2345
|
this.systemPrompt,
|
|
2288
2346
|
"",
|
|
2289
2347
|
"## Room Context",
|
|
2290
|
-
"You are connected to
|
|
2291
|
-
"Use the
|
|
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.",
|
|
2292
2350
|
"",
|
|
2293
2351
|
`Current room_id: ${roomId}`,
|
|
2294
2352
|
`Current requester name: ${requesterName}`,
|
|
2295
2353
|
`Current requester id: ${requesterId}`,
|
|
2296
2354
|
"",
|
|
2297
|
-
"All
|
|
2355
|
+
"All Band MCP tool calls must include room_id."
|
|
2298
2356
|
].join("\n");
|
|
2299
2357
|
}
|
|
2300
2358
|
async handlePermissionRequest(tools, roomId, params) {
|
|
@@ -2403,8 +2461,8 @@ function toErrorMessage(error) {
|
|
|
2403
2461
|
// src/adapters/acp/ACPServer.ts
|
|
2404
2462
|
var import_node_stream2 = require("stream");
|
|
2405
2463
|
|
|
2406
|
-
// src/adapters/acp/
|
|
2407
|
-
var
|
|
2464
|
+
// src/adapters/acp/BandACPServerAdapter.ts
|
|
2465
|
+
var import_node_crypto2 = require("crypto");
|
|
2408
2466
|
|
|
2409
2467
|
// src/converters/acp-server.ts
|
|
2410
2468
|
var ACPServerHistoryConverter = class {
|
|
@@ -2655,12 +2713,12 @@ var AgentRouter = class {
|
|
|
2655
2713
|
}
|
|
2656
2714
|
};
|
|
2657
2715
|
|
|
2658
|
-
// src/adapters/acp/
|
|
2716
|
+
// src/adapters/acp/BandACPServerAdapter.ts
|
|
2659
2717
|
var DEFAULT_MAX_SESSIONS = 100;
|
|
2660
2718
|
var DEFAULT_PROMPT_TIMEOUT_MS = 3e5;
|
|
2661
2719
|
var DEFAULT_PROMPT_COMPLETION_GRACE_MS = 250;
|
|
2662
|
-
var
|
|
2663
|
-
|
|
2720
|
+
var BandACPServerAdapter = class extends SimpleAdapter {
|
|
2721
|
+
bandRest;
|
|
2664
2722
|
maxSessions;
|
|
2665
2723
|
responseTimeoutMs;
|
|
2666
2724
|
promptCompletionGraceMs;
|
|
@@ -2681,7 +2739,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
|
|
|
2681
2739
|
super({
|
|
2682
2740
|
historyConverter: new ACPServerHistoryConverter()
|
|
2683
2741
|
});
|
|
2684
|
-
this.
|
|
2742
|
+
this.bandRest = options.bandRest;
|
|
2685
2743
|
this.maxSessions = options.maxSessions ?? DEFAULT_MAX_SESSIONS;
|
|
2686
2744
|
this.responseTimeoutMs = options.responseTimeoutMs ?? DEFAULT_PROMPT_TIMEOUT_MS;
|
|
2687
2745
|
this.promptCompletionGraceMs = options.promptCompletionGraceMs ?? DEFAULT_PROMPT_COMPLETION_GRACE_MS;
|
|
@@ -2743,7 +2801,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
|
|
|
2743
2801
|
}
|
|
2744
2802
|
async verifyCredentials() {
|
|
2745
2803
|
try {
|
|
2746
|
-
await this.
|
|
2804
|
+
await this.bandRest.getAgentMe();
|
|
2747
2805
|
return true;
|
|
2748
2806
|
} catch {
|
|
2749
2807
|
return false;
|
|
@@ -2752,7 +2810,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
|
|
|
2752
2810
|
async onStarted(agentName, agentDescription) {
|
|
2753
2811
|
await super.onStarted(agentName, agentDescription);
|
|
2754
2812
|
try {
|
|
2755
|
-
const identity = await this.
|
|
2813
|
+
const identity = await this.bandRest.getAgentMe();
|
|
2756
2814
|
this.agentId = identity.id;
|
|
2757
2815
|
} catch {
|
|
2758
2816
|
this.agentId = null;
|
|
@@ -2766,8 +2824,8 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
|
|
|
2766
2824
|
throw new Error(`Maximum ACP sessions (${this.maxSessions}) reached`);
|
|
2767
2825
|
}
|
|
2768
2826
|
try {
|
|
2769
|
-
const room = await this.
|
|
2770
|
-
const sessionId = (0,
|
|
2827
|
+
const room = await this.bandRest.createChat();
|
|
2828
|
+
const sessionId = (0, import_node_crypto2.randomUUID)();
|
|
2771
2829
|
const normalizedMcpServers = normalizeMcpServers(input.mcpServers);
|
|
2772
2830
|
this.sessionToRoom.set(sessionId, room.id);
|
|
2773
2831
|
this.roomToSession.set(room.id, sessionId);
|
|
@@ -2776,7 +2834,7 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
|
|
|
2776
2834
|
this.sessionMcpServers.set(sessionId, normalizedMcpServers);
|
|
2777
2835
|
}
|
|
2778
2836
|
try {
|
|
2779
|
-
await this.
|
|
2837
|
+
await this.bandRest.createChatEvent(room.id, {
|
|
2780
2838
|
content: "ACP session context",
|
|
2781
2839
|
messageType: "task",
|
|
2782
2840
|
metadata: {
|
|
@@ -2809,10 +2867,10 @@ var ThenvoiACPServerAdapter = class extends SimpleAdapter {
|
|
|
2809
2867
|
this.pendingPrompts.set(roomId, pending);
|
|
2810
2868
|
const resolved = this.router.resolve(text, this.sessionModeIds.get(sessionId));
|
|
2811
2869
|
const promptText = this.prependSessionContext(sessionId, resolved.text);
|
|
2812
|
-
const participants = await this.
|
|
2870
|
+
const participants = await this.bandRest.listChatParticipants(roomId);
|
|
2813
2871
|
const mentions = this.resolveMentions(participants, resolved.targetPeer);
|
|
2814
2872
|
try {
|
|
2815
|
-
await this.
|
|
2873
|
+
await this.bandRest.createChatMessage(roomId, {
|
|
2816
2874
|
content: promptText,
|
|
2817
2875
|
mentions
|
|
2818
2876
|
});
|
|
@@ -3065,7 +3123,7 @@ var ACPServer = class {
|
|
|
3065
3123
|
this.authMethods = options?.authMethods ?? [{
|
|
3066
3124
|
id: "api_key",
|
|
3067
3125
|
name: "API Key",
|
|
3068
|
-
description: "Authenticate with THENVOI_API_KEY."
|
|
3126
|
+
description: "Authenticate with BAND_API_KEY (legacy THENVOI_API_KEY)."
|
|
3069
3127
|
}];
|
|
3070
3128
|
this.agentInfo = options?.agentInfo ?? {};
|
|
3071
3129
|
this.extensionHandler = options?.extensionHandler ?? new CursorExtensionHandler();
|
|
@@ -3118,8 +3176,8 @@ var ACPServer = class {
|
|
|
3118
3176
|
}
|
|
3119
3177
|
},
|
|
3120
3178
|
agentInfo: {
|
|
3121
|
-
name: this.agentInfo.name ?? "
|
|
3122
|
-
title: this.agentInfo.title ?? this.adapter.displayName ?? "
|
|
3179
|
+
name: this.agentInfo.name ?? "band-agent",
|
|
3180
|
+
title: this.agentInfo.title ?? this.adapter.displayName ?? "Band Agent",
|
|
3123
3181
|
version: this.agentInfo.version ?? "0.1.0"
|
|
3124
3182
|
},
|
|
3125
3183
|
authMethods: this.authMethods
|
|
@@ -4471,7 +4529,7 @@ var GeminiAdapter = class extends ToolCallingAdapter {
|
|
|
4471
4529
|
};
|
|
4472
4530
|
|
|
4473
4531
|
// src/adapters/google-adk/GoogleADKAdapter.ts
|
|
4474
|
-
var
|
|
4532
|
+
var import_node_crypto3 = require("crypto");
|
|
4475
4533
|
|
|
4476
4534
|
// src/adapters/shared/history.ts
|
|
4477
4535
|
function findLatestTaskMetadata(raw, predicate) {
|
|
@@ -4628,7 +4686,7 @@ var GoogleADKHistoryConverter = class {
|
|
|
4628
4686
|
};
|
|
4629
4687
|
|
|
4630
4688
|
// src/adapters/google-adk/GoogleADKAdapter.ts
|
|
4631
|
-
var APP_NAME = "
|
|
4689
|
+
var APP_NAME = "band";
|
|
4632
4690
|
var DEFAULT_MAX_HISTORY_MESSAGES = 50;
|
|
4633
4691
|
var DEFAULT_MAX_TRANSCRIPT_CHARS = 1e5;
|
|
4634
4692
|
var MAX_TOOL_OUTPUT_PREVIEW = 200;
|
|
@@ -4743,7 +4801,7 @@ var GoogleADKAdapter = class extends SimpleAdapter {
|
|
|
4743
4801
|
agent: this.buildAgent(sdk, tools),
|
|
4744
4802
|
appName: APP_NAME
|
|
4745
4803
|
});
|
|
4746
|
-
const sessionId = (0,
|
|
4804
|
+
const sessionId = (0, import_node_crypto3.randomUUID)();
|
|
4747
4805
|
this.roomSessions.set(context.roomId, sessionId);
|
|
4748
4806
|
await runner.sessionService.createSession({
|
|
4749
4807
|
appName: APP_NAME,
|
|
@@ -4802,7 +4860,7 @@ var GoogleADKAdapter = class extends SimpleAdapter {
|
|
|
4802
4860
|
}
|
|
4803
4861
|
buildAgent(sdk, tools) {
|
|
4804
4862
|
return sdk.createAgent({
|
|
4805
|
-
name: this.agentName || "
|
|
4863
|
+
name: this.agentName || "band_agent",
|
|
4806
4864
|
model: this.model,
|
|
4807
4865
|
instruction: this.systemPrompt,
|
|
4808
4866
|
tools: this.buildTools(sdk, tools)
|
|
@@ -5295,7 +5353,7 @@ function stringifyJsonWithFallback(value, logger, context) {
|
|
|
5295
5353
|
}
|
|
5296
5354
|
|
|
5297
5355
|
// src/adapters/a2a/A2AAdapter.ts
|
|
5298
|
-
var
|
|
5356
|
+
var import_node_crypto4 = require("crypto");
|
|
5299
5357
|
init_errors();
|
|
5300
5358
|
|
|
5301
5359
|
// src/adapters/a2a/types.ts
|
|
@@ -5554,7 +5612,7 @@ var A2AAdapter = class extends SimpleAdapter {
|
|
|
5554
5612
|
return {
|
|
5555
5613
|
message: {
|
|
5556
5614
|
kind: "message",
|
|
5557
|
-
messageId: (0,
|
|
5615
|
+
messageId: (0, import_node_crypto4.randomUUID)(),
|
|
5558
5616
|
role: "user",
|
|
5559
5617
|
parts: [{ kind: "text", text: message.content }],
|
|
5560
5618
|
...contextId ? { contextId } : {},
|
|
@@ -5848,7 +5906,7 @@ function createAuthFetch(authHeaders) {
|
|
|
5848
5906
|
}
|
|
5849
5907
|
|
|
5850
5908
|
// src/adapters/a2a-gateway/A2AGatewayAdapter.ts
|
|
5851
|
-
var
|
|
5909
|
+
var import_node_crypto7 = require("crypto");
|
|
5852
5910
|
init_errors();
|
|
5853
5911
|
|
|
5854
5912
|
// src/adapters/a2a-gateway/history.ts
|
|
@@ -5887,10 +5945,10 @@ var GatewayHistoryConverter = class {
|
|
|
5887
5945
|
};
|
|
5888
5946
|
|
|
5889
5947
|
// src/adapters/a2a-gateway/server.ts
|
|
5890
|
-
var
|
|
5948
|
+
var import_node_crypto6 = require("crypto");
|
|
5891
5949
|
|
|
5892
5950
|
// src/adapters/a2a-gateway/statusEvent.ts
|
|
5893
|
-
var
|
|
5951
|
+
var import_node_crypto5 = require("crypto");
|
|
5894
5952
|
function buildStatusEvent(input) {
|
|
5895
5953
|
return {
|
|
5896
5954
|
kind: "status-update",
|
|
@@ -5902,7 +5960,7 @@ function buildStatusEvent(input) {
|
|
|
5902
5960
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5903
5961
|
message: {
|
|
5904
5962
|
kind: "message",
|
|
5905
|
-
messageId: (0,
|
|
5963
|
+
messageId: (0, import_node_crypto5.randomUUID)(),
|
|
5906
5964
|
role: "agent",
|
|
5907
5965
|
taskId: input.taskId,
|
|
5908
5966
|
contextId: input.contextId,
|
|
@@ -5929,8 +5987,8 @@ var GatewayPeerExecutor = class {
|
|
|
5929
5987
|
this.onCancel = options.onCancel;
|
|
5930
5988
|
}
|
|
5931
5989
|
async execute(requestContext, eventBus) {
|
|
5932
|
-
const taskId = asNonEmptyString2(requestContext.taskId) ?? (0,
|
|
5933
|
-
const contextId = asNonEmptyString2(requestContext.contextId) ?? (0,
|
|
5990
|
+
const taskId = asNonEmptyString2(requestContext.taskId) ?? (0, import_node_crypto6.randomUUID)();
|
|
5991
|
+
const contextId = asNonEmptyString2(requestContext.contextId) ?? (0, import_node_crypto6.randomUUID)();
|
|
5934
5992
|
const message = asA2AMessage(requestContext.userMessage, contextId, taskId);
|
|
5935
5993
|
try {
|
|
5936
5994
|
for await (const event of this.onRequest({
|
|
@@ -5970,7 +6028,7 @@ var GatewayPeerExecutor = class {
|
|
|
5970
6028
|
eventBus.publish(
|
|
5971
6029
|
buildStatusEvent({
|
|
5972
6030
|
taskId,
|
|
5973
|
-
contextId: (0,
|
|
6031
|
+
contextId: (0, import_node_crypto6.randomUUID)(),
|
|
5974
6032
|
state: "canceled",
|
|
5975
6033
|
final: true,
|
|
5976
6034
|
text: "Task canceled."
|
|
@@ -6165,7 +6223,7 @@ function buildAgentCard(peer, gatewayUrl) {
|
|
|
6165
6223
|
id: "default",
|
|
6166
6224
|
name: peer.name,
|
|
6167
6225
|
description: peer.description,
|
|
6168
|
-
tags: ["
|
|
6226
|
+
tags: ["band", "gateway"]
|
|
6169
6227
|
}
|
|
6170
6228
|
],
|
|
6171
6229
|
defaultInputModes: ["text/plain"],
|
|
@@ -6176,7 +6234,7 @@ function asA2AMessage(value, fallbackContextId, fallbackTaskId) {
|
|
|
6176
6234
|
if (!value || typeof value !== "object") {
|
|
6177
6235
|
return {
|
|
6178
6236
|
kind: "message",
|
|
6179
|
-
messageId: (0,
|
|
6237
|
+
messageId: (0, import_node_crypto6.randomUUID)(),
|
|
6180
6238
|
role: "user",
|
|
6181
6239
|
contextId: fallbackContextId,
|
|
6182
6240
|
taskId: fallbackTaskId,
|
|
@@ -6201,7 +6259,7 @@ function asA2AMessage(value, fallbackContextId, fallbackTaskId) {
|
|
|
6201
6259
|
}
|
|
6202
6260
|
return {
|
|
6203
6261
|
kind: "message",
|
|
6204
|
-
messageId: asNonEmptyString2(raw.messageId) ?? (0,
|
|
6262
|
+
messageId: asNonEmptyString2(raw.messageId) ?? (0, import_node_crypto6.randomUUID)(),
|
|
6205
6263
|
role: asNonEmptyString2(raw.role) === "agent" ? "agent" : "user",
|
|
6206
6264
|
contextId: asNonEmptyString2(raw.contextId) ?? fallbackContextId,
|
|
6207
6265
|
taskId: asNonEmptyString2(raw.taskId) ?? fallbackTaskId,
|
|
@@ -6336,7 +6394,7 @@ function safeHeaderEquals(left, right) {
|
|
|
6336
6394
|
if (leftBuffer.length !== rightBuffer.length) {
|
|
6337
6395
|
return false;
|
|
6338
6396
|
}
|
|
6339
|
-
return (0,
|
|
6397
|
+
return (0, import_node_crypto6.timingSafeEqual)(leftBuffer, rightBuffer);
|
|
6340
6398
|
}
|
|
6341
6399
|
|
|
6342
6400
|
// src/adapters/a2a-gateway/A2AGatewayAdapter.ts
|
|
@@ -6347,7 +6405,7 @@ var DEFAULT_RESPONSE_TIMEOUT_MS = 12e4;
|
|
|
6347
6405
|
var DEFAULT_PEER_PAGE_SIZE = 100;
|
|
6348
6406
|
var DEFAULT_MAX_PEER_PAGES = 25;
|
|
6349
6407
|
var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
6350
|
-
|
|
6408
|
+
bandRest;
|
|
6351
6409
|
gatewayUrl;
|
|
6352
6410
|
host;
|
|
6353
6411
|
port;
|
|
@@ -6368,7 +6426,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
|
6368
6426
|
super({
|
|
6369
6427
|
historyConverter: new GatewayHistoryConverter()
|
|
6370
6428
|
});
|
|
6371
|
-
this.
|
|
6429
|
+
this.bandRest = options.bandRest;
|
|
6372
6430
|
this.gatewayUrl = options.gatewayUrl ?? DEFAULT_GATEWAY_URL;
|
|
6373
6431
|
this.host = options.host ?? DEFAULT_HOST;
|
|
6374
6432
|
this.port = options.port ?? DEFAULT_PORT;
|
|
@@ -6448,13 +6506,13 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
|
6448
6506
|
async refreshPeers() {
|
|
6449
6507
|
this.peersBySlug.clear();
|
|
6450
6508
|
this.peersById.clear();
|
|
6451
|
-
if (!this.
|
|
6509
|
+
if (!this.bandRest.listPeers) {
|
|
6452
6510
|
throw new UnsupportedFeatureError(
|
|
6453
6511
|
"Peer listing is not available in current REST adapter"
|
|
6454
6512
|
);
|
|
6455
6513
|
}
|
|
6456
6514
|
for (let page = 1; page <= this.maxPeerPages; page += 1) {
|
|
6457
|
-
const response = await this.
|
|
6515
|
+
const response = await this.bandRest.listPeers({
|
|
6458
6516
|
page,
|
|
6459
6517
|
pageSize: this.peerPageSize,
|
|
6460
6518
|
notInChat: ""
|
|
@@ -6524,7 +6582,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
|
6524
6582
|
try {
|
|
6525
6583
|
await this.emitContextEvent(roomId, contextId);
|
|
6526
6584
|
const content = extractMessageText2(request.message) ?? "";
|
|
6527
|
-
await this.
|
|
6585
|
+
await this.bandRest.createChatMessage(roomId, {
|
|
6528
6586
|
content: buildMentionedContent(peer.name, content),
|
|
6529
6587
|
mentions: buildMentions(peer),
|
|
6530
6588
|
metadata: {
|
|
@@ -6555,7 +6613,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
|
6555
6613
|
contextId: pending.contextId,
|
|
6556
6614
|
state: "failed",
|
|
6557
6615
|
final: true,
|
|
6558
|
-
text: "Timed out waiting for a
|
|
6616
|
+
text: "Timed out waiting for a Band peer response."
|
|
6559
6617
|
});
|
|
6560
6618
|
return;
|
|
6561
6619
|
}
|
|
@@ -6642,7 +6700,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
|
6642
6700
|
if (existingRoom) {
|
|
6643
6701
|
const participants = this.roomParticipants.get(existingRoom) ?? /* @__PURE__ */ new Set();
|
|
6644
6702
|
if (!participants.has(targetPeerId)) {
|
|
6645
|
-
await this.
|
|
6703
|
+
await this.bandRest.addChatParticipant(existingRoom, {
|
|
6646
6704
|
participantId: targetPeerId,
|
|
6647
6705
|
role: "member"
|
|
6648
6706
|
});
|
|
@@ -6651,12 +6709,12 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
|
6651
6709
|
}
|
|
6652
6710
|
return [existingRoom, contextId];
|
|
6653
6711
|
}
|
|
6654
|
-
const normalizedContextId = contextId && contextId.length > 0 ? contextId : (0,
|
|
6655
|
-
const created = await this.
|
|
6712
|
+
const normalizedContextId = contextId && contextId.length > 0 ? contextId : (0, import_node_crypto7.randomUUID)();
|
|
6713
|
+
const created = await this.bandRest.createChat(
|
|
6656
6714
|
`a2a:gateway:${normalizedContextId}`
|
|
6657
6715
|
);
|
|
6658
6716
|
const roomId = created.id;
|
|
6659
|
-
await this.
|
|
6717
|
+
await this.bandRest.addChatParticipant(roomId, {
|
|
6660
6718
|
participantId: targetPeerId,
|
|
6661
6719
|
role: "member"
|
|
6662
6720
|
});
|
|
@@ -6665,7 +6723,7 @@ var A2AGatewayAdapter = class extends SimpleAdapter {
|
|
|
6665
6723
|
return [roomId, normalizedContextId];
|
|
6666
6724
|
}
|
|
6667
6725
|
async emitContextEvent(roomId, contextId) {
|
|
6668
|
-
await this.
|
|
6726
|
+
await this.bandRest.createChatEvent(roomId, {
|
|
6669
6727
|
content: "A2A gateway context",
|
|
6670
6728
|
messageType: "task",
|
|
6671
6729
|
metadata: {
|
|
@@ -6843,10 +6901,10 @@ function toStatusUpdateEvent(message, taskId, contextId) {
|
|
|
6843
6901
|
final,
|
|
6844
6902
|
text: message.content,
|
|
6845
6903
|
metadata: {
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6904
|
+
band_message_id: message.id,
|
|
6905
|
+
band_message_type: message.messageType,
|
|
6906
|
+
band_sender_id: message.senderId,
|
|
6907
|
+
band_room_id: message.roomId
|
|
6850
6908
|
}
|
|
6851
6909
|
});
|
|
6852
6910
|
}
|
|
@@ -7016,8 +7074,8 @@ var ParlantAdapter = class extends SimpleAdapter {
|
|
|
7016
7074
|
message: userMessage,
|
|
7017
7075
|
moderation: "none",
|
|
7018
7076
|
metadata: {
|
|
7019
|
-
|
|
7020
|
-
|
|
7077
|
+
band_source: "band-sdk-typescript",
|
|
7078
|
+
band_room_id: context.roomId
|
|
7021
7079
|
}
|
|
7022
7080
|
},
|
|
7023
7081
|
this.requestOptions()
|
|
@@ -7092,9 +7150,9 @@ var ParlantAdapter = class extends SimpleAdapter {
|
|
|
7092
7150
|
{
|
|
7093
7151
|
agentId: this.agentId,
|
|
7094
7152
|
customerId,
|
|
7095
|
-
title: `
|
|
7153
|
+
title: `Band Room ${roomId.slice(0, 8)}`,
|
|
7096
7154
|
metadata: {
|
|
7097
|
-
|
|
7155
|
+
band_room_id: roomId
|
|
7098
7156
|
}
|
|
7099
7157
|
},
|
|
7100
7158
|
this.requestOptions()
|
|
@@ -7107,7 +7165,7 @@ var ParlantAdapter = class extends SimpleAdapter {
|
|
|
7107
7165
|
source: "system",
|
|
7108
7166
|
message: this.systemPrompt,
|
|
7109
7167
|
metadata: {
|
|
7110
|
-
|
|
7168
|
+
band_system_prompt: true
|
|
7111
7169
|
}
|
|
7112
7170
|
},
|
|
7113
7171
|
this.requestOptions()
|
|
@@ -7161,7 +7219,7 @@ var ParlantAdapter = class extends SimpleAdapter {
|
|
|
7161
7219
|
{
|
|
7162
7220
|
name: customerName,
|
|
7163
7221
|
metadata: {
|
|
7164
|
-
|
|
7222
|
+
band_room_id: roomId
|
|
7165
7223
|
}
|
|
7166
7224
|
},
|
|
7167
7225
|
this.requestOptions()
|
|
@@ -7711,7 +7769,7 @@ var LettaAdapter = class extends SimpleAdapter {
|
|
|
7711
7769
|
const agent = await this.raceTimeout(
|
|
7712
7770
|
(s) => client.agents.create(
|
|
7713
7771
|
{
|
|
7714
|
-
name: `
|
|
7772
|
+
name: `band-room-${roomId.slice(0, 16)}`,
|
|
7715
7773
|
model: this.model,
|
|
7716
7774
|
...this.embedding ? { embedding: this.embedding } : {},
|
|
7717
7775
|
system: this.systemPrompt || void 0,
|
|
@@ -8128,7 +8186,8 @@ init_registrations();
|
|
|
8128
8186
|
// src/mcp/stdio.ts
|
|
8129
8187
|
init_registrations();
|
|
8130
8188
|
init_zod();
|
|
8131
|
-
|
|
8189
|
+
init_schemas();
|
|
8190
|
+
var BandMcpStdioServer = class {
|
|
8132
8191
|
options;
|
|
8133
8192
|
registrations;
|
|
8134
8193
|
mcpServer = null;
|
|
@@ -8157,7 +8216,7 @@ var ThenvoiMcpStdioServer = class {
|
|
|
8157
8216
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
8158
8217
|
const { z: z4 } = await import("zod");
|
|
8159
8218
|
const mcpServer = new McpServer({
|
|
8160
|
-
name: this.options.name ??
|
|
8219
|
+
name: this.options.name ?? MCP_SERVER_NAME,
|
|
8161
8220
|
version: "1.0.0"
|
|
8162
8221
|
});
|
|
8163
8222
|
registerTools3(mcpServer, z4, this.registrations);
|
|
@@ -8188,15 +8247,15 @@ function registerTools3(mcpServer, z4, registrations) {
|
|
|
8188
8247
|
}
|
|
8189
8248
|
|
|
8190
8249
|
// src/mcp/backends.ts
|
|
8191
|
-
async function
|
|
8250
|
+
async function createBandMcpBackend(options) {
|
|
8192
8251
|
const registrationOptions = {
|
|
8193
8252
|
enableMemoryTools: options.enableMemoryTools,
|
|
8194
8253
|
enableContactTools: true,
|
|
8195
8254
|
additionalTools: options.additionalTools
|
|
8196
8255
|
};
|
|
8197
8256
|
if (options.kind === "sdk") {
|
|
8198
|
-
const {
|
|
8199
|
-
const server2 =
|
|
8257
|
+
const { createBandSdkMcpServer: createBandSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
|
|
8258
|
+
const server2 = createBandSdkMcpServer2({
|
|
8200
8259
|
getToolsForRoom: options.getToolsForRoom,
|
|
8201
8260
|
multiRoom: options.multiRoom,
|
|
8202
8261
|
enableMemoryTools: options.enableMemoryTools,
|
|
@@ -8213,7 +8272,7 @@ async function createThenvoiMcpBackend(options) {
|
|
|
8213
8272
|
const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolvedTools, registrationOptions) : buildRoomScopedRegistrations(resolvedTools, registrationOptions);
|
|
8214
8273
|
const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
|
|
8215
8274
|
if (options.kind === "stdio") {
|
|
8216
|
-
const server2 = new
|
|
8275
|
+
const server2 = new BandMcpStdioServer({
|
|
8217
8276
|
tools: resolvedTools,
|
|
8218
8277
|
enableMemoryTools: options.enableMemoryTools,
|
|
8219
8278
|
enableContactTools: true,
|
|
@@ -8229,34 +8288,39 @@ async function createThenvoiMcpBackend(options) {
|
|
|
8229
8288
|
}
|
|
8230
8289
|
};
|
|
8231
8290
|
}
|
|
8291
|
+
const authToken = generateAuthToken();
|
|
8232
8292
|
if (options.kind === "sse") {
|
|
8233
|
-
const server2 = new
|
|
8293
|
+
const server2 = new BandMcpSseServer({
|
|
8234
8294
|
tools: resolvedTools,
|
|
8235
8295
|
enableMemoryTools: options.enableMemoryTools,
|
|
8236
8296
|
enableContactTools: true,
|
|
8237
|
-
additionalTools: options.additionalTools
|
|
8297
|
+
additionalTools: options.additionalTools,
|
|
8298
|
+
authToken
|
|
8238
8299
|
});
|
|
8239
8300
|
await server2.start();
|
|
8240
8301
|
return {
|
|
8241
8302
|
kind: "sse",
|
|
8242
8303
|
server: server2,
|
|
8243
8304
|
allowedTools,
|
|
8305
|
+
authToken,
|
|
8244
8306
|
stop: async () => {
|
|
8245
8307
|
await server2.stop();
|
|
8246
8308
|
}
|
|
8247
8309
|
};
|
|
8248
8310
|
}
|
|
8249
|
-
const server = new
|
|
8311
|
+
const server = new BandMcpServer({
|
|
8250
8312
|
tools: resolvedTools,
|
|
8251
8313
|
enableMemoryTools: options.enableMemoryTools,
|
|
8252
8314
|
enableContactTools: true,
|
|
8253
|
-
additionalTools: options.additionalTools
|
|
8315
|
+
additionalTools: options.additionalTools,
|
|
8316
|
+
authToken
|
|
8254
8317
|
});
|
|
8255
8318
|
await server.start();
|
|
8256
8319
|
return {
|
|
8257
8320
|
kind: "http",
|
|
8258
8321
|
server,
|
|
8259
8322
|
allowedTools,
|
|
8323
|
+
authToken,
|
|
8260
8324
|
stop: async () => {
|
|
8261
8325
|
await server.stop();
|
|
8262
8326
|
}
|
|
@@ -8265,6 +8329,7 @@ async function createThenvoiMcpBackend(options) {
|
|
|
8265
8329
|
|
|
8266
8330
|
// src/adapters/opencode/OpencodeAdapter.ts
|
|
8267
8331
|
init_registrations();
|
|
8332
|
+
init_schemas();
|
|
8268
8333
|
|
|
8269
8334
|
// src/converters/opencode.ts
|
|
8270
8335
|
var OpencodeHistoryConverter = class {
|
|
@@ -8398,7 +8463,7 @@ var SdkOpencodeClientBase = class {
|
|
|
8398
8463
|
const result = await runtime.client.mcp.add({
|
|
8399
8464
|
...this.scope(),
|
|
8400
8465
|
name: input.name,
|
|
8401
|
-
config: { type: "remote", url: input.url }
|
|
8466
|
+
config: { type: "remote", url: input.url, headers: input.headers }
|
|
8402
8467
|
});
|
|
8403
8468
|
return expectRecord(result);
|
|
8404
8469
|
}
|
|
@@ -8589,8 +8654,8 @@ async function readResponseBody(response) {
|
|
|
8589
8654
|
|
|
8590
8655
|
// src/adapters/opencode/OpencodeAdapter.ts
|
|
8591
8656
|
var OPENCODE_SYSTEM_NOTE = [
|
|
8592
|
-
"Responses are relayed back into the
|
|
8593
|
-
"Use the
|
|
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.",
|
|
8594
8659
|
"When you need approval or clarification, ask clearly and wait for the user's next room message."
|
|
8595
8660
|
].join("\n");
|
|
8596
8661
|
function createDeferred() {
|
|
@@ -8621,8 +8686,8 @@ function withDefaults(config) {
|
|
|
8621
8686
|
approvalTimeoutReply: "reject",
|
|
8622
8687
|
questionMode: "manual",
|
|
8623
8688
|
questionWaitTimeoutMs: 3e5,
|
|
8624
|
-
sessionTitlePrefix: "
|
|
8625
|
-
mcpServerName:
|
|
8689
|
+
sessionTitlePrefix: "Band",
|
|
8690
|
+
mcpServerName: MCP_SERVER_NAME,
|
|
8626
8691
|
...config
|
|
8627
8692
|
};
|
|
8628
8693
|
}
|
|
@@ -8678,7 +8743,7 @@ var OpencodeAdapter = class extends SimpleAdapter {
|
|
|
8678
8743
|
directory: config.directory || void 0,
|
|
8679
8744
|
workspace: config.workspace || void 0
|
|
8680
8745
|
}));
|
|
8681
|
-
this.mcpBackendFactory = options.mcpBackendFactory ??
|
|
8746
|
+
this.mcpBackendFactory = options.mcpBackendFactory ?? createBandMcpBackend;
|
|
8682
8747
|
this.logger = options.logger ?? new NoopLogger();
|
|
8683
8748
|
}
|
|
8684
8749
|
async onStarted(agentName, agentDescription) {
|
|
@@ -8832,7 +8897,8 @@ ${OPENCODE_SYSTEM_NOTE}`.trim();
|
|
|
8832
8897
|
}
|
|
8833
8898
|
await client.registerMcpServer({
|
|
8834
8899
|
name: this.config.mcpServerName,
|
|
8835
|
-
url: server.url
|
|
8900
|
+
url: server.url,
|
|
8901
|
+
headers: backend.authToken ? { Authorization: `Bearer ${backend.authToken}` } : void 0
|
|
8836
8902
|
});
|
|
8837
8903
|
} catch (error) {
|
|
8838
8904
|
this.logger.warn("Failed to register OpenCode MCP backend", { error });
|
|
@@ -9470,7 +9536,7 @@ init_registrations();
|
|
|
9470
9536
|
init_zod();
|
|
9471
9537
|
var import_zod8 = require("zod");
|
|
9472
9538
|
var DEFAULT_MODEL2 = "claude-sonnet-4-6";
|
|
9473
|
-
var
|
|
9539
|
+
var bandMcpBridgeFactory = new LazyAsyncValue({
|
|
9474
9540
|
load: async () => {
|
|
9475
9541
|
const module2 = await import("@anthropic-ai/claude-agent-sdk").catch((error) => {
|
|
9476
9542
|
throw new UnsupportedFeatureError(
|
|
@@ -9508,7 +9574,7 @@ var thenvoiMcpBridgeFactory = new LazyAsyncValue({
|
|
|
9508
9574
|
});
|
|
9509
9575
|
return {
|
|
9510
9576
|
serverConfig: createSdkMcpServer2({
|
|
9511
|
-
name:
|
|
9577
|
+
name: MCP_SERVER_NAME,
|
|
9512
9578
|
tools: toolDefinitions
|
|
9513
9579
|
}),
|
|
9514
9580
|
allowedTools: mcpToolNames(new Set(registrations.map((registration) => registration.name)))
|
|
@@ -9559,8 +9625,8 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
|
|
|
9559
9625
|
capabilities: { memory: this.enableMemoryTools }
|
|
9560
9626
|
});
|
|
9561
9627
|
if (this.enableMcpTools) {
|
|
9562
|
-
const
|
|
9563
|
-
this.mcpBridge =
|
|
9628
|
+
const createBandMcpBridge = await bandMcpBridgeFactory.get();
|
|
9629
|
+
this.mcpBridge = createBandMcpBridge({
|
|
9564
9630
|
enableMemoryTools: this.enableMemoryTools,
|
|
9565
9631
|
getToolsForRoom: (roomId) => this.roomTools.get(roomId),
|
|
9566
9632
|
additionalTools: this.additionalMcpTools.length > 0 ? this.additionalMcpTools : void 0
|
|
@@ -9608,14 +9674,14 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
|
|
|
9608
9674
|
}
|
|
9609
9675
|
if (this.mcpBridge && this.enableMcpTools) {
|
|
9610
9676
|
options.mcpServers = {
|
|
9611
|
-
|
|
9677
|
+
[MCP_SERVER_NAME]: this.mcpBridge.serverConfig
|
|
9612
9678
|
};
|
|
9613
9679
|
options.allowedTools = this.mcpBridge.allowedTools;
|
|
9614
9680
|
this.roomTools.set(context.roomId, tools);
|
|
9615
9681
|
}
|
|
9616
9682
|
const roomToolHint = this.enableMcpTools ? `
|
|
9617
9683
|
|
|
9618
|
-
[Tooling note]: For any
|
|
9684
|
+
[Tooling note]: For any mcp__band__* tool call, pass room_id="${context.roomId}".` : "";
|
|
9619
9685
|
const query = queryFn({
|
|
9620
9686
|
prompt: buildConversationPrompt({
|
|
9621
9687
|
history,
|
|
@@ -9704,6 +9770,7 @@ function extractAssistantText3(event) {
|
|
|
9704
9770
|
|
|
9705
9771
|
// src/adapters/codex/CodexAdapter.ts
|
|
9706
9772
|
init_protocols();
|
|
9773
|
+
init_schemas();
|
|
9707
9774
|
|
|
9708
9775
|
// src/adapters/codex/appServerClient.ts
|
|
9709
9776
|
var import_node_child_process2 = require("child_process");
|
|
@@ -10003,8 +10070,8 @@ var CODEX_WEB_SEARCH_MODES = ["disabled", "cached", "live"];
|
|
|
10003
10070
|
var CODEX_REASONING_SUMMARIES = ["auto", "concise", "detailed", "none"];
|
|
10004
10071
|
var CODEX_REASONING_EFFORTS = ["low", "medium", "high", "xhigh"];
|
|
10005
10072
|
var SILENT_REPORTING_TOOLS = /* @__PURE__ */ new Set([
|
|
10006
|
-
|
|
10007
|
-
|
|
10073
|
+
SEND_MESSAGE_TOOL_NAME,
|
|
10074
|
+
SEND_EVENT_TOOL_NAME
|
|
10008
10075
|
]);
|
|
10009
10076
|
var CodexAdapter = class extends SimpleAdapter {
|
|
10010
10077
|
baseConfig;
|
|
@@ -10034,8 +10101,8 @@ var CodexAdapter = class extends SimpleAdapter {
|
|
|
10034
10101
|
includeBaseInstructions: true,
|
|
10035
10102
|
experimentalApi: true,
|
|
10036
10103
|
fallbackSendAgentText: true,
|
|
10037
|
-
clientName: "
|
|
10038
|
-
clientTitle: "
|
|
10104
|
+
clientName: "band_codex_adapter",
|
|
10105
|
+
clientTitle: "Band Codex Adapter",
|
|
10039
10106
|
clientVersion: "0.1.0",
|
|
10040
10107
|
turnTimeoutMs: 18e4,
|
|
10041
10108
|
...options?.config
|
|
@@ -10301,8 +10368,8 @@ var CodexAdapter = class extends SimpleAdapter {
|
|
|
10301
10368
|
await client.connect();
|
|
10302
10369
|
await client.initialize({
|
|
10303
10370
|
clientInfo: {
|
|
10304
|
-
name: this.baseConfig.clientName ?? "
|
|
10305
|
-
title: this.baseConfig.clientTitle ?? "
|
|
10371
|
+
name: this.baseConfig.clientName ?? "band_codex_adapter",
|
|
10372
|
+
title: this.baseConfig.clientTitle ?? "Band Codex Adapter",
|
|
10306
10373
|
version: this.baseConfig.clientVersion ?? "0.1.0"
|
|
10307
10374
|
},
|
|
10308
10375
|
capabilities: {
|
|
@@ -10575,7 +10642,7 @@ var CodexAdapter = class extends SimpleAdapter {
|
|
|
10575
10642
|
tool_call_id: callId
|
|
10576
10643
|
}), "tool_result");
|
|
10577
10644
|
}
|
|
10578
|
-
return !isError && toolName ===
|
|
10645
|
+
return !isError && toolName === SEND_MESSAGE_TOOL_NAME;
|
|
10579
10646
|
} catch (error) {
|
|
10580
10647
|
const output = {
|
|
10581
10648
|
ok: false,
|
|
@@ -11098,6 +11165,7 @@ function parseModelListResponse(value) {
|
|
|
11098
11165
|
ACPServer,
|
|
11099
11166
|
AnthropicAdapter,
|
|
11100
11167
|
AnthropicToolCallingModel,
|
|
11168
|
+
BandACPServerAdapter,
|
|
11101
11169
|
CODEX_REASONING_EFFORTS,
|
|
11102
11170
|
CODEX_REASONING_SUMMARIES,
|
|
11103
11171
|
CODEX_WEB_SEARCH_MODES,
|
|
@@ -11121,7 +11189,6 @@ function parseModelListResponse(value) {
|
|
|
11121
11189
|
OpencodeAdapter,
|
|
11122
11190
|
ParlantAdapter,
|
|
11123
11191
|
ParlantHistoryConverter,
|
|
11124
|
-
ThenvoiACPServerAdapter,
|
|
11125
11192
|
ToolCallingAdapter,
|
|
11126
11193
|
VercelAISDKAdapter,
|
|
11127
11194
|
VercelAISDKToolCallingModel,
|