@band-ai/sdk 0.1.4 → 0.1.10
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 +372 -0
- package/dist/{ClaudeSDKAdapter-CRq4R-WB.d.cts → ClaudeSDKAdapter-DfjaI5ke.d.cts} +9 -7
- package/dist/{ClaudeSDKAdapter-BHOkjN3X.d.ts → ClaudeSDKAdapter-DonPGJ43.d.ts} +9 -7
- package/dist/{acp-server-BdRz9_UN.d.cts → acp-server-CUBXIiG6.d.cts} +2 -2
- package/dist/{acp-server-B1Da7L6u.d.ts → acp-server-NZAeg-WO.d.ts} +2 -2
- package/dist/adapters.cjs +494 -106
- package/dist/adapters.d.cts +12 -12
- package/dist/adapters.d.ts +12 -12
- package/dist/adapters.js +7 -7
- package/dist/{backends-SVMT-7l4.d.cts → backends-DYtEhCZG.d.cts} +7 -2
- package/dist/{backends-CzDbiQar.d.ts → backends-oYAb7EU-.d.ts} +7 -2
- package/dist/{chunk-MSL6CWHY.js → chunk-2BHHR6YW.js} +17 -16
- package/dist/{chunk-EDPKUUJL.js → chunk-6RXWL6TC.js} +9 -1
- package/dist/{chunk-SFVKOEQH.js → chunk-DNPVCR3S.js} +92 -14
- package/dist/{chunk-I5EZG52P.js → chunk-FP237EAG.js} +424 -136
- package/dist/{chunk-RHVH2GZR.js → chunk-J3M3PFFY.js} +81 -31
- package/dist/{chunk-GVEQ3RAH.js → chunk-MLROFDKR.js} +132 -23
- package/dist/{chunk-INA6YZTZ.js → chunk-RDM4TE4B.js} +32 -30
- package/dist/chunk-US226AS4.js +130 -0
- package/dist/{chunk-W5NDZSYE.js → chunk-XA4N2JPH.js} +1 -1
- package/dist/converters.cjs +469 -13
- package/dist/converters.d.cts +5 -5
- package/dist/converters.d.ts +5 -5
- package/dist/converters.js +3 -2
- package/dist/core.cjs +45 -2
- package/dist/core.d.cts +4 -3
- package/dist/core.d.ts +4 -3
- package/dist/core.js +5 -1
- package/dist/disconnectReason-IuADl6TH.d.cts +34 -0
- package/dist/disconnectReason-IuADl6TH.d.ts +34 -0
- package/dist/{dtos-DUpbIu8k.d.cts → dtos-Dd_fTfLn.d.cts} +26 -6
- package/dist/{dtos-DUpbIu8k.d.ts → dtos-Dd_fTfLn.d.ts} +26 -6
- package/dist/index.cjs +1089 -269
- package/dist/index.d.cts +16 -15
- package/dist/index.d.ts +16 -15
- package/dist/index.js +14 -8
- package/dist/linear.cjs +985 -53
- package/dist/linear.d.cts +137 -7
- package/dist/linear.d.ts +137 -7
- package/dist/linear.js +974 -53
- package/dist/mcp-claude.cjs +303 -32
- package/dist/mcp-claude.d.cts +3 -3
- package/dist/mcp-claude.d.ts +3 -3
- package/dist/mcp-claude.js +210 -12
- package/dist/mcp.cjs +313 -45
- package/dist/mcp.d.cts +5 -5
- package/dist/mcp.d.ts +5 -5
- package/dist/mcp.js +3 -3
- package/dist/{opencode-BBcDchcN.d.cts → opencode--iA5-KYk.d.cts} +2 -2
- package/dist/{opencode-DthQQUsZ.d.ts → opencode-YNacv-eJ.d.ts} +2 -2
- package/dist/{pagination-CcDkVFxK.d.ts → pagination-BBLsYLhT.d.ts} +2 -2
- package/dist/{pagination-BPiys10t.d.cts → pagination-CqidD-L_.d.cts} +2 -2
- package/dist/{protocols-DrhzOH6K.d.ts → protocols-BF6jamIl.d.ts} +1 -1
- package/dist/{protocols-CInhtFpA.d.cts → protocols-D2bTrQ_t.d.cts} +1 -1
- package/dist/rest.d.cts +5 -5
- package/dist/rest.d.ts +5 -5
- package/dist/runtime.cjs +721 -172
- package/dist/runtime.d.cts +15 -10
- package/dist/runtime.d.ts +15 -10
- package/dist/runtime.js +11 -8
- package/dist/{schemas-vos1AaBc.d.ts → schemas-B1Fd3oUM.d.ts} +17 -8
- package/dist/{schemas-BpEBkq5V.d.cts → schemas-CI0qgcp_.d.cts} +17 -8
- package/dist/{sdk-CcnQ5OUC.d.ts → sdk-CyqN1W5g.d.ts} +32 -2
- package/dist/{sdk-CwTAxhwI.d.cts → sdk-D2rTDU_o.d.cts} +32 -2
- package/dist/{simpleAdapter-DqhvjsGr.d.cts → simpleAdapter-C_f-01Cu.d.cts} +1 -1
- package/dist/{simpleAdapter-9OE_p6QW.d.ts → simpleAdapter-qQt-tSz4.d.ts} +1 -1
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/{types-CovcHpYf.d.cts → types-CKqrhGB1.d.cts} +2 -2
- package/dist/{types-CxII3XkA.d.ts → types-D3AsUnd0.d.ts} +1 -1
- package/dist/{types-7jVzOeOP.d.ts → types-DNySTI_8.d.ts} +2 -2
- package/dist/{types-CSHFipIc.d.cts → types-DtMms5Fi.d.cts} +1 -1
- package/package.json +22 -21
package/dist/mcp-claude.cjs
CHANGED
|
@@ -30,6 +30,78 @@ var import_zod = require("zod");
|
|
|
30
30
|
var CHAT_EVENT_TYPES = ["tool_call", "tool_result", "thought", "error", "task"];
|
|
31
31
|
var CHAT_MESSAGE_TYPES = ["text", ...CHAT_EVENT_TYPES];
|
|
32
32
|
|
|
33
|
+
// src/contracts/memory.ts
|
|
34
|
+
var SENSORY_MEMORY_TYPES = [
|
|
35
|
+
"iconic",
|
|
36
|
+
// Visual input
|
|
37
|
+
"echoic",
|
|
38
|
+
// Auditory input
|
|
39
|
+
"haptic"
|
|
40
|
+
// Tactile input
|
|
41
|
+
];
|
|
42
|
+
var COGNITIVE_MEMORY_TYPES = [
|
|
43
|
+
"episodic",
|
|
44
|
+
// Events that occurred
|
|
45
|
+
"semantic",
|
|
46
|
+
// Facts, preferences, learned knowledge
|
|
47
|
+
"procedural"
|
|
48
|
+
// How to perform tasks
|
|
49
|
+
];
|
|
50
|
+
function namedValues(values) {
|
|
51
|
+
return Object.fromEntries(values.map((value) => [value, value]));
|
|
52
|
+
}
|
|
53
|
+
var MEMORY_SYSTEM_TYPES = {
|
|
54
|
+
sensory: SENSORY_MEMORY_TYPES,
|
|
55
|
+
// Brief sensory inputs
|
|
56
|
+
working: COGNITIVE_MEMORY_TYPES,
|
|
57
|
+
// Short-term session context
|
|
58
|
+
long_term: COGNITIVE_MEMORY_TYPES
|
|
59
|
+
// Persistent cross-conversation memory
|
|
60
|
+
};
|
|
61
|
+
var MEMORY_SYSTEMS = Object.keys(MEMORY_SYSTEM_TYPES);
|
|
62
|
+
var MEMORY_TYPES = [
|
|
63
|
+
...SENSORY_MEMORY_TYPES,
|
|
64
|
+
...COGNITIVE_MEMORY_TYPES
|
|
65
|
+
];
|
|
66
|
+
var MEMORY_SEGMENTS = [
|
|
67
|
+
"user",
|
|
68
|
+
// User preferences or profile info
|
|
69
|
+
"agent",
|
|
70
|
+
// Facts or events about agents/entities
|
|
71
|
+
"tool",
|
|
72
|
+
// Tool usage or task procedures
|
|
73
|
+
"guideline"
|
|
74
|
+
// Behavioral rules or policies
|
|
75
|
+
];
|
|
76
|
+
var MEMORY_STORE_SCOPES = [
|
|
77
|
+
"subject",
|
|
78
|
+
// About one person/agent; requires subject_id
|
|
79
|
+
"organization"
|
|
80
|
+
// Shared org-wide
|
|
81
|
+
];
|
|
82
|
+
var MEMORY_LIST_SCOPES = [
|
|
83
|
+
"subject",
|
|
84
|
+
// Subject-scoped memories only
|
|
85
|
+
"organization",
|
|
86
|
+
// Organization-scoped memories only
|
|
87
|
+
"all"
|
|
88
|
+
// Both scopes (no scope filter)
|
|
89
|
+
];
|
|
90
|
+
var MEMORY_STATUSES = [
|
|
91
|
+
"active",
|
|
92
|
+
// Normal, visible memories
|
|
93
|
+
"superseded",
|
|
94
|
+
// Outdated; soft-deleted via thenvoi_supersede_memory
|
|
95
|
+
"archived",
|
|
96
|
+
// Hidden but preserved via thenvoi_archive_memory
|
|
97
|
+
"all"
|
|
98
|
+
// Any status (no filter)
|
|
99
|
+
];
|
|
100
|
+
var MEMORY_SYSTEM = namedValues(MEMORY_SYSTEMS);
|
|
101
|
+
var MEMORY_TYPE = namedValues(MEMORY_TYPES);
|
|
102
|
+
var MEMORY_SEGMENT = namedValues(MEMORY_SEGMENTS);
|
|
103
|
+
var MEMORY_STORE_SCOPE = namedValues(MEMORY_STORE_SCOPES);
|
|
104
|
+
|
|
33
105
|
// src/runtime/tools/schemas.ts
|
|
34
106
|
var TOOL_MODELS = {
|
|
35
107
|
thenvoi_send_message: {
|
|
@@ -217,29 +289,22 @@ var TOOL_MODELS = {
|
|
|
217
289
|
},
|
|
218
290
|
scope: {
|
|
219
291
|
type: "string",
|
|
220
|
-
enum: [
|
|
292
|
+
enum: [...MEMORY_LIST_SCOPES],
|
|
221
293
|
description: "Filter by scope."
|
|
222
294
|
},
|
|
223
295
|
system: {
|
|
224
296
|
type: "string",
|
|
225
|
-
enum: [
|
|
297
|
+
enum: [...MEMORY_SYSTEMS],
|
|
226
298
|
description: "Filter by memory system."
|
|
227
299
|
},
|
|
228
300
|
type: {
|
|
229
301
|
type: "string",
|
|
230
|
-
enum: [
|
|
231
|
-
"iconic",
|
|
232
|
-
"echoic",
|
|
233
|
-
"haptic",
|
|
234
|
-
"episodic",
|
|
235
|
-
"semantic",
|
|
236
|
-
"procedural"
|
|
237
|
-
],
|
|
302
|
+
enum: [...MEMORY_TYPES],
|
|
238
303
|
description: "Filter by memory type."
|
|
239
304
|
},
|
|
240
305
|
segment: {
|
|
241
306
|
type: "string",
|
|
242
|
-
enum: [
|
|
307
|
+
enum: [...MEMORY_SEGMENTS],
|
|
243
308
|
description: "Filter by segment."
|
|
244
309
|
},
|
|
245
310
|
content_query: {
|
|
@@ -254,7 +319,7 @@ var TOOL_MODELS = {
|
|
|
254
319
|
},
|
|
255
320
|
status: {
|
|
256
321
|
type: "string",
|
|
257
|
-
enum: [
|
|
322
|
+
enum: [...MEMORY_STATUSES],
|
|
258
323
|
description: "Filter by status."
|
|
259
324
|
}
|
|
260
325
|
},
|
|
@@ -269,24 +334,17 @@ var TOOL_MODELS = {
|
|
|
269
334
|
},
|
|
270
335
|
system: {
|
|
271
336
|
type: "string",
|
|
272
|
-
enum: [
|
|
337
|
+
enum: [...MEMORY_SYSTEMS],
|
|
273
338
|
description: "Memory system tier."
|
|
274
339
|
},
|
|
275
340
|
type: {
|
|
276
341
|
type: "string",
|
|
277
|
-
enum: [
|
|
278
|
-
"iconic",
|
|
279
|
-
"echoic",
|
|
280
|
-
"haptic",
|
|
281
|
-
"episodic",
|
|
282
|
-
"semantic",
|
|
283
|
-
"procedural"
|
|
284
|
-
],
|
|
342
|
+
enum: [...MEMORY_TYPES],
|
|
285
343
|
description: "Memory type (must be valid for selected system)."
|
|
286
344
|
},
|
|
287
345
|
segment: {
|
|
288
346
|
type: "string",
|
|
289
|
-
enum: [
|
|
347
|
+
enum: [...MEMORY_SEGMENTS],
|
|
290
348
|
description: "Logical segment."
|
|
291
349
|
},
|
|
292
350
|
thought: {
|
|
@@ -295,7 +353,7 @@ var TOOL_MODELS = {
|
|
|
295
353
|
},
|
|
296
354
|
scope: {
|
|
297
355
|
type: "string",
|
|
298
|
-
enum: [
|
|
356
|
+
enum: [...MEMORY_STORE_SCOPES],
|
|
299
357
|
description: "Visibility scope."
|
|
300
358
|
},
|
|
301
359
|
subject_id: {
|
|
@@ -414,6 +472,16 @@ function buildRoomScopedRegistrations(resolver, options = {}) {
|
|
|
414
472
|
}
|
|
415
473
|
return registrations;
|
|
416
474
|
}
|
|
475
|
+
function buildSingleContextRegistrations(tools, options = {}) {
|
|
476
|
+
const toolNames = resolveToolNames(options);
|
|
477
|
+
const registrations = buildRegistrations(toolNames, (_toolName, args) => {
|
|
478
|
+
return executeToolCall(tools, _toolName, args);
|
|
479
|
+
}, { injectRoomId: false });
|
|
480
|
+
if (options.additionalTools) {
|
|
481
|
+
registrations.push(...options.additionalTools);
|
|
482
|
+
}
|
|
483
|
+
return registrations;
|
|
484
|
+
}
|
|
417
485
|
function resolveToolNames(options) {
|
|
418
486
|
const names = /* @__PURE__ */ new Set();
|
|
419
487
|
for (const name of BASE_TOOL_NAMES) {
|
|
@@ -501,6 +569,13 @@ function serializeValue(value) {
|
|
|
501
569
|
return String(value);
|
|
502
570
|
}
|
|
503
571
|
}
|
|
572
|
+
function resolveSingleRoomTools(getToolsForRoom) {
|
|
573
|
+
const tools = getToolsForRoom("");
|
|
574
|
+
if (!tools) {
|
|
575
|
+
throw new Error('Single-room mode requires getToolsForRoom("") to return a tools instance');
|
|
576
|
+
}
|
|
577
|
+
return tools;
|
|
578
|
+
}
|
|
504
579
|
|
|
505
580
|
// src/mcp/zod.ts
|
|
506
581
|
function buildZodShape(z2, properties, required) {
|
|
@@ -543,16 +618,16 @@ function jsonSchemaToZod(z2, schema) {
|
|
|
543
618
|
|
|
544
619
|
// src/mcp/sdk.ts
|
|
545
620
|
function createThenvoiSdkMcpServer(options) {
|
|
546
|
-
const
|
|
547
|
-
options.
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
553
|
-
);
|
|
621
|
+
const registrationOptions = {
|
|
622
|
+
enableMemoryTools: options.enableMemoryTools,
|
|
623
|
+
enableContactTools: true,
|
|
624
|
+
additionalTools: options.additionalTools
|
|
625
|
+
};
|
|
626
|
+
const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolveSingleRoomTools(options.getToolsForRoom), registrationOptions) : buildRoomScopedRegistrations(options.getToolsForRoom, registrationOptions);
|
|
554
627
|
const toolDefinitions = registrations.map(toSdkToolDefinition);
|
|
555
628
|
const toolNames = new Set(registrations.map((r) => r.name));
|
|
629
|
+
const contextCache = /* @__PURE__ */ new Map();
|
|
630
|
+
const MAX_CONTEXT_CACHE_ENTRIES = 100;
|
|
556
631
|
const serverConfig = (0, import_claude_agent_sdk.createSdkMcpServer)({
|
|
557
632
|
name: "thenvoi",
|
|
558
633
|
tools: toolDefinitions
|
|
@@ -560,9 +635,205 @@ function createThenvoiSdkMcpServer(options) {
|
|
|
560
635
|
return {
|
|
561
636
|
serverConfig,
|
|
562
637
|
allowedTools: mcpToolNames(toolNames),
|
|
563
|
-
toolDefinitions
|
|
638
|
+
toolDefinitions,
|
|
639
|
+
getSystemPromptContext: async (roomId, contextOptions) => {
|
|
640
|
+
const context = await getOrBuildSystemPromptContext(
|
|
641
|
+
roomId,
|
|
642
|
+
contextOptions,
|
|
643
|
+
options.getToolsForRoom,
|
|
644
|
+
contextCache,
|
|
645
|
+
MAX_CONTEXT_CACHE_ENTRIES
|
|
646
|
+
);
|
|
647
|
+
return context.markdown;
|
|
648
|
+
},
|
|
649
|
+
getSystemPromptContextData: (roomId, contextOptions) => {
|
|
650
|
+
return getOrBuildSystemPromptContext(
|
|
651
|
+
roomId,
|
|
652
|
+
contextOptions,
|
|
653
|
+
options.getToolsForRoom,
|
|
654
|
+
contextCache,
|
|
655
|
+
MAX_CONTEXT_CACHE_ENTRIES
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
async function getOrBuildSystemPromptContext(roomId, contextOptions, getToolsForRoom, contextCache, maxEntries) {
|
|
661
|
+
const ttlMs = contextOptions?.ttlMs ?? 3e4;
|
|
662
|
+
const now = Date.now();
|
|
663
|
+
const cached = contextCache.get(roomId);
|
|
664
|
+
if (cached && cached.expiresAt > now) {
|
|
665
|
+
cached.lastAccessedAt = now;
|
|
666
|
+
return cached.value;
|
|
667
|
+
}
|
|
668
|
+
if (cached) {
|
|
669
|
+
contextCache.delete(roomId);
|
|
670
|
+
}
|
|
671
|
+
const tools = getToolsForRoom(roomId);
|
|
672
|
+
if (!tools) {
|
|
673
|
+
return buildUnavailableSystemPromptContext(roomId);
|
|
674
|
+
}
|
|
675
|
+
const context = await buildSystemPromptContext(roomId, tools);
|
|
676
|
+
contextCache.set(roomId, {
|
|
677
|
+
value: context,
|
|
678
|
+
expiresAt: now + ttlMs,
|
|
679
|
+
lastAccessedAt: now
|
|
680
|
+
});
|
|
681
|
+
evictLeastRecentlyUsedContext(contextCache, maxEntries);
|
|
682
|
+
return context;
|
|
683
|
+
}
|
|
684
|
+
async function buildSystemPromptContext(roomId, tools) {
|
|
685
|
+
const participants = await tools.getParticipants();
|
|
686
|
+
const warnings = [];
|
|
687
|
+
const agentResolution = await resolveAgentIdentity(tools);
|
|
688
|
+
if (agentResolution.warning) {
|
|
689
|
+
warnings.push(agentResolution.warning);
|
|
690
|
+
}
|
|
691
|
+
const roomResolution = await resolveRoomTitle(tools, roomId);
|
|
692
|
+
if (roomResolution.warning) {
|
|
693
|
+
warnings.push(roomResolution.warning);
|
|
694
|
+
}
|
|
695
|
+
const agentIdentity = agentResolution.value;
|
|
696
|
+
const roomTitle = roomResolution.value;
|
|
697
|
+
const normalizedParticipants = participants.map((participant) => ({
|
|
698
|
+
id: String(participant.id),
|
|
699
|
+
name: String(participant.name ?? "Unknown"),
|
|
700
|
+
type: String(participant.type ?? "Unknown"),
|
|
701
|
+
handle: normalizeHandle(participant.handle),
|
|
702
|
+
isSelf: participant.id === agentIdentity?.id
|
|
703
|
+
}));
|
|
704
|
+
const selfHandle = normalizeHandle(agentIdentity?.handle);
|
|
705
|
+
const selfName = agentIdentity?.name ?? "Agent";
|
|
706
|
+
const mentionHandles = normalizedParticipants.filter((participant) => !participant.isSelf).map((participant) => participant.handle).filter((handle) => Boolean(handle));
|
|
707
|
+
const mentionFormat = mentionHandles.length > 0 ? mentionHandles.join(", ") : "No participant handles available";
|
|
708
|
+
const roomLabel = roomTitle ? `"${roomTitle}"` : "this room";
|
|
709
|
+
const agentLabel = selfHandle ? `${selfName} (${selfHandle})` : selfName;
|
|
710
|
+
const participantLines = normalizedParticipants.length > 0 ? normalizedParticipants.map((participant) => {
|
|
711
|
+
const suffix = participant.isSelf ? " (you)" : "";
|
|
712
|
+
const handle = participant.handle ? ` (${participant.handle})` : "";
|
|
713
|
+
return `- **${participant.name}**${handle} -- ${participant.type}${suffix}`;
|
|
714
|
+
}).join("\n") : "- No participants found";
|
|
715
|
+
const markdown = [
|
|
716
|
+
"## Room Context",
|
|
717
|
+
"",
|
|
718
|
+
`You are **${agentLabel}** in room ${roomLabel} (id: ${roomId}).`,
|
|
719
|
+
"",
|
|
720
|
+
"### Participants",
|
|
721
|
+
participantLines,
|
|
722
|
+
"",
|
|
723
|
+
"### Mention Format",
|
|
724
|
+
`To address someone, use their exact handle: ${mentionFormat}`,
|
|
725
|
+
...warnings.length > 0 ? ["", "### Warnings", ...warnings.map((warning) => `- ${warning}`)] : []
|
|
726
|
+
].join("\n");
|
|
727
|
+
return {
|
|
728
|
+
roomId,
|
|
729
|
+
roomTitle,
|
|
730
|
+
agent: {
|
|
731
|
+
id: agentIdentity?.id ?? "unknown-agent",
|
|
732
|
+
name: selfName,
|
|
733
|
+
handle: selfHandle,
|
|
734
|
+
description: agentIdentity?.description ?? null
|
|
735
|
+
},
|
|
736
|
+
participants: normalizedParticipants,
|
|
737
|
+
mentionFormat,
|
|
738
|
+
warnings,
|
|
739
|
+
markdown
|
|
564
740
|
};
|
|
565
741
|
}
|
|
742
|
+
async function resolveAgentIdentity(tools) {
|
|
743
|
+
const maybeTools = tools;
|
|
744
|
+
try {
|
|
745
|
+
if (maybeTools.getAgentIdentity) {
|
|
746
|
+
return { value: await maybeTools.getAgentIdentity(), warning: null };
|
|
747
|
+
}
|
|
748
|
+
if (maybeTools.rest?.getAgentMe) {
|
|
749
|
+
return { value: await maybeTools.rest.getAgentMe(), warning: null };
|
|
750
|
+
}
|
|
751
|
+
} catch (error) {
|
|
752
|
+
return {
|
|
753
|
+
value: null,
|
|
754
|
+
warning: `Unable to resolve agent identity: ${error instanceof Error ? error.message : String(error)}`
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
return { value: null, warning: null };
|
|
758
|
+
}
|
|
759
|
+
async function resolveRoomTitle(tools, roomId) {
|
|
760
|
+
const maybeTools = tools;
|
|
761
|
+
const rest = maybeTools.rest;
|
|
762
|
+
if (!rest?.listChats) {
|
|
763
|
+
return { value: null, warning: null };
|
|
764
|
+
}
|
|
765
|
+
try {
|
|
766
|
+
let page = 1;
|
|
767
|
+
const pageSize = 100;
|
|
768
|
+
while (true) {
|
|
769
|
+
const response = await rest.listChats({ page, pageSize });
|
|
770
|
+
const room = response?.data?.find((entry) => entry.id === roomId);
|
|
771
|
+
if (typeof room?.title === "string" && room.title.length > 0) {
|
|
772
|
+
return { value: room.title, warning: null };
|
|
773
|
+
}
|
|
774
|
+
const totalPages = response?.metadata?.totalPages ?? page;
|
|
775
|
+
if (page >= totalPages) {
|
|
776
|
+
return { value: null, warning: null };
|
|
777
|
+
}
|
|
778
|
+
page += 1;
|
|
779
|
+
}
|
|
780
|
+
} catch (error) {
|
|
781
|
+
return {
|
|
782
|
+
value: null,
|
|
783
|
+
warning: `Unable to resolve room title: ${error instanceof Error ? error.message : String(error)}`
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
function buildUnavailableSystemPromptContext(roomId) {
|
|
788
|
+
const warnings = [`No tool context found for room_id ${roomId}`];
|
|
789
|
+
const markdown = [
|
|
790
|
+
"## Room Context",
|
|
791
|
+
"",
|
|
792
|
+
`You are **Agent** in this room (id: ${roomId}).`,
|
|
793
|
+
"",
|
|
794
|
+
"### Participants",
|
|
795
|
+
"- No participants found",
|
|
796
|
+
"",
|
|
797
|
+
"### Mention Format",
|
|
798
|
+
"No participant handles available",
|
|
799
|
+
"",
|
|
800
|
+
"### Warnings",
|
|
801
|
+
...warnings.map((warning) => `- ${warning}`)
|
|
802
|
+
].join("\n");
|
|
803
|
+
return {
|
|
804
|
+
roomId,
|
|
805
|
+
roomTitle: null,
|
|
806
|
+
agent: {
|
|
807
|
+
id: "unknown-agent",
|
|
808
|
+
name: "Agent",
|
|
809
|
+
handle: null,
|
|
810
|
+
description: null
|
|
811
|
+
},
|
|
812
|
+
participants: [],
|
|
813
|
+
mentionFormat: "No participant handles available",
|
|
814
|
+
warnings,
|
|
815
|
+
markdown
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
function evictLeastRecentlyUsedContext(contextCache, maxEntries) {
|
|
819
|
+
if (contextCache.size <= maxEntries) {
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
let oldestKey = null;
|
|
823
|
+
let oldestAccessedAt = Number.POSITIVE_INFINITY;
|
|
824
|
+
for (const [key, entry] of contextCache.entries()) {
|
|
825
|
+
if (entry.lastAccessedAt < oldestAccessedAt) {
|
|
826
|
+
oldestAccessedAt = entry.lastAccessedAt;
|
|
827
|
+
oldestKey = key;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
if (oldestKey) {
|
|
831
|
+
contextCache.delete(oldestKey);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
function normalizeHandle(handle) {
|
|
835
|
+
return typeof handle === "string" && handle.trim().length > 0 ? handle.trim() : null;
|
|
836
|
+
}
|
|
566
837
|
function toSdkToolDefinition(registration) {
|
|
567
838
|
const shape = buildZodShape(
|
|
568
839
|
import_zod.z,
|
package/dist/mcp-claude.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '@anthropic-ai/claude-agent-sdk';
|
|
2
|
-
import './protocols-
|
|
3
|
-
export { C as CreateThenvoiSdkMcpServerOptions, T as ThenvoiSdkMcpServer,
|
|
4
|
-
import './dtos-
|
|
2
|
+
import './protocols-D2bTrQ_t.cjs';
|
|
3
|
+
export { C as CreateThenvoiSdkMcpServerOptions, G as GetSystemPromptContextOptions, f as GetSystemPromptContextResult, T as ThenvoiSdkMcpServer, g as createThenvoiSdkMcpServer } from './sdk-D2rTDU_o.cjs';
|
|
4
|
+
import './dtos-Dd_fTfLn.cjs';
|
package/dist/mcp-claude.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '@anthropic-ai/claude-agent-sdk';
|
|
2
|
-
import './protocols-
|
|
3
|
-
export { C as CreateThenvoiSdkMcpServerOptions, T as ThenvoiSdkMcpServer,
|
|
4
|
-
import './dtos-
|
|
2
|
+
import './protocols-BF6jamIl.js';
|
|
3
|
+
export { C as CreateThenvoiSdkMcpServerOptions, G as GetSystemPromptContextOptions, f as GetSystemPromptContextResult, T as ThenvoiSdkMcpServer, g as createThenvoiSdkMcpServer } from './sdk-CyqN1W5g.js';
|
|
4
|
+
import './dtos-Dd_fTfLn.js';
|
package/dist/mcp-claude.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildRoomScopedRegistrations,
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
buildSingleContextRegistrations,
|
|
4
|
+
buildZodShape,
|
|
5
|
+
resolveSingleRoomTools
|
|
6
|
+
} from "./chunk-6RXWL6TC.js";
|
|
5
7
|
import {
|
|
6
8
|
mcpToolNames
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MLROFDKR.js";
|
|
8
10
|
import "./chunk-3BKAC4OZ.js";
|
|
9
11
|
import "./chunk-YR3BOQNW.js";
|
|
10
12
|
|
|
@@ -15,16 +17,16 @@ import {
|
|
|
15
17
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
16
18
|
import { z } from "zod";
|
|
17
19
|
function createThenvoiSdkMcpServer(options) {
|
|
18
|
-
const
|
|
19
|
-
options.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
);
|
|
20
|
+
const registrationOptions = {
|
|
21
|
+
enableMemoryTools: options.enableMemoryTools,
|
|
22
|
+
enableContactTools: true,
|
|
23
|
+
additionalTools: options.additionalTools
|
|
24
|
+
};
|
|
25
|
+
const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolveSingleRoomTools(options.getToolsForRoom), registrationOptions) : buildRoomScopedRegistrations(options.getToolsForRoom, registrationOptions);
|
|
26
26
|
const toolDefinitions = registrations.map(toSdkToolDefinition);
|
|
27
27
|
const toolNames = new Set(registrations.map((r) => r.name));
|
|
28
|
+
const contextCache = /* @__PURE__ */ new Map();
|
|
29
|
+
const MAX_CONTEXT_CACHE_ENTRIES = 100;
|
|
28
30
|
const serverConfig = createSdkMcpServer({
|
|
29
31
|
name: "thenvoi",
|
|
30
32
|
tools: toolDefinitions
|
|
@@ -32,9 +34,205 @@ function createThenvoiSdkMcpServer(options) {
|
|
|
32
34
|
return {
|
|
33
35
|
serverConfig,
|
|
34
36
|
allowedTools: mcpToolNames(toolNames),
|
|
35
|
-
toolDefinitions
|
|
37
|
+
toolDefinitions,
|
|
38
|
+
getSystemPromptContext: async (roomId, contextOptions) => {
|
|
39
|
+
const context = await getOrBuildSystemPromptContext(
|
|
40
|
+
roomId,
|
|
41
|
+
contextOptions,
|
|
42
|
+
options.getToolsForRoom,
|
|
43
|
+
contextCache,
|
|
44
|
+
MAX_CONTEXT_CACHE_ENTRIES
|
|
45
|
+
);
|
|
46
|
+
return context.markdown;
|
|
47
|
+
},
|
|
48
|
+
getSystemPromptContextData: (roomId, contextOptions) => {
|
|
49
|
+
return getOrBuildSystemPromptContext(
|
|
50
|
+
roomId,
|
|
51
|
+
contextOptions,
|
|
52
|
+
options.getToolsForRoom,
|
|
53
|
+
contextCache,
|
|
54
|
+
MAX_CONTEXT_CACHE_ENTRIES
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function getOrBuildSystemPromptContext(roomId, contextOptions, getToolsForRoom, contextCache, maxEntries) {
|
|
60
|
+
const ttlMs = contextOptions?.ttlMs ?? 3e4;
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
const cached = contextCache.get(roomId);
|
|
63
|
+
if (cached && cached.expiresAt > now) {
|
|
64
|
+
cached.lastAccessedAt = now;
|
|
65
|
+
return cached.value;
|
|
66
|
+
}
|
|
67
|
+
if (cached) {
|
|
68
|
+
contextCache.delete(roomId);
|
|
69
|
+
}
|
|
70
|
+
const tools = getToolsForRoom(roomId);
|
|
71
|
+
if (!tools) {
|
|
72
|
+
return buildUnavailableSystemPromptContext(roomId);
|
|
73
|
+
}
|
|
74
|
+
const context = await buildSystemPromptContext(roomId, tools);
|
|
75
|
+
contextCache.set(roomId, {
|
|
76
|
+
value: context,
|
|
77
|
+
expiresAt: now + ttlMs,
|
|
78
|
+
lastAccessedAt: now
|
|
79
|
+
});
|
|
80
|
+
evictLeastRecentlyUsedContext(contextCache, maxEntries);
|
|
81
|
+
return context;
|
|
82
|
+
}
|
|
83
|
+
async function buildSystemPromptContext(roomId, tools) {
|
|
84
|
+
const participants = await tools.getParticipants();
|
|
85
|
+
const warnings = [];
|
|
86
|
+
const agentResolution = await resolveAgentIdentity(tools);
|
|
87
|
+
if (agentResolution.warning) {
|
|
88
|
+
warnings.push(agentResolution.warning);
|
|
89
|
+
}
|
|
90
|
+
const roomResolution = await resolveRoomTitle(tools, roomId);
|
|
91
|
+
if (roomResolution.warning) {
|
|
92
|
+
warnings.push(roomResolution.warning);
|
|
93
|
+
}
|
|
94
|
+
const agentIdentity = agentResolution.value;
|
|
95
|
+
const roomTitle = roomResolution.value;
|
|
96
|
+
const normalizedParticipants = participants.map((participant) => ({
|
|
97
|
+
id: String(participant.id),
|
|
98
|
+
name: String(participant.name ?? "Unknown"),
|
|
99
|
+
type: String(participant.type ?? "Unknown"),
|
|
100
|
+
handle: normalizeHandle(participant.handle),
|
|
101
|
+
isSelf: participant.id === agentIdentity?.id
|
|
102
|
+
}));
|
|
103
|
+
const selfHandle = normalizeHandle(agentIdentity?.handle);
|
|
104
|
+
const selfName = agentIdentity?.name ?? "Agent";
|
|
105
|
+
const mentionHandles = normalizedParticipants.filter((participant) => !participant.isSelf).map((participant) => participant.handle).filter((handle) => Boolean(handle));
|
|
106
|
+
const mentionFormat = mentionHandles.length > 0 ? mentionHandles.join(", ") : "No participant handles available";
|
|
107
|
+
const roomLabel = roomTitle ? `"${roomTitle}"` : "this room";
|
|
108
|
+
const agentLabel = selfHandle ? `${selfName} (${selfHandle})` : selfName;
|
|
109
|
+
const participantLines = normalizedParticipants.length > 0 ? normalizedParticipants.map((participant) => {
|
|
110
|
+
const suffix = participant.isSelf ? " (you)" : "";
|
|
111
|
+
const handle = participant.handle ? ` (${participant.handle})` : "";
|
|
112
|
+
return `- **${participant.name}**${handle} -- ${participant.type}${suffix}`;
|
|
113
|
+
}).join("\n") : "- No participants found";
|
|
114
|
+
const markdown = [
|
|
115
|
+
"## Room Context",
|
|
116
|
+
"",
|
|
117
|
+
`You are **${agentLabel}** in room ${roomLabel} (id: ${roomId}).`,
|
|
118
|
+
"",
|
|
119
|
+
"### Participants",
|
|
120
|
+
participantLines,
|
|
121
|
+
"",
|
|
122
|
+
"### Mention Format",
|
|
123
|
+
`To address someone, use their exact handle: ${mentionFormat}`,
|
|
124
|
+
...warnings.length > 0 ? ["", "### Warnings", ...warnings.map((warning) => `- ${warning}`)] : []
|
|
125
|
+
].join("\n");
|
|
126
|
+
return {
|
|
127
|
+
roomId,
|
|
128
|
+
roomTitle,
|
|
129
|
+
agent: {
|
|
130
|
+
id: agentIdentity?.id ?? "unknown-agent",
|
|
131
|
+
name: selfName,
|
|
132
|
+
handle: selfHandle,
|
|
133
|
+
description: agentIdentity?.description ?? null
|
|
134
|
+
},
|
|
135
|
+
participants: normalizedParticipants,
|
|
136
|
+
mentionFormat,
|
|
137
|
+
warnings,
|
|
138
|
+
markdown
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async function resolveAgentIdentity(tools) {
|
|
142
|
+
const maybeTools = tools;
|
|
143
|
+
try {
|
|
144
|
+
if (maybeTools.getAgentIdentity) {
|
|
145
|
+
return { value: await maybeTools.getAgentIdentity(), warning: null };
|
|
146
|
+
}
|
|
147
|
+
if (maybeTools.rest?.getAgentMe) {
|
|
148
|
+
return { value: await maybeTools.rest.getAgentMe(), warning: null };
|
|
149
|
+
}
|
|
150
|
+
} catch (error) {
|
|
151
|
+
return {
|
|
152
|
+
value: null,
|
|
153
|
+
warning: `Unable to resolve agent identity: ${error instanceof Error ? error.message : String(error)}`
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return { value: null, warning: null };
|
|
157
|
+
}
|
|
158
|
+
async function resolveRoomTitle(tools, roomId) {
|
|
159
|
+
const maybeTools = tools;
|
|
160
|
+
const rest = maybeTools.rest;
|
|
161
|
+
if (!rest?.listChats) {
|
|
162
|
+
return { value: null, warning: null };
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
let page = 1;
|
|
166
|
+
const pageSize = 100;
|
|
167
|
+
while (true) {
|
|
168
|
+
const response = await rest.listChats({ page, pageSize });
|
|
169
|
+
const room = response?.data?.find((entry) => entry.id === roomId);
|
|
170
|
+
if (typeof room?.title === "string" && room.title.length > 0) {
|
|
171
|
+
return { value: room.title, warning: null };
|
|
172
|
+
}
|
|
173
|
+
const totalPages = response?.metadata?.totalPages ?? page;
|
|
174
|
+
if (page >= totalPages) {
|
|
175
|
+
return { value: null, warning: null };
|
|
176
|
+
}
|
|
177
|
+
page += 1;
|
|
178
|
+
}
|
|
179
|
+
} catch (error) {
|
|
180
|
+
return {
|
|
181
|
+
value: null,
|
|
182
|
+
warning: `Unable to resolve room title: ${error instanceof Error ? error.message : String(error)}`
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function buildUnavailableSystemPromptContext(roomId) {
|
|
187
|
+
const warnings = [`No tool context found for room_id ${roomId}`];
|
|
188
|
+
const markdown = [
|
|
189
|
+
"## Room Context",
|
|
190
|
+
"",
|
|
191
|
+
`You are **Agent** in this room (id: ${roomId}).`,
|
|
192
|
+
"",
|
|
193
|
+
"### Participants",
|
|
194
|
+
"- No participants found",
|
|
195
|
+
"",
|
|
196
|
+
"### Mention Format",
|
|
197
|
+
"No participant handles available",
|
|
198
|
+
"",
|
|
199
|
+
"### Warnings",
|
|
200
|
+
...warnings.map((warning) => `- ${warning}`)
|
|
201
|
+
].join("\n");
|
|
202
|
+
return {
|
|
203
|
+
roomId,
|
|
204
|
+
roomTitle: null,
|
|
205
|
+
agent: {
|
|
206
|
+
id: "unknown-agent",
|
|
207
|
+
name: "Agent",
|
|
208
|
+
handle: null,
|
|
209
|
+
description: null
|
|
210
|
+
},
|
|
211
|
+
participants: [],
|
|
212
|
+
mentionFormat: "No participant handles available",
|
|
213
|
+
warnings,
|
|
214
|
+
markdown
|
|
36
215
|
};
|
|
37
216
|
}
|
|
217
|
+
function evictLeastRecentlyUsedContext(contextCache, maxEntries) {
|
|
218
|
+
if (contextCache.size <= maxEntries) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
let oldestKey = null;
|
|
222
|
+
let oldestAccessedAt = Number.POSITIVE_INFINITY;
|
|
223
|
+
for (const [key, entry] of contextCache.entries()) {
|
|
224
|
+
if (entry.lastAccessedAt < oldestAccessedAt) {
|
|
225
|
+
oldestAccessedAt = entry.lastAccessedAt;
|
|
226
|
+
oldestKey = key;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (oldestKey) {
|
|
230
|
+
contextCache.delete(oldestKey);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function normalizeHandle(handle) {
|
|
234
|
+
return typeof handle === "string" && handle.trim().length > 0 ? handle.trim() : null;
|
|
235
|
+
}
|
|
38
236
|
function toSdkToolDefinition(registration) {
|
|
39
237
|
const shape = buildZodShape(
|
|
40
238
|
z,
|