@copilotkit/core 1.56.3 → 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 +94 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +9 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +94 -89
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +96 -89
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -128,6 +128,8 @@ function ɵobservePhoenixSocketHealth$(socketSignals$, maxConsecutiveErrors) {
|
|
|
128
128
|
//#endregion
|
|
129
129
|
//#region src/intelligence-agent.ts
|
|
130
130
|
const CLIENT_AG_UI_EVENT = "ag_ui_event";
|
|
131
|
+
const REPLAY_COMPLETE_EVENT = "replay_complete";
|
|
132
|
+
const STREAM_IDLE_EVENT = "stream_idle";
|
|
131
133
|
const STOP_RUN_EVENT = "stop_run";
|
|
132
134
|
var AgentThreadLockedError = class extends Error {
|
|
133
135
|
constructor(threadId) {
|
|
@@ -240,10 +242,14 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
240
242
|
run(input) {
|
|
241
243
|
this.threadId = input.threadId;
|
|
242
244
|
this.canonicalRunId = input.runId;
|
|
243
|
-
return (0, rxjs.defer)(() => this.requestJoinCredentials$("run", input)).pipe((0, rxjs.switchMap)((credentials) =>
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
return (0, rxjs.defer)(() => this.requestJoinCredentials$("run", input)).pipe((0, rxjs.switchMap)((credentials) => {
|
|
246
|
+
if (credentials === null) return (0, rxjs.throwError)(() => /* @__PURE__ */ new Error("REST run request returned no credentials"));
|
|
247
|
+
const canonicalInput = this.applyCanonicalRunIdentity(input, credentials, { fallbackToInputRunId: true });
|
|
248
|
+
return this.observeThread$(canonicalInput, credentials, {
|
|
249
|
+
completeOnRunError: false,
|
|
250
|
+
streamMode: "run"
|
|
251
|
+
});
|
|
252
|
+
}));
|
|
247
253
|
}
|
|
248
254
|
/**
|
|
249
255
|
* Reconnect to an existing thread by fetching websocket credentials and
|
|
@@ -251,19 +257,15 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
251
257
|
*/
|
|
252
258
|
connect(input) {
|
|
253
259
|
this.threadId = input.threadId;
|
|
254
|
-
this.canonicalRunId =
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
completeOnRunError: true,
|
|
264
|
-
streamMode: "connect",
|
|
265
|
-
replayCursor: plan.joinFromEventId
|
|
266
|
-
}));
|
|
260
|
+
this.canonicalRunId = null;
|
|
261
|
+
this.clearReconnectCursor(input.threadId);
|
|
262
|
+
return (0, rxjs.defer)(() => this.requestJoinCredentials$("connect", input)).pipe((0, rxjs.switchMap)((credentials) => {
|
|
263
|
+
if (credentials === null) return rxjs.EMPTY;
|
|
264
|
+
const canonicalInput = this.applyCanonicalRunIdentity(input, credentials, { fallbackToInputRunId: false });
|
|
265
|
+
return this.observeThread$(canonicalInput, credentials, {
|
|
266
|
+
completeOnRunError: false,
|
|
267
|
+
streamMode: "connect"
|
|
268
|
+
});
|
|
267
269
|
}));
|
|
268
270
|
}
|
|
269
271
|
/**
|
|
@@ -280,7 +282,6 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
280
282
|
ownSocket.disconnect();
|
|
281
283
|
if (this.socket === ownSocket) this.socket = null;
|
|
282
284
|
}
|
|
283
|
-
if (this.threadId) this.sharedState.lastSeenEventIds.delete(this.threadId);
|
|
284
285
|
this.canonicalRunId = null;
|
|
285
286
|
}
|
|
286
287
|
cleanup() {
|
|
@@ -302,80 +303,56 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
302
303
|
tools: input.tools,
|
|
303
304
|
context: input.context,
|
|
304
305
|
state: input.state,
|
|
305
|
-
forwardedProps: input.forwardedProps
|
|
306
|
+
forwardedProps: input.forwardedProps,
|
|
307
|
+
...mode === "connect" ? { lastSeenEventId: this.getReconnectCursor(input) } : {}
|
|
306
308
|
}),
|
|
307
309
|
...this.config.credentials ? { credentials: this.config.credentials } : {}
|
|
308
310
|
});
|
|
309
|
-
if (response.status ===
|
|
311
|
+
if (response.status === 204 && mode === "connect") return null;
|
|
312
|
+
if (response.status === 409 && mode === "run") throw new AgentThreadLockedError(input.threadId);
|
|
310
313
|
if (!response.ok) {
|
|
311
314
|
const text = await response.text().catch(() => "");
|
|
312
315
|
throw new Error(text || response.statusText || String(response.status));
|
|
313
316
|
}
|
|
314
|
-
|
|
315
|
-
if (!payload.joinToken) throw new Error("missing joinToken");
|
|
316
|
-
return { joinToken: payload.joinToken };
|
|
317
|
+
return this.normalizeJoinCredentials(await response.json(), input);
|
|
317
318
|
} catch (error) {
|
|
318
319
|
if (error instanceof AgentThreadLockedError) throw error;
|
|
319
320
|
throw new Error(`REST ${mode} request failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
320
321
|
}
|
|
321
322
|
});
|
|
322
323
|
}
|
|
323
|
-
|
|
324
|
-
return (0, rxjs.defer)(async () => {
|
|
325
|
-
try {
|
|
326
|
-
const response = await fetch(this.buildRuntimeUrl("connect"), {
|
|
327
|
-
method: "POST",
|
|
328
|
-
headers: {
|
|
329
|
-
"Content-Type": "application/json",
|
|
330
|
-
...this.config.headers
|
|
331
|
-
},
|
|
332
|
-
body: JSON.stringify({
|
|
333
|
-
threadId: input.threadId,
|
|
334
|
-
runId: input.runId,
|
|
335
|
-
messages: input.messages,
|
|
336
|
-
tools: input.tools,
|
|
337
|
-
context: input.context,
|
|
338
|
-
state: input.state,
|
|
339
|
-
forwardedProps: input.forwardedProps,
|
|
340
|
-
lastSeenEventId: this.getReconnectCursor(input)
|
|
341
|
-
}),
|
|
342
|
-
...this.config.credentials ? { credentials: this.config.credentials } : {}
|
|
343
|
-
});
|
|
344
|
-
if (response.status === 204) return null;
|
|
345
|
-
if (!response.ok) {
|
|
346
|
-
const text = await response.text().catch(() => "");
|
|
347
|
-
throw new Error(text || response.statusText || String(response.status));
|
|
348
|
-
}
|
|
349
|
-
return this.normalizeConnectPlan(await response.json());
|
|
350
|
-
} catch (error) {
|
|
351
|
-
throw new Error(`REST connect request failed: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
normalizeConnectPlan(payload) {
|
|
324
|
+
normalizeJoinCredentials(payload, input) {
|
|
356
325
|
const envelope = payload && typeof payload === "object" ? payload : null;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
326
|
+
const realtime = envelope?.realtime && typeof envelope.realtime === "object" ? envelope.realtime : null;
|
|
327
|
+
if (typeof envelope?.joinToken !== "string" || !envelope.joinToken) throw new Error("missing joinToken");
|
|
328
|
+
if (typeof realtime?.clientUrl !== "string" || !realtime.clientUrl) throw new Error("missing realtime.clientUrl");
|
|
329
|
+
if (typeof realtime.topic !== "string" || !realtime.topic) throw new Error("missing realtime.topic");
|
|
330
|
+
return {
|
|
331
|
+
threadId: typeof envelope.threadId === "string" && envelope.threadId ? envelope.threadId : input.threadId,
|
|
332
|
+
runId: typeof envelope.runId === "string" && envelope.runId ? envelope.runId : null,
|
|
333
|
+
joinToken: envelope.joinToken,
|
|
334
|
+
realtime: {
|
|
335
|
+
clientUrl: realtime.clientUrl,
|
|
336
|
+
topic: realtime.topic
|
|
337
|
+
}
|
|
361
338
|
};
|
|
362
|
-
if (envelope?.mode === "live") {
|
|
363
|
-
if (typeof envelope.joinToken !== "string" || envelope.joinToken.length === 0) throw new Error("missing joinToken");
|
|
364
|
-
return {
|
|
365
|
-
mode: "live",
|
|
366
|
-
joinToken: envelope.joinToken,
|
|
367
|
-
joinFromEventId: typeof envelope.joinFromEventId === "string" ? envelope.joinFromEventId : null,
|
|
368
|
-
events: Array.isArray(envelope.events) ? envelope.events : []
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
throw new Error("invalid connect plan");
|
|
372
339
|
}
|
|
373
340
|
observeThread$(input, credentials, options) {
|
|
341
|
+
return this.observeThreadSession$(input, credentials, options).pipe((0, rxjs_operators.catchError)((error) => {
|
|
342
|
+
if (!this.isSocketReconnectExhaustedError(error)) return (0, rxjs.throwError)(() => error);
|
|
343
|
+
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, {
|
|
344
|
+
...options,
|
|
345
|
+
channelMode: "connect",
|
|
346
|
+
replayCursor: this.getReconnectCursor(input)
|
|
347
|
+
})));
|
|
348
|
+
}));
|
|
349
|
+
}
|
|
350
|
+
observeThreadSession$(input, credentials, options) {
|
|
374
351
|
return (0, rxjs.defer)(() => {
|
|
375
352
|
let ownSocket = null;
|
|
376
353
|
let ownChannel = null;
|
|
377
354
|
const socket$ = ɵphoenixSocket$({
|
|
378
|
-
url:
|
|
355
|
+
url: credentials.realtime.clientUrl,
|
|
379
356
|
options: {
|
|
380
357
|
params: {
|
|
381
358
|
...this.config.socketParams,
|
|
@@ -391,10 +368,10 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
391
368
|
bufferSize: 1,
|
|
392
369
|
refCount: true
|
|
393
370
|
}));
|
|
394
|
-
const
|
|
371
|
+
const params = this.createThreadChannelParams(input, options.channelMode ?? options.streamMode, options.replayCursor);
|
|
395
372
|
const channel$ = ɵphoenixChannel$({
|
|
396
373
|
socket$,
|
|
397
|
-
topic,
|
|
374
|
+
topic: credentials.realtime.topic,
|
|
398
375
|
params
|
|
399
376
|
}).pipe((0, rxjs_operators.tap)(({ channel }) => {
|
|
400
377
|
ownChannel = channel;
|
|
@@ -404,8 +381,14 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
404
381
|
refCount: true
|
|
405
382
|
}));
|
|
406
383
|
const threadEvents$ = this.observeThreadEvents$(input.threadId, channel$, options).pipe((0, rxjs_operators.share)());
|
|
407
|
-
const
|
|
408
|
-
|
|
384
|
+
const replayComplete$ = this.observeControlEvent$(input.threadId, channel$, REPLAY_COMPLETE_EVENT).pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.share)());
|
|
385
|
+
const streamIdle$ = this.observeControlEvent$(input.threadId, channel$, STREAM_IDLE_EVENT).pipe((0, rxjs_operators.shareReplay)({
|
|
386
|
+
bufferSize: 1,
|
|
387
|
+
refCount: true
|
|
388
|
+
}));
|
|
389
|
+
const streamIdleCompletion$ = options.streamMode === "connect" ? streamIdle$.pipe((0, rxjs_operators.take)(1)) : rxjs.EMPTY;
|
|
390
|
+
const terminal$ = (0, rxjs.merge)(threadEvents$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.endWith)(null), (0, rxjs_operators.take)(1)), streamIdleCompletion$);
|
|
391
|
+
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)));
|
|
409
392
|
});
|
|
410
393
|
}
|
|
411
394
|
joinThreadChannel$(channel$) {
|
|
@@ -417,16 +400,23 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
417
400
|
observeThreadEvents$(threadId, channel$, options) {
|
|
418
401
|
return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, CLIENT_AG_UI_EVENT)), (0, rxjs_operators.tap)((payload) => {
|
|
419
402
|
this.updateLastSeenEventId(threadId, payload);
|
|
420
|
-
}), (0, rxjs_operators.mergeMap)((payload) =>
|
|
403
|
+
}), (0, rxjs_operators.mergeMap)((payload) => this.createThreadNotifications(payload, {
|
|
404
|
+
completeOnRunError: options.completeOnRunError,
|
|
405
|
+
completeOnRunFinished: options.streamMode === "run",
|
|
406
|
+
errorOnRunError: options.streamMode === "run"
|
|
407
|
+
})), (0, rxjs.dematerialize)());
|
|
408
|
+
}
|
|
409
|
+
observeControlEvent$(threadId, channel$, eventName) {
|
|
410
|
+
return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, eventName)), (0, rxjs_operators.tap)((payload) => this.updateLastSeenEventIdFromControl(threadId, payload)));
|
|
421
411
|
}
|
|
422
412
|
observeChannelEvent$(channel, eventName) {
|
|
423
413
|
return ɵobservePhoenixEvent$(channel, eventName);
|
|
424
414
|
}
|
|
425
|
-
createThreadNotifications(payload,
|
|
426
|
-
if (payload.type === _ag_ui_client.EventType.RUN_FINISHED) return [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()];
|
|
415
|
+
createThreadNotifications(payload, options) {
|
|
416
|
+
if (payload.type === _ag_ui_client.EventType.RUN_FINISHED) return options.completeOnRunFinished ? [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()] : [rxjs.Notification.createNext(payload)];
|
|
427
417
|
if (payload.type === _ag_ui_client.EventType.RUN_ERROR) {
|
|
428
418
|
const errorMessage = payload.message ?? "Run error";
|
|
429
|
-
return completeOnRunError ? [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()] : [rxjs.Notification.createNext(payload), rxjs.Notification.createError(new Error(errorMessage))];
|
|
419
|
+
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)];
|
|
430
420
|
}
|
|
431
421
|
return [rxjs.Notification.createNext(payload)];
|
|
432
422
|
}
|
|
@@ -435,34 +425,31 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
435
425
|
const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
|
|
436
426
|
return new URL(path, new URL(this.config.runtimeUrl, origin)).toString();
|
|
437
427
|
}
|
|
438
|
-
|
|
439
|
-
|
|
428
|
+
createThreadChannelParams(input, streamMode, replayCursor) {
|
|
429
|
+
return streamMode === "run" ? {
|
|
440
430
|
stream_mode: "run",
|
|
441
431
|
run_id: input.runId
|
|
442
432
|
} : {
|
|
443
433
|
stream_mode: "connect",
|
|
444
434
|
last_seen_event_id: replayCursor === void 0 ? this.getReconnectCursor(input) : replayCursor
|
|
445
435
|
};
|
|
446
|
-
return {
|
|
447
|
-
topic: `thread:${input.threadId}`,
|
|
448
|
-
params
|
|
449
|
-
};
|
|
450
436
|
}
|
|
451
437
|
getLastSeenEventId(threadId) {
|
|
452
438
|
return this.sharedState.lastSeenEventIds.get(threadId) ?? null;
|
|
453
439
|
}
|
|
454
440
|
getReconnectCursor(input) {
|
|
455
|
-
return this.
|
|
441
|
+
return this.getLastSeenEventId(input.threadId);
|
|
456
442
|
}
|
|
457
|
-
|
|
458
|
-
|
|
443
|
+
clearReconnectCursor(threadId) {
|
|
444
|
+
this.sharedState.lastSeenEventIds.delete(threadId);
|
|
459
445
|
}
|
|
460
446
|
updateLastSeenEventId(threadId, payload) {
|
|
461
447
|
const eventId = this.readEventId(payload);
|
|
462
448
|
if (!eventId) return;
|
|
463
449
|
this.sharedState.lastSeenEventIds.set(threadId, eventId);
|
|
464
450
|
}
|
|
465
|
-
|
|
451
|
+
updateLastSeenEventIdFromControl(threadId, payload) {
|
|
452
|
+
const eventId = this.readControlEventId(payload);
|
|
466
453
|
if (!eventId) return;
|
|
467
454
|
this.sharedState.lastSeenEventIds.set(threadId, eventId);
|
|
468
455
|
}
|
|
@@ -472,6 +459,24 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
472
459
|
const runnerEventId = metadata.cpki_event_id;
|
|
473
460
|
return typeof runnerEventId === "string" ? runnerEventId : null;
|
|
474
461
|
}
|
|
462
|
+
readControlEventId(payload) {
|
|
463
|
+
if (!payload || typeof payload !== "object") return null;
|
|
464
|
+
const latestEventId = payload.latestEventId;
|
|
465
|
+
return typeof latestEventId === "string" ? latestEventId : null;
|
|
466
|
+
}
|
|
467
|
+
applyCanonicalRunIdentity(input, credentials, options) {
|
|
468
|
+
this.threadId = credentials.threadId;
|
|
469
|
+
const runId = credentials.runId ?? (options.fallbackToInputRunId ? input.runId : null);
|
|
470
|
+
this.canonicalRunId = runId;
|
|
471
|
+
return {
|
|
472
|
+
...input,
|
|
473
|
+
threadId: credentials.threadId,
|
|
474
|
+
...runId === null ? {} : { runId }
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
isSocketReconnectExhaustedError(error) {
|
|
478
|
+
return error instanceof Error && error.message.includes("WebSocket connection failed after");
|
|
479
|
+
}
|
|
475
480
|
};
|
|
476
481
|
|
|
477
482
|
//#endregion
|