@copilotkit/core 1.56.2 → 1.56.4
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/dist/index.cjs +285 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -25
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +93 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +285 -125
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +292 -130
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -2
package/dist/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function(global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@ag-ui/client'), require('@copilotkit/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema'), require('rxjs/fetch')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', '@ag-ui/client', '@copilotkit/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema', 'rxjs/fetch'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitCore = {}), global.AgUIClient,global.CopilotKitShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema,global.rxjs_fetch));
|
|
5
|
-
})(this, function(exports, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema, rxjs_fetch) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tanstack/pacer'), require('@ag-ui/client'), require('@copilotkit/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema'), require('rxjs/fetch')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', '@tanstack/pacer', '@ag-ui/client', '@copilotkit/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema', 'rxjs/fetch'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitCore = {}), global._tanstack_pacer,global.AgUIClient,global.CopilotKitShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema,global.rxjs_fetch));
|
|
5
|
+
})(this, function(exports, _tanstack_pacer, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema, rxjs_fetch) {
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
7
7
|
|
|
8
8
|
//#region src/utils/phoenix-observable.ts
|
|
@@ -167,6 +167,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
167
167
|
//#endregion
|
|
168
168
|
//#region src/intelligence-agent.ts
|
|
169
169
|
const CLIENT_AG_UI_EVENT = "ag_ui_event";
|
|
170
|
+
const REPLAY_COMPLETE_EVENT = "replay_complete";
|
|
171
|
+
const STREAM_IDLE_EVENT = "stream_idle";
|
|
170
172
|
const STOP_RUN_EVENT = "stop_run";
|
|
171
173
|
var AgentThreadLockedError = class extends Error {
|
|
172
174
|
constructor(threadId) {
|
|
@@ -180,7 +182,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
180
182
|
_defineProperty(this, "config", void 0);
|
|
181
183
|
_defineProperty(this, "socket", null);
|
|
182
184
|
_defineProperty(this, "activeChannel", null);
|
|
183
|
-
_defineProperty(this, "
|
|
185
|
+
_defineProperty(this, "canonicalRunId", null);
|
|
184
186
|
_defineProperty(this, "sharedState", void 0);
|
|
185
187
|
this.config = config;
|
|
186
188
|
this.sharedState = sharedState;
|
|
@@ -217,7 +219,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
217
219
|
var _this$agentId;
|
|
218
220
|
this.isRunning = true;
|
|
219
221
|
this.agentId = (_this$agentId = this.agentId) !== null && _this$agentId !== void 0 ? _this$agentId : (0, _ag_ui_client.randomUUID)();
|
|
220
|
-
const
|
|
222
|
+
const effectiveParameters = (parameters === null || parameters === void 0 ? void 0 : parameters.runId) || !this.canonicalRunId ? parameters : {
|
|
223
|
+
...parameters,
|
|
224
|
+
runId: this.canonicalRunId
|
|
225
|
+
};
|
|
226
|
+
const input = this.prepareRunAgentInput(effectiveParameters);
|
|
221
227
|
let result;
|
|
222
228
|
const previousMessageIds = new Set(this.messages.map((m) => m.id));
|
|
223
229
|
const subscribers = [
|
|
@@ -256,14 +262,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
256
262
|
}
|
|
257
263
|
}
|
|
258
264
|
abortRun() {
|
|
259
|
-
if (this.activeChannel && this.
|
|
265
|
+
if (this.activeChannel && this.canonicalRunId) {
|
|
260
266
|
const fallback = setTimeout(() => clear(), 5e3);
|
|
261
267
|
const clear = () => {
|
|
262
268
|
clearTimeout(fallback);
|
|
263
269
|
this.detachActiveRun();
|
|
264
270
|
this.cleanup();
|
|
265
271
|
};
|
|
266
|
-
this.activeChannel.push(STOP_RUN_EVENT, { run_id: this.
|
|
272
|
+
this.activeChannel.push(STOP_RUN_EVENT, { run_id: this.canonicalRunId }).receive("ok", clear).receive("error", clear).receive("timeout", clear);
|
|
267
273
|
} else {
|
|
268
274
|
this.detachActiveRun();
|
|
269
275
|
this.cleanup();
|
|
@@ -275,11 +281,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
275
281
|
*/
|
|
276
282
|
run(input) {
|
|
277
283
|
this.threadId = input.threadId;
|
|
278
|
-
this.
|
|
279
|
-
return (0, rxjs.defer)(() => this.requestJoinCredentials$("run", input)).pipe((0, rxjs.switchMap)((credentials) =>
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
284
|
+
this.canonicalRunId = input.runId;
|
|
285
|
+
return (0, rxjs.defer)(() => this.requestJoinCredentials$("run", input)).pipe((0, rxjs.switchMap)((credentials) => {
|
|
286
|
+
if (credentials === null) return (0, rxjs.throwError)(() => /* @__PURE__ */ new Error("REST run request returned no credentials"));
|
|
287
|
+
const canonicalInput = this.applyCanonicalRunIdentity(input, credentials, { fallbackToInputRunId: true });
|
|
288
|
+
return this.observeThread$(canonicalInput, credentials, {
|
|
289
|
+
completeOnRunError: false,
|
|
290
|
+
streamMode: "run"
|
|
291
|
+
});
|
|
292
|
+
}));
|
|
283
293
|
}
|
|
284
294
|
/**
|
|
285
295
|
* Reconnect to an existing thread by fetching websocket credentials and
|
|
@@ -287,21 +297,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
287
297
|
*/
|
|
288
298
|
connect(input) {
|
|
289
299
|
this.threadId = input.threadId;
|
|
290
|
-
this.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if (
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
for (const event of plan.events) this.updateRunIdFromEvent(event);
|
|
300
|
-
return (0, rxjs.concat)((0, rxjs.from)(plan.events), this.observeThread$(input, { joinToken: plan.joinToken }, {
|
|
301
|
-
completeOnRunError: true,
|
|
302
|
-
streamMode: "connect",
|
|
303
|
-
replayCursor: plan.joinFromEventId
|
|
304
|
-
}));
|
|
300
|
+
this.canonicalRunId = null;
|
|
301
|
+
this.clearReconnectCursor(input.threadId);
|
|
302
|
+
return (0, rxjs.defer)(() => this.requestJoinCredentials$("connect", input)).pipe((0, rxjs.switchMap)((credentials) => {
|
|
303
|
+
if (credentials === null) return rxjs.EMPTY;
|
|
304
|
+
const canonicalInput = this.applyCanonicalRunIdentity(input, credentials, { fallbackToInputRunId: false });
|
|
305
|
+
return this.observeThread$(canonicalInput, credentials, {
|
|
306
|
+
completeOnRunError: false,
|
|
307
|
+
streamMode: "connect"
|
|
308
|
+
});
|
|
305
309
|
}));
|
|
306
310
|
}
|
|
307
311
|
/**
|
|
@@ -318,8 +322,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
318
322
|
ownSocket.disconnect();
|
|
319
323
|
if (this.socket === ownSocket) this.socket = null;
|
|
320
324
|
}
|
|
321
|
-
|
|
322
|
-
this.runId = null;
|
|
325
|
+
this.canonicalRunId = null;
|
|
323
326
|
}
|
|
324
327
|
cleanup() {
|
|
325
328
|
this.cleanupOwned(this.activeChannel, this.socket);
|
|
@@ -340,80 +343,57 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
340
343
|
tools: input.tools,
|
|
341
344
|
context: input.context,
|
|
342
345
|
state: input.state,
|
|
343
|
-
forwardedProps: input.forwardedProps
|
|
346
|
+
forwardedProps: input.forwardedProps,
|
|
347
|
+
...mode === "connect" ? { lastSeenEventId: this.getReconnectCursor(input) } : {}
|
|
344
348
|
}),
|
|
345
349
|
...this.config.credentials ? { credentials: this.config.credentials } : {}
|
|
346
350
|
});
|
|
347
|
-
if (response.status ===
|
|
351
|
+
if (response.status === 204 && mode === "connect") return null;
|
|
352
|
+
if (response.status === 409 && mode === "run") throw new AgentThreadLockedError(input.threadId);
|
|
348
353
|
if (!response.ok) {
|
|
349
354
|
const text = await response.text().catch(() => "");
|
|
350
355
|
throw new Error(text || response.statusText || String(response.status));
|
|
351
356
|
}
|
|
352
|
-
|
|
353
|
-
if (!payload.joinToken) throw new Error("missing joinToken");
|
|
354
|
-
return { joinToken: payload.joinToken };
|
|
357
|
+
return this.normalizeJoinCredentials(await response.json(), input);
|
|
355
358
|
} catch (error) {
|
|
356
359
|
if (error instanceof AgentThreadLockedError) throw error;
|
|
357
360
|
throw new Error(`REST ${mode} request failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
358
361
|
}
|
|
359
362
|
});
|
|
360
363
|
}
|
|
361
|
-
|
|
362
|
-
return (0, rxjs.defer)(async () => {
|
|
363
|
-
try {
|
|
364
|
-
const response = await fetch(this.buildRuntimeUrl("connect"), {
|
|
365
|
-
method: "POST",
|
|
366
|
-
headers: {
|
|
367
|
-
"Content-Type": "application/json",
|
|
368
|
-
...this.config.headers
|
|
369
|
-
},
|
|
370
|
-
body: JSON.stringify({
|
|
371
|
-
threadId: input.threadId,
|
|
372
|
-
runId: input.runId,
|
|
373
|
-
messages: input.messages,
|
|
374
|
-
tools: input.tools,
|
|
375
|
-
context: input.context,
|
|
376
|
-
state: input.state,
|
|
377
|
-
forwardedProps: input.forwardedProps,
|
|
378
|
-
lastSeenEventId: this.getReconnectCursor(input)
|
|
379
|
-
}),
|
|
380
|
-
...this.config.credentials ? { credentials: this.config.credentials } : {}
|
|
381
|
-
});
|
|
382
|
-
if (response.status === 204) return null;
|
|
383
|
-
if (!response.ok) {
|
|
384
|
-
const text = await response.text().catch(() => "");
|
|
385
|
-
throw new Error(text || response.statusText || String(response.status));
|
|
386
|
-
}
|
|
387
|
-
return this.normalizeConnectPlan(await response.json());
|
|
388
|
-
} catch (error) {
|
|
389
|
-
throw new Error(`REST connect request failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
normalizeConnectPlan(payload) {
|
|
364
|
+
normalizeJoinCredentials(payload, input) {
|
|
394
365
|
const envelope = payload && typeof payload === "object" ? payload : null;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
366
|
+
const realtime = (envelope === null || envelope === void 0 ? void 0 : envelope.realtime) && typeof envelope.realtime === "object" ? envelope.realtime : null;
|
|
367
|
+
if (typeof (envelope === null || envelope === void 0 ? void 0 : envelope.joinToken) !== "string" || !envelope.joinToken) throw new Error("missing joinToken");
|
|
368
|
+
if (typeof (realtime === null || realtime === void 0 ? void 0 : realtime.clientUrl) !== "string" || !realtime.clientUrl) throw new Error("missing realtime.clientUrl");
|
|
369
|
+
if (typeof realtime.topic !== "string" || !realtime.topic) throw new Error("missing realtime.topic");
|
|
370
|
+
return {
|
|
371
|
+
threadId: typeof envelope.threadId === "string" && envelope.threadId ? envelope.threadId : input.threadId,
|
|
372
|
+
runId: typeof envelope.runId === "string" && envelope.runId ? envelope.runId : null,
|
|
373
|
+
joinToken: envelope.joinToken,
|
|
374
|
+
realtime: {
|
|
375
|
+
clientUrl: realtime.clientUrl,
|
|
376
|
+
topic: realtime.topic
|
|
377
|
+
}
|
|
399
378
|
};
|
|
400
|
-
if ((envelope === null || envelope === void 0 ? void 0 : envelope.mode) === "live") {
|
|
401
|
-
if (typeof envelope.joinToken !== "string" || envelope.joinToken.length === 0) throw new Error("missing joinToken");
|
|
402
|
-
return {
|
|
403
|
-
mode: "live",
|
|
404
|
-
joinToken: envelope.joinToken,
|
|
405
|
-
joinFromEventId: typeof envelope.joinFromEventId === "string" ? envelope.joinFromEventId : null,
|
|
406
|
-
events: Array.isArray(envelope.events) ? envelope.events : []
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
throw new Error("invalid connect plan");
|
|
410
379
|
}
|
|
411
380
|
observeThread$(input, credentials, options) {
|
|
381
|
+
return this.observeThreadSession$(input, credentials, options).pipe((0, rxjs_operators.catchError)((error) => {
|
|
382
|
+
if (!this.isSocketReconnectExhaustedError(error)) return (0, rxjs.throwError)(() => error);
|
|
383
|
+
return this.requestJoinCredentials$("connect", input).pipe((0, rxjs.switchMap)((refreshedCredentials) => refreshedCredentials === null ? rxjs.EMPTY : this.observeThread$(this.applyCanonicalRunIdentity(input, refreshedCredentials, { fallbackToInputRunId: options.streamMode === "run" }), refreshedCredentials, {
|
|
384
|
+
...options,
|
|
385
|
+
channelMode: "connect",
|
|
386
|
+
replayCursor: this.getReconnectCursor(input)
|
|
387
|
+
})));
|
|
388
|
+
}));
|
|
389
|
+
}
|
|
390
|
+
observeThreadSession$(input, credentials, options) {
|
|
412
391
|
return (0, rxjs.defer)(() => {
|
|
392
|
+
var _options$channelMode;
|
|
413
393
|
let ownSocket = null;
|
|
414
394
|
let ownChannel = null;
|
|
415
395
|
const socket$ = ɵphoenixSocket$({
|
|
416
|
-
url:
|
|
396
|
+
url: credentials.realtime.clientUrl,
|
|
417
397
|
options: {
|
|
418
398
|
params: {
|
|
419
399
|
...this.config.socketParams,
|
|
@@ -429,10 +409,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
429
409
|
bufferSize: 1,
|
|
430
410
|
refCount: true
|
|
431
411
|
}));
|
|
432
|
-
const
|
|
412
|
+
const params = this.createThreadChannelParams(input, (_options$channelMode = options.channelMode) !== null && _options$channelMode !== void 0 ? _options$channelMode : options.streamMode, options.replayCursor);
|
|
433
413
|
const channel$ = ɵphoenixChannel$({
|
|
434
414
|
socket$,
|
|
435
|
-
topic,
|
|
415
|
+
topic: credentials.realtime.topic,
|
|
436
416
|
params
|
|
437
417
|
}).pipe((0, rxjs_operators.tap)(({ channel }) => {
|
|
438
418
|
ownChannel = channel;
|
|
@@ -442,8 +422,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
442
422
|
refCount: true
|
|
443
423
|
}));
|
|
444
424
|
const threadEvents$ = this.observeThreadEvents$(input.threadId, channel$, options).pipe((0, rxjs_operators.share)());
|
|
445
|
-
const
|
|
446
|
-
|
|
425
|
+
const replayComplete$ = this.observeControlEvent$(input.threadId, channel$, REPLAY_COMPLETE_EVENT).pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.share)());
|
|
426
|
+
const streamIdle$ = this.observeControlEvent$(input.threadId, channel$, STREAM_IDLE_EVENT).pipe((0, rxjs_operators.shareReplay)({
|
|
427
|
+
bufferSize: 1,
|
|
428
|
+
refCount: true
|
|
429
|
+
}));
|
|
430
|
+
const streamIdleCompletion$ = options.streamMode === "connect" ? streamIdle$.pipe((0, rxjs_operators.take)(1)) : rxjs.EMPTY;
|
|
431
|
+
const terminal$ = (0, rxjs.merge)(threadEvents$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.endWith)(null), (0, rxjs_operators.take)(1)), streamIdleCompletion$);
|
|
432
|
+
return (0, rxjs.merge)(this.joinThreadChannel$(channel$), this.observeSocketHealth$(socket$).pipe((0, rxjs_operators.takeUntil)(terminal$)), threadEvents$.pipe((0, rxjs_operators.takeUntil)(streamIdleCompletion$)), replayComplete$.pipe((0, rxjs_operators.takeUntil)(terminal$)), streamIdleCompletion$.pipe((0, rxjs_operators.ignoreElements)())).pipe((0, rxjs_operators.finalize)(() => this.cleanupOwned(ownChannel, ownSocket)));
|
|
447
433
|
});
|
|
448
434
|
}
|
|
449
435
|
joinThreadChannel$(channel$) {
|
|
@@ -455,18 +441,24 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
455
441
|
observeThreadEvents$(threadId, channel$, options) {
|
|
456
442
|
return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, CLIENT_AG_UI_EVENT)), (0, rxjs_operators.tap)((payload) => {
|
|
457
443
|
this.updateLastSeenEventId(threadId, payload);
|
|
458
|
-
|
|
459
|
-
|
|
444
|
+
}), (0, rxjs_operators.mergeMap)((payload) => this.createThreadNotifications(payload, {
|
|
445
|
+
completeOnRunError: options.completeOnRunError,
|
|
446
|
+
completeOnRunFinished: options.streamMode === "run",
|
|
447
|
+
errorOnRunError: options.streamMode === "run"
|
|
448
|
+
})), (0, rxjs.dematerialize)());
|
|
449
|
+
}
|
|
450
|
+
observeControlEvent$(threadId, channel$, eventName) {
|
|
451
|
+
return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, eventName)), (0, rxjs_operators.tap)((payload) => this.updateLastSeenEventIdFromControl(threadId, payload)));
|
|
460
452
|
}
|
|
461
453
|
observeChannelEvent$(channel, eventName) {
|
|
462
454
|
return ɵobservePhoenixEvent$(channel, eventName);
|
|
463
455
|
}
|
|
464
|
-
createThreadNotifications(payload,
|
|
465
|
-
if (payload.type === _ag_ui_client.EventType.RUN_FINISHED) return [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()];
|
|
456
|
+
createThreadNotifications(payload, options) {
|
|
457
|
+
if (payload.type === _ag_ui_client.EventType.RUN_FINISHED) return options.completeOnRunFinished ? [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()] : [rxjs.Notification.createNext(payload)];
|
|
466
458
|
if (payload.type === _ag_ui_client.EventType.RUN_ERROR) {
|
|
467
459
|
var _message;
|
|
468
460
|
const errorMessage = (_message = payload.message) !== null && _message !== void 0 ? _message : "Run error";
|
|
469
|
-
return completeOnRunError ? [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()] : [rxjs.Notification.createNext(payload), rxjs.Notification.createError(new Error(errorMessage))];
|
|
461
|
+
return options.completeOnRunError ? [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()] : options.errorOnRunError ? [rxjs.Notification.createNext(payload), rxjs.Notification.createError(new Error(errorMessage))] : [rxjs.Notification.createNext(payload)];
|
|
470
462
|
}
|
|
471
463
|
return [rxjs.Notification.createNext(payload)];
|
|
472
464
|
}
|
|
@@ -475,62 +467,60 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
475
467
|
const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
|
|
476
468
|
return new URL(path, new URL(this.config.runtimeUrl, origin)).toString();
|
|
477
469
|
}
|
|
478
|
-
|
|
479
|
-
|
|
470
|
+
createThreadChannelParams(input, streamMode, replayCursor) {
|
|
471
|
+
return streamMode === "run" ? {
|
|
480
472
|
stream_mode: "run",
|
|
481
473
|
run_id: input.runId
|
|
482
474
|
} : {
|
|
483
475
|
stream_mode: "connect",
|
|
484
476
|
last_seen_event_id: replayCursor === void 0 ? this.getReconnectCursor(input) : replayCursor
|
|
485
477
|
};
|
|
486
|
-
return {
|
|
487
|
-
topic: `thread:${input.threadId}`,
|
|
488
|
-
params
|
|
489
|
-
};
|
|
490
478
|
}
|
|
491
479
|
getLastSeenEventId(threadId) {
|
|
492
480
|
var _this$sharedState$las;
|
|
493
481
|
return (_this$sharedState$las = this.sharedState.lastSeenEventIds.get(threadId)) !== null && _this$sharedState$las !== void 0 ? _this$sharedState$las : null;
|
|
494
482
|
}
|
|
495
483
|
getReconnectCursor(input) {
|
|
496
|
-
return this.
|
|
484
|
+
return this.getLastSeenEventId(input.threadId);
|
|
497
485
|
}
|
|
498
|
-
|
|
499
|
-
|
|
486
|
+
clearReconnectCursor(threadId) {
|
|
487
|
+
this.sharedState.lastSeenEventIds.delete(threadId);
|
|
500
488
|
}
|
|
501
489
|
updateLastSeenEventId(threadId, payload) {
|
|
502
490
|
const eventId = this.readEventId(payload);
|
|
503
491
|
if (!eventId) return;
|
|
504
492
|
this.sharedState.lastSeenEventIds.set(threadId, eventId);
|
|
505
493
|
}
|
|
506
|
-
|
|
494
|
+
updateLastSeenEventIdFromControl(threadId, payload) {
|
|
495
|
+
const eventId = this.readControlEventId(payload);
|
|
507
496
|
if (!eventId) return;
|
|
508
497
|
this.sharedState.lastSeenEventIds.set(threadId, eventId);
|
|
509
498
|
}
|
|
510
|
-
/**
|
|
511
|
-
* Keep `this.runId` in sync with the backend's actual run ID.
|
|
512
|
-
*
|
|
513
|
-
* During a `connect` (resume) flow the client generates a fresh `runId`
|
|
514
|
-
* via `prepareRunAgentInput`, but the backend is running under its own
|
|
515
|
-
* run ID. If the client later sends `STOP_RUN_EVENT` with the wrong
|
|
516
|
-
* `runId`, the gateway's runner channel will not match it and the agent
|
|
517
|
-
* keeps running. Extracting the run ID from live events fixes this.
|
|
518
|
-
*
|
|
519
|
-
* The runner normalises events to `run_id` (snake_case) before pushing
|
|
520
|
-
* to the gateway, so we check both `runId` and `run_id`.
|
|
521
|
-
*/
|
|
522
|
-
updateRunIdFromEvent(payload) {
|
|
523
|
-
var _record$runId;
|
|
524
|
-
const record = payload;
|
|
525
|
-
const eventRunId = (_record$runId = record.runId) !== null && _record$runId !== void 0 ? _record$runId : record.run_id;
|
|
526
|
-
if (typeof eventRunId === "string" && eventRunId.length > 0) this.runId = eventRunId;
|
|
527
|
-
}
|
|
528
499
|
readEventId(payload) {
|
|
529
500
|
const metadata = payload.metadata;
|
|
530
501
|
if (!metadata || typeof metadata !== "object") return null;
|
|
531
502
|
const runnerEventId = metadata.cpki_event_id;
|
|
532
503
|
return typeof runnerEventId === "string" ? runnerEventId : null;
|
|
533
504
|
}
|
|
505
|
+
readControlEventId(payload) {
|
|
506
|
+
if (!payload || typeof payload !== "object") return null;
|
|
507
|
+
const latestEventId = payload.latestEventId;
|
|
508
|
+
return typeof latestEventId === "string" ? latestEventId : null;
|
|
509
|
+
}
|
|
510
|
+
applyCanonicalRunIdentity(input, credentials, options) {
|
|
511
|
+
var _credentials$runId;
|
|
512
|
+
this.threadId = credentials.threadId;
|
|
513
|
+
const runId = (_credentials$runId = credentials.runId) !== null && _credentials$runId !== void 0 ? _credentials$runId : options.fallbackToInputRunId ? input.runId : null;
|
|
514
|
+
this.canonicalRunId = runId;
|
|
515
|
+
return {
|
|
516
|
+
...input,
|
|
517
|
+
threadId: credentials.threadId,
|
|
518
|
+
...runId === null ? {} : { runId }
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
isSocketReconnectExhaustedError(error) {
|
|
522
|
+
return error instanceof Error && error.message.includes("WebSocket connection failed after");
|
|
523
|
+
}
|
|
534
524
|
};
|
|
535
525
|
|
|
536
526
|
//#endregion
|
|
@@ -2473,8 +2463,21 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2473
2463
|
CopilotKitCoreErrorCode["TRANSCRIPTION_RATE_LIMITED"] = "transcription_rate_limited";
|
|
2474
2464
|
CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
|
|
2475
2465
|
CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
|
|
2466
|
+
CopilotKitCoreErrorCode["SUBSCRIBER_CALLBACK_FAILED"] = "subscriber_callback_failed";
|
|
2476
2467
|
return CopilotKitCoreErrorCode;
|
|
2477
2468
|
}({});
|
|
2469
|
+
/**
|
|
2470
|
+
* Runtime allowlist derived from {@link SUBSCRIBE_TO_AGENT_KEYS}. Hoisted
|
|
2471
|
+
* to module scope so the Set is allocated once, not per-subscription.
|
|
2472
|
+
*/
|
|
2473
|
+
const ALLOWED_KEYS = new Set([
|
|
2474
|
+
"onMessagesChanged",
|
|
2475
|
+
"onStateChanged",
|
|
2476
|
+
"onRunInitialized",
|
|
2477
|
+
"onRunFinalized",
|
|
2478
|
+
"onRunFailed",
|
|
2479
|
+
"onRunErrorEvent"
|
|
2480
|
+
]);
|
|
2478
2481
|
let CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ function(CopilotKitCoreRuntimeConnectionStatus) {
|
|
2479
2482
|
CopilotKitCoreRuntimeConnectionStatus["Disconnected"] = "disconnected";
|
|
2480
2483
|
CopilotKitCoreRuntimeConnectionStatus["Connected"] = "connected";
|
|
@@ -2543,6 +2546,16 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2543
2546
|
}, "Subscriber onError error:");
|
|
2544
2547
|
}
|
|
2545
2548
|
/**
|
|
2549
|
+
* Log a message to the console and emit an error to subscribers.
|
|
2550
|
+
* Catches failures from `emitError` itself to prevent unhandled rejections.
|
|
2551
|
+
*/
|
|
2552
|
+
logAndEmitError(message, params, logLevel = "error") {
|
|
2553
|
+
console[logLevel](message, params.error);
|
|
2554
|
+
this.emitError(params).catch((emitErr) => {
|
|
2555
|
+
console.error(message + " — emitError itself failed:", emitErr);
|
|
2556
|
+
});
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2546
2559
|
* Snapshot accessors
|
|
2547
2560
|
*/
|
|
2548
2561
|
get context() {
|
|
@@ -2579,17 +2592,30 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2579
2592
|
return this._properties;
|
|
2580
2593
|
}
|
|
2581
2594
|
/**
|
|
2582
|
-
* Default throttle interval (ms)
|
|
2583
|
-
*
|
|
2584
|
-
* `
|
|
2585
|
-
* or `<CopilotChat>` overrides this default and disables throttling.
|
|
2595
|
+
* Default throttle interval (ms) used by `subscribeToAgentWithOptions()`
|
|
2596
|
+
* when the caller does not specify an explicit `throttleMs`.
|
|
2597
|
+
* `undefined` means no default is configured; `0` means no throttling.
|
|
2586
2598
|
*/
|
|
2587
2599
|
get defaultThrottleMs() {
|
|
2588
2600
|
return this._defaultThrottleMs;
|
|
2589
2601
|
}
|
|
2602
|
+
/**
|
|
2603
|
+
* Set the default throttle interval (ms) for `subscribeToAgentWithOptions()`.
|
|
2604
|
+
*
|
|
2605
|
+
* Accepts a non-negative finite number or `undefined` (to clear the
|
|
2606
|
+
* default). Invalid values (NaN, Infinity, negative) are logged as
|
|
2607
|
+
* errors and ignored — the previous valid value is preserved.
|
|
2608
|
+
*/
|
|
2590
2609
|
setDefaultThrottleMs(value) {
|
|
2591
2610
|
if (value !== void 0 && (!Number.isFinite(value) || value < 0)) {
|
|
2592
|
-
this.
|
|
2611
|
+
this.logAndEmitError(`CopilotKitCore.setDefaultThrottleMs: value must be a non-negative finite number or undefined, got ${value}. Keeping current value (${this._defaultThrottleMs}).`, {
|
|
2612
|
+
error: /* @__PURE__ */ new Error(`setDefaultThrottleMs: invalid value (${value}), keeping current value (${this._defaultThrottleMs})`),
|
|
2613
|
+
code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,
|
|
2614
|
+
context: {
|
|
2615
|
+
value,
|
|
2616
|
+
currentValue: this._defaultThrottleMs
|
|
2617
|
+
}
|
|
2618
|
+
});
|
|
2593
2619
|
return;
|
|
2594
2620
|
}
|
|
2595
2621
|
this._defaultThrottleMs = value;
|
|
@@ -2716,6 +2742,138 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2716
2742
|
} };
|
|
2717
2743
|
}
|
|
2718
2744
|
/**
|
|
2745
|
+
* Subscribe to an agent's notification and lifecycle events with
|
|
2746
|
+
* optional configuration (e.g. throttling).
|
|
2747
|
+
*
|
|
2748
|
+
* Wraps every callback with error protection (`safeCall`) and applies
|
|
2749
|
+
* the options before delegating to `agent.subscribe()`.
|
|
2750
|
+
*
|
|
2751
|
+
* See {@link SubscribeToAgentSubscriber} for the accepted callback subset
|
|
2752
|
+
* and the rationale for excluding AG-UI event handlers.
|
|
2753
|
+
*/
|
|
2754
|
+
subscribeToAgentWithOptions(agent, subscriber, options) {
|
|
2755
|
+
var _ref, _options$throttleMs;
|
|
2756
|
+
const resolved = (_ref = (_options$throttleMs = options === null || options === void 0 ? void 0 : options.throttleMs) !== null && _options$throttleMs !== void 0 ? _options$throttleMs : this._defaultThrottleMs) !== null && _ref !== void 0 ? _ref : 0;
|
|
2757
|
+
let effectiveMs = 0;
|
|
2758
|
+
if (!Number.isFinite(resolved) || resolved < 0) {
|
|
2759
|
+
const source = (options === null || options === void 0 ? void 0 : options.throttleMs) !== void 0 ? "throttleMs" : "defaultThrottleMs";
|
|
2760
|
+
this.logAndEmitError(`CopilotKitCore.subscribeToAgentWithOptions: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`, {
|
|
2761
|
+
error: /* @__PURE__ */ new Error(`subscribeToAgentWithOptions: invalid ${source} (${resolved}), falling back to unthrottled`),
|
|
2762
|
+
code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,
|
|
2763
|
+
context: {
|
|
2764
|
+
agentId: agent.agentId,
|
|
2765
|
+
source,
|
|
2766
|
+
value: resolved
|
|
2767
|
+
}
|
|
2768
|
+
});
|
|
2769
|
+
} else effectiveMs = resolved;
|
|
2770
|
+
const agentLabel = agent.agentId || "(unknown agent)";
|
|
2771
|
+
const safeCall = (label, fn, ...args) => {
|
|
2772
|
+
const reportError = (err, verb) => {
|
|
2773
|
+
this.logAndEmitError(`CopilotKitCore.subscribeToAgentWithOptions[${agentLabel}]: ${label} callback ${verb}:`, {
|
|
2774
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
2775
|
+
code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,
|
|
2776
|
+
context: {
|
|
2777
|
+
agentId: agent.agentId,
|
|
2778
|
+
callback: label
|
|
2779
|
+
}
|
|
2780
|
+
});
|
|
2781
|
+
};
|
|
2782
|
+
try {
|
|
2783
|
+
const result = fn(...args);
|
|
2784
|
+
if (result instanceof Promise) return result.catch((err) => {
|
|
2785
|
+
reportError(err, "rejected");
|
|
2786
|
+
});
|
|
2787
|
+
return result;
|
|
2788
|
+
} catch (err) {
|
|
2789
|
+
reportError(err, "threw");
|
|
2790
|
+
}
|
|
2791
|
+
};
|
|
2792
|
+
const guardAll = (sub) => {
|
|
2793
|
+
const guarded = {};
|
|
2794
|
+
if (sub.onMessagesChanged) {
|
|
2795
|
+
const fn = sub.onMessagesChanged;
|
|
2796
|
+
guarded.onMessagesChanged = (params) => safeCall("onMessagesChanged", fn, params);
|
|
2797
|
+
}
|
|
2798
|
+
if (sub.onStateChanged) {
|
|
2799
|
+
const fn = sub.onStateChanged;
|
|
2800
|
+
guarded.onStateChanged = (params) => safeCall("onStateChanged", fn, params);
|
|
2801
|
+
}
|
|
2802
|
+
if (sub.onRunInitialized) {
|
|
2803
|
+
const fn = sub.onRunInitialized;
|
|
2804
|
+
guarded.onRunInitialized = (params) => safeCall("onRunInitialized", fn, params);
|
|
2805
|
+
}
|
|
2806
|
+
if (sub.onRunFinalized) {
|
|
2807
|
+
const fn = sub.onRunFinalized;
|
|
2808
|
+
guarded.onRunFinalized = (params) => safeCall("onRunFinalized", fn, params);
|
|
2809
|
+
}
|
|
2810
|
+
if (sub.onRunFailed) {
|
|
2811
|
+
const fn = sub.onRunFailed;
|
|
2812
|
+
guarded.onRunFailed = (params) => safeCall("onRunFailed", fn, params);
|
|
2813
|
+
}
|
|
2814
|
+
if (sub.onRunErrorEvent) {
|
|
2815
|
+
const fn = sub.onRunErrorEvent;
|
|
2816
|
+
guarded.onRunErrorEvent = (params) => safeCall("onRunErrorEvent", fn, params);
|
|
2817
|
+
}
|
|
2818
|
+
return guarded;
|
|
2819
|
+
};
|
|
2820
|
+
for (const key of Object.keys(subscriber)) if (typeof subscriber[key] === "function" && !ALLOWED_KEYS.has(key)) {
|
|
2821
|
+
const message = `CopilotKitCore.subscribeToAgentWithOptions[${agentLabel}]: callback "${key}" is not supported and was dropped. Supported callbacks: ${Array.from(ALLOWED_KEYS).join(", ")}. Use agent.subscribe() directly for event handlers and per-item notifications.`;
|
|
2822
|
+
this.logAndEmitError(message, {
|
|
2823
|
+
error: new Error(message),
|
|
2824
|
+
code: CopilotKitCoreErrorCode.SUBSCRIBER_CALLBACK_FAILED,
|
|
2825
|
+
context: {
|
|
2826
|
+
agentId: agent.agentId,
|
|
2827
|
+
droppedCallback: key
|
|
2828
|
+
}
|
|
2829
|
+
}, "warn");
|
|
2830
|
+
}
|
|
2831
|
+
if (effectiveMs <= 0) {
|
|
2832
|
+
const subscription = agent.subscribe(guardAll(subscriber));
|
|
2833
|
+
return { unsubscribe: () => subscription.unsubscribe() };
|
|
2834
|
+
}
|
|
2835
|
+
let active = true;
|
|
2836
|
+
let latestMessagesParams = null;
|
|
2837
|
+
let latestStateParams = null;
|
|
2838
|
+
const flushPending = () => {
|
|
2839
|
+
if (active && subscriber.onMessagesChanged && latestMessagesParams) {
|
|
2840
|
+
const params = latestMessagesParams;
|
|
2841
|
+
latestMessagesParams = null;
|
|
2842
|
+
safeCall("onMessagesChanged", subscriber.onMessagesChanged, params);
|
|
2843
|
+
}
|
|
2844
|
+
if (active && subscriber.onStateChanged && latestStateParams) {
|
|
2845
|
+
const params = latestStateParams;
|
|
2846
|
+
latestStateParams = null;
|
|
2847
|
+
safeCall("onStateChanged", subscriber.onStateChanged, params);
|
|
2848
|
+
}
|
|
2849
|
+
};
|
|
2850
|
+
const throttler = new _tanstack_pacer.Throttler(flushPending, {
|
|
2851
|
+
wait: effectiveMs,
|
|
2852
|
+
leading: true,
|
|
2853
|
+
trailing: true
|
|
2854
|
+
});
|
|
2855
|
+
const lifecycleOnly = {};
|
|
2856
|
+
if (subscriber.onRunInitialized) lifecycleOnly.onRunInitialized = subscriber.onRunInitialized;
|
|
2857
|
+
if (subscriber.onRunFinalized) lifecycleOnly.onRunFinalized = subscriber.onRunFinalized;
|
|
2858
|
+
if (subscriber.onRunFailed) lifecycleOnly.onRunFailed = subscriber.onRunFailed;
|
|
2859
|
+
if (subscriber.onRunErrorEvent) lifecycleOnly.onRunErrorEvent = subscriber.onRunErrorEvent;
|
|
2860
|
+
const wrappedSubscriber = guardAll(lifecycleOnly);
|
|
2861
|
+
if (subscriber.onMessagesChanged) wrappedSubscriber.onMessagesChanged = (params) => {
|
|
2862
|
+
latestMessagesParams = params;
|
|
2863
|
+
throttler.maybeExecute();
|
|
2864
|
+
};
|
|
2865
|
+
if (subscriber.onStateChanged) wrappedSubscriber.onStateChanged = (params) => {
|
|
2866
|
+
latestStateParams = params;
|
|
2867
|
+
throttler.maybeExecute();
|
|
2868
|
+
};
|
|
2869
|
+
const subscription = agent.subscribe(wrappedSubscriber);
|
|
2870
|
+
return { unsubscribe: () => {
|
|
2871
|
+
active = false;
|
|
2872
|
+
throttler.cancel();
|
|
2873
|
+
subscription.unsubscribe();
|
|
2874
|
+
} };
|
|
2875
|
+
}
|
|
2876
|
+
/**
|
|
2719
2877
|
* Agent connectivity (delegated to RunHandler)
|
|
2720
2878
|
*/
|
|
2721
2879
|
async connectAgent(params) {
|
|
@@ -3264,15 +3422,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3264
3422
|
threadUpserted: props(),
|
|
3265
3423
|
threadDeleted: props()
|
|
3266
3424
|
});
|
|
3267
|
-
function
|
|
3268
|
-
return [...threads].sort((left, right) =>
|
|
3425
|
+
function sortThreadsByRecency(threads) {
|
|
3426
|
+
return [...threads].sort((left, right) => {
|
|
3427
|
+
var _ref, _left$lastRunAt, _ref2, _right$lastRunAt;
|
|
3428
|
+
const leftKey = (_ref = (_left$lastRunAt = left.lastRunAt) !== null && _left$lastRunAt !== void 0 ? _left$lastRunAt : left.updatedAt) !== null && _ref !== void 0 ? _ref : left.createdAt;
|
|
3429
|
+
return ((_ref2 = (_right$lastRunAt = right.lastRunAt) !== null && _right$lastRunAt !== void 0 ? _right$lastRunAt : right.updatedAt) !== null && _ref2 !== void 0 ? _ref2 : right.createdAt).localeCompare(leftKey);
|
|
3430
|
+
});
|
|
3269
3431
|
}
|
|
3270
3432
|
function upsertThread(threads, thread) {
|
|
3271
3433
|
const existingIndex = threads.findIndex((item) => item.id === thread.id);
|
|
3272
|
-
if (existingIndex === -1) return
|
|
3434
|
+
if (existingIndex === -1) return sortThreadsByRecency([...threads, thread]);
|
|
3273
3435
|
const next = [...threads];
|
|
3274
3436
|
next[existingIndex] = thread;
|
|
3275
|
-
return
|
|
3437
|
+
return sortThreadsByRecency(next);
|
|
3276
3438
|
}
|
|
3277
3439
|
const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.contextChanged, (state, { context }) => ({
|
|
3278
3440
|
...state,
|
|
@@ -3305,7 +3467,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
3305
3467
|
if (sessionId !== state.sessionId) return state;
|
|
3306
3468
|
return {
|
|
3307
3469
|
...state,
|
|
3308
|
-
threads:
|
|
3470
|
+
threads: sortThreadsByRecency(threads),
|
|
3309
3471
|
isLoading: false,
|
|
3310
3472
|
error: null,
|
|
3311
3473
|
metadataJoinCode: joinCode,
|