@copilotkit/core 1.75.0 → 1.75.1
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 +100 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +18 -12
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +101 -29
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +106 -29
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -25,20 +25,23 @@ let zod_to_json_schema = require("zod-to-json-schema");
|
|
|
25
25
|
*
|
|
26
26
|
* `transformChunks` is still applied — message reassembly is needed either way.
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* Connection-local replay hooks track the phase before applying events. An
|
|
29
|
+
* explicitly live RUN_ERROR clears busy without closing the connection;
|
|
30
|
+
* historical errors remain data. Connections without hooks retain the existing
|
|
31
|
+
* completion behavior. Subscriber, detach, and result contracts are preserved.
|
|
31
32
|
*
|
|
32
33
|
* TODO: Remove this in favour of the base implementation once AG-UI's
|
|
33
34
|
* AbstractAgent supports opting out of `verifyEvents` for transports whose
|
|
34
|
-
* connection life-cycle isn't a single run
|
|
35
|
+
* connection life-cycle isn't a single run AND preserves the connection-local
|
|
36
|
+
* replay lifecycle and running-state behavior below. Skipping verification alone
|
|
37
|
+
* is insufficient. As of `@ag-ui/client@0.0.57`
|
|
35
38
|
* `connectAgent(parameters?, subscriber?)` takes no such option.
|
|
36
39
|
*
|
|
37
40
|
* @param agent - The agent whose `connect()` stream should be consumed.
|
|
38
41
|
* @param parameters - Run parameters, forwarded to `prepareRunAgentInput`.
|
|
39
42
|
* @param subscriber - Optional one-shot subscriber for this connect call.
|
|
40
43
|
*/
|
|
41
|
-
async function ɵconnectWithoutEventVerification(agent, parameters, subscriber) {
|
|
44
|
+
async function ɵconnectWithoutEventVerification(agent, parameters, subscriber, connect) {
|
|
42
45
|
const self = agent;
|
|
43
46
|
try {
|
|
44
47
|
agent.isRunning = true;
|
|
@@ -46,10 +49,20 @@ async function ɵconnectWithoutEventVerification(agent, parameters, subscriber)
|
|
|
46
49
|
const input = self.prepareRunAgentInput(parameters);
|
|
47
50
|
let result;
|
|
48
51
|
const previousMessageIds = new Set(agent.messages.map((m) => m.id));
|
|
52
|
+
let isReplaying = true;
|
|
53
|
+
const liveErrors = /* @__PURE__ */ new WeakSet();
|
|
49
54
|
const subscribers = [
|
|
50
|
-
{
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
{
|
|
56
|
+
onRunStartedEvent: () => {
|
|
57
|
+
agent.isRunning = true;
|
|
58
|
+
},
|
|
59
|
+
onRunErrorEvent: ({ event }) => {
|
|
60
|
+
if (liveErrors.has(event)) agent.isRunning = false;
|
|
61
|
+
},
|
|
62
|
+
onRunFinishedEvent: (event) => {
|
|
63
|
+
if (event.outcome === "success") result = event.result;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
53
66
|
...agent.subscribers,
|
|
54
67
|
subscriber ?? {}
|
|
55
68
|
];
|
|
@@ -59,7 +72,18 @@ async function ɵconnectWithoutEventVerification(agent, parameters, subscriber)
|
|
|
59
72
|
self.activeRunCompletionPromise = new Promise((resolve) => {
|
|
60
73
|
resolveCompletion = resolve;
|
|
61
74
|
});
|
|
62
|
-
const
|
|
75
|
+
const lifecycle = {
|
|
76
|
+
onReplayStarted: () => {
|
|
77
|
+
isReplaying = true;
|
|
78
|
+
agent.isRunning = true;
|
|
79
|
+
},
|
|
80
|
+
onReplayFinished: () => {
|
|
81
|
+
isReplaying = false;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const source$ = (0, rxjs.defer)(() => connect ? connect(input, lifecycle) : self.connect(input)).pipe((0, rxjs_operators.tap)((event) => {
|
|
85
|
+
if (!isReplaying && event.type === _ag_ui_client.EventType.RUN_ERROR) liveErrors.add(event);
|
|
86
|
+
}), (0, _ag_ui_client.transformChunks)(self.debugLogger), (0, rxjs_operators.takeUntil)(self.activeRunDetach$));
|
|
63
87
|
const applied$ = self.apply(input, source$, subscribers);
|
|
64
88
|
await (0, rxjs.lastValueFrom)(self.processApplyEvents(input, applied$, subscribers).pipe((0, rxjs_operators.catchError)((error) => {
|
|
65
89
|
agent.isRunning = false;
|
|
@@ -210,6 +234,7 @@ const REPLAY_FAILED_EVENT = "replay_failed";
|
|
|
210
234
|
const STREAM_IDLE_EVENT = "stream_idle";
|
|
211
235
|
const STOP_RUN_EVENT = "stop_run";
|
|
212
236
|
const CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS = 100;
|
|
237
|
+
const CONNECT_IDLE_WARNING_MS = 3e4;
|
|
213
238
|
const MAX_UNOPENED_CREDENTIAL_REFRESHES = 2;
|
|
214
239
|
var AgentThreadLockedError = class extends Error {
|
|
215
240
|
constructor(threadId) {
|
|
@@ -297,7 +322,7 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
297
322
|
...parameters,
|
|
298
323
|
runId: this.canonicalRunId
|
|
299
324
|
};
|
|
300
|
-
return ɵconnectWithoutEventVerification(this, effectiveParameters, subscriber);
|
|
325
|
+
return ɵconnectWithoutEventVerification(this, effectiveParameters, subscriber, (input, lifecycle) => this.connect(input, lifecycle));
|
|
301
326
|
}
|
|
302
327
|
abortRun() {
|
|
303
328
|
if (this.activeChannel && this.canonicalRunId) {
|
|
@@ -346,17 +371,22 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
346
371
|
* gateway only streams events past it instead of replaying the
|
|
347
372
|
* entire history every time the chat re-opens a socket.
|
|
348
373
|
*/
|
|
349
|
-
connect(input) {
|
|
374
|
+
connect(input, lifecycle) {
|
|
350
375
|
this.threadId = input.threadId;
|
|
351
376
|
this.canonicalRunId = null;
|
|
352
377
|
const replayCursor = this.getReconnectCursor(input);
|
|
353
378
|
return (0, rxjs.defer)(() => this.requestJoinCredentials$("connect", input, replayCursor)).pipe((0, rxjs.switchMap)((credentials) => {
|
|
354
|
-
if (credentials === null)
|
|
379
|
+
if (credentials === null) {
|
|
380
|
+
lifecycle?.onReplayStarted?.();
|
|
381
|
+
lifecycle?.onReplayFinished?.();
|
|
382
|
+
return rxjs.EMPTY;
|
|
383
|
+
}
|
|
355
384
|
const canonicalInput = this.applyCanonicalRunIdentity(input, credentials, { fallbackToInputRunId: false });
|
|
356
385
|
return this.observeThread$(canonicalInput, credentials, {
|
|
357
386
|
completeOnRunError: false,
|
|
358
387
|
streamMode: "connect",
|
|
359
|
-
replayCursor
|
|
388
|
+
replayCursor,
|
|
389
|
+
lifecycle
|
|
360
390
|
});
|
|
361
391
|
}));
|
|
362
392
|
}
|
|
@@ -456,8 +486,24 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
456
486
|
}
|
|
457
487
|
observeThreadSession$(input, credentials, options) {
|
|
458
488
|
return (0, rxjs.defer)(() => {
|
|
489
|
+
options.lifecycle?.onReplayStarted?.();
|
|
459
490
|
let ownSocket = null;
|
|
460
491
|
let ownChannel = null;
|
|
492
|
+
let replayFinished = false;
|
|
493
|
+
let warnedAboutIdle = false;
|
|
494
|
+
let idleWarning;
|
|
495
|
+
const clearIdleWarning = () => {
|
|
496
|
+
clearTimeout(idleWarning);
|
|
497
|
+
idleWarning = void 0;
|
|
498
|
+
};
|
|
499
|
+
const scheduleIdleWarning = () => {
|
|
500
|
+
clearIdleWarning();
|
|
501
|
+
if (options.streamMode !== "connect" || !replayFinished || warnedAboutIdle) return;
|
|
502
|
+
idleWarning = setTimeout(() => {
|
|
503
|
+
warnedAboutIdle = true;
|
|
504
|
+
this.debugLogger?.lifecycle("INTELLIGENCE", "No progress or stream_idle for 30 seconds after replay_complete; the run may still be active or its status unavailable.", { threadId: input.threadId });
|
|
505
|
+
}, CONNECT_IDLE_WARNING_MS);
|
|
506
|
+
};
|
|
461
507
|
const socket$ = ɵphoenixSocket$({
|
|
462
508
|
url: credentials.realtime.clientUrl,
|
|
463
509
|
options: {
|
|
@@ -491,6 +537,7 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
491
537
|
let latestObservedReplayCursor = null;
|
|
492
538
|
const threadEvents$ = this.observeThreadEvents$(input.threadId, channel$, options).pipe((0, rxjs_operators.tap)((payload) => {
|
|
493
539
|
latestObservedReplayCursor = this.readEventId(payload) ?? latestObservedReplayCursor;
|
|
540
|
+
scheduleIdleWarning();
|
|
494
541
|
}), (0, rxjs_operators.share)());
|
|
495
542
|
const controlCursor = {
|
|
496
543
|
applied: null,
|
|
@@ -499,18 +546,33 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
499
546
|
const replayFailed$ = channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, REPLAY_FAILED_EVENT)), (0, rxjs_operators.tap)(() => {
|
|
500
547
|
controlCursor.replayFailed = true;
|
|
501
548
|
}));
|
|
502
|
-
const replayComplete$ = this.observeControlEvent$(input.threadId, channel$, REPLAY_COMPLETE_EVENT, controlCursor).pipe((0, rxjs_operators.
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
549
|
+
const replayComplete$ = this.observeControlEvent$(input.threadId, channel$, REPLAY_COMPLETE_EVENT, controlCursor).pipe((0, rxjs_operators.tap)(() => {
|
|
550
|
+
replayFinished = true;
|
|
551
|
+
scheduleIdleWarning();
|
|
552
|
+
options.lifecycle?.onReplayFinished?.();
|
|
553
|
+
}), (0, rxjs_operators.share)());
|
|
554
|
+
const streamIdle$ = this.observeControlEvent$(input.threadId, channel$, STREAM_IDLE_EVENT, controlCursor).pipe((0, rxjs_operators.share)());
|
|
555
|
+
const replayRestart$ = (0, rxjs.merge)(this.observeControlEvent$(input.threadId, channel$, "phx_error", controlCursor), ɵobservePhoenixSocketSignals$(socket$).pipe((0, rxjs_operators.filter)((signal) => signal.type === "error"))).pipe((0, rxjs_operators.tap)(() => {
|
|
556
|
+
replayFinished = false;
|
|
557
|
+
warnedAboutIdle = false;
|
|
558
|
+
clearIdleWarning();
|
|
559
|
+
options.lifecycle?.onReplayStarted?.();
|
|
560
|
+
}), (0, rxjs_operators.share)());
|
|
561
|
+
const streamIdleCompletion$ = options.streamMode === "connect" ? replayRestart$.pipe((0, rxjs_operators.startWith)(null), (0, rxjs.switchMap)(() => (0, rxjs.merge)((0, rxjs.combineLatest)([replayComplete$.pipe((0, rxjs_operators.take)(1)), streamIdle$.pipe((0, rxjs_operators.take)(1))]), streamIdle$.pipe((0, rxjs_operators.take)(1), (0, rxjs_operators.filter)((payload) => this.canFallbackCompleteConnect(payload, reconnectCursor, latestObservedReplayCursor)), (0, rxjs_operators.delay)(CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS), (0, rxjs_operators.tap)(() => {
|
|
562
|
+
this.debugLogger?.lifecycle("INTELLIGENCE", "Completing connection on stream_idle fallback without replay_complete.", {
|
|
563
|
+
threadId: input.threadId,
|
|
564
|
+
fallbackMs: CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS
|
|
565
|
+
});
|
|
566
|
+
})))), (0, rxjs_operators.take)(1), (0, rxjs_operators.shareReplay)({
|
|
507
567
|
bufferSize: 1,
|
|
508
568
|
refCount: true
|
|
509
|
-
}));
|
|
510
|
-
const streamIdleCompletion$ = options.streamMode === "connect" ? (0, rxjs.merge)((0, rxjs.combineLatest)([replayComplete$.pipe((0, rxjs_operators.take)(1)), streamIdle$.pipe((0, rxjs_operators.take)(1))]), streamIdle$.pipe((0, rxjs_operators.take)(1), (0, rxjs_operators.filter)((payload) => this.canFallbackCompleteConnect(payload, reconnectCursor, latestObservedReplayCursor)), (0, rxjs_operators.delay)(CONNECT_STREAM_IDLE_REPLAY_FALLBACK_MS))).pipe((0, rxjs_operators.take)(1)) : rxjs.EMPTY;
|
|
569
|
+
})) : rxjs.EMPTY;
|
|
511
570
|
const threadCompleted$ = threadEvents$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.endWith)(null), (0, rxjs_operators.take)(1));
|
|
512
571
|
const terminal$ = (0, rxjs.merge)(threadCompleted$, streamIdleCompletion$);
|
|
513
|
-
return (0, rxjs.merge)(
|
|
572
|
+
return (0, rxjs.merge)(replayFailed$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.takeUntil)(terminal$)), replayComplete$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.takeUntil)(terminal$)), this.joinThreadChannel$(channel$), this.observeSocketHealth$(socket$, options.onSocketOpen).pipe((0, rxjs_operators.takeUntil)(terminal$)), threadEvents$.pipe((0, rxjs_operators.takeUntil)(streamIdleCompletion$)), streamIdleCompletion$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.takeUntil)(threadCompleted$))).pipe((0, rxjs_operators.finalize)(() => {
|
|
573
|
+
clearIdleWarning();
|
|
574
|
+
this.cleanupOwned(ownChannel, ownSocket);
|
|
575
|
+
}));
|
|
514
576
|
});
|
|
515
577
|
}
|
|
516
578
|
joinThreadChannel$(channel$) {
|
|
@@ -992,7 +1054,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
992
1054
|
});
|
|
993
1055
|
}
|
|
994
1056
|
async connectAgent(parameters, subscriber) {
|
|
995
|
-
if (this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return ɵconnectWithoutEventVerification(this, parameters, subscriber);
|
|
1057
|
+
if (this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return ɵconnectWithoutEventVerification(this, parameters, subscriber, (input, lifecycle) => this.connect(input, lifecycle));
|
|
996
1058
|
if (this.delegate) await this.delegate.detachActiveRun();
|
|
997
1059
|
await this.resolveDelegate();
|
|
998
1060
|
const delegate = this.delegate;
|
|
@@ -1013,7 +1075,10 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1013
1075
|
this.isRunning = false;
|
|
1014
1076
|
},
|
|
1015
1077
|
onRunErrorEvent: () => {
|
|
1016
|
-
this.isRunning =
|
|
1078
|
+
this.isRunning = delegate.isRunning;
|
|
1079
|
+
},
|
|
1080
|
+
onRunStartedEvent: () => {
|
|
1081
|
+
this.isRunning = delegate.isRunning;
|
|
1017
1082
|
}
|
|
1018
1083
|
});
|
|
1019
1084
|
const forwardedSubs = this.subscribers.map((s) => delegate.subscribe(s));
|
|
@@ -1028,9 +1093,9 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1028
1093
|
for (const sub of forwardedSubs) sub.unsubscribe();
|
|
1029
1094
|
}
|
|
1030
1095
|
}
|
|
1031
|
-
connect(input) {
|
|
1032
|
-
if (this.runtimeMode === "pending" || this.transport === "auto" && this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return (0, rxjs.defer)(() => (0, rxjs.from)(this.ensureRuntimeConfiguration())).pipe((0, rxjs_operators.switchMap)(() => this.connect(input)));
|
|
1033
|
-
if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return this.#connectViaDelegate(input);
|
|
1096
|
+
connect(input, lifecycle) {
|
|
1097
|
+
if (this.runtimeMode === "pending" || this.transport === "auto" && this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return (0, rxjs.defer)(() => (0, rxjs.from)(this.ensureRuntimeConfiguration())).pipe((0, rxjs_operators.switchMap)(() => this.connect(input, lifecycle)));
|
|
1098
|
+
if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return this.#connectViaDelegate(input, lifecycle);
|
|
1034
1099
|
return this.#connectViaHttp(input);
|
|
1035
1100
|
}
|
|
1036
1101
|
run(input) {
|
|
@@ -1038,8 +1103,8 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1038
1103
|
if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return this.#runViaDelegate(input);
|
|
1039
1104
|
return this.#runViaHttp(input);
|
|
1040
1105
|
}
|
|
1041
|
-
#connectViaDelegate(input) {
|
|
1042
|
-
return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.connect(input))));
|
|
1106
|
+
#connectViaDelegate(input, lifecycle) {
|
|
1107
|
+
return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.connect(input, lifecycle))));
|
|
1043
1108
|
}
|
|
1044
1109
|
#connectViaHttp(unfiltered) {
|
|
1045
1110
|
const input = this.#applyMessageFilter(unfiltered);
|
|
@@ -1233,6 +1298,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1233
1298
|
delegate.agentId = this.routedAgentId();
|
|
1234
1299
|
delegate.description = this.description;
|
|
1235
1300
|
delegate.threadId = this.threadId;
|
|
1301
|
+
delegate.debugLogger = this.debugLogger;
|
|
1236
1302
|
delegate.setMessages(this.messages);
|
|
1237
1303
|
delegate.setState(this.state);
|
|
1238
1304
|
if (hasHeaders(delegate)) delegate.headers = { ...this.headers };
|
|
@@ -5404,6 +5470,7 @@ const ALLOWED_KEYS = new Set([
|
|
|
5404
5470
|
"onMessagesChanged",
|
|
5405
5471
|
"onStateChanged",
|
|
5406
5472
|
"onRunInitialized",
|
|
5473
|
+
"onRunStartedEvent",
|
|
5407
5474
|
"onRunFinalized",
|
|
5408
5475
|
"onRunFailed",
|
|
5409
5476
|
"onRunErrorEvent"
|
|
@@ -6005,6 +6072,10 @@ var CopilotKitCore = class {
|
|
|
6005
6072
|
const fn = sub.onRunInitialized;
|
|
6006
6073
|
guarded.onRunInitialized = (params) => safeCall("onRunInitialized", fn, params);
|
|
6007
6074
|
}
|
|
6075
|
+
if (sub.onRunStartedEvent) {
|
|
6076
|
+
const fn = sub.onRunStartedEvent;
|
|
6077
|
+
guarded.onRunStartedEvent = (params) => safeCall("onRunStartedEvent", fn, params);
|
|
6078
|
+
}
|
|
6008
6079
|
if (sub.onRunFinalized) {
|
|
6009
6080
|
const fn = sub.onRunFinalized;
|
|
6010
6081
|
guarded.onRunFinalized = (params) => safeCall("onRunFinalized", fn, params);
|
|
@@ -6056,6 +6127,7 @@ var CopilotKitCore = class {
|
|
|
6056
6127
|
});
|
|
6057
6128
|
const lifecycleOnly = {};
|
|
6058
6129
|
if (subscriber.onRunInitialized) lifecycleOnly.onRunInitialized = subscriber.onRunInitialized;
|
|
6130
|
+
if (subscriber.onRunStartedEvent) lifecycleOnly.onRunStartedEvent = subscriber.onRunStartedEvent;
|
|
6059
6131
|
if (subscriber.onRunFinalized) lifecycleOnly.onRunFinalized = subscriber.onRunFinalized;
|
|
6060
6132
|
if (subscriber.onRunFailed) lifecycleOnly.onRunFailed = subscriber.onRunFailed;
|
|
6061
6133
|
if (subscriber.onRunErrorEvent) lifecycleOnly.onRunErrorEvent = subscriber.onRunErrorEvent;
|