@copilotkit/core 1.57.0 → 1.57.1-canary.1778272612
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 +183 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +174 -84
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +173 -83
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +183 -52
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +172 -59
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -254,10 +254,22 @@ var IntelligenceAgent = class IntelligenceAgent extends AbstractAgent {
|
|
|
254
254
|
* Reconnect to an existing thread by fetching websocket credentials and
|
|
255
255
|
* joining the realtime thread channel.
|
|
256
256
|
*/
|
|
257
|
+
/**
|
|
258
|
+
* Reconnect to an existing thread by fetching websocket credentials
|
|
259
|
+
* and joining the realtime thread channel.
|
|
260
|
+
*
|
|
261
|
+
* Note: this method does NOT clear the replay cursor. Whether to
|
|
262
|
+
* request a full historical replay vs. resume from
|
|
263
|
+
* `lastSeenEventId` is a decision the caller (typically
|
|
264
|
+
* `RunHandler.connectAgent`) makes by calling
|
|
265
|
+
* {@link clearReconnectCursor} ahead of time on a fresh thread
|
|
266
|
+
* restore. Same-thread churn re-connects preserve the cursor so the
|
|
267
|
+
* gateway only streams events past it instead of replaying the
|
|
268
|
+
* entire history every time the chat re-opens a socket.
|
|
269
|
+
*/
|
|
257
270
|
connect(input) {
|
|
258
271
|
this.threadId = input.threadId;
|
|
259
272
|
this.canonicalRunId = null;
|
|
260
|
-
this.clearReconnectCursor(input.threadId);
|
|
261
273
|
return defer(() => this.requestJoinCredentials$("connect", input)).pipe(switchMap((credentials) => {
|
|
262
274
|
if (credentials === null) return EMPTY;
|
|
263
275
|
const canonicalInput = this.applyCanonicalRunIdentity(input, credentials, { fallbackToInputRunId: false });
|
|
@@ -439,6 +451,14 @@ var IntelligenceAgent = class IntelligenceAgent extends AbstractAgent {
|
|
|
439
451
|
getReconnectCursor(input) {
|
|
440
452
|
return this.getLastSeenEventId(input.threadId);
|
|
441
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Drop the cached `lastSeenEventId` cursor for `threadId` so the
|
|
456
|
+
* next connect to that topic asks the gateway for a full historical
|
|
457
|
+
* replay (rather than resuming). Public because
|
|
458
|
+
* `RunHandler.connectAgent` calls it on a detected thread switch
|
|
459
|
+
* to rebuild local state from scratch, and skips it on same-thread
|
|
460
|
+
* churn so the gateway can resume.
|
|
461
|
+
*/
|
|
442
462
|
clearReconnectCursor(threadId) {
|
|
443
463
|
this.sharedState.lastSeenEventIds.delete(threadId);
|
|
444
464
|
}
|
|
@@ -501,6 +521,7 @@ function withAbortErrorHandling(observable) {
|
|
|
501
521
|
var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAgent {
|
|
502
522
|
runtimeUrl;
|
|
503
523
|
credentials;
|
|
524
|
+
runtimeAgentId;
|
|
504
525
|
transport;
|
|
505
526
|
singleEndpointUrl;
|
|
506
527
|
runtimeMode;
|
|
@@ -511,7 +532,8 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
511
532
|
constructor(config) {
|
|
512
533
|
const normalizedRuntimeUrl = config.runtimeUrl ? config.runtimeUrl.replace(/\/$/, "") : void 0;
|
|
513
534
|
const transport = config.transport ?? "auto";
|
|
514
|
-
const
|
|
535
|
+
const routedId = config.runtimeAgentId ?? config.agentId ?? "";
|
|
536
|
+
const runUrl = transport === "single" ? normalizedRuntimeUrl ?? config.runtimeUrl ?? "" : `${normalizedRuntimeUrl ?? config.runtimeUrl}/agent/${encodeURIComponent(routedId)}/run`;
|
|
515
537
|
if (!runUrl) throw new Error("ProxiedCopilotRuntimeAgent requires a runtimeUrl when transport is set to 'single'.");
|
|
516
538
|
super({
|
|
517
539
|
...config,
|
|
@@ -519,6 +541,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
519
541
|
});
|
|
520
542
|
this.runtimeUrl = normalizedRuntimeUrl ?? config.runtimeUrl;
|
|
521
543
|
this.credentials = config.credentials;
|
|
544
|
+
this.runtimeAgentId = config.runtimeAgentId;
|
|
522
545
|
this.transport = transport;
|
|
523
546
|
this.runtimeMode = config.runtimeMode ?? RUNTIME_MODE_SSE;
|
|
524
547
|
this.intelligence = config.intelligence;
|
|
@@ -526,6 +549,21 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
526
549
|
if (config.debug) this.debug = config.debug;
|
|
527
550
|
if (this.transport === "single") this.singleEndpointUrl = this.runtimeUrl;
|
|
528
551
|
}
|
|
552
|
+
/**
|
|
553
|
+
* The agent id used for outbound runtime requests — `runtimeAgentId` when
|
|
554
|
+
* set (manually-registered proxy), otherwise `agentId` (registry id
|
|
555
|
+
* matches runtime id). Subscriber bookkeeping keeps using `agentId`
|
|
556
|
+
* directly.
|
|
557
|
+
*
|
|
558
|
+
* Throws when both are unset: a proxy reaching an HTTP path with no
|
|
559
|
+
* routable id is a bug, and a missing id would otherwise produce a
|
|
560
|
+
* malformed `/agent//run` or `/agent/undefined/connect` URL silently.
|
|
561
|
+
*/
|
|
562
|
+
routedAgentId() {
|
|
563
|
+
const id = this.runtimeAgentId ?? this.agentId;
|
|
564
|
+
if (!id) throw new Error("ProxiedCopilotRuntimeAgent: cannot make a runtime request without an agentId or runtimeAgentId.");
|
|
565
|
+
return id;
|
|
566
|
+
}
|
|
529
567
|
get capabilities() {
|
|
530
568
|
return this._capabilities;
|
|
531
569
|
}
|
|
@@ -545,6 +583,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
545
583
|
}
|
|
546
584
|
if (!this.agentId || !this.threadId) return;
|
|
547
585
|
if (typeof fetch === "undefined") return;
|
|
586
|
+
const routedId = this.routedAgentId();
|
|
548
587
|
if (this.transport === "single") {
|
|
549
588
|
if (!this.singleEndpointUrl) return;
|
|
550
589
|
const headers = new Headers({
|
|
@@ -557,7 +596,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
557
596
|
body: JSON.stringify({
|
|
558
597
|
method: "agent/stop",
|
|
559
598
|
params: {
|
|
560
|
-
agentId:
|
|
599
|
+
agentId: routedId,
|
|
561
600
|
threadId: this.threadId
|
|
562
601
|
}
|
|
563
602
|
}),
|
|
@@ -568,7 +607,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
568
607
|
return;
|
|
569
608
|
}
|
|
570
609
|
if (!this.runtimeUrl) return;
|
|
571
|
-
const stopPath = `${this.runtimeUrl}/agent/${encodeURIComponent(
|
|
610
|
+
const stopPath = `${this.runtimeUrl}/agent/${encodeURIComponent(routedId)}/stop/${encodeURIComponent(this.threadId)}`;
|
|
572
611
|
const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
|
|
573
612
|
const base = new URL(this.runtimeUrl, origin);
|
|
574
613
|
const stopUrl = new URL(stopPath, base);
|
|
@@ -632,12 +671,13 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
632
671
|
return defer(() => from(this.resolveDelegate())).pipe(switchMap$1((delegate) => withAbortErrorHandling(delegate.connect(input))));
|
|
633
672
|
}
|
|
634
673
|
#connectViaHttp(input) {
|
|
674
|
+
const routedId = this.routedAgentId();
|
|
635
675
|
if (this.transport === "single") {
|
|
636
676
|
if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
|
|
637
|
-
const requestInit = this.createSingleRouteRequestInit(input, "agent/connect", { agentId:
|
|
677
|
+
const requestInit = this.createSingleRouteRequestInit(input, "agent/connect", { agentId: routedId });
|
|
638
678
|
return withAbortErrorHandling(transformHttpEventStream(runHttpRequest(this.singleEndpointUrl, requestInit)));
|
|
639
679
|
}
|
|
640
|
-
return withAbortErrorHandling(transformHttpEventStream(runHttpRequest(`${this.runtimeUrl}/agent/${
|
|
680
|
+
return withAbortErrorHandling(transformHttpEventStream(runHttpRequest(`${this.runtimeUrl}/agent/${routedId}/connect`, this.requestInit(input))));
|
|
641
681
|
}
|
|
642
682
|
#runViaDelegate(input) {
|
|
643
683
|
return defer(() => from(this.resolveDelegate())).pipe(switchMap$1((delegate) => withAbortErrorHandling(delegate.run(input))));
|
|
@@ -645,7 +685,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
645
685
|
#runViaHttp(input) {
|
|
646
686
|
if (this.transport === "single") {
|
|
647
687
|
if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
|
|
648
|
-
const requestInit = this.createSingleRouteRequestInit(input, "agent/run", { agentId: this.
|
|
688
|
+
const requestInit = this.createSingleRouteRequestInit(input, "agent/run", { agentId: this.routedAgentId() });
|
|
649
689
|
return withAbortErrorHandling(transformHttpEventStream(runHttpRequest(this.singleEndpointUrl, requestInit)));
|
|
650
690
|
}
|
|
651
691
|
return withAbortErrorHandling(super.run(input));
|
|
@@ -654,6 +694,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
654
694
|
const cloned = new ProxiedCopilotRuntimeAgent({
|
|
655
695
|
runtimeUrl: this.runtimeUrl,
|
|
656
696
|
agentId: this.agentId,
|
|
697
|
+
runtimeAgentId: this.runtimeAgentId,
|
|
657
698
|
description: this.description,
|
|
658
699
|
headers: { ...this.headers },
|
|
659
700
|
credentials: this.credentials,
|
|
@@ -672,6 +713,22 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
672
713
|
}
|
|
673
714
|
return cloned;
|
|
674
715
|
}
|
|
716
|
+
/**
|
|
717
|
+
* Drop the delegate's cached `lastSeenEventId` for this thread so
|
|
718
|
+
* the next connect requests a full historical replay from the
|
|
719
|
+
* gateway. Used by `RunHandler.connectAgent` on a detected thread
|
|
720
|
+
* switch (the chat moved between threads, so its local
|
|
721
|
+
* messages/state are about to be cleared and need rebuilding from
|
|
722
|
+
* the gateway). Skipped on same-thread churn re-connects so the
|
|
723
|
+
* gateway can resume from the cursor instead.
|
|
724
|
+
*
|
|
725
|
+
* No-op for non-Intelligence runtime modes — the HTTP transport
|
|
726
|
+
* doesn't replay.
|
|
727
|
+
*/
|
|
728
|
+
clearReplayCursor(threadId) {
|
|
729
|
+
if (this.runtimeMode !== RUNTIME_MODE_INTELLIGENCE) return;
|
|
730
|
+
this.delegate?.clearReconnectCursor?.(threadId);
|
|
731
|
+
}
|
|
675
732
|
async resolveDelegate() {
|
|
676
733
|
await this.ensureRuntimeMode();
|
|
677
734
|
if (!this.delegate) {
|
|
@@ -762,17 +819,18 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends HttpAg
|
|
|
762
819
|
};
|
|
763
820
|
}
|
|
764
821
|
createIntelligenceDelegate() {
|
|
765
|
-
|
|
822
|
+
const routedId = this.routedAgentId();
|
|
823
|
+
if (!this.runtimeUrl || !routedId || !this.intelligence?.wsUrl) throw new Error("Intelligence mode requires runtimeUrl, agentId, and intelligence websocket metadata");
|
|
766
824
|
return new IntelligenceAgent({
|
|
767
825
|
url: this.intelligence.wsUrl,
|
|
768
826
|
runtimeUrl: this.runtimeUrl,
|
|
769
|
-
agentId:
|
|
827
|
+
agentId: routedId,
|
|
770
828
|
headers: { ...this.headers },
|
|
771
829
|
credentials: this.credentials
|
|
772
830
|
});
|
|
773
831
|
}
|
|
774
832
|
syncDelegate(delegate) {
|
|
775
|
-
delegate.agentId = this.
|
|
833
|
+
delegate.agentId = this.routedAgentId();
|
|
776
834
|
delegate.description = this.description;
|
|
777
835
|
delegate.threadId = this.threadId;
|
|
778
836
|
delegate.setMessages(this.messages);
|
|
@@ -906,6 +964,52 @@ var AgentRegistry = class {
|
|
|
906
964
|
this.notifyAgentsChanged();
|
|
907
965
|
}
|
|
908
966
|
/**
|
|
967
|
+
* Register a proxied agent that routes outbound runtime requests to an
|
|
968
|
+
* existing runtime agent (`runtimeAgentId`) while exposing a distinct local
|
|
969
|
+
* registry id (`agentId`). Throws if `agentId` is already taken by either a
|
|
970
|
+
* local or runtime-discovered agent.
|
|
971
|
+
*
|
|
972
|
+
* Use this to mount multiple frontend agents against a single runtime
|
|
973
|
+
* agent (e.g. a chat-1 / chat-2 pair both proxying to "default") without
|
|
974
|
+
* implicit per-thread cloning. The returned `unregister` removes the proxy
|
|
975
|
+
* from the registry and emits `onAgentsChanged`.
|
|
976
|
+
*/
|
|
977
|
+
registerProxiedAgent({ agentId, runtimeAgentId }) {
|
|
978
|
+
if (Object.prototype.hasOwnProperty.call(this._agents, agentId)) throw new Error(`CopilotKitCore.registerProxiedAgent: agentId "${agentId}" is already registered. Pick a different agentId, or unregister the existing agent first.`);
|
|
979
|
+
const friends = this.core;
|
|
980
|
+
const debug = friends.debug;
|
|
981
|
+
const agent = new ProxiedCopilotRuntimeAgent({
|
|
982
|
+
runtimeUrl: this._runtimeUrl,
|
|
983
|
+
agentId,
|
|
984
|
+
runtimeAgentId,
|
|
985
|
+
transport: this._runtimeTransport,
|
|
986
|
+
credentials: friends.credentials,
|
|
987
|
+
runtimeMode: this._runtimeUrl ? this._runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connected ? this._runtimeMode : "pending" : RUNTIME_MODE_SSE,
|
|
988
|
+
intelligence: this._intelligence,
|
|
989
|
+
debug: debug ? resolveDebugConfig(debug) : void 0
|
|
990
|
+
});
|
|
991
|
+
this.applyHeadersToAgent(agent);
|
|
992
|
+
this.localAgents[agentId] = agent;
|
|
993
|
+
this._agents = {
|
|
994
|
+
...this.localAgents,
|
|
995
|
+
...this.remoteAgents
|
|
996
|
+
};
|
|
997
|
+
this.notifyAgentsChanged();
|
|
998
|
+
return {
|
|
999
|
+
agent,
|
|
1000
|
+
unregister: () => {
|
|
1001
|
+
if (this.localAgents[agentId] === agent) {
|
|
1002
|
+
delete this.localAgents[agentId];
|
|
1003
|
+
this._agents = {
|
|
1004
|
+
...this.localAgents,
|
|
1005
|
+
...this.remoteAgents
|
|
1006
|
+
};
|
|
1007
|
+
this.notifyAgentsChanged();
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
909
1013
|
* Get an agent by ID
|
|
910
1014
|
*/
|
|
911
1015
|
getAgent(id) {
|
|
@@ -1185,16 +1289,10 @@ var SuggestionEngine = class {
|
|
|
1185
1289
|
/**
|
|
1186
1290
|
* Reload suggestions for a specific agent
|
|
1187
1291
|
* This triggers generation of new suggestions based on current configs
|
|
1188
|
-
*
|
|
1189
|
-
* @param agentId - The consumer agent ID
|
|
1190
|
-
* @param consumerAgent - Optional: the specific agent instance whose messages should be used
|
|
1191
|
-
* for availability filtering and context. When running with per-thread clones, the thread
|
|
1192
|
-
* clone holds the conversation messages; passing it here ensures dynamic suggestions fire
|
|
1193
|
-
* after the first message even though the registry agent has an empty message list.
|
|
1194
1292
|
*/
|
|
1195
|
-
reloadSuggestions(agentId
|
|
1293
|
+
reloadSuggestions(agentId) {
|
|
1196
1294
|
this.clearSuggestions(agentId);
|
|
1197
|
-
const agent =
|
|
1295
|
+
const agent = this.core.getAgent(agentId);
|
|
1198
1296
|
const messageCount = agent?.messages?.length ?? 0;
|
|
1199
1297
|
let hasAnySuggestions = false;
|
|
1200
1298
|
for (const config of Object.values(this._suggestionsConfig)) {
|
|
@@ -1207,7 +1305,7 @@ var SuggestionEngine = class {
|
|
|
1207
1305
|
hasAnySuggestions = true;
|
|
1208
1306
|
this.notifySuggestionsStartedLoading(agentId);
|
|
1209
1307
|
}
|
|
1210
|
-
this.generateSuggestions(suggestionId, config, agentId
|
|
1308
|
+
this.generateSuggestions(suggestionId, config, agentId);
|
|
1211
1309
|
} else if (isStaticSuggestionsConfig(config)) this.addStaticSuggestions(suggestionId, config, agentId);
|
|
1212
1310
|
}
|
|
1213
1311
|
}
|
|
@@ -1235,12 +1333,12 @@ var SuggestionEngine = class {
|
|
|
1235
1333
|
/**
|
|
1236
1334
|
* Generate suggestions using a provider agent
|
|
1237
1335
|
*/
|
|
1238
|
-
async generateSuggestions(suggestionId, config, consumerAgentId
|
|
1336
|
+
async generateSuggestions(suggestionId, config, consumerAgentId) {
|
|
1239
1337
|
let agent = void 0;
|
|
1240
1338
|
try {
|
|
1241
1339
|
const suggestionsProviderAgent = this.core.getAgent(config.providerAgentId ?? "default");
|
|
1242
1340
|
if (!suggestionsProviderAgent) throw new Error(`Suggestions provider agent not found: ${config.providerAgentId}`);
|
|
1243
|
-
const suggestionsConsumerAgent =
|
|
1341
|
+
const suggestionsConsumerAgent = this.core.getAgent(consumerAgentId);
|
|
1244
1342
|
if (!suggestionsConsumerAgent) throw new Error(`Suggestions consumer agent not found: ${consumerAgentId}`);
|
|
1245
1343
|
agent = suggestionsProviderAgent.clone();
|
|
1246
1344
|
agent.threadId = suggestionId;
|
|
@@ -1468,6 +1566,23 @@ var RunHandler = class {
|
|
|
1468
1566
|
* `processAgentResult`.
|
|
1469
1567
|
*/
|
|
1470
1568
|
_runDepth = 0;
|
|
1569
|
+
/**
|
|
1570
|
+
* Tracks the threadId of the most recent `connectAgent` call so we
|
|
1571
|
+
* can distinguish a fresh thread restore (different threadId than
|
|
1572
|
+
* last time — chat is rebuilding state from scratch, must clear
|
|
1573
|
+
* messages/state and ask the gateway for a full replay) from a
|
|
1574
|
+
* same-thread churn re-connect (effect-dep churn or transient
|
|
1575
|
+
* disconnect — local messages/state are still meaningful, must
|
|
1576
|
+
* preserve them and let the gateway resume from
|
|
1577
|
+
* `lastSeenEventId`).
|
|
1578
|
+
*
|
|
1579
|
+
* Tyler's bug fired because every `connectAgent` was treated as a
|
|
1580
|
+
* fresh restore, which forced the gateway to replay the full
|
|
1581
|
+
* thread history on every churn re-connect and amplified the
|
|
1582
|
+
* downstream churn into duplicate `cpki_event_id` rows in the
|
|
1583
|
+
* inspector and intermittent "Message not found" toasts.
|
|
1584
|
+
*/
|
|
1585
|
+
_lastConnectedThreadId = null;
|
|
1471
1586
|
constructor(core) {
|
|
1472
1587
|
this.core = core;
|
|
1473
1588
|
}
|
|
@@ -1541,14 +1656,17 @@ var RunHandler = class {
|
|
|
1541
1656
|
*/
|
|
1542
1657
|
async connectAgent({ agent }) {
|
|
1543
1658
|
try {
|
|
1659
|
+
const incomingThreadId = agent.threadId ?? null;
|
|
1660
|
+
const isFreshRestore = incomingThreadId !== this._lastConnectedThreadId;
|
|
1661
|
+
this._lastConnectedThreadId = incomingThreadId;
|
|
1544
1662
|
await agent.detachActiveRun();
|
|
1545
|
-
|
|
1546
|
-
|
|
1663
|
+
if (isFreshRestore) {
|
|
1664
|
+
agent.setMessages([]);
|
|
1665
|
+
agent.setState({});
|
|
1666
|
+
const proxied = agent;
|
|
1667
|
+
if (incomingThreadId && typeof proxied.clearReplayCursor === "function") proxied.clearReplayCursor(incomingThreadId);
|
|
1668
|
+
}
|
|
1547
1669
|
if (agent instanceof HttpAgent) agent.headers = { ...this._internal.headers };
|
|
1548
|
-
await this._internal.notifySubscribers((subscriber) => subscriber.onAgentRunStarted?.({
|
|
1549
|
-
copilotkit: this.core,
|
|
1550
|
-
agent
|
|
1551
|
-
}), "Subscriber onAgentRunStarted error:");
|
|
1552
1670
|
const runAgentResult = await agent.connectAgent({
|
|
1553
1671
|
forwardedProps: this._internal.properties,
|
|
1554
1672
|
tools: this.buildFrontendTools(agent.agentId),
|
|
@@ -1579,11 +1697,6 @@ var RunHandler = class {
|
|
|
1579
1697
|
if (agent.agentId) this._internal.suggestionEngine.clearSuggestions(agent.agentId);
|
|
1580
1698
|
if (agent instanceof HttpAgent) agent.headers = { ...this._internal.headers };
|
|
1581
1699
|
if (agent.detachActiveRun) await agent.detachActiveRun();
|
|
1582
|
-
this._internal.subscribeAgentToStateManager(agent);
|
|
1583
|
-
await this._internal.notifySubscribers((subscriber) => subscriber.onAgentRunStarted?.({
|
|
1584
|
-
copilotkit: this.core,
|
|
1585
|
-
agent
|
|
1586
|
-
}), "Subscriber onAgentRunStarted error:");
|
|
1587
1700
|
const isTopLevel = this._runDepth === 0;
|
|
1588
1701
|
let originalAbortRun;
|
|
1589
1702
|
if (isTopLevel) {
|
|
@@ -1654,7 +1767,7 @@ var RunHandler = class {
|
|
|
1654
1767
|
await this._internal.waitForPendingFrameworkUpdates();
|
|
1655
1768
|
return await this.runAgent({ agent });
|
|
1656
1769
|
}
|
|
1657
|
-
this._internal.suggestionEngine.reloadSuggestions(agentId
|
|
1770
|
+
this._internal.suggestionEngine.reloadSuggestions(agentId);
|
|
1658
1771
|
return runAgentResult;
|
|
1659
1772
|
}
|
|
1660
1773
|
/**
|
|
@@ -2066,21 +2179,14 @@ var StateManager = class {
|
|
|
2066
2179
|
initialize() {}
|
|
2067
2180
|
/**
|
|
2068
2181
|
* Subscribe to an agent's events to track state and messages.
|
|
2069
|
-
*
|
|
2070
|
-
* Registry agents (subscribed via `onAgentsChanged`) use the bare `agentId`
|
|
2071
|
-
* key so that `unsubscribeFromAgent(agentId)` can remove them when they
|
|
2072
|
-
* are replaced. Per-thread clones (subscribed via `subscribeAgentToStateManager`)
|
|
2073
|
-
* pass `{ isClone: true }` to use a composite `agentId:threadId` key, keeping
|
|
2074
|
-
* their subscription independent of the registry agent's.
|
|
2075
2182
|
*/
|
|
2076
|
-
subscribeToAgent(agent
|
|
2183
|
+
subscribeToAgent(agent) {
|
|
2077
2184
|
if (!agent.agentId) return;
|
|
2078
2185
|
const agentId = agent.agentId;
|
|
2079
|
-
const
|
|
2080
|
-
const existingUnsubscribe = this.agentSubscriptions.get(subscriptionKey);
|
|
2186
|
+
const existingUnsubscribe = this.agentSubscriptions.get(agentId);
|
|
2081
2187
|
if (existingUnsubscribe) {
|
|
2082
2188
|
existingUnsubscribe();
|
|
2083
|
-
this.agentSubscriptions.delete(
|
|
2189
|
+
this.agentSubscriptions.delete(agentId);
|
|
2084
2190
|
}
|
|
2085
2191
|
let revoked = false;
|
|
2086
2192
|
let subRunId;
|
|
@@ -2124,16 +2230,13 @@ var StateManager = class {
|
|
|
2124
2230
|
this.handleNewMessage(agent, message, input ? effectiveInput(input) : void 0);
|
|
2125
2231
|
}
|
|
2126
2232
|
});
|
|
2127
|
-
this.agentSubscriptions.set(
|
|
2233
|
+
this.agentSubscriptions.set(agentId, () => {
|
|
2128
2234
|
revoked = true;
|
|
2129
2235
|
unsubscribe();
|
|
2130
2236
|
});
|
|
2131
2237
|
}
|
|
2132
2238
|
/**
|
|
2133
|
-
* Unsubscribe
|
|
2134
|
-
* Per-thread clone subscriptions use composite `agentId:threadId` keys and
|
|
2135
|
-
* are replaced (not removed) by subsequent subscribeToAgent(agent, { isClone: true })
|
|
2136
|
-
* calls for the same (agentId, threadId) pair.
|
|
2239
|
+
* Unsubscribe an agent's subscription.
|
|
2137
2240
|
*/
|
|
2138
2241
|
unsubscribeFromAgent(agentId) {
|
|
2139
2242
|
const unsubscribe = this.agentSubscriptions.get(agentId);
|
|
@@ -2418,7 +2521,16 @@ var CopilotKitCore = class {
|
|
|
2418
2521
|
if (agent.agentId) this.stateManager.subscribeToAgent(agent);
|
|
2419
2522
|
});
|
|
2420
2523
|
const currentAgentIds = new Set(Object.keys(agents));
|
|
2421
|
-
for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) if (this.previousAgentIds.has(agentId) && !currentAgentIds.has(agentId))
|
|
2524
|
+
for (const agentId of Object.keys(this.threadStoreRegistry.getAll())) if (this.previousAgentIds.has(agentId) && !currentAgentIds.has(agentId)) try {
|
|
2525
|
+
this.threadStoreRegistry.unregister(agentId);
|
|
2526
|
+
} catch (err) {
|
|
2527
|
+
console.error(`CopilotKitCore.onAgentsChanged: threadStoreRegistry.unregister failed for "${agentId}":`, err);
|
|
2528
|
+
}
|
|
2529
|
+
for (const agentId of this.previousAgentIds) if (!currentAgentIds.has(agentId)) try {
|
|
2530
|
+
this.stateManager.unsubscribeFromAgent(agentId);
|
|
2531
|
+
} catch (err) {
|
|
2532
|
+
console.error(`CopilotKitCore.onAgentsChanged: stateManager.unsubscribeFromAgent failed for "${agentId}":`, err);
|
|
2533
|
+
}
|
|
2422
2534
|
this.previousAgentIds = currentAgentIds;
|
|
2423
2535
|
} });
|
|
2424
2536
|
}
|
|
@@ -2581,6 +2693,28 @@ var CopilotKitCore = class {
|
|
|
2581
2693
|
removeAgent__unsafe_dev_only(id) {
|
|
2582
2694
|
this.agentRegistry.removeAgent__unsafe_dev_only(id);
|
|
2583
2695
|
}
|
|
2696
|
+
/**
|
|
2697
|
+
* Register a proxied agent against an existing runtime agent. The proxy is
|
|
2698
|
+
* exposed under `agentId` (local registry id) and routes outbound runtime
|
|
2699
|
+
* requests to `runtimeAgentId`. Throws if `agentId` is already taken.
|
|
2700
|
+
*
|
|
2701
|
+
* Returns the minted proxy and an `unregister` handle for cleanup.
|
|
2702
|
+
*
|
|
2703
|
+
* Use this to mount multiple frontend agents against a single runtime
|
|
2704
|
+
* agent (e.g. one per chat window) without implicit per-thread cloning.
|
|
2705
|
+
*
|
|
2706
|
+
* @example
|
|
2707
|
+
* const { agent, unregister } = copilotkit.registerProxiedAgent({
|
|
2708
|
+
* agentId: "chat-1",
|
|
2709
|
+
* runtimeAgentId: "default",
|
|
2710
|
+
* });
|
|
2711
|
+
* // ... <CopilotChat agentId="chat-1" />
|
|
2712
|
+
* // on cleanup:
|
|
2713
|
+
* unregister();
|
|
2714
|
+
*/
|
|
2715
|
+
registerProxiedAgent(params) {
|
|
2716
|
+
return this.agentRegistry.registerProxiedAgent(params);
|
|
2717
|
+
}
|
|
2584
2718
|
getAgent(id) {
|
|
2585
2719
|
return this.agentRegistry.getAgent(id);
|
|
2586
2720
|
}
|
|
@@ -2814,9 +2948,6 @@ var CopilotKitCore = class {
|
|
|
2814
2948
|
getRunIdsForThread(agentId, threadId) {
|
|
2815
2949
|
return this.stateManager.getRunIdsForThread(agentId, threadId);
|
|
2816
2950
|
}
|
|
2817
|
-
subscribeAgentToStateManager(agent) {
|
|
2818
|
-
this.stateManager.subscribeToAgent(agent, { isClone: true });
|
|
2819
|
-
}
|
|
2820
2951
|
/**
|
|
2821
2952
|
* Internal method used by RunHandler to build frontend tools
|
|
2822
2953
|
*/
|