@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/index.cjs
CHANGED
|
@@ -133,6 +133,114 @@ var init_chatEvents = __esm({
|
|
|
133
133
|
}
|
|
134
134
|
});
|
|
135
135
|
|
|
136
|
+
// src/contracts/memory.ts
|
|
137
|
+
function namedValues(values) {
|
|
138
|
+
return Object.fromEntries(values.map((value) => [value, value]));
|
|
139
|
+
}
|
|
140
|
+
function isMemorySystem(value) {
|
|
141
|
+
return MEMORY_SYSTEMS.includes(value);
|
|
142
|
+
}
|
|
143
|
+
function isMemoryType(value) {
|
|
144
|
+
return MEMORY_TYPES.includes(value);
|
|
145
|
+
}
|
|
146
|
+
function isMemoryTypeForSystem(system, type) {
|
|
147
|
+
return MEMORY_SYSTEM_TYPES[system].includes(type);
|
|
148
|
+
}
|
|
149
|
+
function isMemorySegment(value) {
|
|
150
|
+
return MEMORY_SEGMENTS.includes(value);
|
|
151
|
+
}
|
|
152
|
+
function isMemoryStoreScope(value) {
|
|
153
|
+
return MEMORY_STORE_SCOPES.includes(value);
|
|
154
|
+
}
|
|
155
|
+
function isMemoryListScope(value) {
|
|
156
|
+
return MEMORY_LIST_SCOPES.includes(value);
|
|
157
|
+
}
|
|
158
|
+
function isMemoryStatus(value) {
|
|
159
|
+
return MEMORY_STATUSES.includes(value);
|
|
160
|
+
}
|
|
161
|
+
function expectedList(values) {
|
|
162
|
+
return values.join(", ");
|
|
163
|
+
}
|
|
164
|
+
function expectedMemoryTypesForSystem(system) {
|
|
165
|
+
return expectedList(MEMORY_SYSTEM_TYPES[system]);
|
|
166
|
+
}
|
|
167
|
+
function memoryTypeForSystemError(system) {
|
|
168
|
+
return `type must be one of: ${expectedMemoryTypesForSystem(system)} for system "${system}"`;
|
|
169
|
+
}
|
|
170
|
+
var SENSORY_MEMORY_TYPES, COGNITIVE_MEMORY_TYPES, MEMORY_SYSTEM_TYPES, MEMORY_SYSTEMS, MEMORY_TYPES, MEMORY_SEGMENTS, MEMORY_STORE_SCOPES, MEMORY_LIST_SCOPES, MEMORY_STATUSES, MEMORY_SYSTEM, MEMORY_TYPE, MEMORY_SEGMENT, MEMORY_STORE_SCOPE;
|
|
171
|
+
var init_memory = __esm({
|
|
172
|
+
"src/contracts/memory.ts"() {
|
|
173
|
+
"use strict";
|
|
174
|
+
SENSORY_MEMORY_TYPES = [
|
|
175
|
+
"iconic",
|
|
176
|
+
// Visual input
|
|
177
|
+
"echoic",
|
|
178
|
+
// Auditory input
|
|
179
|
+
"haptic"
|
|
180
|
+
// Tactile input
|
|
181
|
+
];
|
|
182
|
+
COGNITIVE_MEMORY_TYPES = [
|
|
183
|
+
"episodic",
|
|
184
|
+
// Events that occurred
|
|
185
|
+
"semantic",
|
|
186
|
+
// Facts, preferences, learned knowledge
|
|
187
|
+
"procedural"
|
|
188
|
+
// How to perform tasks
|
|
189
|
+
];
|
|
190
|
+
MEMORY_SYSTEM_TYPES = {
|
|
191
|
+
sensory: SENSORY_MEMORY_TYPES,
|
|
192
|
+
// Brief sensory inputs
|
|
193
|
+
working: COGNITIVE_MEMORY_TYPES,
|
|
194
|
+
// Short-term session context
|
|
195
|
+
long_term: COGNITIVE_MEMORY_TYPES
|
|
196
|
+
// Persistent cross-conversation memory
|
|
197
|
+
};
|
|
198
|
+
MEMORY_SYSTEMS = Object.keys(MEMORY_SYSTEM_TYPES);
|
|
199
|
+
MEMORY_TYPES = [
|
|
200
|
+
...SENSORY_MEMORY_TYPES,
|
|
201
|
+
...COGNITIVE_MEMORY_TYPES
|
|
202
|
+
];
|
|
203
|
+
MEMORY_SEGMENTS = [
|
|
204
|
+
"user",
|
|
205
|
+
// User preferences or profile info
|
|
206
|
+
"agent",
|
|
207
|
+
// Facts or events about agents/entities
|
|
208
|
+
"tool",
|
|
209
|
+
// Tool usage or task procedures
|
|
210
|
+
"guideline"
|
|
211
|
+
// Behavioral rules or policies
|
|
212
|
+
];
|
|
213
|
+
MEMORY_STORE_SCOPES = [
|
|
214
|
+
"subject",
|
|
215
|
+
// About one person/agent; requires subject_id
|
|
216
|
+
"organization"
|
|
217
|
+
// Shared org-wide
|
|
218
|
+
];
|
|
219
|
+
MEMORY_LIST_SCOPES = [
|
|
220
|
+
"subject",
|
|
221
|
+
// Subject-scoped memories only
|
|
222
|
+
"organization",
|
|
223
|
+
// Organization-scoped memories only
|
|
224
|
+
"all"
|
|
225
|
+
// Both scopes (no scope filter)
|
|
226
|
+
];
|
|
227
|
+
MEMORY_STATUSES = [
|
|
228
|
+
"active",
|
|
229
|
+
// Normal, visible memories
|
|
230
|
+
"superseded",
|
|
231
|
+
// Outdated; soft-deleted via thenvoi_supersede_memory
|
|
232
|
+
"archived",
|
|
233
|
+
// Hidden but preserved via thenvoi_archive_memory
|
|
234
|
+
"all"
|
|
235
|
+
// Any status (no filter)
|
|
236
|
+
];
|
|
237
|
+
MEMORY_SYSTEM = namedValues(MEMORY_SYSTEMS);
|
|
238
|
+
MEMORY_TYPE = namedValues(MEMORY_TYPES);
|
|
239
|
+
MEMORY_SEGMENT = namedValues(MEMORY_SEGMENTS);
|
|
240
|
+
MEMORY_STORE_SCOPE = namedValues(MEMORY_STORE_SCOPES);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
136
244
|
// src/runtime/tools/schemas.ts
|
|
137
245
|
function mcpToolNames(names) {
|
|
138
246
|
return [...names].sort((a, b) => a.localeCompare(b)).map((name) => `${MCP_TOOL_PREFIX}${name}`);
|
|
@@ -146,6 +254,7 @@ var init_schemas = __esm({
|
|
|
146
254
|
"src/runtime/tools/schemas.ts"() {
|
|
147
255
|
"use strict";
|
|
148
256
|
init_chatEvents();
|
|
257
|
+
init_memory();
|
|
149
258
|
TOOL_MODELS = {
|
|
150
259
|
thenvoi_send_message: {
|
|
151
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.",
|
|
@@ -332,29 +441,22 @@ var init_schemas = __esm({
|
|
|
332
441
|
},
|
|
333
442
|
scope: {
|
|
334
443
|
type: "string",
|
|
335
|
-
enum: [
|
|
444
|
+
enum: [...MEMORY_LIST_SCOPES],
|
|
336
445
|
description: "Filter by scope."
|
|
337
446
|
},
|
|
338
447
|
system: {
|
|
339
448
|
type: "string",
|
|
340
|
-
enum: [
|
|
449
|
+
enum: [...MEMORY_SYSTEMS],
|
|
341
450
|
description: "Filter by memory system."
|
|
342
451
|
},
|
|
343
452
|
type: {
|
|
344
453
|
type: "string",
|
|
345
|
-
enum: [
|
|
346
|
-
"iconic",
|
|
347
|
-
"echoic",
|
|
348
|
-
"haptic",
|
|
349
|
-
"episodic",
|
|
350
|
-
"semantic",
|
|
351
|
-
"procedural"
|
|
352
|
-
],
|
|
454
|
+
enum: [...MEMORY_TYPES],
|
|
353
455
|
description: "Filter by memory type."
|
|
354
456
|
},
|
|
355
457
|
segment: {
|
|
356
458
|
type: "string",
|
|
357
|
-
enum: [
|
|
459
|
+
enum: [...MEMORY_SEGMENTS],
|
|
358
460
|
description: "Filter by segment."
|
|
359
461
|
},
|
|
360
462
|
content_query: {
|
|
@@ -369,7 +471,7 @@ var init_schemas = __esm({
|
|
|
369
471
|
},
|
|
370
472
|
status: {
|
|
371
473
|
type: "string",
|
|
372
|
-
enum: [
|
|
474
|
+
enum: [...MEMORY_STATUSES],
|
|
373
475
|
description: "Filter by status."
|
|
374
476
|
}
|
|
375
477
|
},
|
|
@@ -384,24 +486,17 @@ var init_schemas = __esm({
|
|
|
384
486
|
},
|
|
385
487
|
system: {
|
|
386
488
|
type: "string",
|
|
387
|
-
enum: [
|
|
489
|
+
enum: [...MEMORY_SYSTEMS],
|
|
388
490
|
description: "Memory system tier."
|
|
389
491
|
},
|
|
390
492
|
type: {
|
|
391
493
|
type: "string",
|
|
392
|
-
enum: [
|
|
393
|
-
"iconic",
|
|
394
|
-
"echoic",
|
|
395
|
-
"haptic",
|
|
396
|
-
"episodic",
|
|
397
|
-
"semantic",
|
|
398
|
-
"procedural"
|
|
399
|
-
],
|
|
494
|
+
enum: [...MEMORY_TYPES],
|
|
400
495
|
description: "Memory type (must be valid for selected system)."
|
|
401
496
|
},
|
|
402
497
|
segment: {
|
|
403
498
|
type: "string",
|
|
404
|
-
enum: [
|
|
499
|
+
enum: [...MEMORY_SEGMENTS],
|
|
405
500
|
description: "Logical segment."
|
|
406
501
|
},
|
|
407
502
|
thought: {
|
|
@@ -410,7 +505,7 @@ var init_schemas = __esm({
|
|
|
410
505
|
},
|
|
411
506
|
scope: {
|
|
412
507
|
type: "string",
|
|
413
|
-
enum: [
|
|
508
|
+
enum: [...MEMORY_STORE_SCOPES],
|
|
414
509
|
description: "Visibility scope."
|
|
415
510
|
},
|
|
416
511
|
subject_id: {
|
|
@@ -598,6 +693,13 @@ function serializeValue(value) {
|
|
|
598
693
|
return String(value);
|
|
599
694
|
}
|
|
600
695
|
}
|
|
696
|
+
function resolveSingleRoomTools(getToolsForRoom) {
|
|
697
|
+
const tools = getToolsForRoom("");
|
|
698
|
+
if (!tools) {
|
|
699
|
+
throw new Error('Single-room mode requires getToolsForRoom("") to return a tools instance');
|
|
700
|
+
}
|
|
701
|
+
return tools;
|
|
702
|
+
}
|
|
601
703
|
var init_registrations = __esm({
|
|
602
704
|
"src/mcp/registrations.ts"() {
|
|
603
705
|
"use strict";
|
|
@@ -607,42 +709,42 @@ var init_registrations = __esm({
|
|
|
607
709
|
});
|
|
608
710
|
|
|
609
711
|
// src/mcp/zod.ts
|
|
610
|
-
function buildZodShape(
|
|
712
|
+
function buildZodShape(z6, properties, required) {
|
|
611
713
|
const shape = {};
|
|
612
714
|
for (const [name, schema] of Object.entries(properties)) {
|
|
613
|
-
const validator = jsonSchemaToZod(
|
|
715
|
+
const validator = jsonSchemaToZod(z6, schema);
|
|
614
716
|
shape[name] = required.has(name) ? validator : validator.optional();
|
|
615
717
|
}
|
|
616
718
|
return shape;
|
|
617
719
|
}
|
|
618
|
-
function jsonSchemaToZod(
|
|
720
|
+
function jsonSchemaToZod(z6, schema) {
|
|
619
721
|
const type = schema.type;
|
|
620
722
|
if (type === "string") {
|
|
621
723
|
if (Array.isArray(schema.enum) && schema.enum.every((v) => typeof v === "string")) {
|
|
622
724
|
const values = schema.enum;
|
|
623
725
|
if (values.length > 0) {
|
|
624
|
-
return
|
|
726
|
+
return z6.enum(values);
|
|
625
727
|
}
|
|
626
728
|
}
|
|
627
|
-
return
|
|
729
|
+
return z6.string();
|
|
628
730
|
}
|
|
629
731
|
if (type === "integer" || type === "number") {
|
|
630
|
-
return
|
|
732
|
+
return z6.number();
|
|
631
733
|
}
|
|
632
734
|
if (type === "boolean") {
|
|
633
|
-
return
|
|
735
|
+
return z6.boolean();
|
|
634
736
|
}
|
|
635
737
|
if (type === "array") {
|
|
636
738
|
const itemSchema = schema.items;
|
|
637
739
|
if (itemSchema && typeof itemSchema === "object") {
|
|
638
|
-
return
|
|
740
|
+
return z6.array(jsonSchemaToZod(z6, itemSchema));
|
|
639
741
|
}
|
|
640
|
-
return
|
|
742
|
+
return z6.array(z6.unknown());
|
|
641
743
|
}
|
|
642
744
|
if (type === "object") {
|
|
643
|
-
return
|
|
745
|
+
return z6.record(z6.string(), z6.unknown());
|
|
644
746
|
}
|
|
645
|
-
return
|
|
747
|
+
return z6.unknown();
|
|
646
748
|
}
|
|
647
749
|
var init_zod = __esm({
|
|
648
750
|
"src/mcp/zod.ts"() {
|
|
@@ -656,16 +758,16 @@ __export(sdk_exports, {
|
|
|
656
758
|
createThenvoiSdkMcpServer: () => createThenvoiSdkMcpServer
|
|
657
759
|
});
|
|
658
760
|
function createThenvoiSdkMcpServer(options) {
|
|
659
|
-
const
|
|
660
|
-
options.
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
);
|
|
761
|
+
const registrationOptions = {
|
|
762
|
+
enableMemoryTools: options.enableMemoryTools,
|
|
763
|
+
enableContactTools: true,
|
|
764
|
+
additionalTools: options.additionalTools
|
|
765
|
+
};
|
|
766
|
+
const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolveSingleRoomTools(options.getToolsForRoom), registrationOptions) : buildRoomScopedRegistrations(options.getToolsForRoom, registrationOptions);
|
|
667
767
|
const toolDefinitions = registrations.map(toSdkToolDefinition);
|
|
668
768
|
const toolNames = new Set(registrations.map((r) => r.name));
|
|
769
|
+
const contextCache = /* @__PURE__ */ new Map();
|
|
770
|
+
const MAX_CONTEXT_CACHE_ENTRIES = 100;
|
|
669
771
|
const serverConfig = (0, import_claude_agent_sdk.createSdkMcpServer)({
|
|
670
772
|
name: "thenvoi",
|
|
671
773
|
tools: toolDefinitions
|
|
@@ -673,12 +775,208 @@ function createThenvoiSdkMcpServer(options) {
|
|
|
673
775
|
return {
|
|
674
776
|
serverConfig,
|
|
675
777
|
allowedTools: mcpToolNames(toolNames),
|
|
676
|
-
toolDefinitions
|
|
778
|
+
toolDefinitions,
|
|
779
|
+
getSystemPromptContext: async (roomId, contextOptions) => {
|
|
780
|
+
const context = await getOrBuildSystemPromptContext(
|
|
781
|
+
roomId,
|
|
782
|
+
contextOptions,
|
|
783
|
+
options.getToolsForRoom,
|
|
784
|
+
contextCache,
|
|
785
|
+
MAX_CONTEXT_CACHE_ENTRIES
|
|
786
|
+
);
|
|
787
|
+
return context.markdown;
|
|
788
|
+
},
|
|
789
|
+
getSystemPromptContextData: (roomId, contextOptions) => {
|
|
790
|
+
return getOrBuildSystemPromptContext(
|
|
791
|
+
roomId,
|
|
792
|
+
contextOptions,
|
|
793
|
+
options.getToolsForRoom,
|
|
794
|
+
contextCache,
|
|
795
|
+
MAX_CONTEXT_CACHE_ENTRIES
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
async function getOrBuildSystemPromptContext(roomId, contextOptions, getToolsForRoom, contextCache, maxEntries) {
|
|
801
|
+
const ttlMs = contextOptions?.ttlMs ?? 3e4;
|
|
802
|
+
const now = Date.now();
|
|
803
|
+
const cached = contextCache.get(roomId);
|
|
804
|
+
if (cached && cached.expiresAt > now) {
|
|
805
|
+
cached.lastAccessedAt = now;
|
|
806
|
+
return cached.value;
|
|
807
|
+
}
|
|
808
|
+
if (cached) {
|
|
809
|
+
contextCache.delete(roomId);
|
|
810
|
+
}
|
|
811
|
+
const tools = getToolsForRoom(roomId);
|
|
812
|
+
if (!tools) {
|
|
813
|
+
return buildUnavailableSystemPromptContext(roomId);
|
|
814
|
+
}
|
|
815
|
+
const context = await buildSystemPromptContext(roomId, tools);
|
|
816
|
+
contextCache.set(roomId, {
|
|
817
|
+
value: context,
|
|
818
|
+
expiresAt: now + ttlMs,
|
|
819
|
+
lastAccessedAt: now
|
|
820
|
+
});
|
|
821
|
+
evictLeastRecentlyUsedContext(contextCache, maxEntries);
|
|
822
|
+
return context;
|
|
823
|
+
}
|
|
824
|
+
async function buildSystemPromptContext(roomId, tools) {
|
|
825
|
+
const participants = await tools.getParticipants();
|
|
826
|
+
const warnings = [];
|
|
827
|
+
const agentResolution = await resolveAgentIdentity(tools);
|
|
828
|
+
if (agentResolution.warning) {
|
|
829
|
+
warnings.push(agentResolution.warning);
|
|
830
|
+
}
|
|
831
|
+
const roomResolution = await resolveRoomTitle(tools, roomId);
|
|
832
|
+
if (roomResolution.warning) {
|
|
833
|
+
warnings.push(roomResolution.warning);
|
|
834
|
+
}
|
|
835
|
+
const agentIdentity = agentResolution.value;
|
|
836
|
+
const roomTitle = roomResolution.value;
|
|
837
|
+
const normalizedParticipants = participants.map((participant) => ({
|
|
838
|
+
id: String(participant.id),
|
|
839
|
+
name: String(participant.name ?? "Unknown"),
|
|
840
|
+
type: String(participant.type ?? "Unknown"),
|
|
841
|
+
handle: normalizeHandle2(participant.handle),
|
|
842
|
+
isSelf: participant.id === agentIdentity?.id
|
|
843
|
+
}));
|
|
844
|
+
const selfHandle = normalizeHandle2(agentIdentity?.handle);
|
|
845
|
+
const selfName = agentIdentity?.name ?? "Agent";
|
|
846
|
+
const mentionHandles = normalizedParticipants.filter((participant) => !participant.isSelf).map((participant) => participant.handle).filter((handle) => Boolean(handle));
|
|
847
|
+
const mentionFormat = mentionHandles.length > 0 ? mentionHandles.join(", ") : "No participant handles available";
|
|
848
|
+
const roomLabel = roomTitle ? `"${roomTitle}"` : "this room";
|
|
849
|
+
const agentLabel = selfHandle ? `${selfName} (${selfHandle})` : selfName;
|
|
850
|
+
const participantLines = normalizedParticipants.length > 0 ? normalizedParticipants.map((participant) => {
|
|
851
|
+
const suffix = participant.isSelf ? " (you)" : "";
|
|
852
|
+
const handle = participant.handle ? ` (${participant.handle})` : "";
|
|
853
|
+
return `- **${participant.name}**${handle} -- ${participant.type}${suffix}`;
|
|
854
|
+
}).join("\n") : "- No participants found";
|
|
855
|
+
const markdown = [
|
|
856
|
+
"## Room Context",
|
|
857
|
+
"",
|
|
858
|
+
`You are **${agentLabel}** in room ${roomLabel} (id: ${roomId}).`,
|
|
859
|
+
"",
|
|
860
|
+
"### Participants",
|
|
861
|
+
participantLines,
|
|
862
|
+
"",
|
|
863
|
+
"### Mention Format",
|
|
864
|
+
`To address someone, use their exact handle: ${mentionFormat}`,
|
|
865
|
+
...warnings.length > 0 ? ["", "### Warnings", ...warnings.map((warning) => `- ${warning}`)] : []
|
|
866
|
+
].join("\n");
|
|
867
|
+
return {
|
|
868
|
+
roomId,
|
|
869
|
+
roomTitle,
|
|
870
|
+
agent: {
|
|
871
|
+
id: agentIdentity?.id ?? "unknown-agent",
|
|
872
|
+
name: selfName,
|
|
873
|
+
handle: selfHandle,
|
|
874
|
+
description: agentIdentity?.description ?? null
|
|
875
|
+
},
|
|
876
|
+
participants: normalizedParticipants,
|
|
877
|
+
mentionFormat,
|
|
878
|
+
warnings,
|
|
879
|
+
markdown
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
async function resolveAgentIdentity(tools) {
|
|
883
|
+
const maybeTools = tools;
|
|
884
|
+
try {
|
|
885
|
+
if (maybeTools.getAgentIdentity) {
|
|
886
|
+
return { value: await maybeTools.getAgentIdentity(), warning: null };
|
|
887
|
+
}
|
|
888
|
+
if (maybeTools.rest?.getAgentMe) {
|
|
889
|
+
return { value: await maybeTools.rest.getAgentMe(), warning: null };
|
|
890
|
+
}
|
|
891
|
+
} catch (error) {
|
|
892
|
+
return {
|
|
893
|
+
value: null,
|
|
894
|
+
warning: `Unable to resolve agent identity: ${error instanceof Error ? error.message : String(error)}`
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
return { value: null, warning: null };
|
|
898
|
+
}
|
|
899
|
+
async function resolveRoomTitle(tools, roomId) {
|
|
900
|
+
const maybeTools = tools;
|
|
901
|
+
const rest = maybeTools.rest;
|
|
902
|
+
if (!rest?.listChats) {
|
|
903
|
+
return { value: null, warning: null };
|
|
904
|
+
}
|
|
905
|
+
try {
|
|
906
|
+
let page = 1;
|
|
907
|
+
const pageSize = 100;
|
|
908
|
+
while (true) {
|
|
909
|
+
const response = await rest.listChats({ page, pageSize });
|
|
910
|
+
const room = response?.data?.find((entry) => entry.id === roomId);
|
|
911
|
+
if (typeof room?.title === "string" && room.title.length > 0) {
|
|
912
|
+
return { value: room.title, warning: null };
|
|
913
|
+
}
|
|
914
|
+
const totalPages = response?.metadata?.totalPages ?? page;
|
|
915
|
+
if (page >= totalPages) {
|
|
916
|
+
return { value: null, warning: null };
|
|
917
|
+
}
|
|
918
|
+
page += 1;
|
|
919
|
+
}
|
|
920
|
+
} catch (error) {
|
|
921
|
+
return {
|
|
922
|
+
value: null,
|
|
923
|
+
warning: `Unable to resolve room title: ${error instanceof Error ? error.message : String(error)}`
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
function buildUnavailableSystemPromptContext(roomId) {
|
|
928
|
+
const warnings = [`No tool context found for room_id ${roomId}`];
|
|
929
|
+
const markdown = [
|
|
930
|
+
"## Room Context",
|
|
931
|
+
"",
|
|
932
|
+
`You are **Agent** in this room (id: ${roomId}).`,
|
|
933
|
+
"",
|
|
934
|
+
"### Participants",
|
|
935
|
+
"- No participants found",
|
|
936
|
+
"",
|
|
937
|
+
"### Mention Format",
|
|
938
|
+
"No participant handles available",
|
|
939
|
+
"",
|
|
940
|
+
"### Warnings",
|
|
941
|
+
...warnings.map((warning) => `- ${warning}`)
|
|
942
|
+
].join("\n");
|
|
943
|
+
return {
|
|
944
|
+
roomId,
|
|
945
|
+
roomTitle: null,
|
|
946
|
+
agent: {
|
|
947
|
+
id: "unknown-agent",
|
|
948
|
+
name: "Agent",
|
|
949
|
+
handle: null,
|
|
950
|
+
description: null
|
|
951
|
+
},
|
|
952
|
+
participants: [],
|
|
953
|
+
mentionFormat: "No participant handles available",
|
|
954
|
+
warnings,
|
|
955
|
+
markdown
|
|
677
956
|
};
|
|
678
957
|
}
|
|
958
|
+
function evictLeastRecentlyUsedContext(contextCache, maxEntries) {
|
|
959
|
+
if (contextCache.size <= maxEntries) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
let oldestKey = null;
|
|
963
|
+
let oldestAccessedAt = Number.POSITIVE_INFINITY;
|
|
964
|
+
for (const [key, entry] of contextCache.entries()) {
|
|
965
|
+
if (entry.lastAccessedAt < oldestAccessedAt) {
|
|
966
|
+
oldestAccessedAt = entry.lastAccessedAt;
|
|
967
|
+
oldestKey = key;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
if (oldestKey) {
|
|
971
|
+
contextCache.delete(oldestKey);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
function normalizeHandle2(handle) {
|
|
975
|
+
return typeof handle === "string" && handle.trim().length > 0 ? handle.trim() : null;
|
|
976
|
+
}
|
|
679
977
|
function toSdkToolDefinition(registration) {
|
|
680
978
|
const shape = buildZodShape(
|
|
681
|
-
|
|
979
|
+
import_zod7.z,
|
|
682
980
|
registration.inputSchema.properties,
|
|
683
981
|
new Set(registration.inputSchema.required)
|
|
684
982
|
);
|
|
@@ -689,12 +987,12 @@ function toSdkToolDefinition(registration) {
|
|
|
689
987
|
async (args) => registration.execute(args)
|
|
690
988
|
);
|
|
691
989
|
}
|
|
692
|
-
var import_claude_agent_sdk,
|
|
990
|
+
var import_claude_agent_sdk, import_zod7;
|
|
693
991
|
var init_sdk = __esm({
|
|
694
992
|
"src/mcp/sdk.ts"() {
|
|
695
993
|
"use strict";
|
|
696
994
|
import_claude_agent_sdk = require("@anthropic-ai/claude-agent-sdk");
|
|
697
|
-
|
|
995
|
+
import_zod7 = require("zod");
|
|
698
996
|
init_schemas();
|
|
699
997
|
init_registrations();
|
|
700
998
|
init_zod();
|
|
@@ -729,6 +1027,8 @@ __export(src_exports, {
|
|
|
729
1027
|
TOOL_MODELS: () => TOOL_MODELS,
|
|
730
1028
|
ThenvoiLink: () => ThenvoiLink,
|
|
731
1029
|
VercelAISDKAdapter: () => VercelAISDKAdapter,
|
|
1030
|
+
WebSocketDisconnectError: () => WebSocketDisconnectError,
|
|
1031
|
+
deriveDefaultRestUrl: () => deriveDefaultRestUrl,
|
|
732
1032
|
isDirectExecution: () => isDirectExecution,
|
|
733
1033
|
loadAgentConfig: () => loadAgentConfig,
|
|
734
1034
|
loadAgentConfigFromEnv: () => loadAgentConfigFromEnv
|
|
@@ -1758,56 +2058,242 @@ var payloadSchemas = {
|
|
|
1758
2058
|
|
|
1759
2059
|
// src/platform/streaming/PhoenixChannelsTransport.ts
|
|
1760
2060
|
var import_phoenix = require("phoenix");
|
|
1761
|
-
var import_ws = require("ws");
|
|
1762
2061
|
init_errors();
|
|
2062
|
+
|
|
2063
|
+
// src/platform/streaming/disconnectReason.ts
|
|
2064
|
+
var import_zod2 = require("zod");
|
|
2065
|
+
var UPGRADE_CODES = [
|
|
2066
|
+
"invalid_on_conflict",
|
|
2067
|
+
"connection_conflict",
|
|
2068
|
+
"too_many_requests",
|
|
2069
|
+
"tracking_failed"
|
|
2070
|
+
];
|
|
2071
|
+
var UPGRADE_REASONS = {
|
|
2072
|
+
invalid_on_conflict: {
|
|
2073
|
+
status: 400,
|
|
2074
|
+
message: "Invalid websocket conflict policy.",
|
|
2075
|
+
retryable: false
|
|
2076
|
+
},
|
|
2077
|
+
connection_conflict: {
|
|
2078
|
+
status: 409,
|
|
2079
|
+
message: "Websocket connection conflict.",
|
|
2080
|
+
retryable: false
|
|
2081
|
+
},
|
|
2082
|
+
too_many_requests: {
|
|
2083
|
+
status: 429,
|
|
2084
|
+
message: "Too many websocket connection attempts.",
|
|
2085
|
+
retryable: true
|
|
2086
|
+
},
|
|
2087
|
+
tracking_failed: {
|
|
2088
|
+
status: 503,
|
|
2089
|
+
message: "Websocket connection tracking failed.",
|
|
2090
|
+
retryable: true
|
|
2091
|
+
}
|
|
2092
|
+
};
|
|
2093
|
+
var upgradeErrorSchema = import_zod2.z.object({
|
|
2094
|
+
status: import_zod2.z.number(),
|
|
2095
|
+
body: import_zod2.z.preprocess(
|
|
2096
|
+
(body) => {
|
|
2097
|
+
if (typeof body !== "string") {
|
|
2098
|
+
return body;
|
|
2099
|
+
}
|
|
2100
|
+
try {
|
|
2101
|
+
return JSON.parse(body);
|
|
2102
|
+
} catch {
|
|
2103
|
+
return null;
|
|
2104
|
+
}
|
|
2105
|
+
},
|
|
2106
|
+
import_zod2.z.object({
|
|
2107
|
+
error: import_zod2.z.object({
|
|
2108
|
+
code: import_zod2.z.enum(UPGRADE_CODES),
|
|
2109
|
+
message: import_zod2.z.string().optional(),
|
|
2110
|
+
retry_after: import_zod2.z.number().nullable().optional(),
|
|
2111
|
+
request_id: import_zod2.z.string().nullable().optional()
|
|
2112
|
+
})
|
|
2113
|
+
})
|
|
2114
|
+
),
|
|
2115
|
+
headers: import_zod2.z.record(import_zod2.z.unknown()).optional()
|
|
2116
|
+
});
|
|
2117
|
+
var WebSocketDisconnectError = class extends Error {
|
|
2118
|
+
reason;
|
|
2119
|
+
constructor(reason) {
|
|
2120
|
+
super(reason.message);
|
|
2121
|
+
this.name = "WebSocketDisconnectError";
|
|
2122
|
+
this.reason = reason;
|
|
2123
|
+
}
|
|
2124
|
+
};
|
|
2125
|
+
function parseSupersedeDisconnectReason(payload) {
|
|
2126
|
+
if (typeof payload.reason !== "string" || typeof payload.message !== "string") {
|
|
2127
|
+
return null;
|
|
2128
|
+
}
|
|
2129
|
+
return {
|
|
2130
|
+
source: "agent_control",
|
|
2131
|
+
code: payload.reason,
|
|
2132
|
+
message: payload.message,
|
|
2133
|
+
retryable: false,
|
|
2134
|
+
retryAfter: typeof payload.retry_after === "number" ? payload.retry_after : null,
|
|
2135
|
+
targetSocketId: typeof payload.target_socket_id === "string" ? payload.target_socket_id : null,
|
|
2136
|
+
correlationId: typeof payload.correlation_id === "string" ? payload.correlation_id : null
|
|
2137
|
+
};
|
|
2138
|
+
}
|
|
2139
|
+
function parseUpgradeDisconnectReason(event) {
|
|
2140
|
+
const parsed = upgradeErrorSchema.safeParse(event);
|
|
2141
|
+
if (!parsed.success) {
|
|
2142
|
+
return null;
|
|
2143
|
+
}
|
|
2144
|
+
const { status, body, headers } = parsed.data;
|
|
2145
|
+
const {
|
|
2146
|
+
code,
|
|
2147
|
+
message,
|
|
2148
|
+
retry_after: retryAfter,
|
|
2149
|
+
request_id: requestId
|
|
2150
|
+
} = body.error;
|
|
2151
|
+
const reason = UPGRADE_REASONS[code];
|
|
2152
|
+
if (status !== reason.status) {
|
|
2153
|
+
return null;
|
|
2154
|
+
}
|
|
2155
|
+
return {
|
|
2156
|
+
source: "upgrade",
|
|
2157
|
+
status: reason.status,
|
|
2158
|
+
code,
|
|
2159
|
+
message: message ?? reason.message,
|
|
2160
|
+
retryable: reason.retryable,
|
|
2161
|
+
retryAfter: retryAfter ?? retryAfterFromHeaders(headers),
|
|
2162
|
+
requestId: requestId ?? null
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
function genericCloseReason(event) {
|
|
2166
|
+
return {
|
|
2167
|
+
source: "websocket_close",
|
|
2168
|
+
code: "websocket.closed",
|
|
2169
|
+
message: "Phoenix socket closed without a platform disconnect reason.",
|
|
2170
|
+
retryable: true,
|
|
2171
|
+
closeCode: typeof event?.code === "number" ? event.code : null,
|
|
2172
|
+
closeReason: typeof event?.reason === "string" && event.reason.length > 0 ? event.reason : null
|
|
2173
|
+
};
|
|
2174
|
+
}
|
|
2175
|
+
function retryAfterFromHeaders(headers) {
|
|
2176
|
+
const value = headers?.["retry-after"] ?? headers?.["Retry-After"];
|
|
2177
|
+
if (typeof value === "number") {
|
|
2178
|
+
return value;
|
|
2179
|
+
}
|
|
2180
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
2181
|
+
const seconds = Number(value);
|
|
2182
|
+
return Number.isFinite(seconds) ? seconds : null;
|
|
2183
|
+
}
|
|
2184
|
+
return null;
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
// src/platform/streaming/nodeWebSocketFactory.ts
|
|
2188
|
+
var import_ws = require("ws");
|
|
2189
|
+
function createNodeWebSocketFactory(headers) {
|
|
2190
|
+
const Constructor = import_ws.WebSocket;
|
|
2191
|
+
class ThenvoiNodeWebSocket {
|
|
2192
|
+
constructor(address, protocols) {
|
|
2193
|
+
const socket = new Constructor(address, protocols, headers ? { headers } : void 0);
|
|
2194
|
+
socket.once("unexpected-response", (request, response) => {
|
|
2195
|
+
void emitUpgradeError(socket, request, response);
|
|
2196
|
+
});
|
|
2197
|
+
return socket;
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
return ThenvoiNodeWebSocket;
|
|
2201
|
+
}
|
|
2202
|
+
async function emitUpgradeError(websocket, request, response) {
|
|
2203
|
+
const body = await readResponseBody(response);
|
|
2204
|
+
const error = new Error(
|
|
2205
|
+
`Unexpected server response: ${response.statusCode ?? "unknown"}`
|
|
2206
|
+
);
|
|
2207
|
+
error.status = response.statusCode;
|
|
2208
|
+
error.body = body;
|
|
2209
|
+
error.headers = response.headers;
|
|
2210
|
+
request.destroy();
|
|
2211
|
+
websocket.emit("error", error);
|
|
2212
|
+
websocket.emit("close", 1006, Buffer.alloc(0));
|
|
2213
|
+
}
|
|
2214
|
+
async function readResponseBody(response) {
|
|
2215
|
+
const chunks = [];
|
|
2216
|
+
for await (const chunk of response) {
|
|
2217
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
2218
|
+
}
|
|
2219
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
// src/platform/streaming/PhoenixChannelsTransport.ts
|
|
1763
2223
|
var PhoenixChannelsTransport = class {
|
|
1764
2224
|
socket;
|
|
2225
|
+
agentId;
|
|
1765
2226
|
channels = /* @__PURE__ */ new Map();
|
|
1766
2227
|
channelRefs = /* @__PURE__ */ new Map();
|
|
1767
2228
|
pendingJoins = /* @__PURE__ */ new Map();
|
|
1768
2229
|
logger;
|
|
2230
|
+
onTerminalDisconnect;
|
|
1769
2231
|
onHandlerError;
|
|
1770
2232
|
connected = false;
|
|
1771
2233
|
connectPromise = null;
|
|
1772
2234
|
connectResolve = null;
|
|
2235
|
+
connectReject = null;
|
|
2236
|
+
lastDisconnectReason = null;
|
|
2237
|
+
terminalDisconnectError = null;
|
|
2238
|
+
runForeverWaiters = /* @__PURE__ */ new Set();
|
|
2239
|
+
stoppingReconnect = false;
|
|
2240
|
+
suppressNextCloseReason = false;
|
|
1773
2241
|
constructor(options) {
|
|
1774
2242
|
this.logger = options.logger ?? new NoopLogger();
|
|
2243
|
+
this.agentId = options.agentId;
|
|
2244
|
+
this.onTerminalDisconnect = options.onTerminalDisconnect;
|
|
1775
2245
|
let wsUrl = options.wsUrl;
|
|
1776
2246
|
if (wsUrl.endsWith("/websocket")) {
|
|
1777
2247
|
wsUrl = wsUrl.slice(0, -"/websocket".length);
|
|
1778
2248
|
}
|
|
2249
|
+
const reconnectAfterMs = options.reconnectAfterMs ?? ((tries) => [1e3, 2e3, 5e3, 1e4, 3e4][tries - 1] ?? 3e4);
|
|
1779
2250
|
this.socket = new import_phoenix.Socket(wsUrl, {
|
|
1780
2251
|
params: {
|
|
1781
|
-
|
|
1782
|
-
|
|
2252
|
+
agent_id: options.agentId,
|
|
2253
|
+
...options.conflictPolicy ? { on_conflict: options.conflictPolicy } : {}
|
|
1783
2254
|
},
|
|
1784
2255
|
heartbeatIntervalMs: options.heartbeatIntervalMs,
|
|
1785
|
-
reconnectAfterMs:
|
|
1786
|
-
|
|
2256
|
+
reconnectAfterMs: (tries) => {
|
|
2257
|
+
if (this.terminalDisconnectError) {
|
|
2258
|
+
return Number.POSITIVE_INFINITY;
|
|
2259
|
+
}
|
|
2260
|
+
return reconnectAfterMs(tries);
|
|
2261
|
+
},
|
|
2262
|
+
transport: options.websocketFactory ?? resolveWebSocketFactory(options.apiKey)
|
|
1787
2263
|
});
|
|
1788
2264
|
this.socket.onOpen(() => {
|
|
1789
|
-
this.
|
|
1790
|
-
this.connectResolve?.();
|
|
1791
|
-
this.connectResolve = null;
|
|
1792
|
-
this.logger.info("Phoenix socket opened", {
|
|
1793
|
-
channels: getSocketChannelCount(this.socket)
|
|
1794
|
-
});
|
|
2265
|
+
void this.handleOpen();
|
|
1795
2266
|
});
|
|
1796
2267
|
this.socket.onClose((event) => {
|
|
1797
|
-
this.
|
|
1798
|
-
if (getSocketChannelCount(this.socket) === 0) {
|
|
1799
|
-
this.socket.disconnect();
|
|
1800
|
-
}
|
|
1801
|
-
this.logger.info("Phoenix socket closed", {
|
|
1802
|
-
code: event?.code ?? null,
|
|
1803
|
-
reason: event?.reason ?? null
|
|
1804
|
-
});
|
|
2268
|
+
this.recordSocketClose(event);
|
|
1805
2269
|
});
|
|
1806
2270
|
this.socket.onError((event) => {
|
|
2271
|
+
const errorEvent = unwrapErrorEvent(event);
|
|
2272
|
+
const upgradeReason = parseUpgradeDisconnectReason(errorEvent);
|
|
2273
|
+
if (upgradeReason) {
|
|
2274
|
+
if (upgradeReason.retryable) {
|
|
2275
|
+
this.lastDisconnectReason = upgradeReason;
|
|
2276
|
+
this.connectReject?.(new WebSocketDisconnectError(upgradeReason));
|
|
2277
|
+
this.stopReconnectIfNoChannels({ suppressCloseReason: true });
|
|
2278
|
+
} else {
|
|
2279
|
+
this.recordTerminalDisconnect(upgradeReason);
|
|
2280
|
+
}
|
|
2281
|
+
this.logger.warn("Phoenix socket upgrade failed", {
|
|
2282
|
+
reason: upgradeReason
|
|
2283
|
+
});
|
|
2284
|
+
return;
|
|
2285
|
+
}
|
|
2286
|
+
this.connectReject?.(
|
|
2287
|
+
new TransportError("Phoenix socket connection failed", errorEvent)
|
|
2288
|
+
);
|
|
2289
|
+
this.stopReconnectIfNoChannels({ suppressCloseReason: true });
|
|
1807
2290
|
this.logger.warn("Phoenix socket error", { event });
|
|
1808
2291
|
});
|
|
1809
2292
|
}
|
|
1810
2293
|
async connect() {
|
|
2294
|
+
if (this.terminalDisconnectError) {
|
|
2295
|
+
throw this.terminalDisconnectError;
|
|
2296
|
+
}
|
|
1811
2297
|
if (this.connected) {
|
|
1812
2298
|
return;
|
|
1813
2299
|
}
|
|
@@ -1831,15 +2317,30 @@ var PhoenixChannelsTransport = class {
|
|
|
1831
2317
|
await this.connectPromise;
|
|
1832
2318
|
}
|
|
1833
2319
|
async disconnect() {
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
2320
|
+
const results = await Promise.allSettled(
|
|
2321
|
+
[...this.channels.keys()].map((topic) => this.leave(topic))
|
|
2322
|
+
);
|
|
1837
2323
|
this.socket.disconnect();
|
|
1838
2324
|
this.connected = false;
|
|
2325
|
+
const failures = [];
|
|
2326
|
+
for (const result of results) {
|
|
2327
|
+
if (result.status === "rejected") {
|
|
2328
|
+
failures.push(result.reason);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
if (failures.length > 0) {
|
|
2332
|
+
throw new AggregateError(
|
|
2333
|
+
failures,
|
|
2334
|
+
"Failed to leave one or more Phoenix topics during disconnect"
|
|
2335
|
+
);
|
|
2336
|
+
}
|
|
1839
2337
|
}
|
|
1840
2338
|
isConnected() {
|
|
1841
2339
|
return this.connected;
|
|
1842
2340
|
}
|
|
2341
|
+
getDisconnectReason() {
|
|
2342
|
+
return this.lastDisconnectReason;
|
|
2343
|
+
}
|
|
1843
2344
|
async join(topic, handlers) {
|
|
1844
2345
|
if (this.channels.has(topic)) {
|
|
1845
2346
|
return;
|
|
@@ -1875,7 +2376,10 @@ var PhoenixChannelsTransport = class {
|
|
|
1875
2376
|
channel.join().receive("ok", () => resolve()).receive(
|
|
1876
2377
|
"error",
|
|
1877
2378
|
(error) => reject(new TransportError(`Failed to join topic ${topic}`, error))
|
|
1878
|
-
).receive(
|
|
2379
|
+
).receive(
|
|
2380
|
+
"timeout",
|
|
2381
|
+
() => reject(new TransportError(`Timeout joining topic ${topic}`))
|
|
2382
|
+
);
|
|
1879
2383
|
});
|
|
1880
2384
|
} catch (error) {
|
|
1881
2385
|
for (const [event, ref] of refs) {
|
|
@@ -1903,19 +2407,127 @@ var PhoenixChannelsTransport = class {
|
|
|
1903
2407
|
channel.leave().receive("ok", () => resolve()).receive(
|
|
1904
2408
|
"error",
|
|
1905
2409
|
(error) => reject(new TransportError(`Failed to leave topic ${topic}`, error))
|
|
1906
|
-
).receive(
|
|
2410
|
+
).receive(
|
|
2411
|
+
"timeout",
|
|
2412
|
+
() => reject(new TransportError(`Timeout leaving topic ${topic}`))
|
|
2413
|
+
);
|
|
1907
2414
|
});
|
|
1908
2415
|
this.channels.delete(topic);
|
|
1909
2416
|
this.logger.debug("Left topic", { topic });
|
|
1910
2417
|
}
|
|
1911
2418
|
async runForever(signal) {
|
|
2419
|
+
if (this.terminalDisconnectError) {
|
|
2420
|
+
throw this.terminalDisconnectError;
|
|
2421
|
+
}
|
|
1912
2422
|
if (signal.aborted) {
|
|
1913
2423
|
return;
|
|
1914
2424
|
}
|
|
1915
|
-
await new Promise((resolve) => {
|
|
1916
|
-
|
|
2425
|
+
await new Promise((resolve, reject) => {
|
|
2426
|
+
let settled = false;
|
|
2427
|
+
const abortController = new AbortController();
|
|
2428
|
+
const waiter = {
|
|
2429
|
+
reject: (error) => {
|
|
2430
|
+
if (settled) {
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
settled = true;
|
|
2434
|
+
this.runForeverWaiters.delete(waiter);
|
|
2435
|
+
abortController.abort();
|
|
2436
|
+
reject(error);
|
|
2437
|
+
}
|
|
2438
|
+
};
|
|
2439
|
+
this.runForeverWaiters.add(waiter);
|
|
2440
|
+
signal.addEventListener(
|
|
2441
|
+
"abort",
|
|
2442
|
+
() => {
|
|
2443
|
+
if (settled) {
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
settled = true;
|
|
2447
|
+
this.runForeverWaiters.delete(waiter);
|
|
2448
|
+
resolve();
|
|
2449
|
+
},
|
|
2450
|
+
{ once: true, signal: abortController.signal }
|
|
2451
|
+
);
|
|
2452
|
+
});
|
|
2453
|
+
}
|
|
2454
|
+
async handleOpen() {
|
|
2455
|
+
try {
|
|
2456
|
+
await this.subscribeAgentControl();
|
|
2457
|
+
} catch (error) {
|
|
2458
|
+
this.connected = false;
|
|
2459
|
+
this.socket.disconnect();
|
|
2460
|
+
this.connectReject?.(
|
|
2461
|
+
error instanceof Error ? error : new TransportError(String(error))
|
|
2462
|
+
);
|
|
2463
|
+
this.logger.warn("Failed to join mandatory agent_control channel", {
|
|
2464
|
+
error
|
|
2465
|
+
});
|
|
2466
|
+
return;
|
|
2467
|
+
}
|
|
2468
|
+
this.connected = true;
|
|
2469
|
+
this.connectResolve?.();
|
|
2470
|
+
this.connectResolve = null;
|
|
2471
|
+
this.connectReject = null;
|
|
2472
|
+
this.logger.info("Phoenix socket opened", {
|
|
2473
|
+
channels: getSocketChannelCount(this.socket)
|
|
2474
|
+
});
|
|
2475
|
+
}
|
|
2476
|
+
stopReconnectIfNoChannels(options = {}) {
|
|
2477
|
+
if (this.stoppingReconnect || getSocketChannelCount(this.socket) !== 0) {
|
|
2478
|
+
return;
|
|
2479
|
+
}
|
|
2480
|
+
this.suppressNextCloseReason = options.suppressCloseReason ?? false;
|
|
2481
|
+
this.stoppingReconnect = true;
|
|
2482
|
+
this.socket.disconnect();
|
|
2483
|
+
this.stoppingReconnect = false;
|
|
2484
|
+
}
|
|
2485
|
+
async subscribeAgentControl() {
|
|
2486
|
+
if (!this.agentId) {
|
|
2487
|
+
return;
|
|
2488
|
+
}
|
|
2489
|
+
await this.join(`agent_control:${this.agentId}`, {
|
|
2490
|
+
supersede: (payload) => {
|
|
2491
|
+
const reason = parseSupersedeDisconnectReason(payload);
|
|
2492
|
+
if (!reason) {
|
|
2493
|
+
this.logger.warn("Invalid agent_control supersede payload", {
|
|
2494
|
+
payload
|
|
2495
|
+
});
|
|
2496
|
+
return;
|
|
2497
|
+
}
|
|
2498
|
+
this.recordTerminalDisconnect(reason);
|
|
2499
|
+
}
|
|
1917
2500
|
});
|
|
1918
2501
|
}
|
|
2502
|
+
recordSocketClose(event) {
|
|
2503
|
+
this.connected = false;
|
|
2504
|
+
const suppressCloseReason = this.suppressNextCloseReason;
|
|
2505
|
+
this.suppressNextCloseReason = false;
|
|
2506
|
+
this.stopReconnectIfNoChannels();
|
|
2507
|
+
if (!suppressCloseReason && !this.terminalDisconnectError && !this.lastDisconnectReason) {
|
|
2508
|
+
this.lastDisconnectReason = genericCloseReason(event);
|
|
2509
|
+
}
|
|
2510
|
+
this.logger.info("Phoenix socket closed", {
|
|
2511
|
+
code: event?.code ?? null,
|
|
2512
|
+
reason: event?.reason ?? null,
|
|
2513
|
+
platformReason: this.lastDisconnectReason
|
|
2514
|
+
});
|
|
2515
|
+
}
|
|
2516
|
+
recordTerminalDisconnect(reason) {
|
|
2517
|
+
if (this.terminalDisconnectError) {
|
|
2518
|
+
return;
|
|
2519
|
+
}
|
|
2520
|
+
const error = new WebSocketDisconnectError(reason);
|
|
2521
|
+
this.lastDisconnectReason = reason;
|
|
2522
|
+
this.terminalDisconnectError = error;
|
|
2523
|
+
this.onTerminalDisconnect?.(reason);
|
|
2524
|
+
this.connectReject?.(error);
|
|
2525
|
+
for (const waiter of this.runForeverWaiters) {
|
|
2526
|
+
waiter.reject(error);
|
|
2527
|
+
}
|
|
2528
|
+
this.runForeverWaiters.clear();
|
|
2529
|
+
this.socket.disconnect();
|
|
2530
|
+
}
|
|
1919
2531
|
async waitForConnection(timeoutMs = 1e4) {
|
|
1920
2532
|
if (this.connected) {
|
|
1921
2533
|
return;
|
|
@@ -1923,20 +2535,43 @@ var PhoenixChannelsTransport = class {
|
|
|
1923
2535
|
await new Promise((resolve, reject) => {
|
|
1924
2536
|
const timeout = setTimeout(() => {
|
|
1925
2537
|
this.connectResolve = null;
|
|
1926
|
-
|
|
2538
|
+
this.connectReject = null;
|
|
2539
|
+
reject(
|
|
2540
|
+
new TransportError("Timed out waiting for Phoenix socket connection")
|
|
2541
|
+
);
|
|
1927
2542
|
}, timeoutMs);
|
|
1928
2543
|
this.connectResolve = () => {
|
|
1929
2544
|
clearTimeout(timeout);
|
|
2545
|
+
this.connectReject = null;
|
|
1930
2546
|
resolve();
|
|
1931
2547
|
};
|
|
2548
|
+
this.connectReject = (error) => {
|
|
2549
|
+
clearTimeout(timeout);
|
|
2550
|
+
this.connectResolve = null;
|
|
2551
|
+
this.connectReject = null;
|
|
2552
|
+
reject(
|
|
2553
|
+
error instanceof Error ? error : new TransportError(String(error))
|
|
2554
|
+
);
|
|
2555
|
+
};
|
|
1932
2556
|
});
|
|
1933
2557
|
}
|
|
1934
2558
|
};
|
|
1935
|
-
function resolveWebSocketFactory() {
|
|
2559
|
+
function resolveWebSocketFactory(apiKey) {
|
|
1936
2560
|
if (typeof process !== "undefined" && process.versions?.node) {
|
|
1937
|
-
return
|
|
2561
|
+
return createNodeWebSocketFactory({ "x-api-key": apiKey });
|
|
2562
|
+
}
|
|
2563
|
+
throw new TransportError(
|
|
2564
|
+
"Phoenix WebSocket API-key auth requires a WebSocket transport that can set handshake headers."
|
|
2565
|
+
);
|
|
2566
|
+
}
|
|
2567
|
+
function unwrapErrorEvent(event) {
|
|
2568
|
+
if (!isErrorEvent(event)) {
|
|
2569
|
+
return event;
|
|
1938
2570
|
}
|
|
1939
|
-
return
|
|
2571
|
+
return event.error;
|
|
2572
|
+
}
|
|
2573
|
+
function isErrorEvent(event) {
|
|
2574
|
+
return typeof event === "object" && event !== null && "error" in event;
|
|
1940
2575
|
}
|
|
1941
2576
|
function removeSocketChannel(socket, channel) {
|
|
1942
2577
|
const candidate = socket;
|
|
@@ -1959,6 +2594,12 @@ function deriveDefaultRestUrl(wsUrl) {
|
|
|
1959
2594
|
const protocol = parsed.protocol === "ws:" ? "http:" : "https:";
|
|
1960
2595
|
return `${protocol}//${parsed.host}`;
|
|
1961
2596
|
}
|
|
2597
|
+
function roomTopics(roomId) {
|
|
2598
|
+
return {
|
|
2599
|
+
chat: `chat_room:${roomId}`,
|
|
2600
|
+
participants: `room_participants:${roomId}`
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
1962
2603
|
function toPlatformMessage(roomId, message) {
|
|
1963
2604
|
return {
|
|
1964
2605
|
id: message.id,
|
|
@@ -1985,6 +2626,8 @@ var ThenvoiLink = class {
|
|
|
1985
2626
|
eventQueue = [];
|
|
1986
2627
|
waiters = [];
|
|
1987
2628
|
connected = false;
|
|
2629
|
+
lastDisconnectReason = null;
|
|
2630
|
+
terminalDisconnectError = null;
|
|
1988
2631
|
constructor(options) {
|
|
1989
2632
|
this.agentId = options.agentId;
|
|
1990
2633
|
this.apiKey = options.apiKey;
|
|
@@ -2006,17 +2649,35 @@ var ThenvoiLink = class {
|
|
|
2006
2649
|
wsUrl: this.wsUrl,
|
|
2007
2650
|
apiKey: this.apiKey,
|
|
2008
2651
|
agentId: this.agentId,
|
|
2009
|
-
logger: this.logger
|
|
2652
|
+
logger: this.logger,
|
|
2653
|
+
conflictPolicy: options.conflictPolicy,
|
|
2654
|
+
onTerminalDisconnect: (reason) => {
|
|
2655
|
+
this.recordDisconnectReason(reason);
|
|
2656
|
+
}
|
|
2010
2657
|
});
|
|
2011
2658
|
}
|
|
2012
2659
|
isConnected() {
|
|
2013
2660
|
return this.connected;
|
|
2014
2661
|
}
|
|
2662
|
+
getDisconnectReason() {
|
|
2663
|
+
return this.lastDisconnectReason;
|
|
2664
|
+
}
|
|
2015
2665
|
async connect() {
|
|
2016
2666
|
if (this.connected) {
|
|
2017
2667
|
return;
|
|
2018
2668
|
}
|
|
2019
|
-
|
|
2669
|
+
try {
|
|
2670
|
+
await this.transport.connect();
|
|
2671
|
+
} catch (error) {
|
|
2672
|
+
if (error instanceof WebSocketDisconnectError) {
|
|
2673
|
+
if (error.reason.retryable) {
|
|
2674
|
+
this.lastDisconnectReason = error.reason;
|
|
2675
|
+
} else {
|
|
2676
|
+
this.recordDisconnectError(error);
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
throw error;
|
|
2680
|
+
}
|
|
2020
2681
|
this.connected = true;
|
|
2021
2682
|
}
|
|
2022
2683
|
async disconnect() {
|
|
@@ -2030,8 +2691,23 @@ var ThenvoiLink = class {
|
|
|
2030
2691
|
this.connected = false;
|
|
2031
2692
|
}
|
|
2032
2693
|
async runForever(signal) {
|
|
2694
|
+
if (this.terminalDisconnectError) {
|
|
2695
|
+
throw this.terminalDisconnectError;
|
|
2696
|
+
}
|
|
2033
2697
|
await this.transport.runForever(signal);
|
|
2034
2698
|
}
|
|
2699
|
+
recordDisconnectReason(reason) {
|
|
2700
|
+
this.recordDisconnectError(new WebSocketDisconnectError(reason));
|
|
2701
|
+
}
|
|
2702
|
+
recordDisconnectError(error) {
|
|
2703
|
+
this.connected = false;
|
|
2704
|
+
this.lastDisconnectReason = error.reason;
|
|
2705
|
+
this.terminalDisconnectError = error;
|
|
2706
|
+
while (this.waiters.length > 0) {
|
|
2707
|
+
const waiter = this.waiters.shift();
|
|
2708
|
+
waiter?.reject(error);
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2035
2711
|
queueEvent(event) {
|
|
2036
2712
|
const waiter = this.waiters.shift();
|
|
2037
2713
|
if (waiter) {
|
|
@@ -2056,32 +2732,42 @@ var ThenvoiLink = class {
|
|
|
2056
2732
|
if (this.subscribedRooms.has(roomId)) {
|
|
2057
2733
|
return;
|
|
2058
2734
|
}
|
|
2059
|
-
await this.
|
|
2060
|
-
message_created: (payload) => {
|
|
2061
|
-
this.emit("message_created", payload, roomId);
|
|
2062
|
-
}
|
|
2063
|
-
});
|
|
2064
|
-
await this.transport.join(`room_participants:${roomId}`, {
|
|
2065
|
-
participant_added: (payload) => {
|
|
2066
|
-
this.emit("participant_added", payload, roomId);
|
|
2067
|
-
},
|
|
2068
|
-
participant_removed: (payload) => {
|
|
2069
|
-
this.emit("participant_removed", payload, roomId);
|
|
2070
|
-
},
|
|
2071
|
-
room_deleted: (payload) => {
|
|
2072
|
-
this.emit("room_deleted", payload, roomId);
|
|
2073
|
-
}
|
|
2074
|
-
});
|
|
2735
|
+
await this.joinRoomTopics(roomId);
|
|
2075
2736
|
this.subscribedRooms.add(roomId);
|
|
2076
2737
|
}
|
|
2077
2738
|
async unsubscribeRoom(roomId) {
|
|
2078
2739
|
if (!this.subscribedRooms.has(roomId)) {
|
|
2079
2740
|
return;
|
|
2080
2741
|
}
|
|
2081
|
-
|
|
2082
|
-
await this.transport.leave(
|
|
2742
|
+
const topics = roomTopics(roomId);
|
|
2743
|
+
await this.transport.leave(topics.chat);
|
|
2744
|
+
await this.transport.leave(topics.participants);
|
|
2083
2745
|
this.subscribedRooms.delete(roomId);
|
|
2084
2746
|
}
|
|
2747
|
+
async joinRoomTopics(roomId) {
|
|
2748
|
+
const topics = roomTopics(roomId);
|
|
2749
|
+
await this.transport.join(topics.chat, {
|
|
2750
|
+
message_created: (payload) => {
|
|
2751
|
+
this.emit("message_created", payload, roomId);
|
|
2752
|
+
}
|
|
2753
|
+
});
|
|
2754
|
+
try {
|
|
2755
|
+
await this.transport.join(topics.participants, {
|
|
2756
|
+
participant_added: (payload) => {
|
|
2757
|
+
this.emit("participant_added", payload, roomId);
|
|
2758
|
+
},
|
|
2759
|
+
participant_removed: (payload) => {
|
|
2760
|
+
this.emit("participant_removed", payload, roomId);
|
|
2761
|
+
},
|
|
2762
|
+
room_deleted: (payload) => {
|
|
2763
|
+
this.emit("room_deleted", payload, roomId);
|
|
2764
|
+
}
|
|
2765
|
+
});
|
|
2766
|
+
} catch (error) {
|
|
2767
|
+
await this.transport.leave(topics.chat);
|
|
2768
|
+
throw error;
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2085
2771
|
async subscribeAgentContacts() {
|
|
2086
2772
|
assertCapability(this.capabilities, "contacts", "Contacts streaming");
|
|
2087
2773
|
await this.transport.join(`agent_contacts:${this.agentId}`, {
|
|
@@ -2103,6 +2789,9 @@ var ThenvoiLink = class {
|
|
|
2103
2789
|
await this.transport.leave(`agent_contacts:${this.agentId}`);
|
|
2104
2790
|
}
|
|
2105
2791
|
async nextEvent(signal) {
|
|
2792
|
+
if (this.terminalDisconnectError) {
|
|
2793
|
+
throw this.terminalDisconnectError;
|
|
2794
|
+
}
|
|
2106
2795
|
if (signal?.aborted) {
|
|
2107
2796
|
return null;
|
|
2108
2797
|
}
|
|
@@ -2110,19 +2799,19 @@ var ThenvoiLink = class {
|
|
|
2110
2799
|
if (queued) {
|
|
2111
2800
|
return queued;
|
|
2112
2801
|
}
|
|
2113
|
-
return new Promise((resolve) => {
|
|
2802
|
+
return new Promise((resolve, reject) => {
|
|
2114
2803
|
let settled = false;
|
|
2115
2804
|
const onAbort = () => {
|
|
2116
2805
|
const index = this.waiters.indexOf(waiter);
|
|
2117
2806
|
if (index >= 0) {
|
|
2118
2807
|
this.waiters.splice(index, 1);
|
|
2119
2808
|
}
|
|
2120
|
-
|
|
2809
|
+
finalizeResolve(null);
|
|
2121
2810
|
};
|
|
2122
2811
|
const cleanup = () => {
|
|
2123
2812
|
signal?.removeEventListener("abort", onAbort);
|
|
2124
2813
|
};
|
|
2125
|
-
const
|
|
2814
|
+
const finalizeResolve = (event) => {
|
|
2126
2815
|
if (settled) {
|
|
2127
2816
|
return;
|
|
2128
2817
|
}
|
|
@@ -2130,8 +2819,17 @@ var ThenvoiLink = class {
|
|
|
2130
2819
|
cleanup();
|
|
2131
2820
|
resolve(event);
|
|
2132
2821
|
};
|
|
2822
|
+
const finalizeReject = (error) => {
|
|
2823
|
+
if (settled) {
|
|
2824
|
+
return;
|
|
2825
|
+
}
|
|
2826
|
+
settled = true;
|
|
2827
|
+
cleanup();
|
|
2828
|
+
reject(error);
|
|
2829
|
+
};
|
|
2133
2830
|
const waiter = {
|
|
2134
|
-
resolve:
|
|
2831
|
+
resolve: finalizeResolve,
|
|
2832
|
+
reject: finalizeReject,
|
|
2135
2833
|
cleanup
|
|
2136
2834
|
};
|
|
2137
2835
|
this.waiters.push(waiter);
|
|
@@ -2143,7 +2841,10 @@ var ThenvoiLink = class {
|
|
|
2143
2841
|
next: async () => {
|
|
2144
2842
|
const value = await this.nextEvent();
|
|
2145
2843
|
if (value === null) {
|
|
2146
|
-
return {
|
|
2844
|
+
return {
|
|
2845
|
+
done: true,
|
|
2846
|
+
value: void 0
|
|
2847
|
+
};
|
|
2147
2848
|
}
|
|
2148
2849
|
return { done: false, value };
|
|
2149
2850
|
}
|
|
@@ -2225,7 +2926,9 @@ var ThenvoiLink = class {
|
|
|
2225
2926
|
}
|
|
2226
2927
|
async listChats(request, requestOptions) {
|
|
2227
2928
|
if (!this.rest.listChats) {
|
|
2228
|
-
throw new UnsupportedFeatureError(
|
|
2929
|
+
throw new UnsupportedFeatureError(
|
|
2930
|
+
"Chat listing is not available in current REST adapter"
|
|
2931
|
+
);
|
|
2229
2932
|
}
|
|
2230
2933
|
return this.rest.listChats(request, requestOptions);
|
|
2231
2934
|
}
|
|
@@ -2558,6 +3261,7 @@ init_errors();
|
|
|
2558
3261
|
init_chatEvents();
|
|
2559
3262
|
init_protocols();
|
|
2560
3263
|
init_schemas();
|
|
3264
|
+
init_memory();
|
|
2561
3265
|
var REQUIRED_ADAPTER_TOOL_METHODS = [
|
|
2562
3266
|
"sendMessage",
|
|
2563
3267
|
"sendEvent",
|
|
@@ -2592,40 +3296,6 @@ var CONTACT_REQUEST_ACTIONS = /* @__PURE__ */ new Set([
|
|
|
2592
3296
|
"reject",
|
|
2593
3297
|
"cancel"
|
|
2594
3298
|
]);
|
|
2595
|
-
var MEMORY_SYSTEMS = /* @__PURE__ */ new Set([
|
|
2596
|
-
"sensory",
|
|
2597
|
-
"working",
|
|
2598
|
-
"long_term"
|
|
2599
|
-
]);
|
|
2600
|
-
var MEMORY_TYPES = /* @__PURE__ */ new Set([
|
|
2601
|
-
"iconic",
|
|
2602
|
-
"echoic",
|
|
2603
|
-
"haptic",
|
|
2604
|
-
"episodic",
|
|
2605
|
-
"semantic",
|
|
2606
|
-
"procedural"
|
|
2607
|
-
]);
|
|
2608
|
-
var MEMORY_SEGMENTS = /* @__PURE__ */ new Set([
|
|
2609
|
-
"user",
|
|
2610
|
-
"agent",
|
|
2611
|
-
"tool",
|
|
2612
|
-
"guideline"
|
|
2613
|
-
]);
|
|
2614
|
-
var LIST_MEMORY_SCOPES = /* @__PURE__ */ new Set([
|
|
2615
|
-
"subject",
|
|
2616
|
-
"organization",
|
|
2617
|
-
"all"
|
|
2618
|
-
]);
|
|
2619
|
-
var LIST_MEMORY_STATUSES = /* @__PURE__ */ new Set([
|
|
2620
|
-
"active",
|
|
2621
|
-
"superseded",
|
|
2622
|
-
"archived",
|
|
2623
|
-
"all"
|
|
2624
|
-
]);
|
|
2625
|
-
var MEMORY_SCOPES = /* @__PURE__ */ new Set([
|
|
2626
|
-
"subject",
|
|
2627
|
-
"organization"
|
|
2628
|
-
]);
|
|
2629
3299
|
var AgentTools = class {
|
|
2630
3300
|
roomId;
|
|
2631
3301
|
capabilities;
|
|
@@ -3203,6 +3873,9 @@ var AgentTools = class {
|
|
|
3203
3873
|
const status = this.normalizeOptionalMemoryStatus(arguments_.status);
|
|
3204
3874
|
const subjectId = this.normalizeOptionalString(arguments_.subject_id);
|
|
3205
3875
|
const contentQuery = this.normalizeOptionalString(arguments_.content_query);
|
|
3876
|
+
if (system && type && !isMemoryTypeForSystem(system, type)) {
|
|
3877
|
+
throw new ValidationError(memoryTypeForSystemError(system));
|
|
3878
|
+
}
|
|
3206
3879
|
return {
|
|
3207
3880
|
...subjectId ? { subject_id: subjectId } : {},
|
|
3208
3881
|
...scope ? { scope } : {},
|
|
@@ -3224,13 +3897,21 @@ var AgentTools = class {
|
|
|
3224
3897
|
const subjectId = this.normalizeOptionalString(arguments_.subject_id);
|
|
3225
3898
|
const metadata = this.normalizeOptionalMetadata(arguments_.metadata);
|
|
3226
3899
|
if (!system) {
|
|
3227
|
-
throw new ValidationError(
|
|
3900
|
+
throw new ValidationError(`system must be one of: ${expectedList(MEMORY_SYSTEMS)}`);
|
|
3228
3901
|
}
|
|
3229
3902
|
if (!type) {
|
|
3230
|
-
throw new ValidationError(
|
|
3903
|
+
throw new ValidationError(`type must be one of: ${expectedList(MEMORY_TYPES)}`);
|
|
3904
|
+
}
|
|
3905
|
+
if (!isMemoryTypeForSystem(system, type)) {
|
|
3906
|
+
throw new ValidationError(memoryTypeForSystemError(system));
|
|
3231
3907
|
}
|
|
3232
3908
|
if (!segment) {
|
|
3233
|
-
throw new ValidationError(
|
|
3909
|
+
throw new ValidationError(`segment must be one of: ${expectedList(MEMORY_SEGMENTS)}`);
|
|
3910
|
+
}
|
|
3911
|
+
if (scope === "subject" && !subjectId) {
|
|
3912
|
+
throw new ValidationError(
|
|
3913
|
+
'scope="subject" requires a subject_id (the UUID of the person or agent the memory is about). If you do not have a concrete subject UUID, retry with scope="organization" and omit subject_id. Do not invent a UUID.'
|
|
3914
|
+
);
|
|
3234
3915
|
}
|
|
3235
3916
|
return {
|
|
3236
3917
|
content,
|
|
@@ -3310,8 +3991,8 @@ var AgentTools = class {
|
|
|
3310
3991
|
if (!normalized) {
|
|
3311
3992
|
return void 0;
|
|
3312
3993
|
}
|
|
3313
|
-
if (!
|
|
3314
|
-
throw new ValidationError(
|
|
3994
|
+
if (!isMemoryListScope(normalized)) {
|
|
3995
|
+
throw new ValidationError(`scope must be one of: ${expectedList(MEMORY_LIST_SCOPES)}`);
|
|
3315
3996
|
}
|
|
3316
3997
|
return normalized;
|
|
3317
3998
|
}
|
|
@@ -3321,7 +4002,7 @@ var AgentTools = class {
|
|
|
3321
4002
|
return void 0;
|
|
3322
4003
|
}
|
|
3323
4004
|
if (!isMemorySystem(normalized)) {
|
|
3324
|
-
throw new ValidationError(
|
|
4005
|
+
throw new ValidationError(`system must be one of: ${expectedList(MEMORY_SYSTEMS)}`);
|
|
3325
4006
|
}
|
|
3326
4007
|
return normalized;
|
|
3327
4008
|
}
|
|
@@ -3331,7 +4012,7 @@ var AgentTools = class {
|
|
|
3331
4012
|
return void 0;
|
|
3332
4013
|
}
|
|
3333
4014
|
if (!isMemoryType(normalized)) {
|
|
3334
|
-
throw new ValidationError(
|
|
4015
|
+
throw new ValidationError(`type must be one of: ${expectedList(MEMORY_TYPES)}`);
|
|
3335
4016
|
}
|
|
3336
4017
|
return normalized;
|
|
3337
4018
|
}
|
|
@@ -3341,7 +4022,7 @@ var AgentTools = class {
|
|
|
3341
4022
|
return void 0;
|
|
3342
4023
|
}
|
|
3343
4024
|
if (!isMemorySegment(normalized)) {
|
|
3344
|
-
throw new ValidationError(
|
|
4025
|
+
throw new ValidationError(`segment must be one of: ${expectedList(MEMORY_SEGMENTS)}`);
|
|
3345
4026
|
}
|
|
3346
4027
|
return normalized;
|
|
3347
4028
|
}
|
|
@@ -3351,7 +4032,7 @@ var AgentTools = class {
|
|
|
3351
4032
|
return void 0;
|
|
3352
4033
|
}
|
|
3353
4034
|
if (!isMemoryStatus(normalized)) {
|
|
3354
|
-
throw new ValidationError(
|
|
4035
|
+
throw new ValidationError(`status must be one of: ${expectedList(MEMORY_STATUSES)}`);
|
|
3355
4036
|
}
|
|
3356
4037
|
return normalized;
|
|
3357
4038
|
}
|
|
@@ -3360,8 +4041,8 @@ var AgentTools = class {
|
|
|
3360
4041
|
if (!normalized) {
|
|
3361
4042
|
return void 0;
|
|
3362
4043
|
}
|
|
3363
|
-
if (!
|
|
3364
|
-
throw new ValidationError(
|
|
4044
|
+
if (!isMemoryStoreScope(normalized)) {
|
|
4045
|
+
throw new ValidationError(`scope must be one of: ${expectedList(MEMORY_STORE_SCOPES)}`);
|
|
3365
4046
|
}
|
|
3366
4047
|
return normalized;
|
|
3367
4048
|
}
|
|
@@ -3369,24 +4050,6 @@ var AgentTools = class {
|
|
|
3369
4050
|
function isContactRequestAction(value) {
|
|
3370
4051
|
return CONTACT_REQUEST_ACTIONS.has(value);
|
|
3371
4052
|
}
|
|
3372
|
-
function isMemorySystem(value) {
|
|
3373
|
-
return MEMORY_SYSTEMS.has(value);
|
|
3374
|
-
}
|
|
3375
|
-
function isMemoryType(value) {
|
|
3376
|
-
return MEMORY_TYPES.has(value);
|
|
3377
|
-
}
|
|
3378
|
-
function isMemorySegment(value) {
|
|
3379
|
-
return MEMORY_SEGMENTS.has(value);
|
|
3380
|
-
}
|
|
3381
|
-
function isStoreMemoryScope(value) {
|
|
3382
|
-
return MEMORY_SCOPES.has(value);
|
|
3383
|
-
}
|
|
3384
|
-
function isListMemoryScope(value) {
|
|
3385
|
-
return LIST_MEMORY_SCOPES.has(value);
|
|
3386
|
-
}
|
|
3387
|
-
function isMemoryStatus(value) {
|
|
3388
|
-
return LIST_MEMORY_STATUSES.has(value);
|
|
3389
|
-
}
|
|
3390
4053
|
function coercePositiveInt(value, fallback) {
|
|
3391
4054
|
const num = Number(value ?? fallback);
|
|
3392
4055
|
return Number.isFinite(num) && num >= 1 ? Math.floor(num) : fallback;
|
|
@@ -3426,17 +4089,19 @@ function validateToolArgs(toolName, args) {
|
|
|
3426
4089
|
}
|
|
3427
4090
|
}
|
|
3428
4091
|
if (toolName === "thenvoi_store_memory") {
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
if (typeof args.
|
|
3433
|
-
errors.push(`
|
|
4092
|
+
if (typeof args.system === "string" && !isMemorySystem(args.system)) {
|
|
4093
|
+
errors.push(`system: Invalid value '${args.system}'. Expected one of: ${expectedList(MEMORY_SYSTEMS)}`);
|
|
4094
|
+
}
|
|
4095
|
+
if (typeof args.type === "string" && !isMemoryType(args.type)) {
|
|
4096
|
+
errors.push(`type: Invalid value '${args.type}'. Expected one of: ${expectedList(MEMORY_TYPES)}`);
|
|
3434
4097
|
}
|
|
3435
|
-
if (typeof args.type === "string" && !
|
|
3436
|
-
errors.push(
|
|
4098
|
+
if (typeof args.system === "string" && isMemorySystem(args.system) && typeof args.type === "string" && isMemoryType(args.type) && !isMemoryTypeForSystem(args.system, args.type)) {
|
|
4099
|
+
errors.push(
|
|
4100
|
+
`type: Invalid value '${args.type}' for system '${args.system}'. Expected one of: ${expectedMemoryTypesForSystem(args.system)}`
|
|
4101
|
+
);
|
|
3437
4102
|
}
|
|
3438
|
-
if (typeof args.segment === "string" && !
|
|
3439
|
-
errors.push(`segment: Invalid value '${args.segment}'. Expected one of: ${
|
|
4103
|
+
if (typeof args.segment === "string" && !isMemorySegment(args.segment)) {
|
|
4104
|
+
errors.push(`segment: Invalid value '${args.segment}'. Expected one of: ${expectedList(MEMORY_SEGMENTS)}`);
|
|
3440
4105
|
}
|
|
3441
4106
|
}
|
|
3442
4107
|
if (errors.length > 0) {
|
|
@@ -3503,6 +4168,29 @@ var MessageRetryTracker = class {
|
|
|
3503
4168
|
}
|
|
3504
4169
|
};
|
|
3505
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
|
+
|
|
3506
4194
|
// src/runtime/formatters.ts
|
|
3507
4195
|
function isMetadataMap(value) {
|
|
3508
4196
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -3516,7 +4204,7 @@ function replaceUuidMentions(content, participants) {
|
|
|
3516
4204
|
const participantId = participant.id;
|
|
3517
4205
|
const handle = participant.handle;
|
|
3518
4206
|
if (typeof participantId === "string" && typeof handle === "string") {
|
|
3519
|
-
next = next.replaceAll(`@[[${participantId}]]`,
|
|
4207
|
+
next = next.replaceAll(`@[[${participantId}]]`, ensureHandlePrefix(handle) ?? "");
|
|
3520
4208
|
}
|
|
3521
4209
|
}
|
|
3522
4210
|
return next;
|
|
@@ -3548,7 +4236,9 @@ function buildParticipantsMessage(participants) {
|
|
|
3548
4236
|
const participantType = String(participant.type ?? "Unknown");
|
|
3549
4237
|
const participantName = String(participant.name ?? "Unknown");
|
|
3550
4238
|
const participantHandle = String(participant.handle ?? "Unknown");
|
|
3551
|
-
lines.push(
|
|
4239
|
+
lines.push(
|
|
4240
|
+
`- ${ensureHandlePrefix(participantHandle) ?? ""} \u2014 ${participantName} (${participantType})`
|
|
4241
|
+
);
|
|
3552
4242
|
}
|
|
3553
4243
|
lines.push("");
|
|
3554
4244
|
lines.push(
|
|
@@ -4028,7 +4718,7 @@ var AgentRuntime = class {
|
|
|
4028
4718
|
await this.link.disconnect();
|
|
4029
4719
|
}
|
|
4030
4720
|
async stop(timeoutMs) {
|
|
4031
|
-
if (!this.running
|
|
4721
|
+
if (this.stopping || !this.running && !this.fatalError) {
|
|
4032
4722
|
return true;
|
|
4033
4723
|
}
|
|
4034
4724
|
this.stopping = true;
|
|
@@ -4048,7 +4738,8 @@ var AgentRuntime = class {
|
|
|
4048
4738
|
}
|
|
4049
4739
|
}
|
|
4050
4740
|
for (const roomId of [...this.subscribedRooms]) {
|
|
4051
|
-
|
|
4741
|
+
const remaining = deadline === void 0 ? void 0 : Math.max(0, deadline - Date.now());
|
|
4742
|
+
await this.leaveTrackedRoom(roomId, remaining);
|
|
4052
4743
|
}
|
|
4053
4744
|
for (const roomId of [...this.contexts.keys()]) {
|
|
4054
4745
|
await this.onSessionCleanup(roomId);
|
|
@@ -4084,7 +4775,13 @@ var AgentRuntime = class {
|
|
|
4084
4775
|
}
|
|
4085
4776
|
async consumeLoop(signal) {
|
|
4086
4777
|
while (!signal.aborted) {
|
|
4087
|
-
|
|
4778
|
+
let event;
|
|
4779
|
+
try {
|
|
4780
|
+
event = await this.link.nextEvent(signal);
|
|
4781
|
+
} catch (error) {
|
|
4782
|
+
await this.failRuntime(error, syntheticRuntimeFailureEvent(this.agentId));
|
|
4783
|
+
return;
|
|
4784
|
+
}
|
|
4088
4785
|
if (!event) {
|
|
4089
4786
|
return;
|
|
4090
4787
|
}
|
|
@@ -4247,13 +4944,13 @@ var AgentRuntime = class {
|
|
|
4247
4944
|
}
|
|
4248
4945
|
});
|
|
4249
4946
|
}
|
|
4250
|
-
async leaveTrackedRoom(roomId) {
|
|
4947
|
+
async leaveTrackedRoom(roomId, timeoutMs) {
|
|
4251
4948
|
await trackRoomLeave({
|
|
4252
4949
|
link: this.link,
|
|
4253
4950
|
roomId,
|
|
4254
4951
|
trackedRooms: this.subscribedRooms,
|
|
4255
4952
|
onLeft: async (leftRoomId) => {
|
|
4256
|
-
await this.executions.get(leftRoomId)?.stop();
|
|
4953
|
+
await this.executions.get(leftRoomId)?.stop(timeoutMs);
|
|
4257
4954
|
this.contexts.delete(leftRoomId);
|
|
4258
4955
|
this.executions.delete(leftRoomId);
|
|
4259
4956
|
await this.onSessionCleanup(leftRoomId);
|
|
@@ -4290,27 +4987,27 @@ var AgentRuntime = class {
|
|
|
4290
4987
|
}
|
|
4291
4988
|
}
|
|
4292
4989
|
};
|
|
4990
|
+
function syntheticRuntimeFailureEvent(agentId) {
|
|
4991
|
+
return {
|
|
4992
|
+
type: "message_created",
|
|
4993
|
+
roomId: null,
|
|
4994
|
+
payload: {
|
|
4995
|
+
id: "runtime-failed",
|
|
4996
|
+
content: "",
|
|
4997
|
+
sender_id: agentId,
|
|
4998
|
+
sender_type: "Agent",
|
|
4999
|
+
sender_name: null,
|
|
5000
|
+
message_type: "text",
|
|
5001
|
+
metadata: {},
|
|
5002
|
+
inserted_at: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
5003
|
+
updated_at: (/* @__PURE__ */ new Date(0)).toISOString()
|
|
5004
|
+
}
|
|
5005
|
+
};
|
|
5006
|
+
}
|
|
4293
5007
|
function assertNever(value) {
|
|
4294
5008
|
throw new Error(`Unhandled platform event: ${JSON.stringify(value)}`);
|
|
4295
5009
|
}
|
|
4296
5010
|
|
|
4297
|
-
// src/runtime/types.ts
|
|
4298
|
-
var HistoryProvider = class {
|
|
4299
|
-
raw;
|
|
4300
|
-
constructor(raw) {
|
|
4301
|
-
this.raw = raw;
|
|
4302
|
-
}
|
|
4303
|
-
convert(converter) {
|
|
4304
|
-
return converter.convert(this.raw);
|
|
4305
|
-
}
|
|
4306
|
-
get length() {
|
|
4307
|
-
return this.raw.length;
|
|
4308
|
-
}
|
|
4309
|
-
};
|
|
4310
|
-
var SYNTHETIC_SENDER_TYPE = "System";
|
|
4311
|
-
var SYNTHETIC_CONTACT_EVENTS_SENDER_ID = "contact-events";
|
|
4312
|
-
var SYNTHETIC_CONTACT_EVENTS_SENDER_NAME = "Contact Events";
|
|
4313
|
-
|
|
4314
5011
|
// src/runtime/PlatformRuntime.ts
|
|
4315
5012
|
init_errors();
|
|
4316
5013
|
|
|
@@ -5156,7 +5853,8 @@ var PlatformRuntime = class {
|
|
|
5156
5853
|
agentId: this._agentId,
|
|
5157
5854
|
apiKey: this._apiKey,
|
|
5158
5855
|
wsUrl: this._wsUrl,
|
|
5159
|
-
restUrl: this._restUrl
|
|
5856
|
+
restUrl: this._restUrl,
|
|
5857
|
+
logger: this.logger
|
|
5160
5858
|
});
|
|
5161
5859
|
}
|
|
5162
5860
|
if (this.configuredIdentity) {
|
|
@@ -5659,16 +6357,15 @@ var GenericAdapter = class extends SimpleAdapter {
|
|
|
5659
6357
|
// src/adapters/codex/CodexAdapter.ts
|
|
5660
6358
|
init_protocols();
|
|
5661
6359
|
|
|
5662
|
-
// src/runtime/prompts.ts
|
|
5663
|
-
var
|
|
6360
|
+
// src/runtime/prompts/base.ts
|
|
6361
|
+
var ENVIRONMENT_SECTION = `
|
|
5664
6362
|
## Environment
|
|
5665
6363
|
|
|
5666
6364
|
Multi-participant chat. Messages show sender: [Name]: content.
|
|
5667
6365
|
Messages prefixed with [System]: are platform updates (participant changes, contact updates, etc.) \u2014 not messages from users.
|
|
5668
6366
|
Use \`thenvoi_send_message(content, mentions)\` to respond. Plain text output is not delivered.
|
|
5669
|
-
Mentions use handles: @<username> for users, @<username>/<agent-name> for agents
|
|
5670
|
-
|
|
5671
|
-
## CRITICAL: Delegate When You Cannot Help Directly
|
|
6367
|
+
Mentions use handles: @<username> for users, @<username>/<agent-name> for agents.`;
|
|
6368
|
+
var MULTI_AGENT_RULES_SECTION = `## CRITICAL: Delegate When You Cannot Help Directly
|
|
5672
6369
|
|
|
5673
6370
|
You have NO internet access and NO real-time data. When asked about weather, news, stock prices,
|
|
5674
6371
|
or any current information you cannot answer directly:
|
|
@@ -5694,14 +6391,12 @@ Only remove agents if the user explicitly requests it.
|
|
|
5694
6391
|
When someone asks you to get information from another agent:
|
|
5695
6392
|
1. Ask the other agent for the information
|
|
5696
6393
|
2. When you receive the response, IMMEDIATELY relay it back to the ORIGINAL REQUESTER
|
|
5697
|
-
3. Do NOT just thank the helper agent - the requester is waiting for their answer
|
|
5698
|
-
|
|
5699
|
-
## IMPORTANT: Always Share Your Thinking
|
|
6394
|
+
3. Do NOT just thank the helper agent - the requester is waiting for their answer!`;
|
|
6395
|
+
var THINKING_SECTION = `## IMPORTANT: Always Share Your Thinking
|
|
5700
6396
|
|
|
5701
6397
|
You MUST call \`thenvoi_send_event(content, message_type="thought")\` BEFORE every action.
|
|
5702
|
-
This is required so users can see your reasoning process
|
|
5703
|
-
|
|
5704
|
-
## Examples
|
|
6398
|
+
This is required so users can see your reasoning process.`;
|
|
6399
|
+
var EXAMPLES_SECTION = `## Examples
|
|
5705
6400
|
|
|
5706
6401
|
### Simple question - answer directly
|
|
5707
6402
|
[John Doe]: What's 2+2?
|
|
@@ -5734,8 +6429,75 @@ This is required so users can see your reasoning process.
|
|
|
5734
6429
|
|
|
5735
6430
|
[Weather Agent]: London is 8\xB0C and rainy.
|
|
5736
6431
|
-> thenvoi_send_event("Got London weather. Relaying to John Doe.", message_type="thought")
|
|
5737
|
-
-> thenvoi_send_message("London is 8\xB0C and rainy.", mentions=["@john"])
|
|
5738
|
-
|
|
6432
|
+
-> thenvoi_send_message("London is 8\xB0C and rainy.", mentions=["@john"])`;
|
|
6433
|
+
var BASE_INSTRUCTIONS = [
|
|
6434
|
+
ENVIRONMENT_SECTION,
|
|
6435
|
+
MULTI_AGENT_RULES_SECTION,
|
|
6436
|
+
THINKING_SECTION,
|
|
6437
|
+
EXAMPLES_SECTION
|
|
6438
|
+
].join("\n\n") + "\n";
|
|
6439
|
+
|
|
6440
|
+
// src/runtime/prompts/memory.ts
|
|
6441
|
+
init_memory();
|
|
6442
|
+
init_schemas();
|
|
6443
|
+
var MEMORY_INTRO = `## Memory Tools
|
|
6444
|
+
|
|
6445
|
+
You have access to memory tools for storing and retrieving information
|
|
6446
|
+
across conversations. Use \`thenvoi_store_memory\` to persist important
|
|
6447
|
+
information and \`thenvoi_list_memories\` / \`thenvoi_get_memory\` to recall it.
|
|
6448
|
+
Use \`thenvoi_supersede_memory\` to mark outdated memories and
|
|
6449
|
+
\`thenvoi_archive_memory\` to hide memories that should be preserved.`;
|
|
6450
|
+
function longTermPattern(label, type, segment, scope) {
|
|
6451
|
+
return {
|
|
6452
|
+
label,
|
|
6453
|
+
system: MEMORY_SYSTEM.long_term,
|
|
6454
|
+
type,
|
|
6455
|
+
segment,
|
|
6456
|
+
scope
|
|
6457
|
+
};
|
|
6458
|
+
}
|
|
6459
|
+
var COMMON_MEMORY_PATTERNS = [
|
|
6460
|
+
longTermPattern("Facts learned about a specific agent/entity", MEMORY_TYPE.semantic, MEMORY_SEGMENT.agent, MEMORY_STORE_SCOPE.subject),
|
|
6461
|
+
longTermPattern("Events involving a specific person/agent", MEMORY_TYPE.episodic, MEMORY_SEGMENT.agent, MEMORY_STORE_SCOPE.subject),
|
|
6462
|
+
longTermPattern("A user's preferences or profile info", MEMORY_TYPE.semantic, MEMORY_SEGMENT.user, MEMORY_STORE_SCOPE.subject),
|
|
6463
|
+
longTermPattern("Org-wide knowledge or how to perform a task", MEMORY_TYPE.procedural, MEMORY_SEGMENT.tool, MEMORY_STORE_SCOPE.organization)
|
|
6464
|
+
];
|
|
6465
|
+
function renderMemoryPattern(pattern) {
|
|
6466
|
+
return `- ${pattern.label}: \`system="${pattern.system}"\`, \`type="${pattern.type}"\`, \`segment="${pattern.segment}"\`, \`scope="${pattern.scope}"\``;
|
|
6467
|
+
}
|
|
6468
|
+
var MEMORY_COMMON_PATTERNS = [
|
|
6469
|
+
"Common patterns:",
|
|
6470
|
+
...COMMON_MEMORY_PATTERNS.map(renderMemoryPattern)
|
|
6471
|
+
].join("\n");
|
|
6472
|
+
var MEMORY_SCOPE_GUIDANCE = `Prefer \`scope="${MEMORY_STORE_SCOPE.subject}"\` whenever the memory is about a specific person or agent, so it
|
|
6473
|
+
stays attached to that subject rather than leaking org-wide. Storing with \`scope="${MEMORY_STORE_SCOPE.subject}"\` requires a
|
|
6474
|
+
real \`subject_id\` UUID, so resolve it first via \`thenvoi_lookup_peers\` or the participant list.
|
|
6475
|
+
Reserve \`scope="${MEMORY_STORE_SCOPE.organization}"\` for knowledge that is genuinely shared across the whole organization and
|
|
6476
|
+
is not about any one subject.`;
|
|
6477
|
+
function quoteChoices(values) {
|
|
6478
|
+
return values.map((value) => `\`"${value}"\``).join(" | ");
|
|
6479
|
+
}
|
|
6480
|
+
function memoryTypeLines() {
|
|
6481
|
+
return Object.entries(MEMORY_SYSTEM_TYPES).map(([system, types]) => ` - ${system}: ${quoteChoices(types)}`).join("\n");
|
|
6482
|
+
}
|
|
6483
|
+
function buildMemorySection() {
|
|
6484
|
+
const storeMemoryProps = TOOL_MODELS.thenvoi_store_memory.properties;
|
|
6485
|
+
const systems = storeMemoryProps.system.enum;
|
|
6486
|
+
const segments = storeMemoryProps.segment.enum;
|
|
6487
|
+
const scopes = storeMemoryProps.scope.enum;
|
|
6488
|
+
const fieldRules = `When calling \`thenvoi_store_memory\`, the \`system\`, \`type\`, \`segment\`, and \`scope\` fields
|
|
6489
|
+
must use these exact values (case-sensitive):
|
|
6490
|
+
|
|
6491
|
+
- **system**: ${quoteChoices(systems)}
|
|
6492
|
+
- **type** (must match the chosen system):
|
|
6493
|
+
${memoryTypeLines()}
|
|
6494
|
+
- **segment**: ${quoteChoices(segments)}
|
|
6495
|
+
- **scope**: ${quoteChoices(scopes)}`;
|
|
6496
|
+
return [MEMORY_INTRO, fieldRules, MEMORY_COMMON_PATTERNS, MEMORY_SCOPE_GUIDANCE].join("\n\n");
|
|
6497
|
+
}
|
|
6498
|
+
var MEMORY_SECTION = buildMemorySection();
|
|
6499
|
+
|
|
6500
|
+
// src/runtime/prompts/templates.ts
|
|
5739
6501
|
var TEMPLATES = {
|
|
5740
6502
|
default: `You are {agent_name}, {agent_description}.
|
|
5741
6503
|
|
|
@@ -5754,11 +6516,17 @@ ${customSection}`.trim();
|
|
|
5754
6516
|
}
|
|
5755
6517
|
const template = options?.template ?? "default";
|
|
5756
6518
|
const templateString = TEMPLATES[template] ?? TEMPLATES.default;
|
|
5757
|
-
|
|
6519
|
+
const parts = [
|
|
6520
|
+
templateString.replaceAll("{agent_name}", agentName).replaceAll("{agent_description}", agentDescription).replaceAll("{custom_section}", customSection)
|
|
6521
|
+
];
|
|
6522
|
+
if (options?.capabilities?.memory) {
|
|
6523
|
+
parts.push(MEMORY_SECTION);
|
|
6524
|
+
}
|
|
6525
|
+
return parts.join("\n\n");
|
|
5758
6526
|
}
|
|
5759
6527
|
|
|
5760
6528
|
// src/runtime/tools/customTools.ts
|
|
5761
|
-
var
|
|
6529
|
+
var import_zod3 = require("zod");
|
|
5762
6530
|
var import_zod_to_json_schema = require("zod-to-json-schema");
|
|
5763
6531
|
var CustomToolDefinitionError = class extends Error {
|
|
5764
6532
|
constructor(message) {
|
|
@@ -6453,7 +7221,8 @@ var CodexAdapter = class extends SimpleAdapter {
|
|
|
6453
7221
|
agentName: this.agentName,
|
|
6454
7222
|
agentDescription: this.agentDescription,
|
|
6455
7223
|
customSection,
|
|
6456
|
-
includeBaseInstructions: this.baseConfig.includeBaseInstructions ?? true
|
|
7224
|
+
includeBaseInstructions: this.baseConfig.includeBaseInstructions ?? true,
|
|
7225
|
+
capabilities: { memory: this.includeMemoryTools }
|
|
6457
7226
|
}).trim();
|
|
6458
7227
|
this.systemPrompt = prompt.length > 0 ? prompt : null;
|
|
6459
7228
|
}
|
|
@@ -8576,7 +9345,8 @@ var GoogleADKAdapter = class extends SimpleAdapter {
|
|
|
8576
9345
|
this.systemPrompt = this.systemPromptOverride ?? renderSystemPrompt({
|
|
8577
9346
|
agentName,
|
|
8578
9347
|
agentDescription,
|
|
8579
|
-
customSection: this.customSection
|
|
9348
|
+
customSection: this.customSection,
|
|
9349
|
+
capabilities: { memory: this.enableMemoryTools }
|
|
8580
9350
|
});
|
|
8581
9351
|
}
|
|
8582
9352
|
async onMessage(message, tools, history, participantsMessage, contactsMessage, context) {
|
|
@@ -8816,7 +9586,8 @@ var LangGraphAdapter = class extends SimpleAdapter {
|
|
|
8816
9586
|
this.renderedSystemPrompt = this.systemPromptOverride ?? renderSystemPrompt({
|
|
8817
9587
|
agentName,
|
|
8818
9588
|
agentDescription,
|
|
8819
|
-
customSection: this.customSection
|
|
9589
|
+
customSection: this.customSection,
|
|
9590
|
+
capabilities: { memory: this.includeMemoryTools }
|
|
8820
9591
|
});
|
|
8821
9592
|
}
|
|
8822
9593
|
async onMessage(message, tools, history, participantsMessage, contactsMessage, context) {
|
|
@@ -8835,14 +9606,17 @@ var LangGraphAdapter = class extends SimpleAdapter {
|
|
|
8835
9606
|
];
|
|
8836
9607
|
}
|
|
8837
9608
|
const graph = await this.resolveGraph(sdk, langGraphTools);
|
|
8838
|
-
const
|
|
8839
|
-
|
|
8840
|
-
|
|
8841
|
-
|
|
8842
|
-
|
|
8843
|
-
context.
|
|
8844
|
-
|
|
8845
|
-
|
|
9609
|
+
const usesCheckpointer = Boolean(this.checkpointer);
|
|
9610
|
+
const isFirstBootstrap = context.isSessionBootstrap && !this.bootstrappedRooms.has(context.roomId);
|
|
9611
|
+
const replayHistory = !usesCheckpointer || isFirstBootstrap;
|
|
9612
|
+
const includeSystemPrompt = this.usesCustomGraph && (!usesCheckpointer || isFirstBootstrap);
|
|
9613
|
+
if (context.isSessionBootstrap) {
|
|
9614
|
+
this.bootstrappedRooms.add(context.roomId);
|
|
9615
|
+
}
|
|
9616
|
+
const messages = this.buildMessages(history, message, participantsMessage, contactsMessage, {
|
|
9617
|
+
replayHistory,
|
|
9618
|
+
includeSystemPrompt
|
|
9619
|
+
});
|
|
8846
9620
|
const input = { messages };
|
|
8847
9621
|
const graphConfig = {
|
|
8848
9622
|
configurable: {
|
|
@@ -8869,6 +9643,10 @@ var LangGraphAdapter = class extends SimpleAdapter {
|
|
|
8869
9643
|
async onCleanup(roomId) {
|
|
8870
9644
|
this.bootstrappedRooms.delete(roomId);
|
|
8871
9645
|
}
|
|
9646
|
+
/** A caller-supplied graph rather than the built-in createReactAgent. */
|
|
9647
|
+
get usesCustomGraph() {
|
|
9648
|
+
return Boolean(this.graph || this.graphFactory);
|
|
9649
|
+
}
|
|
8872
9650
|
resolveGraph(sdk, langGraphTools) {
|
|
8873
9651
|
if (this.graphFactory) {
|
|
8874
9652
|
return Promise.resolve(this.graphFactory(langGraphTools));
|
|
@@ -8889,14 +9667,13 @@ var LangGraphAdapter = class extends SimpleAdapter {
|
|
|
8889
9667
|
prompt: this.renderedSystemPrompt
|
|
8890
9668
|
}));
|
|
8891
9669
|
}
|
|
8892
|
-
buildMessages(history, message, participantsMessage, contactsMessage,
|
|
9670
|
+
buildMessages(history, message, participantsMessage, contactsMessage, options) {
|
|
8893
9671
|
const messages = [];
|
|
8894
|
-
if (
|
|
9672
|
+
if (options.includeSystemPrompt) {
|
|
8895
9673
|
messages.push(["system", this.renderedSystemPrompt]);
|
|
8896
|
-
this.bootstrappedRooms.add(roomId);
|
|
8897
9674
|
}
|
|
8898
|
-
if (
|
|
8899
|
-
const historical = history.raw.slice(-this.maxHistoryMessages);
|
|
9675
|
+
if (options.replayHistory && history.length > 0) {
|
|
9676
|
+
const historical = history.raw.filter((item) => item.id !== message.id).slice(-this.maxHistoryMessages);
|
|
8900
9677
|
for (const item of historical) {
|
|
8901
9678
|
const role = String(item.sender_type ?? "") === "Agent" ? "assistant" : "user";
|
|
8902
9679
|
const content = String(item.content ?? "");
|
|
@@ -8915,7 +9692,7 @@ var LangGraphAdapter = class extends SimpleAdapter {
|
|
|
8915
9692
|
return messages;
|
|
8916
9693
|
}
|
|
8917
9694
|
async forwardStreamEvents(graph, input, config, tools) {
|
|
8918
|
-
const stream = graph.streamEvents?.(input, config,
|
|
9695
|
+
const stream = graph.streamEvents?.(input, { ...config, version: "v2" });
|
|
8919
9696
|
if (!stream) {
|
|
8920
9697
|
return null;
|
|
8921
9698
|
}
|
|
@@ -8942,6 +9719,10 @@ var LangGraphAdapter = class extends SimpleAdapter {
|
|
|
8942
9719
|
);
|
|
8943
9720
|
}
|
|
8944
9721
|
if (eventType === "on_chain_end") {
|
|
9722
|
+
const chainName = String(data.name ?? "");
|
|
9723
|
+
if (!this.usesCustomGraph && chainName !== "LangGraph" && chainName !== "agent") {
|
|
9724
|
+
continue;
|
|
9725
|
+
}
|
|
8945
9726
|
const output = asOptionalRecord(data.data) ?? {};
|
|
8946
9727
|
const text = extractAssistantText(output.output);
|
|
8947
9728
|
if (text) {
|
|
@@ -9003,18 +9784,25 @@ function stringifyToolResult2(value, logger, toolName) {
|
|
|
9003
9784
|
});
|
|
9004
9785
|
}
|
|
9005
9786
|
function extractAssistantText(result) {
|
|
9006
|
-
if (typeof result === "string"
|
|
9007
|
-
|
|
9787
|
+
if (typeof result === "string") {
|
|
9788
|
+
const trimmed = result.trim();
|
|
9789
|
+
return trimmed.length > 0 && !isInternalLangGraphMarker(trimmed) ? trimmed : null;
|
|
9008
9790
|
}
|
|
9009
9791
|
const record = asOptionalRecord(result) ?? {};
|
|
9792
|
+
if (isLangChainAssistantMessage(record)) {
|
|
9793
|
+
const text = asLangChainMessageContent(record);
|
|
9794
|
+
if (text && !isInternalLangGraphMarker(text)) {
|
|
9795
|
+
return text;
|
|
9796
|
+
}
|
|
9797
|
+
}
|
|
9010
9798
|
const directContent = asMessageContent(record.content);
|
|
9011
|
-
if (directContent) {
|
|
9799
|
+
if (directContent && !isInternalLangGraphMarker(directContent)) {
|
|
9012
9800
|
return directContent;
|
|
9013
9801
|
}
|
|
9014
9802
|
const messages = Array.isArray(record.messages) ? record.messages : [];
|
|
9015
9803
|
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
9016
9804
|
const text = asMessageText(messages[index]);
|
|
9017
|
-
if (text) {
|
|
9805
|
+
if (text && !isInternalLangGraphMarker(text)) {
|
|
9018
9806
|
return text;
|
|
9019
9807
|
}
|
|
9020
9808
|
}
|
|
@@ -9031,12 +9819,40 @@ function asMessageText(value) {
|
|
|
9031
9819
|
if (!record) {
|
|
9032
9820
|
return null;
|
|
9033
9821
|
}
|
|
9822
|
+
if (isLangChainAssistantMessage(record)) {
|
|
9823
|
+
return asLangChainMessageContent(record);
|
|
9824
|
+
}
|
|
9034
9825
|
const role = String(record.role ?? "");
|
|
9035
9826
|
if (role !== "assistant") {
|
|
9036
9827
|
return null;
|
|
9037
9828
|
}
|
|
9038
9829
|
return asMessageContent(record.content);
|
|
9039
9830
|
}
|
|
9831
|
+
function isLangChainAssistantMessage(record) {
|
|
9832
|
+
const id = record.id;
|
|
9833
|
+
if (Array.isArray(id)) {
|
|
9834
|
+
const typeName = String(id[id.length - 1] ?? "");
|
|
9835
|
+
if (typeName === "AIMessage" || typeName === "AIMessageChunk") {
|
|
9836
|
+
return true;
|
|
9837
|
+
}
|
|
9838
|
+
}
|
|
9839
|
+
const getType = record.getType;
|
|
9840
|
+
if (typeof getType === "function") {
|
|
9841
|
+
try {
|
|
9842
|
+
return getType.call(record) === "ai";
|
|
9843
|
+
} catch {
|
|
9844
|
+
return false;
|
|
9845
|
+
}
|
|
9846
|
+
}
|
|
9847
|
+
return false;
|
|
9848
|
+
}
|
|
9849
|
+
function asLangChainMessageContent(record) {
|
|
9850
|
+
const kwargs = asOptionalRecord(record.kwargs);
|
|
9851
|
+
return asMessageContent(kwargs?.content ?? record.content);
|
|
9852
|
+
}
|
|
9853
|
+
function isInternalLangGraphMarker(text) {
|
|
9854
|
+
return text === "__end__" || text === "__start__";
|
|
9855
|
+
}
|
|
9040
9856
|
function asMessageContent(value) {
|
|
9041
9857
|
if (typeof value === "string" && value.trim().length > 0) {
|
|
9042
9858
|
return value.trim();
|
|
@@ -11956,12 +12772,12 @@ var ThenvoiMcpStdioServer = class {
|
|
|
11956
12772
|
}
|
|
11957
12773
|
const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
11958
12774
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
11959
|
-
const { z:
|
|
12775
|
+
const { z: z6 } = await import("zod");
|
|
11960
12776
|
const mcpServer = new McpServer({
|
|
11961
12777
|
name: this.options.name ?? "thenvoi",
|
|
11962
12778
|
version: "1.0.0"
|
|
11963
12779
|
});
|
|
11964
|
-
registerTools(mcpServer,
|
|
12780
|
+
registerTools(mcpServer, z6, this.registrations);
|
|
11965
12781
|
const transport = new StdioServerTransport(this.options.stdin, this.options.stdout);
|
|
11966
12782
|
await mcpServer.connect(transport);
|
|
11967
12783
|
this.mcpServer = mcpServer;
|
|
@@ -11973,14 +12789,14 @@ var ThenvoiMcpStdioServer = class {
|
|
|
11973
12789
|
this.mcpServer = null;
|
|
11974
12790
|
}
|
|
11975
12791
|
};
|
|
11976
|
-
function registerTools(mcpServer,
|
|
12792
|
+
function registerTools(mcpServer, z6, registrations) {
|
|
11977
12793
|
for (const reg of registrations) {
|
|
11978
|
-
const zodShape = buildZodShape(
|
|
12794
|
+
const zodShape = buildZodShape(z6, reg.inputSchema.properties, new Set(reg.inputSchema.required));
|
|
11979
12795
|
mcpServer.registerTool(
|
|
11980
12796
|
reg.name,
|
|
11981
12797
|
{
|
|
11982
12798
|
description: reg.description,
|
|
11983
|
-
inputSchema:
|
|
12799
|
+
inputSchema: z6.object(zodShape)
|
|
11984
12800
|
},
|
|
11985
12801
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK handler signature is complex; our McpToolResult is compatible
|
|
11986
12802
|
async (args) => reg.execute(args)
|
|
@@ -12039,7 +12855,7 @@ var ThenvoiMcpServer = class {
|
|
|
12039
12855
|
const express = expressModule.default ?? expressModule;
|
|
12040
12856
|
const http = await import("http");
|
|
12041
12857
|
const { randomUUID: randomUUID6 } = await import("crypto");
|
|
12042
|
-
const { z:
|
|
12858
|
+
const { z: z6 } = await import("zod");
|
|
12043
12859
|
const serverName = this.options.name ?? "thenvoi";
|
|
12044
12860
|
const app = express();
|
|
12045
12861
|
app.use(express.json());
|
|
@@ -12060,7 +12876,7 @@ var ThenvoiMcpServer = class {
|
|
|
12060
12876
|
StreamableHTTPServerTransport,
|
|
12061
12877
|
serverName,
|
|
12062
12878
|
sessionIdGenerator: randomUUID6,
|
|
12063
|
-
z:
|
|
12879
|
+
z: z6
|
|
12064
12880
|
});
|
|
12065
12881
|
}
|
|
12066
12882
|
session.lastSeenAt = Date.now();
|
|
@@ -12186,14 +13002,14 @@ function sendMcpError(res, status, message) {
|
|
|
12186
13002
|
id: null
|
|
12187
13003
|
});
|
|
12188
13004
|
}
|
|
12189
|
-
function registerTools2(mcpServer,
|
|
13005
|
+
function registerTools2(mcpServer, z6, registrations) {
|
|
12190
13006
|
for (const reg of registrations) {
|
|
12191
|
-
const zodShape = buildZodShape(
|
|
13007
|
+
const zodShape = buildZodShape(z6, reg.inputSchema.properties, new Set(reg.inputSchema.required));
|
|
12192
13008
|
mcpServer.registerTool(
|
|
12193
13009
|
reg.name,
|
|
12194
13010
|
{
|
|
12195
13011
|
description: reg.description,
|
|
12196
|
-
inputSchema:
|
|
13012
|
+
inputSchema: z6.object(zodShape)
|
|
12197
13013
|
},
|
|
12198
13014
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK handler signature is complex; our McpToolResult is compatible
|
|
12199
13015
|
async (args) => reg.execute(args)
|
|
@@ -12268,7 +13084,7 @@ var ThenvoiMcpSseServer = class {
|
|
|
12268
13084
|
const expressModule = await import("express");
|
|
12269
13085
|
const express = expressModule.default ?? expressModule;
|
|
12270
13086
|
const http = await import("http");
|
|
12271
|
-
const { z:
|
|
13087
|
+
const { z: z6 } = await import("zod");
|
|
12272
13088
|
const app = express();
|
|
12273
13089
|
app.use(express.json());
|
|
12274
13090
|
app.get("/healthz", (_req, res) => {
|
|
@@ -12280,7 +13096,7 @@ var ThenvoiMcpSseServer = class {
|
|
|
12280
13096
|
name: this.options.name ?? "thenvoi",
|
|
12281
13097
|
version: "1.0.0"
|
|
12282
13098
|
});
|
|
12283
|
-
registerTools3(mcpServer,
|
|
13099
|
+
registerTools3(mcpServer, z6, this.registrations);
|
|
12284
13100
|
await mcpServer.connect(transport);
|
|
12285
13101
|
const sessionId = transport.sessionId;
|
|
12286
13102
|
this.sessions.set(sessionId, {
|
|
@@ -12372,10 +13188,10 @@ var ThenvoiMcpSseServer = class {
|
|
|
12372
13188
|
}
|
|
12373
13189
|
}
|
|
12374
13190
|
};
|
|
12375
|
-
function registerTools3(mcpServer,
|
|
13191
|
+
function registerTools3(mcpServer, z6, registrations) {
|
|
12376
13192
|
for (const registration of registrations) {
|
|
12377
13193
|
const zodShape = buildZodShape(
|
|
12378
|
-
|
|
13194
|
+
z6,
|
|
12379
13195
|
registration.inputSchema.properties,
|
|
12380
13196
|
new Set(registration.inputSchema.required)
|
|
12381
13197
|
);
|
|
@@ -12383,7 +13199,7 @@ function registerTools3(mcpServer, z5, registrations) {
|
|
|
12383
13199
|
registration.name,
|
|
12384
13200
|
{
|
|
12385
13201
|
description: registration.description,
|
|
12386
|
-
inputSchema:
|
|
13202
|
+
inputSchema: z6.object(zodShape)
|
|
12387
13203
|
},
|
|
12388
13204
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- MCP SDK handler signature is complex; our McpToolResult is compatible
|
|
12389
13205
|
async (args) => registration.execute(args)
|
|
@@ -12413,20 +13229,17 @@ function checkPort2(http, port) {
|
|
|
12413
13229
|
|
|
12414
13230
|
// src/mcp/backends.ts
|
|
12415
13231
|
async function createThenvoiMcpBackend(options) {
|
|
12416
|
-
const
|
|
12417
|
-
options.
|
|
12418
|
-
|
|
12419
|
-
|
|
12420
|
-
|
|
12421
|
-
additionalTools: options.additionalTools
|
|
12422
|
-
}
|
|
12423
|
-
);
|
|
12424
|
-
const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
|
|
13232
|
+
const registrationOptions = {
|
|
13233
|
+
enableMemoryTools: options.enableMemoryTools,
|
|
13234
|
+
enableContactTools: true,
|
|
13235
|
+
additionalTools: options.additionalTools
|
|
13236
|
+
};
|
|
12425
13237
|
if (options.kind === "sdk") {
|
|
12426
13238
|
const { createThenvoiSdkMcpServer: createThenvoiSdkMcpServer2 } = await Promise.resolve().then(() => (init_sdk(), sdk_exports));
|
|
12427
13239
|
const server2 = createThenvoiSdkMcpServer2({
|
|
12428
|
-
enableMemoryTools: options.enableMemoryTools,
|
|
12429
13240
|
getToolsForRoom: options.getToolsForRoom,
|
|
13241
|
+
multiRoom: options.multiRoom,
|
|
13242
|
+
enableMemoryTools: options.enableMemoryTools,
|
|
12430
13243
|
additionalTools: options.additionalTools
|
|
12431
13244
|
});
|
|
12432
13245
|
return {
|
|
@@ -12436,9 +13249,12 @@ async function createThenvoiMcpBackend(options) {
|
|
|
12436
13249
|
stop: async () => void 0
|
|
12437
13250
|
};
|
|
12438
13251
|
}
|
|
13252
|
+
const resolvedTools = options.multiRoom === false ? resolveSingleRoomTools(options.getToolsForRoom) : options.getToolsForRoom;
|
|
13253
|
+
const registrations = options.multiRoom === false ? buildSingleContextRegistrations(resolvedTools, registrationOptions) : buildRoomScopedRegistrations(resolvedTools, registrationOptions);
|
|
13254
|
+
const allowedTools = mcpToolNames(new Set(registrations.map((registration) => registration.name)));
|
|
12439
13255
|
if (options.kind === "stdio") {
|
|
12440
13256
|
const server2 = new ThenvoiMcpStdioServer({
|
|
12441
|
-
tools:
|
|
13257
|
+
tools: resolvedTools,
|
|
12442
13258
|
enableMemoryTools: options.enableMemoryTools,
|
|
12443
13259
|
enableContactTools: true,
|
|
12444
13260
|
additionalTools: options.additionalTools
|
|
@@ -12455,7 +13271,7 @@ async function createThenvoiMcpBackend(options) {
|
|
|
12455
13271
|
}
|
|
12456
13272
|
if (options.kind === "sse") {
|
|
12457
13273
|
const server2 = new ThenvoiMcpSseServer({
|
|
12458
|
-
tools:
|
|
13274
|
+
tools: resolvedTools,
|
|
12459
13275
|
enableMemoryTools: options.enableMemoryTools,
|
|
12460
13276
|
enableContactTools: true,
|
|
12461
13277
|
additionalTools: options.additionalTools
|
|
@@ -12471,7 +13287,7 @@ async function createThenvoiMcpBackend(options) {
|
|
|
12471
13287
|
};
|
|
12472
13288
|
}
|
|
12473
13289
|
const server = new ThenvoiMcpServer({
|
|
12474
|
-
tools:
|
|
13290
|
+
tools: resolvedTools,
|
|
12475
13291
|
enableMemoryTools: options.enableMemoryTools,
|
|
12476
13292
|
enableContactTools: true,
|
|
12477
13293
|
additionalTools: options.additionalTools
|
|
@@ -12710,7 +13526,7 @@ var SdkOpencodeClientBase = class {
|
|
|
12710
13526
|
}
|
|
12711
13527
|
const response = await fetch(url, { method: "DELETE" });
|
|
12712
13528
|
if (!response.ok && response.status !== 404) {
|
|
12713
|
-
throw new HttpStatusError(response.status, await
|
|
13529
|
+
throw new HttpStatusError(response.status, await readResponseBody2(response));
|
|
12714
13530
|
}
|
|
12715
13531
|
}
|
|
12716
13532
|
};
|
|
@@ -12799,7 +13615,7 @@ async function findAvailablePort3() {
|
|
|
12799
13615
|
});
|
|
12800
13616
|
});
|
|
12801
13617
|
}
|
|
12802
|
-
async function
|
|
13618
|
+
async function readResponseBody2(response) {
|
|
12803
13619
|
const contentType = response.headers.get("content-type") ?? "";
|
|
12804
13620
|
if (contentType.includes("application/json")) {
|
|
12805
13621
|
try {
|
|
@@ -12911,7 +13727,8 @@ var OpencodeAdapter = class extends SimpleAdapter {
|
|
|
12911
13727
|
agentName,
|
|
12912
13728
|
agentDescription,
|
|
12913
13729
|
customSection: this.config.customSection,
|
|
12914
|
-
includeBaseInstructions: this.config.includeBaseInstructions
|
|
13730
|
+
includeBaseInstructions: this.config.includeBaseInstructions,
|
|
13731
|
+
capabilities: { memory: this.config.enableMemoryTools }
|
|
12915
13732
|
}).trim();
|
|
12916
13733
|
this.systemPrompt = `${systemPrompt}
|
|
12917
13734
|
|
|
@@ -13691,7 +14508,7 @@ function extractClaudeSessionId(raw) {
|
|
|
13691
14508
|
// src/adapters/claude-sdk/ClaudeSDKAdapter.ts
|
|
13692
14509
|
init_registrations();
|
|
13693
14510
|
init_zod();
|
|
13694
|
-
var
|
|
14511
|
+
var import_zod10 = require("zod");
|
|
13695
14512
|
var DEFAULT_MODEL2 = "claude-sonnet-4-6";
|
|
13696
14513
|
var thenvoiMcpBridgeFactory = new LazyAsyncValue({
|
|
13697
14514
|
load: async () => {
|
|
@@ -13718,7 +14535,7 @@ var thenvoiMcpBridgeFactory = new LazyAsyncValue({
|
|
|
13718
14535
|
);
|
|
13719
14536
|
const toolDefinitions = registrations.map((registration) => {
|
|
13720
14537
|
const shape = buildZodShape(
|
|
13721
|
-
|
|
14538
|
+
import_zod10.z,
|
|
13722
14539
|
registration.inputSchema.properties,
|
|
13723
14540
|
new Set(registration.inputSchema.required)
|
|
13724
14541
|
);
|
|
@@ -13778,7 +14595,8 @@ var ClaudeSDKAdapter = class extends SimpleAdapter {
|
|
|
13778
14595
|
agentName,
|
|
13779
14596
|
agentDescription,
|
|
13780
14597
|
customSection: this.customSection,
|
|
13781
|
-
includeBaseInstructions: this.includeBaseInstructions
|
|
14598
|
+
includeBaseInstructions: this.includeBaseInstructions,
|
|
14599
|
+
capabilities: { memory: this.enableMemoryTools }
|
|
13782
14600
|
});
|
|
13783
14601
|
if (this.enableMcpTools) {
|
|
13784
14602
|
const createThenvoiMcpBridge = await thenvoiMcpBridgeFactory.get();
|
|
@@ -13953,6 +14771,8 @@ init_schemas();
|
|
|
13953
14771
|
TOOL_MODELS,
|
|
13954
14772
|
ThenvoiLink,
|
|
13955
14773
|
VercelAISDKAdapter,
|
|
14774
|
+
WebSocketDisconnectError,
|
|
14775
|
+
deriveDefaultRestUrl,
|
|
13956
14776
|
isDirectExecution,
|
|
13957
14777
|
loadAgentConfig,
|
|
13958
14778
|
loadAgentConfigFromEnv
|