@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
|
@@ -4,15 +4,37 @@ import {
|
|
|
4
4
|
SYNTHETIC_CONTACT_EVENTS_SENDER_NAME,
|
|
5
5
|
SYNTHETIC_SENDER_TYPE,
|
|
6
6
|
buildParticipantsMessage
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RDM4TE4B.js";
|
|
8
8
|
import {
|
|
9
9
|
CHAT_EVENT_TYPES,
|
|
10
10
|
CHAT_TOOL_NAMES,
|
|
11
|
+
MEMORY_LIST_SCOPES,
|
|
12
|
+
MEMORY_SEGMENTS,
|
|
13
|
+
MEMORY_STATUSES,
|
|
14
|
+
MEMORY_STORE_SCOPES,
|
|
15
|
+
MEMORY_SYSTEMS,
|
|
11
16
|
MEMORY_TOOL_NAMES,
|
|
17
|
+
MEMORY_TYPES,
|
|
12
18
|
TOOL_MODELS,
|
|
13
19
|
assertChatEventType,
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
expectedList,
|
|
21
|
+
expectedMemoryTypesForSystem,
|
|
22
|
+
getToolDescription,
|
|
23
|
+
isMemoryListScope,
|
|
24
|
+
isMemorySegment,
|
|
25
|
+
isMemoryStatus,
|
|
26
|
+
isMemoryStoreScope,
|
|
27
|
+
isMemorySystem,
|
|
28
|
+
isMemoryType,
|
|
29
|
+
isMemoryTypeForSystem,
|
|
30
|
+
memoryTypeForSystemError
|
|
31
|
+
} from "./chunk-MLROFDKR.js";
|
|
32
|
+
import {
|
|
33
|
+
WebSocketDisconnectError,
|
|
34
|
+
genericCloseReason,
|
|
35
|
+
parseSupersedeDisconnectReason,
|
|
36
|
+
parseUpgradeDisconnectReason
|
|
37
|
+
} from "./chunk-US226AS4.js";
|
|
16
38
|
import {
|
|
17
39
|
DEFAULT_REQUEST_OPTIONS,
|
|
18
40
|
FernRestAdapter,
|
|
@@ -143,55 +165,117 @@ var payloadSchemas = {
|
|
|
143
165
|
|
|
144
166
|
// src/platform/streaming/PhoenixChannelsTransport.ts
|
|
145
167
|
import { Socket } from "phoenix";
|
|
168
|
+
|
|
169
|
+
// src/platform/streaming/nodeWebSocketFactory.ts
|
|
146
170
|
import { WebSocket as NodeWebSocket } from "ws";
|
|
171
|
+
function createNodeWebSocketFactory(headers) {
|
|
172
|
+
const Constructor = NodeWebSocket;
|
|
173
|
+
class ThenvoiNodeWebSocket {
|
|
174
|
+
constructor(address, protocols) {
|
|
175
|
+
const socket = new Constructor(address, protocols, headers ? { headers } : void 0);
|
|
176
|
+
socket.once("unexpected-response", (request, response) => {
|
|
177
|
+
void emitUpgradeError(socket, request, response);
|
|
178
|
+
});
|
|
179
|
+
return socket;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return ThenvoiNodeWebSocket;
|
|
183
|
+
}
|
|
184
|
+
async function emitUpgradeError(websocket, request, response) {
|
|
185
|
+
const body = await readResponseBody(response);
|
|
186
|
+
const error = new Error(
|
|
187
|
+
`Unexpected server response: ${response.statusCode ?? "unknown"}`
|
|
188
|
+
);
|
|
189
|
+
error.status = response.statusCode;
|
|
190
|
+
error.body = body;
|
|
191
|
+
error.headers = response.headers;
|
|
192
|
+
request.destroy();
|
|
193
|
+
websocket.emit("error", error);
|
|
194
|
+
websocket.emit("close", 1006, Buffer.alloc(0));
|
|
195
|
+
}
|
|
196
|
+
async function readResponseBody(response) {
|
|
197
|
+
const chunks = [];
|
|
198
|
+
for await (const chunk of response) {
|
|
199
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
200
|
+
}
|
|
201
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/platform/streaming/PhoenixChannelsTransport.ts
|
|
147
205
|
var PhoenixChannelsTransport = class {
|
|
148
206
|
socket;
|
|
207
|
+
agentId;
|
|
149
208
|
channels = /* @__PURE__ */ new Map();
|
|
150
209
|
channelRefs = /* @__PURE__ */ new Map();
|
|
151
210
|
pendingJoins = /* @__PURE__ */ new Map();
|
|
152
211
|
logger;
|
|
212
|
+
onTerminalDisconnect;
|
|
153
213
|
onHandlerError;
|
|
154
214
|
connected = false;
|
|
155
215
|
connectPromise = null;
|
|
156
216
|
connectResolve = null;
|
|
217
|
+
connectReject = null;
|
|
218
|
+
lastDisconnectReason = null;
|
|
219
|
+
terminalDisconnectError = null;
|
|
220
|
+
runForeverWaiters = /* @__PURE__ */ new Set();
|
|
221
|
+
stoppingReconnect = false;
|
|
222
|
+
suppressNextCloseReason = false;
|
|
157
223
|
constructor(options) {
|
|
158
224
|
this.logger = options.logger ?? new NoopLogger();
|
|
225
|
+
this.agentId = options.agentId;
|
|
226
|
+
this.onTerminalDisconnect = options.onTerminalDisconnect;
|
|
159
227
|
let wsUrl = options.wsUrl;
|
|
160
228
|
if (wsUrl.endsWith("/websocket")) {
|
|
161
229
|
wsUrl = wsUrl.slice(0, -"/websocket".length);
|
|
162
230
|
}
|
|
231
|
+
const reconnectAfterMs = options.reconnectAfterMs ?? ((tries) => [1e3, 2e3, 5e3, 1e4, 3e4][tries - 1] ?? 3e4);
|
|
163
232
|
this.socket = new Socket(wsUrl, {
|
|
164
233
|
params: {
|
|
165
|
-
|
|
166
|
-
|
|
234
|
+
agent_id: options.agentId,
|
|
235
|
+
...options.conflictPolicy ? { on_conflict: options.conflictPolicy } : {}
|
|
167
236
|
},
|
|
168
237
|
heartbeatIntervalMs: options.heartbeatIntervalMs,
|
|
169
|
-
reconnectAfterMs:
|
|
170
|
-
|
|
238
|
+
reconnectAfterMs: (tries) => {
|
|
239
|
+
if (this.terminalDisconnectError) {
|
|
240
|
+
return Number.POSITIVE_INFINITY;
|
|
241
|
+
}
|
|
242
|
+
return reconnectAfterMs(tries);
|
|
243
|
+
},
|
|
244
|
+
transport: options.websocketFactory ?? resolveWebSocketFactory(options.apiKey)
|
|
171
245
|
});
|
|
172
246
|
this.socket.onOpen(() => {
|
|
173
|
-
this.
|
|
174
|
-
this.connectResolve?.();
|
|
175
|
-
this.connectResolve = null;
|
|
176
|
-
this.logger.info("Phoenix socket opened", {
|
|
177
|
-
channels: getSocketChannelCount(this.socket)
|
|
178
|
-
});
|
|
247
|
+
void this.handleOpen();
|
|
179
248
|
});
|
|
180
249
|
this.socket.onClose((event) => {
|
|
181
|
-
this.
|
|
182
|
-
if (getSocketChannelCount(this.socket) === 0) {
|
|
183
|
-
this.socket.disconnect();
|
|
184
|
-
}
|
|
185
|
-
this.logger.info("Phoenix socket closed", {
|
|
186
|
-
code: event?.code ?? null,
|
|
187
|
-
reason: event?.reason ?? null
|
|
188
|
-
});
|
|
250
|
+
this.recordSocketClose(event);
|
|
189
251
|
});
|
|
190
252
|
this.socket.onError((event) => {
|
|
253
|
+
const errorEvent = unwrapErrorEvent(event);
|
|
254
|
+
const upgradeReason = parseUpgradeDisconnectReason(errorEvent);
|
|
255
|
+
if (upgradeReason) {
|
|
256
|
+
if (upgradeReason.retryable) {
|
|
257
|
+
this.lastDisconnectReason = upgradeReason;
|
|
258
|
+
this.connectReject?.(new WebSocketDisconnectError(upgradeReason));
|
|
259
|
+
this.stopReconnectIfNoChannels({ suppressCloseReason: true });
|
|
260
|
+
} else {
|
|
261
|
+
this.recordTerminalDisconnect(upgradeReason);
|
|
262
|
+
}
|
|
263
|
+
this.logger.warn("Phoenix socket upgrade failed", {
|
|
264
|
+
reason: upgradeReason
|
|
265
|
+
});
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
this.connectReject?.(
|
|
269
|
+
new TransportError("Phoenix socket connection failed", errorEvent)
|
|
270
|
+
);
|
|
271
|
+
this.stopReconnectIfNoChannels({ suppressCloseReason: true });
|
|
191
272
|
this.logger.warn("Phoenix socket error", { event });
|
|
192
273
|
});
|
|
193
274
|
}
|
|
194
275
|
async connect() {
|
|
276
|
+
if (this.terminalDisconnectError) {
|
|
277
|
+
throw this.terminalDisconnectError;
|
|
278
|
+
}
|
|
195
279
|
if (this.connected) {
|
|
196
280
|
return;
|
|
197
281
|
}
|
|
@@ -215,15 +299,30 @@ var PhoenixChannelsTransport = class {
|
|
|
215
299
|
await this.connectPromise;
|
|
216
300
|
}
|
|
217
301
|
async disconnect() {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
302
|
+
const results = await Promise.allSettled(
|
|
303
|
+
[...this.channels.keys()].map((topic) => this.leave(topic))
|
|
304
|
+
);
|
|
221
305
|
this.socket.disconnect();
|
|
222
306
|
this.connected = false;
|
|
307
|
+
const failures = [];
|
|
308
|
+
for (const result of results) {
|
|
309
|
+
if (result.status === "rejected") {
|
|
310
|
+
failures.push(result.reason);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (failures.length > 0) {
|
|
314
|
+
throw new AggregateError(
|
|
315
|
+
failures,
|
|
316
|
+
"Failed to leave one or more Phoenix topics during disconnect"
|
|
317
|
+
);
|
|
318
|
+
}
|
|
223
319
|
}
|
|
224
320
|
isConnected() {
|
|
225
321
|
return this.connected;
|
|
226
322
|
}
|
|
323
|
+
getDisconnectReason() {
|
|
324
|
+
return this.lastDisconnectReason;
|
|
325
|
+
}
|
|
227
326
|
async join(topic, handlers) {
|
|
228
327
|
if (this.channels.has(topic)) {
|
|
229
328
|
return;
|
|
@@ -259,7 +358,10 @@ var PhoenixChannelsTransport = class {
|
|
|
259
358
|
channel.join().receive("ok", () => resolve()).receive(
|
|
260
359
|
"error",
|
|
261
360
|
(error) => reject(new TransportError(`Failed to join topic ${topic}`, error))
|
|
262
|
-
).receive(
|
|
361
|
+
).receive(
|
|
362
|
+
"timeout",
|
|
363
|
+
() => reject(new TransportError(`Timeout joining topic ${topic}`))
|
|
364
|
+
);
|
|
263
365
|
});
|
|
264
366
|
} catch (error) {
|
|
265
367
|
for (const [event, ref] of refs) {
|
|
@@ -287,19 +389,127 @@ var PhoenixChannelsTransport = class {
|
|
|
287
389
|
channel.leave().receive("ok", () => resolve()).receive(
|
|
288
390
|
"error",
|
|
289
391
|
(error) => reject(new TransportError(`Failed to leave topic ${topic}`, error))
|
|
290
|
-
).receive(
|
|
392
|
+
).receive(
|
|
393
|
+
"timeout",
|
|
394
|
+
() => reject(new TransportError(`Timeout leaving topic ${topic}`))
|
|
395
|
+
);
|
|
291
396
|
});
|
|
292
397
|
this.channels.delete(topic);
|
|
293
398
|
this.logger.debug("Left topic", { topic });
|
|
294
399
|
}
|
|
295
400
|
async runForever(signal) {
|
|
401
|
+
if (this.terminalDisconnectError) {
|
|
402
|
+
throw this.terminalDisconnectError;
|
|
403
|
+
}
|
|
296
404
|
if (signal.aborted) {
|
|
297
405
|
return;
|
|
298
406
|
}
|
|
299
|
-
await new Promise((resolve) => {
|
|
300
|
-
|
|
407
|
+
await new Promise((resolve, reject) => {
|
|
408
|
+
let settled = false;
|
|
409
|
+
const abortController = new AbortController();
|
|
410
|
+
const waiter = {
|
|
411
|
+
reject: (error) => {
|
|
412
|
+
if (settled) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
settled = true;
|
|
416
|
+
this.runForeverWaiters.delete(waiter);
|
|
417
|
+
abortController.abort();
|
|
418
|
+
reject(error);
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
this.runForeverWaiters.add(waiter);
|
|
422
|
+
signal.addEventListener(
|
|
423
|
+
"abort",
|
|
424
|
+
() => {
|
|
425
|
+
if (settled) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
settled = true;
|
|
429
|
+
this.runForeverWaiters.delete(waiter);
|
|
430
|
+
resolve();
|
|
431
|
+
},
|
|
432
|
+
{ once: true, signal: abortController.signal }
|
|
433
|
+
);
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
async handleOpen() {
|
|
437
|
+
try {
|
|
438
|
+
await this.subscribeAgentControl();
|
|
439
|
+
} catch (error) {
|
|
440
|
+
this.connected = false;
|
|
441
|
+
this.socket.disconnect();
|
|
442
|
+
this.connectReject?.(
|
|
443
|
+
error instanceof Error ? error : new TransportError(String(error))
|
|
444
|
+
);
|
|
445
|
+
this.logger.warn("Failed to join mandatory agent_control channel", {
|
|
446
|
+
error
|
|
447
|
+
});
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
this.connected = true;
|
|
451
|
+
this.connectResolve?.();
|
|
452
|
+
this.connectResolve = null;
|
|
453
|
+
this.connectReject = null;
|
|
454
|
+
this.logger.info("Phoenix socket opened", {
|
|
455
|
+
channels: getSocketChannelCount(this.socket)
|
|
301
456
|
});
|
|
302
457
|
}
|
|
458
|
+
stopReconnectIfNoChannels(options = {}) {
|
|
459
|
+
if (this.stoppingReconnect || getSocketChannelCount(this.socket) !== 0) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
this.suppressNextCloseReason = options.suppressCloseReason ?? false;
|
|
463
|
+
this.stoppingReconnect = true;
|
|
464
|
+
this.socket.disconnect();
|
|
465
|
+
this.stoppingReconnect = false;
|
|
466
|
+
}
|
|
467
|
+
async subscribeAgentControl() {
|
|
468
|
+
if (!this.agentId) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
await this.join(`agent_control:${this.agentId}`, {
|
|
472
|
+
supersede: (payload) => {
|
|
473
|
+
const reason = parseSupersedeDisconnectReason(payload);
|
|
474
|
+
if (!reason) {
|
|
475
|
+
this.logger.warn("Invalid agent_control supersede payload", {
|
|
476
|
+
payload
|
|
477
|
+
});
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
this.recordTerminalDisconnect(reason);
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
recordSocketClose(event) {
|
|
485
|
+
this.connected = false;
|
|
486
|
+
const suppressCloseReason = this.suppressNextCloseReason;
|
|
487
|
+
this.suppressNextCloseReason = false;
|
|
488
|
+
this.stopReconnectIfNoChannels();
|
|
489
|
+
if (!suppressCloseReason && !this.terminalDisconnectError && !this.lastDisconnectReason) {
|
|
490
|
+
this.lastDisconnectReason = genericCloseReason(event);
|
|
491
|
+
}
|
|
492
|
+
this.logger.info("Phoenix socket closed", {
|
|
493
|
+
code: event?.code ?? null,
|
|
494
|
+
reason: event?.reason ?? null,
|
|
495
|
+
platformReason: this.lastDisconnectReason
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
recordTerminalDisconnect(reason) {
|
|
499
|
+
if (this.terminalDisconnectError) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
const error = new WebSocketDisconnectError(reason);
|
|
503
|
+
this.lastDisconnectReason = reason;
|
|
504
|
+
this.terminalDisconnectError = error;
|
|
505
|
+
this.onTerminalDisconnect?.(reason);
|
|
506
|
+
this.connectReject?.(error);
|
|
507
|
+
for (const waiter of this.runForeverWaiters) {
|
|
508
|
+
waiter.reject(error);
|
|
509
|
+
}
|
|
510
|
+
this.runForeverWaiters.clear();
|
|
511
|
+
this.socket.disconnect();
|
|
512
|
+
}
|
|
303
513
|
async waitForConnection(timeoutMs = 1e4) {
|
|
304
514
|
if (this.connected) {
|
|
305
515
|
return;
|
|
@@ -307,20 +517,43 @@ var PhoenixChannelsTransport = class {
|
|
|
307
517
|
await new Promise((resolve, reject) => {
|
|
308
518
|
const timeout = setTimeout(() => {
|
|
309
519
|
this.connectResolve = null;
|
|
310
|
-
|
|
520
|
+
this.connectReject = null;
|
|
521
|
+
reject(
|
|
522
|
+
new TransportError("Timed out waiting for Phoenix socket connection")
|
|
523
|
+
);
|
|
311
524
|
}, timeoutMs);
|
|
312
525
|
this.connectResolve = () => {
|
|
313
526
|
clearTimeout(timeout);
|
|
527
|
+
this.connectReject = null;
|
|
314
528
|
resolve();
|
|
315
529
|
};
|
|
530
|
+
this.connectReject = (error) => {
|
|
531
|
+
clearTimeout(timeout);
|
|
532
|
+
this.connectResolve = null;
|
|
533
|
+
this.connectReject = null;
|
|
534
|
+
reject(
|
|
535
|
+
error instanceof Error ? error : new TransportError(String(error))
|
|
536
|
+
);
|
|
537
|
+
};
|
|
316
538
|
});
|
|
317
539
|
}
|
|
318
540
|
};
|
|
319
|
-
function resolveWebSocketFactory() {
|
|
541
|
+
function resolveWebSocketFactory(apiKey) {
|
|
320
542
|
if (typeof process !== "undefined" && process.versions?.node) {
|
|
321
|
-
return
|
|
543
|
+
return createNodeWebSocketFactory({ "x-api-key": apiKey });
|
|
544
|
+
}
|
|
545
|
+
throw new TransportError(
|
|
546
|
+
"Phoenix WebSocket API-key auth requires a WebSocket transport that can set handshake headers."
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
function unwrapErrorEvent(event) {
|
|
550
|
+
if (!isErrorEvent(event)) {
|
|
551
|
+
return event;
|
|
322
552
|
}
|
|
323
|
-
return
|
|
553
|
+
return event.error;
|
|
554
|
+
}
|
|
555
|
+
function isErrorEvent(event) {
|
|
556
|
+
return typeof event === "object" && event !== null && "error" in event;
|
|
324
557
|
}
|
|
325
558
|
function removeSocketChannel(socket, channel) {
|
|
326
559
|
const candidate = socket;
|
|
@@ -342,6 +575,12 @@ function deriveDefaultRestUrl(wsUrl) {
|
|
|
342
575
|
const protocol = parsed.protocol === "ws:" ? "http:" : "https:";
|
|
343
576
|
return `${protocol}//${parsed.host}`;
|
|
344
577
|
}
|
|
578
|
+
function roomTopics(roomId) {
|
|
579
|
+
return {
|
|
580
|
+
chat: `chat_room:${roomId}`,
|
|
581
|
+
participants: `room_participants:${roomId}`
|
|
582
|
+
};
|
|
583
|
+
}
|
|
345
584
|
function toPlatformMessage(roomId, message) {
|
|
346
585
|
return {
|
|
347
586
|
id: message.id,
|
|
@@ -368,6 +607,8 @@ var ThenvoiLink = class {
|
|
|
368
607
|
eventQueue = [];
|
|
369
608
|
waiters = [];
|
|
370
609
|
connected = false;
|
|
610
|
+
lastDisconnectReason = null;
|
|
611
|
+
terminalDisconnectError = null;
|
|
371
612
|
constructor(options) {
|
|
372
613
|
this.agentId = options.agentId;
|
|
373
614
|
this.apiKey = options.apiKey;
|
|
@@ -389,17 +630,35 @@ var ThenvoiLink = class {
|
|
|
389
630
|
wsUrl: this.wsUrl,
|
|
390
631
|
apiKey: this.apiKey,
|
|
391
632
|
agentId: this.agentId,
|
|
392
|
-
logger: this.logger
|
|
633
|
+
logger: this.logger,
|
|
634
|
+
conflictPolicy: options.conflictPolicy,
|
|
635
|
+
onTerminalDisconnect: (reason) => {
|
|
636
|
+
this.recordDisconnectReason(reason);
|
|
637
|
+
}
|
|
393
638
|
});
|
|
394
639
|
}
|
|
395
640
|
isConnected() {
|
|
396
641
|
return this.connected;
|
|
397
642
|
}
|
|
643
|
+
getDisconnectReason() {
|
|
644
|
+
return this.lastDisconnectReason;
|
|
645
|
+
}
|
|
398
646
|
async connect() {
|
|
399
647
|
if (this.connected) {
|
|
400
648
|
return;
|
|
401
649
|
}
|
|
402
|
-
|
|
650
|
+
try {
|
|
651
|
+
await this.transport.connect();
|
|
652
|
+
} catch (error) {
|
|
653
|
+
if (error instanceof WebSocketDisconnectError) {
|
|
654
|
+
if (error.reason.retryable) {
|
|
655
|
+
this.lastDisconnectReason = error.reason;
|
|
656
|
+
} else {
|
|
657
|
+
this.recordDisconnectError(error);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
throw error;
|
|
661
|
+
}
|
|
403
662
|
this.connected = true;
|
|
404
663
|
}
|
|
405
664
|
async disconnect() {
|
|
@@ -413,8 +672,23 @@ var ThenvoiLink = class {
|
|
|
413
672
|
this.connected = false;
|
|
414
673
|
}
|
|
415
674
|
async runForever(signal) {
|
|
675
|
+
if (this.terminalDisconnectError) {
|
|
676
|
+
throw this.terminalDisconnectError;
|
|
677
|
+
}
|
|
416
678
|
await this.transport.runForever(signal);
|
|
417
679
|
}
|
|
680
|
+
recordDisconnectReason(reason) {
|
|
681
|
+
this.recordDisconnectError(new WebSocketDisconnectError(reason));
|
|
682
|
+
}
|
|
683
|
+
recordDisconnectError(error) {
|
|
684
|
+
this.connected = false;
|
|
685
|
+
this.lastDisconnectReason = error.reason;
|
|
686
|
+
this.terminalDisconnectError = error;
|
|
687
|
+
while (this.waiters.length > 0) {
|
|
688
|
+
const waiter = this.waiters.shift();
|
|
689
|
+
waiter?.reject(error);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
418
692
|
queueEvent(event) {
|
|
419
693
|
const waiter = this.waiters.shift();
|
|
420
694
|
if (waiter) {
|
|
@@ -439,32 +713,42 @@ var ThenvoiLink = class {
|
|
|
439
713
|
if (this.subscribedRooms.has(roomId)) {
|
|
440
714
|
return;
|
|
441
715
|
}
|
|
442
|
-
await this.
|
|
443
|
-
message_created: (payload) => {
|
|
444
|
-
this.emit("message_created", payload, roomId);
|
|
445
|
-
}
|
|
446
|
-
});
|
|
447
|
-
await this.transport.join(`room_participants:${roomId}`, {
|
|
448
|
-
participant_added: (payload) => {
|
|
449
|
-
this.emit("participant_added", payload, roomId);
|
|
450
|
-
},
|
|
451
|
-
participant_removed: (payload) => {
|
|
452
|
-
this.emit("participant_removed", payload, roomId);
|
|
453
|
-
},
|
|
454
|
-
room_deleted: (payload) => {
|
|
455
|
-
this.emit("room_deleted", payload, roomId);
|
|
456
|
-
}
|
|
457
|
-
});
|
|
716
|
+
await this.joinRoomTopics(roomId);
|
|
458
717
|
this.subscribedRooms.add(roomId);
|
|
459
718
|
}
|
|
460
719
|
async unsubscribeRoom(roomId) {
|
|
461
720
|
if (!this.subscribedRooms.has(roomId)) {
|
|
462
721
|
return;
|
|
463
722
|
}
|
|
464
|
-
|
|
465
|
-
await this.transport.leave(
|
|
723
|
+
const topics = roomTopics(roomId);
|
|
724
|
+
await this.transport.leave(topics.chat);
|
|
725
|
+
await this.transport.leave(topics.participants);
|
|
466
726
|
this.subscribedRooms.delete(roomId);
|
|
467
727
|
}
|
|
728
|
+
async joinRoomTopics(roomId) {
|
|
729
|
+
const topics = roomTopics(roomId);
|
|
730
|
+
await this.transport.join(topics.chat, {
|
|
731
|
+
message_created: (payload) => {
|
|
732
|
+
this.emit("message_created", payload, roomId);
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
try {
|
|
736
|
+
await this.transport.join(topics.participants, {
|
|
737
|
+
participant_added: (payload) => {
|
|
738
|
+
this.emit("participant_added", payload, roomId);
|
|
739
|
+
},
|
|
740
|
+
participant_removed: (payload) => {
|
|
741
|
+
this.emit("participant_removed", payload, roomId);
|
|
742
|
+
},
|
|
743
|
+
room_deleted: (payload) => {
|
|
744
|
+
this.emit("room_deleted", payload, roomId);
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
} catch (error) {
|
|
748
|
+
await this.transport.leave(topics.chat);
|
|
749
|
+
throw error;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
468
752
|
async subscribeAgentContacts() {
|
|
469
753
|
assertCapability(this.capabilities, "contacts", "Contacts streaming");
|
|
470
754
|
await this.transport.join(`agent_contacts:${this.agentId}`, {
|
|
@@ -486,6 +770,9 @@ var ThenvoiLink = class {
|
|
|
486
770
|
await this.transport.leave(`agent_contacts:${this.agentId}`);
|
|
487
771
|
}
|
|
488
772
|
async nextEvent(signal) {
|
|
773
|
+
if (this.terminalDisconnectError) {
|
|
774
|
+
throw this.terminalDisconnectError;
|
|
775
|
+
}
|
|
489
776
|
if (signal?.aborted) {
|
|
490
777
|
return null;
|
|
491
778
|
}
|
|
@@ -493,19 +780,19 @@ var ThenvoiLink = class {
|
|
|
493
780
|
if (queued) {
|
|
494
781
|
return queued;
|
|
495
782
|
}
|
|
496
|
-
return new Promise((resolve) => {
|
|
783
|
+
return new Promise((resolve, reject) => {
|
|
497
784
|
let settled = false;
|
|
498
785
|
const onAbort = () => {
|
|
499
786
|
const index = this.waiters.indexOf(waiter);
|
|
500
787
|
if (index >= 0) {
|
|
501
788
|
this.waiters.splice(index, 1);
|
|
502
789
|
}
|
|
503
|
-
|
|
790
|
+
finalizeResolve(null);
|
|
504
791
|
};
|
|
505
792
|
const cleanup = () => {
|
|
506
793
|
signal?.removeEventListener("abort", onAbort);
|
|
507
794
|
};
|
|
508
|
-
const
|
|
795
|
+
const finalizeResolve = (event) => {
|
|
509
796
|
if (settled) {
|
|
510
797
|
return;
|
|
511
798
|
}
|
|
@@ -513,8 +800,17 @@ var ThenvoiLink = class {
|
|
|
513
800
|
cleanup();
|
|
514
801
|
resolve(event);
|
|
515
802
|
};
|
|
803
|
+
const finalizeReject = (error) => {
|
|
804
|
+
if (settled) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
settled = true;
|
|
808
|
+
cleanup();
|
|
809
|
+
reject(error);
|
|
810
|
+
};
|
|
516
811
|
const waiter = {
|
|
517
|
-
resolve:
|
|
812
|
+
resolve: finalizeResolve,
|
|
813
|
+
reject: finalizeReject,
|
|
518
814
|
cleanup
|
|
519
815
|
};
|
|
520
816
|
this.waiters.push(waiter);
|
|
@@ -526,7 +822,10 @@ var ThenvoiLink = class {
|
|
|
526
822
|
next: async () => {
|
|
527
823
|
const value = await this.nextEvent();
|
|
528
824
|
if (value === null) {
|
|
529
|
-
return {
|
|
825
|
+
return {
|
|
826
|
+
done: true,
|
|
827
|
+
value: void 0
|
|
828
|
+
};
|
|
530
829
|
}
|
|
531
830
|
return { done: false, value };
|
|
532
831
|
}
|
|
@@ -608,7 +907,9 @@ var ThenvoiLink = class {
|
|
|
608
907
|
}
|
|
609
908
|
async listChats(request, requestOptions) {
|
|
610
909
|
if (!this.rest.listChats) {
|
|
611
|
-
throw new UnsupportedFeatureError(
|
|
910
|
+
throw new UnsupportedFeatureError(
|
|
911
|
+
"Chat listing is not available in current REST adapter"
|
|
912
|
+
);
|
|
612
913
|
}
|
|
613
914
|
return this.rest.listChats(request, requestOptions);
|
|
614
915
|
}
|
|
@@ -968,40 +1269,6 @@ var CONTACT_REQUEST_ACTIONS = /* @__PURE__ */ new Set([
|
|
|
968
1269
|
"reject",
|
|
969
1270
|
"cancel"
|
|
970
1271
|
]);
|
|
971
|
-
var MEMORY_SYSTEMS = /* @__PURE__ */ new Set([
|
|
972
|
-
"sensory",
|
|
973
|
-
"working",
|
|
974
|
-
"long_term"
|
|
975
|
-
]);
|
|
976
|
-
var MEMORY_TYPES = /* @__PURE__ */ new Set([
|
|
977
|
-
"iconic",
|
|
978
|
-
"echoic",
|
|
979
|
-
"haptic",
|
|
980
|
-
"episodic",
|
|
981
|
-
"semantic",
|
|
982
|
-
"procedural"
|
|
983
|
-
]);
|
|
984
|
-
var MEMORY_SEGMENTS = /* @__PURE__ */ new Set([
|
|
985
|
-
"user",
|
|
986
|
-
"agent",
|
|
987
|
-
"tool",
|
|
988
|
-
"guideline"
|
|
989
|
-
]);
|
|
990
|
-
var LIST_MEMORY_SCOPES = /* @__PURE__ */ new Set([
|
|
991
|
-
"subject",
|
|
992
|
-
"organization",
|
|
993
|
-
"all"
|
|
994
|
-
]);
|
|
995
|
-
var LIST_MEMORY_STATUSES = /* @__PURE__ */ new Set([
|
|
996
|
-
"active",
|
|
997
|
-
"superseded",
|
|
998
|
-
"archived",
|
|
999
|
-
"all"
|
|
1000
|
-
]);
|
|
1001
|
-
var MEMORY_SCOPES = /* @__PURE__ */ new Set([
|
|
1002
|
-
"subject",
|
|
1003
|
-
"organization"
|
|
1004
|
-
]);
|
|
1005
1272
|
var AgentTools = class {
|
|
1006
1273
|
roomId;
|
|
1007
1274
|
capabilities;
|
|
@@ -1579,6 +1846,9 @@ var AgentTools = class {
|
|
|
1579
1846
|
const status = this.normalizeOptionalMemoryStatus(arguments_.status);
|
|
1580
1847
|
const subjectId = this.normalizeOptionalString(arguments_.subject_id);
|
|
1581
1848
|
const contentQuery = this.normalizeOptionalString(arguments_.content_query);
|
|
1849
|
+
if (system && type && !isMemoryTypeForSystem(system, type)) {
|
|
1850
|
+
throw new ValidationError(memoryTypeForSystemError(system));
|
|
1851
|
+
}
|
|
1582
1852
|
return {
|
|
1583
1853
|
...subjectId ? { subject_id: subjectId } : {},
|
|
1584
1854
|
...scope ? { scope } : {},
|
|
@@ -1600,13 +1870,21 @@ var AgentTools = class {
|
|
|
1600
1870
|
const subjectId = this.normalizeOptionalString(arguments_.subject_id);
|
|
1601
1871
|
const metadata = this.normalizeOptionalMetadata(arguments_.metadata);
|
|
1602
1872
|
if (!system) {
|
|
1603
|
-
throw new ValidationError(
|
|
1873
|
+
throw new ValidationError(`system must be one of: ${expectedList(MEMORY_SYSTEMS)}`);
|
|
1604
1874
|
}
|
|
1605
1875
|
if (!type) {
|
|
1606
|
-
throw new ValidationError(
|
|
1876
|
+
throw new ValidationError(`type must be one of: ${expectedList(MEMORY_TYPES)}`);
|
|
1877
|
+
}
|
|
1878
|
+
if (!isMemoryTypeForSystem(system, type)) {
|
|
1879
|
+
throw new ValidationError(memoryTypeForSystemError(system));
|
|
1607
1880
|
}
|
|
1608
1881
|
if (!segment) {
|
|
1609
|
-
throw new ValidationError(
|
|
1882
|
+
throw new ValidationError(`segment must be one of: ${expectedList(MEMORY_SEGMENTS)}`);
|
|
1883
|
+
}
|
|
1884
|
+
if (scope === "subject" && !subjectId) {
|
|
1885
|
+
throw new ValidationError(
|
|
1886
|
+
'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.'
|
|
1887
|
+
);
|
|
1610
1888
|
}
|
|
1611
1889
|
return {
|
|
1612
1890
|
content,
|
|
@@ -1686,8 +1964,8 @@ var AgentTools = class {
|
|
|
1686
1964
|
if (!normalized) {
|
|
1687
1965
|
return void 0;
|
|
1688
1966
|
}
|
|
1689
|
-
if (!
|
|
1690
|
-
throw new ValidationError(
|
|
1967
|
+
if (!isMemoryListScope(normalized)) {
|
|
1968
|
+
throw new ValidationError(`scope must be one of: ${expectedList(MEMORY_LIST_SCOPES)}`);
|
|
1691
1969
|
}
|
|
1692
1970
|
return normalized;
|
|
1693
1971
|
}
|
|
@@ -1697,7 +1975,7 @@ var AgentTools = class {
|
|
|
1697
1975
|
return void 0;
|
|
1698
1976
|
}
|
|
1699
1977
|
if (!isMemorySystem(normalized)) {
|
|
1700
|
-
throw new ValidationError(
|
|
1978
|
+
throw new ValidationError(`system must be one of: ${expectedList(MEMORY_SYSTEMS)}`);
|
|
1701
1979
|
}
|
|
1702
1980
|
return normalized;
|
|
1703
1981
|
}
|
|
@@ -1707,7 +1985,7 @@ var AgentTools = class {
|
|
|
1707
1985
|
return void 0;
|
|
1708
1986
|
}
|
|
1709
1987
|
if (!isMemoryType(normalized)) {
|
|
1710
|
-
throw new ValidationError(
|
|
1988
|
+
throw new ValidationError(`type must be one of: ${expectedList(MEMORY_TYPES)}`);
|
|
1711
1989
|
}
|
|
1712
1990
|
return normalized;
|
|
1713
1991
|
}
|
|
@@ -1717,7 +1995,7 @@ var AgentTools = class {
|
|
|
1717
1995
|
return void 0;
|
|
1718
1996
|
}
|
|
1719
1997
|
if (!isMemorySegment(normalized)) {
|
|
1720
|
-
throw new ValidationError(
|
|
1998
|
+
throw new ValidationError(`segment must be one of: ${expectedList(MEMORY_SEGMENTS)}`);
|
|
1721
1999
|
}
|
|
1722
2000
|
return normalized;
|
|
1723
2001
|
}
|
|
@@ -1727,7 +2005,7 @@ var AgentTools = class {
|
|
|
1727
2005
|
return void 0;
|
|
1728
2006
|
}
|
|
1729
2007
|
if (!isMemoryStatus(normalized)) {
|
|
1730
|
-
throw new ValidationError(
|
|
2008
|
+
throw new ValidationError(`status must be one of: ${expectedList(MEMORY_STATUSES)}`);
|
|
1731
2009
|
}
|
|
1732
2010
|
return normalized;
|
|
1733
2011
|
}
|
|
@@ -1736,8 +2014,8 @@ var AgentTools = class {
|
|
|
1736
2014
|
if (!normalized) {
|
|
1737
2015
|
return void 0;
|
|
1738
2016
|
}
|
|
1739
|
-
if (!
|
|
1740
|
-
throw new ValidationError(
|
|
2017
|
+
if (!isMemoryStoreScope(normalized)) {
|
|
2018
|
+
throw new ValidationError(`scope must be one of: ${expectedList(MEMORY_STORE_SCOPES)}`);
|
|
1741
2019
|
}
|
|
1742
2020
|
return normalized;
|
|
1743
2021
|
}
|
|
@@ -1745,24 +2023,6 @@ var AgentTools = class {
|
|
|
1745
2023
|
function isContactRequestAction(value) {
|
|
1746
2024
|
return CONTACT_REQUEST_ACTIONS.has(value);
|
|
1747
2025
|
}
|
|
1748
|
-
function isMemorySystem(value) {
|
|
1749
|
-
return MEMORY_SYSTEMS.has(value);
|
|
1750
|
-
}
|
|
1751
|
-
function isMemoryType(value) {
|
|
1752
|
-
return MEMORY_TYPES.has(value);
|
|
1753
|
-
}
|
|
1754
|
-
function isMemorySegment(value) {
|
|
1755
|
-
return MEMORY_SEGMENTS.has(value);
|
|
1756
|
-
}
|
|
1757
|
-
function isStoreMemoryScope(value) {
|
|
1758
|
-
return MEMORY_SCOPES.has(value);
|
|
1759
|
-
}
|
|
1760
|
-
function isListMemoryScope(value) {
|
|
1761
|
-
return LIST_MEMORY_SCOPES.has(value);
|
|
1762
|
-
}
|
|
1763
|
-
function isMemoryStatus(value) {
|
|
1764
|
-
return LIST_MEMORY_STATUSES.has(value);
|
|
1765
|
-
}
|
|
1766
2026
|
function coercePositiveInt(value, fallback) {
|
|
1767
2027
|
const num = Number(value ?? fallback);
|
|
1768
2028
|
return Number.isFinite(num) && num >= 1 ? Math.floor(num) : fallback;
|
|
@@ -1802,17 +2062,19 @@ function validateToolArgs(toolName, args) {
|
|
|
1802
2062
|
}
|
|
1803
2063
|
}
|
|
1804
2064
|
if (toolName === "thenvoi_store_memory") {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
const validSegments = ["user", "agent", "tool", "guideline"];
|
|
1808
|
-
if (typeof args.system === "string" && !validSystems.includes(args.system)) {
|
|
1809
|
-
errors.push(`system: Invalid value '${args.system}'. Expected one of: ${validSystems.join(", ")}`);
|
|
2065
|
+
if (typeof args.system === "string" && !isMemorySystem(args.system)) {
|
|
2066
|
+
errors.push(`system: Invalid value '${args.system}'. Expected one of: ${expectedList(MEMORY_SYSTEMS)}`);
|
|
1810
2067
|
}
|
|
1811
|
-
if (typeof args.type === "string" && !
|
|
1812
|
-
errors.push(`type: Invalid value '${args.type}'. Expected one of: ${
|
|
2068
|
+
if (typeof args.type === "string" && !isMemoryType(args.type)) {
|
|
2069
|
+
errors.push(`type: Invalid value '${args.type}'. Expected one of: ${expectedList(MEMORY_TYPES)}`);
|
|
1813
2070
|
}
|
|
1814
|
-
if (typeof args.
|
|
1815
|
-
errors.push(
|
|
2071
|
+
if (typeof args.system === "string" && isMemorySystem(args.system) && typeof args.type === "string" && isMemoryType(args.type) && !isMemoryTypeForSystem(args.system, args.type)) {
|
|
2072
|
+
errors.push(
|
|
2073
|
+
`type: Invalid value '${args.type}' for system '${args.system}'. Expected one of: ${expectedMemoryTypesForSystem(args.system)}`
|
|
2074
|
+
);
|
|
2075
|
+
}
|
|
2076
|
+
if (typeof args.segment === "string" && !isMemorySegment(args.segment)) {
|
|
2077
|
+
errors.push(`segment: Invalid value '${args.segment}'. Expected one of: ${expectedList(MEMORY_SEGMENTS)}`);
|
|
1816
2078
|
}
|
|
1817
2079
|
}
|
|
1818
2080
|
if (errors.length > 0) {
|
|
@@ -2349,7 +2611,7 @@ var AgentRuntime = class {
|
|
|
2349
2611
|
await this.link.disconnect();
|
|
2350
2612
|
}
|
|
2351
2613
|
async stop(timeoutMs) {
|
|
2352
|
-
if (!this.running
|
|
2614
|
+
if (this.stopping || !this.running && !this.fatalError) {
|
|
2353
2615
|
return true;
|
|
2354
2616
|
}
|
|
2355
2617
|
this.stopping = true;
|
|
@@ -2369,7 +2631,8 @@ var AgentRuntime = class {
|
|
|
2369
2631
|
}
|
|
2370
2632
|
}
|
|
2371
2633
|
for (const roomId of [...this.subscribedRooms]) {
|
|
2372
|
-
|
|
2634
|
+
const remaining = deadline === void 0 ? void 0 : Math.max(0, deadline - Date.now());
|
|
2635
|
+
await this.leaveTrackedRoom(roomId, remaining);
|
|
2373
2636
|
}
|
|
2374
2637
|
for (const roomId of [...this.contexts.keys()]) {
|
|
2375
2638
|
await this.onSessionCleanup(roomId);
|
|
@@ -2405,7 +2668,13 @@ var AgentRuntime = class {
|
|
|
2405
2668
|
}
|
|
2406
2669
|
async consumeLoop(signal) {
|
|
2407
2670
|
while (!signal.aborted) {
|
|
2408
|
-
|
|
2671
|
+
let event;
|
|
2672
|
+
try {
|
|
2673
|
+
event = await this.link.nextEvent(signal);
|
|
2674
|
+
} catch (error) {
|
|
2675
|
+
await this.failRuntime(error, syntheticRuntimeFailureEvent(this.agentId));
|
|
2676
|
+
return;
|
|
2677
|
+
}
|
|
2409
2678
|
if (!event) {
|
|
2410
2679
|
return;
|
|
2411
2680
|
}
|
|
@@ -2568,13 +2837,13 @@ var AgentRuntime = class {
|
|
|
2568
2837
|
}
|
|
2569
2838
|
});
|
|
2570
2839
|
}
|
|
2571
|
-
async leaveTrackedRoom(roomId) {
|
|
2840
|
+
async leaveTrackedRoom(roomId, timeoutMs) {
|
|
2572
2841
|
await trackRoomLeave({
|
|
2573
2842
|
link: this.link,
|
|
2574
2843
|
roomId,
|
|
2575
2844
|
trackedRooms: this.subscribedRooms,
|
|
2576
2845
|
onLeft: async (leftRoomId) => {
|
|
2577
|
-
await this.executions.get(leftRoomId)?.stop();
|
|
2846
|
+
await this.executions.get(leftRoomId)?.stop(timeoutMs);
|
|
2578
2847
|
this.contexts.delete(leftRoomId);
|
|
2579
2848
|
this.executions.delete(leftRoomId);
|
|
2580
2849
|
await this.onSessionCleanup(leftRoomId);
|
|
@@ -2611,6 +2880,23 @@ var AgentRuntime = class {
|
|
|
2611
2880
|
}
|
|
2612
2881
|
}
|
|
2613
2882
|
};
|
|
2883
|
+
function syntheticRuntimeFailureEvent(agentId) {
|
|
2884
|
+
return {
|
|
2885
|
+
type: "message_created",
|
|
2886
|
+
roomId: null,
|
|
2887
|
+
payload: {
|
|
2888
|
+
id: "runtime-failed",
|
|
2889
|
+
content: "",
|
|
2890
|
+
sender_id: agentId,
|
|
2891
|
+
sender_type: "Agent",
|
|
2892
|
+
sender_name: null,
|
|
2893
|
+
message_type: "text",
|
|
2894
|
+
metadata: {},
|
|
2895
|
+
inserted_at: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
2896
|
+
updated_at: (/* @__PURE__ */ new Date(0)).toISOString()
|
|
2897
|
+
}
|
|
2898
|
+
};
|
|
2899
|
+
}
|
|
2614
2900
|
function assertNever(value) {
|
|
2615
2901
|
throw new Error(`Unhandled platform event: ${JSON.stringify(value)}`);
|
|
2616
2902
|
}
|
|
@@ -3453,7 +3739,8 @@ var PlatformRuntime = class {
|
|
|
3453
3739
|
agentId: this._agentId,
|
|
3454
3740
|
apiKey: this._apiKey,
|
|
3455
3741
|
wsUrl: this._wsUrl,
|
|
3456
|
-
restUrl: this._restUrl
|
|
3742
|
+
restUrl: this._restUrl,
|
|
3743
|
+
logger: this.logger
|
|
3457
3744
|
});
|
|
3458
3745
|
}
|
|
3459
3746
|
if (this.configuredIdentity) {
|
|
@@ -3670,6 +3957,7 @@ async function runWithGracefulShutdown(agent, options) {
|
|
|
3670
3957
|
}
|
|
3671
3958
|
|
|
3672
3959
|
export {
|
|
3960
|
+
deriveDefaultRestUrl,
|
|
3673
3961
|
ThenvoiLink,
|
|
3674
3962
|
Execution,
|
|
3675
3963
|
AgentTools,
|