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