@copilotkit/core 1.75.1 → 1.76.0
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 +204 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +18 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +207 -48
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +214 -48
- package/dist/index.umd.js.map +1 -1
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
|
@@ -7,6 +7,23 @@ let rxjs_operators = require("rxjs/operators");
|
|
|
7
7
|
let phoenix = require("phoenix");
|
|
8
8
|
let zod_to_json_schema = require("zod-to-json-schema");
|
|
9
9
|
|
|
10
|
+
//#region src/utils/http-agent.ts
|
|
11
|
+
/**
|
|
12
|
+
* Whether an agent is an `HttpAgent`, including one built from another copy of
|
|
13
|
+
* `@ag-ui/client` (an app that pins its own 0.x version next to CopilotKit's
|
|
14
|
+
* 1.0, for example). `instanceof` is false across package copies, which made
|
|
15
|
+
* CopilotKit silently skip headers and abort wiring for those agents. The
|
|
16
|
+
* fallback checks the public fields CopilotKit uses, which every published
|
|
17
|
+
* `HttpAgent` has.
|
|
18
|
+
*/
|
|
19
|
+
function ɵisHttpAgent(agent) {
|
|
20
|
+
if (agent instanceof _ag_ui_client.HttpAgent) return true;
|
|
21
|
+
if (typeof agent !== "object" || agent === null) return false;
|
|
22
|
+
const candidate = agent;
|
|
23
|
+
return typeof candidate.url === "string" && typeof candidate.headers === "object" && candidate.headers !== null && candidate.abortController instanceof AbortController && typeof candidate.runAgent === "function";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
10
27
|
//#region src/utils/connect-replay.ts
|
|
11
28
|
/**
|
|
12
29
|
* Runs an agent's `connect()` stream through the AbstractAgent apply pipeline
|
|
@@ -23,18 +40,27 @@ let zod_to_json_schema = require("zod-to-json-schema");
|
|
|
23
40
|
* Cannot send event type 'RUN_STARTED': The run has already errored with
|
|
24
41
|
* 'RUN_ERROR'. No further events can be sent.
|
|
25
42
|
*
|
|
26
|
-
*
|
|
43
|
+
* The AG-UI 1.0 compatibility boundary still runs first, so stored 0.x history
|
|
44
|
+
* is translated (THINKING_* events, `binary` parts, legacy nulls) exactly as in
|
|
45
|
+
* the base pipeline. `enforceEvents` is omitted too: a replay is stored
|
|
46
|
+
* history, and one event that the 1.0 schema rejects (the Intelligence gateway
|
|
47
|
+
* replays RUN_STARTED without `runId`, for example) must not stop the whole
|
|
48
|
+
* thread from hydrating. That keeps the leniency this path had before 1.0.
|
|
27
49
|
*
|
|
28
50
|
* Connection-local replay hooks track the phase before applying events. An
|
|
29
51
|
* explicitly live RUN_ERROR clears busy without closing the connection;
|
|
30
52
|
* historical errors remain data. Connections without hooks retain the existing
|
|
31
|
-
* completion behavior.
|
|
53
|
+
* completion behavior.
|
|
54
|
+
*
|
|
55
|
+
* Apart from the above, this mirrors the base `AbstractAgent.connectAgent`
|
|
56
|
+
* implementation, so callers keep the same subscriber notifications, detach
|
|
57
|
+
* semantics, and `{ result, newMessages }` return shape.
|
|
32
58
|
*
|
|
33
59
|
* TODO: Remove this in favour of the base implementation once AG-UI's
|
|
34
60
|
* AbstractAgent supports opting out of `verifyEvents` for transports whose
|
|
35
61
|
* connection life-cycle isn't a single run AND preserves the connection-local
|
|
36
62
|
* replay lifecycle and running-state behavior below. Skipping verification alone
|
|
37
|
-
* is insufficient. As of `@ag-ui/client@
|
|
63
|
+
* is insufficient. As of `@ag-ui/client@1.0.1`
|
|
38
64
|
* `connectAgent(parameters?, subscriber?)` takes no such option.
|
|
39
65
|
*
|
|
40
66
|
* @param agent - The agent whose `connect()` stream should be consumed.
|
|
@@ -43,6 +69,9 @@ let zod_to_json_schema = require("zod-to-json-schema");
|
|
|
43
69
|
*/
|
|
44
70
|
async function ɵconnectWithoutEventVerification(agent, parameters, subscriber, connect) {
|
|
45
71
|
const self = agent;
|
|
72
|
+
let finalizeRun = () => {
|
|
73
|
+
agent.isRunning = false;
|
|
74
|
+
};
|
|
46
75
|
try {
|
|
47
76
|
agent.isRunning = true;
|
|
48
77
|
agent.agentId = agent.agentId ?? (0, _ag_ui_client.randomUUID)();
|
|
@@ -66,12 +95,35 @@ async function ɵconnectWithoutEventVerification(agent, parameters, subscriber,
|
|
|
66
95
|
...agent.subscribers,
|
|
67
96
|
subscriber ?? {}
|
|
68
97
|
];
|
|
69
|
-
|
|
70
|
-
self.activeRunDetach$ =
|
|
98
|
+
const activeRunDetach$ = new rxjs.Subject();
|
|
99
|
+
self.activeRunDetach$ = activeRunDetach$;
|
|
71
100
|
let resolveCompletion;
|
|
72
101
|
self.activeRunCompletionPromise = new Promise((resolve) => {
|
|
73
102
|
resolveCompletion = resolve;
|
|
74
103
|
});
|
|
104
|
+
let detached = false;
|
|
105
|
+
let finalized = false;
|
|
106
|
+
const detachSubscription = activeRunDetach$.subscribe(() => {
|
|
107
|
+
detached = true;
|
|
108
|
+
});
|
|
109
|
+
finalizeRun = () => {
|
|
110
|
+
if (finalized) return;
|
|
111
|
+
finalized = true;
|
|
112
|
+
detachSubscription.unsubscribe();
|
|
113
|
+
if (self.activeRunDetach$ === activeRunDetach$) {
|
|
114
|
+
agent.isRunning = false;
|
|
115
|
+
self.activeRunCompletionPromise = void 0;
|
|
116
|
+
self.activeRunDetach$ = void 0;
|
|
117
|
+
self.onFinalize(input, subscribers);
|
|
118
|
+
}
|
|
119
|
+
resolveCompletion?.();
|
|
120
|
+
resolveCompletion = void 0;
|
|
121
|
+
};
|
|
122
|
+
await self.onInitialize(input, subscribers);
|
|
123
|
+
if (detached) return {
|
|
124
|
+
result: void 0,
|
|
125
|
+
newMessages: []
|
|
126
|
+
};
|
|
75
127
|
const lifecycle = {
|
|
76
128
|
onReplayStarted: () => {
|
|
77
129
|
isReplaying = true;
|
|
@@ -81,29 +133,23 @@ async function ɵconnectWithoutEventVerification(agent, parameters, subscriber,
|
|
|
81
133
|
isReplaying = false;
|
|
82
134
|
}
|
|
83
135
|
};
|
|
84
|
-
const source$ = (0, rxjs.defer)(() => connect ? connect(input, lifecycle) : self.connect(input)).pipe((0, rxjs_operators.tap)((event) => {
|
|
136
|
+
const source$ = (0, rxjs.defer)(() => new _ag_ui_client.CompatibilityBoundary().run(input, { run: () => connect ? connect(input, lifecycle) : self.connect(input) })).pipe((0, rxjs_operators.tap)((event) => {
|
|
85
137
|
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)(
|
|
138
|
+
}), (0, _ag_ui_client.transformChunks)(self.debugLogger), (0, rxjs_operators.takeUntil)(activeRunDetach$));
|
|
87
139
|
const applied$ = self.apply(input, source$, subscribers);
|
|
88
140
|
await (0, rxjs.lastValueFrom)(self.processApplyEvents(input, applied$, subscribers).pipe((0, rxjs_operators.catchError)((error) => {
|
|
141
|
+
if (self.activeRunDetach$ !== activeRunDetach$) return rxjs.EMPTY;
|
|
89
142
|
agent.isRunning = false;
|
|
90
143
|
if (error instanceof _ag_ui_client.AGUIConnectNotImplementedError) return rxjs.EMPTY;
|
|
91
144
|
return self.onError(input, error, subscribers);
|
|
92
|
-
}), (0, rxjs_operators.finalize)(() => {
|
|
93
|
-
agent.isRunning = false;
|
|
94
|
-
self.onFinalize(input, subscribers);
|
|
95
|
-
resolveCompletion?.();
|
|
96
|
-
resolveCompletion = void 0;
|
|
97
|
-
self.activeRunCompletionPromise = void 0;
|
|
98
|
-
self.activeRunDetach$ = void 0;
|
|
99
|
-
})), { defaultValue: void 0 });
|
|
145
|
+
}), (0, rxjs_operators.finalize)(() => finalizeRun())), { defaultValue: void 0 });
|
|
100
146
|
const newMessages = (0, _ag_ui_client.structuredClone_)(agent.messages).filter((m) => !previousMessageIds.has(m.id));
|
|
101
147
|
return {
|
|
102
148
|
result,
|
|
103
149
|
newMessages
|
|
104
150
|
};
|
|
105
151
|
} finally {
|
|
106
|
-
|
|
152
|
+
finalizeRun();
|
|
107
153
|
}
|
|
108
154
|
}
|
|
109
155
|
|
|
@@ -586,7 +632,7 @@ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAg
|
|
|
586
632
|
observeThreadEvents$(threadId, channel$, options) {
|
|
587
633
|
return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, CLIENT_AG_UI_EVENT)), (0, rxjs_operators.tap)((payload) => {
|
|
588
634
|
this.updateLastSeenEventId(threadId, payload);
|
|
589
|
-
}), (0, rxjs_operators.mergeMap)((payload) => this.createThreadNotifications(payload, {
|
|
635
|
+
}), (0, rxjs_operators.map)((payload) => options.streamMode === "run" ? (0, _copilotkit_shared.stripIntelligenceRoutingFields)(payload) : payload), (0, rxjs_operators.mergeMap)((payload) => this.createThreadNotifications(payload, {
|
|
590
636
|
completeOnRunError: options.completeOnRunError,
|
|
591
637
|
completeOnRunFinished: options.streamMode === "run",
|
|
592
638
|
errorOnRunError: options.streamMode === "run"
|
|
@@ -840,6 +886,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
840
886
|
_capabilities;
|
|
841
887
|
delegate;
|
|
842
888
|
runtimeInfoPromise;
|
|
889
|
+
connectionAttempt;
|
|
843
890
|
_messageFilter;
|
|
844
891
|
/**
|
|
845
892
|
* The HTTP `run` this agent started and has not yet seen finish, as the
|
|
@@ -902,13 +949,12 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
902
949
|
this.runtimeMode = runtimeMode;
|
|
903
950
|
this.intelligence = intelligence;
|
|
904
951
|
if (unchanged) return;
|
|
952
|
+
this.connectionAttempt = void 0;
|
|
905
953
|
this.runtimeInfoPromise = void 0;
|
|
906
954
|
const staleDelegate = this.delegate;
|
|
907
955
|
this.delegate = void 0;
|
|
908
|
-
if (staleDelegate)
|
|
909
|
-
|
|
910
|
-
this.detachActiveRun();
|
|
911
|
-
}
|
|
956
|
+
if (staleDelegate) staleDelegate.abortRun();
|
|
957
|
+
this.detachActiveRun();
|
|
912
958
|
}
|
|
913
959
|
/**
|
|
914
960
|
* The agent id used for outbound runtime requests — `runtimeAgentId` when
|
|
@@ -999,8 +1045,11 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
999
1045
|
return this._capabilities ?? {};
|
|
1000
1046
|
}
|
|
1001
1047
|
async detachActiveRun() {
|
|
1002
|
-
|
|
1003
|
-
|
|
1048
|
+
this.connectionAttempt = void 0;
|
|
1049
|
+
this.isRunning = false;
|
|
1050
|
+
const delegateDetach = this.delegate?.detachActiveRun();
|
|
1051
|
+
const proxyDetach = super.detachActiveRun();
|
|
1052
|
+
await Promise.all([delegateDetach, proxyDetach]);
|
|
1004
1053
|
}
|
|
1005
1054
|
abortRun() {
|
|
1006
1055
|
if (this.delegate) {
|
|
@@ -1054,41 +1103,74 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1054
1103
|
});
|
|
1055
1104
|
}
|
|
1056
1105
|
async connectAgent(parameters, subscriber) {
|
|
1106
|
+
const detached = this.detachActiveRun();
|
|
1107
|
+
const connection = {};
|
|
1108
|
+
const threadId = this.threadId;
|
|
1109
|
+
this.connectionAttempt = connection;
|
|
1110
|
+
const isCurrentConnection = () => this.connectionAttempt === connection && this.threadId === threadId;
|
|
1111
|
+
await detached;
|
|
1112
|
+
if (!isCurrentConnection()) return {
|
|
1113
|
+
result: void 0,
|
|
1114
|
+
newMessages: []
|
|
1115
|
+
};
|
|
1116
|
+
await this.ensureRuntimeConfiguration();
|
|
1117
|
+
if (!isCurrentConnection()) return {
|
|
1118
|
+
result: void 0,
|
|
1119
|
+
newMessages: []
|
|
1120
|
+
};
|
|
1057
1121
|
if (this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return ɵconnectWithoutEventVerification(this, parameters, subscriber, (input, lifecycle) => this.connect(input, lifecycle));
|
|
1058
|
-
if (this.delegate) await this.delegate.detachActiveRun();
|
|
1059
1122
|
await this.resolveDelegate();
|
|
1123
|
+
if (!isCurrentConnection()) return {
|
|
1124
|
+
result: void 0,
|
|
1125
|
+
newMessages: []
|
|
1126
|
+
};
|
|
1060
1127
|
const delegate = this.delegate;
|
|
1061
1128
|
const bridgeSub = delegate.subscribe({
|
|
1062
1129
|
onMessagesChanged: () => {
|
|
1130
|
+
if (!isCurrentConnection()) return;
|
|
1063
1131
|
this.setMessages([...delegate.messages]);
|
|
1064
1132
|
},
|
|
1065
1133
|
onStateChanged: () => {
|
|
1134
|
+
if (!isCurrentConnection()) return;
|
|
1066
1135
|
this.setState({ ...delegate.state });
|
|
1067
1136
|
},
|
|
1068
1137
|
onRunInitialized: () => {
|
|
1138
|
+
if (!isCurrentConnection()) return;
|
|
1069
1139
|
this.isRunning = true;
|
|
1070
1140
|
},
|
|
1071
1141
|
onRunFinalized: () => {
|
|
1142
|
+
if (!isCurrentConnection()) return;
|
|
1143
|
+
this.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(delegate.pendingInterrupts);
|
|
1072
1144
|
this.isRunning = false;
|
|
1073
1145
|
},
|
|
1074
1146
|
onRunFailed: () => {
|
|
1147
|
+
if (!isCurrentConnection()) return;
|
|
1075
1148
|
this.isRunning = false;
|
|
1076
1149
|
},
|
|
1077
1150
|
onRunErrorEvent: () => {
|
|
1151
|
+
if (!isCurrentConnection()) return;
|
|
1078
1152
|
this.isRunning = delegate.isRunning;
|
|
1079
1153
|
},
|
|
1080
1154
|
onRunStartedEvent: () => {
|
|
1155
|
+
if (!isCurrentConnection()) return;
|
|
1081
1156
|
this.isRunning = delegate.isRunning;
|
|
1082
1157
|
}
|
|
1083
1158
|
});
|
|
1084
|
-
const forwardedSubs = this.subscribers.map((
|
|
1159
|
+
const forwardedSubs = [...this.subscribers, ...subscriber ? [subscriber] : []].map((subscriber) => delegate.subscribe(new Proxy(subscriber, { get(target, property, receiver) {
|
|
1160
|
+
const callback = Reflect.get(target, property, receiver);
|
|
1161
|
+
if (typeof callback !== "function") return callback;
|
|
1162
|
+
return (...args) => isCurrentConnection() ? Reflect.apply(callback, target, args) : void 0;
|
|
1163
|
+
} })));
|
|
1085
1164
|
try {
|
|
1086
|
-
const result = await delegate.connectAgent(parameters
|
|
1087
|
-
|
|
1088
|
-
|
|
1165
|
+
const result = await delegate.connectAgent(parameters);
|
|
1166
|
+
if (isCurrentConnection()) {
|
|
1167
|
+
this.setMessages([...delegate.messages]);
|
|
1168
|
+
this.setState({ ...delegate.state });
|
|
1169
|
+
this.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(delegate.pendingInterrupts);
|
|
1170
|
+
}
|
|
1089
1171
|
return result;
|
|
1090
1172
|
} finally {
|
|
1091
|
-
this.isRunning = false;
|
|
1173
|
+
if (isCurrentConnection()) this.isRunning = false;
|
|
1092
1174
|
bridgeSub.unsubscribe();
|
|
1093
1175
|
for (const sub of forwardedSubs) sub.unsubscribe();
|
|
1094
1176
|
}
|
|
@@ -1110,14 +1192,31 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1110
1192
|
const input = this.#applyMessageFilter(unfiltered);
|
|
1111
1193
|
this.activeRun = void 0;
|
|
1112
1194
|
const routedId = this.routedAgentId();
|
|
1195
|
+
let httpEvents;
|
|
1113
1196
|
if (this.transport === "single") {
|
|
1114
1197
|
if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
|
|
1115
1198
|
const requestInit = this.createSingleRouteRequestInit(input, "agent/connect", { agentId: routedId });
|
|
1116
|
-
|
|
1199
|
+
httpEvents = (0, _ag_ui_client.runHttpRequest)(() => this.fetch(this.singleEndpointUrl, requestInit));
|
|
1200
|
+
} else {
|
|
1201
|
+
const connectUrl = `${this.runtimeUrl}/agent/${routedId}/connect`;
|
|
1202
|
+
const connectRequestInit = this.requestInit(input);
|
|
1203
|
+
httpEvents = (0, _ag_ui_client.runHttpRequest)(() => this.fetch(connectUrl, connectRequestInit));
|
|
1117
1204
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1205
|
+
return withAbortErrorHandling((0, rxjs.defer)(() => {
|
|
1206
|
+
let replayStarted = false;
|
|
1207
|
+
const emptyHistory = [{
|
|
1208
|
+
type: _ag_ui_client.EventType.MESSAGES_SNAPSHOT,
|
|
1209
|
+
messages: []
|
|
1210
|
+
}, {
|
|
1211
|
+
type: _ag_ui_client.EventType.STATE_SNAPSHOT,
|
|
1212
|
+
snapshot: {}
|
|
1213
|
+
}];
|
|
1214
|
+
return (0, _ag_ui_client.transformHttpEventStream)(httpEvents).pipe((0, rxjs_operators.concatMap)((event) => {
|
|
1215
|
+
if (replayStarted) return (0, rxjs.of)(event);
|
|
1216
|
+
replayStarted = true;
|
|
1217
|
+
return (0, rxjs.from)([...emptyHistory, event]);
|
|
1218
|
+
}), (0, rxjs_operators.concatWith)((0, rxjs.defer)(() => replayStarted ? rxjs.EMPTY : (0, rxjs.from)(emptyHistory))));
|
|
1219
|
+
}));
|
|
1121
1220
|
}
|
|
1122
1221
|
#runViaDelegate(input) {
|
|
1123
1222
|
return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.run(input))));
|
|
@@ -1160,6 +1259,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1160
1259
|
cloned.threadId = this.threadId;
|
|
1161
1260
|
cloned.setState(this.state);
|
|
1162
1261
|
cloned.setMessages(this.messages);
|
|
1262
|
+
cloned.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(this.pendingInterrupts);
|
|
1163
1263
|
if (this.delegate) {
|
|
1164
1264
|
const clonedDelegate = this.delegate.clone();
|
|
1165
1265
|
cloned.delegate = clonedDelegate;
|
|
@@ -1197,6 +1297,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1197
1297
|
if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE || this.runtimeMode !== "pending" && this.transport !== "auto") return;
|
|
1198
1298
|
if (!this.runtimeUrl) throw new Error("Runtime URL is not set");
|
|
1199
1299
|
const runtimeInfoPromise = this.runtimeInfoPromise ?? this.fetchRuntimeInfo().then((runtimeInfo) => {
|
|
1300
|
+
if (this.runtimeInfoPromise !== runtimeInfoPromise) return;
|
|
1200
1301
|
this.runtimeMode = runtimeInfo.mode ?? _copilotkit_shared.RUNTIME_MODE_SSE;
|
|
1201
1302
|
this.intelligence = runtimeInfo.intelligence;
|
|
1202
1303
|
});
|
|
@@ -1301,6 +1402,7 @@ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui
|
|
|
1301
1402
|
delegate.debugLogger = this.debugLogger;
|
|
1302
1403
|
delegate.setMessages(this.messages);
|
|
1303
1404
|
delegate.setState(this.state);
|
|
1405
|
+
delegate.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(this.pendingInterrupts);
|
|
1304
1406
|
if (hasHeaders(delegate)) delegate.headers = { ...this.headers };
|
|
1305
1407
|
if (hasCredentials(delegate)) delegate.credentials = this.credentials;
|
|
1306
1408
|
}
|
|
@@ -1736,7 +1838,7 @@ var AgentRegistry = class {
|
|
|
1736
1838
|
* because only `HttpAgent` carries a `headers` field. See #5635.
|
|
1737
1839
|
*/
|
|
1738
1840
|
applyHeadersToAgent(agent) {
|
|
1739
|
-
if (agent
|
|
1841
|
+
if (ɵisHttpAgent(agent)) {
|
|
1740
1842
|
if (!this.agentOwnHeaders.has(agent)) this.agentOwnHeaders.set(agent, { ...agent.headers });
|
|
1741
1843
|
agent.headers = {
|
|
1742
1844
|
...this.agentOwnHeaders.get(agent),
|
|
@@ -3087,6 +3189,7 @@ var RunHandler = class {
|
|
|
3087
3189
|
* inspector and intermittent "Message not found" toasts.
|
|
3088
3190
|
*/
|
|
3089
3191
|
_lastConnectedThreadIdsByAgent = /* @__PURE__ */ new Map();
|
|
3192
|
+
_lastActiveThreadIdsByAgent = /* @__PURE__ */ new Map();
|
|
3090
3193
|
_anonymousAgentIds = /* @__PURE__ */ new WeakMap();
|
|
3091
3194
|
_nextAnonymousAgentId = 0;
|
|
3092
3195
|
/** Prevent reconnects from starting an interaction already executing locally. */
|
|
@@ -3264,7 +3367,8 @@ var RunHandler = class {
|
|
|
3264
3367
|
* Connect an agent (establish initial connection)
|
|
3265
3368
|
*/
|
|
3266
3369
|
async connectAgent({ agent }) {
|
|
3267
|
-
|
|
3370
|
+
const connection = {};
|
|
3371
|
+
this._connectionGenerations.set(agent, connection);
|
|
3268
3372
|
const incomingThreadId = agent.threadId ?? null;
|
|
3269
3373
|
const previousReplay = this._interactionAbortControllers.get(agent);
|
|
3270
3374
|
if (previousReplay && previousReplay.threadId !== incomingThreadId) {
|
|
@@ -3274,12 +3378,19 @@ var RunHandler = class {
|
|
|
3274
3378
|
}
|
|
3275
3379
|
try {
|
|
3276
3380
|
const restoreKey = this.getConnectRestoreKey(agent);
|
|
3277
|
-
const
|
|
3278
|
-
this._lastConnectedThreadIdsByAgent.
|
|
3381
|
+
const previousThreadId = this._lastActiveThreadIdsByAgent.get(restoreKey);
|
|
3382
|
+
const isFreshRestore = incomingThreadId !== (previousThreadId ?? this._lastConnectedThreadIdsByAgent.get(restoreKey) ?? null);
|
|
3279
3383
|
await agent.detachActiveRun();
|
|
3384
|
+
if (this._connectionGenerations.get(agent) !== connection || (agent.threadId ?? null) !== incomingThreadId) return {
|
|
3385
|
+
result: void 0,
|
|
3386
|
+
newMessages: []
|
|
3387
|
+
};
|
|
3388
|
+
this._lastConnectedThreadIdsByAgent.set(restoreKey, incomingThreadId);
|
|
3389
|
+
this._lastActiveThreadIdsByAgent.set(restoreKey, incomingThreadId);
|
|
3280
3390
|
if (isFreshRestore) {
|
|
3281
3391
|
agent.setMessages([]);
|
|
3282
3392
|
agent.setState({});
|
|
3393
|
+
if (previousThreadId !== void 0 && previousThreadId !== incomingThreadId) agent.pendingInterrupts = [];
|
|
3283
3394
|
const cursorAware = agent;
|
|
3284
3395
|
if (incomingThreadId) {
|
|
3285
3396
|
if (typeof cursorAware.clearReplayCursor === "function") cursorAware.clearReplayCursor(incomingThreadId);
|
|
@@ -3291,12 +3402,16 @@ var RunHandler = class {
|
|
|
3291
3402
|
copilotkit: this.core,
|
|
3292
3403
|
agent
|
|
3293
3404
|
}), "Subscriber onAgentRunStarted error:");
|
|
3405
|
+
if (this._connectionGenerations.get(agent) !== connection || (agent.threadId ?? null) !== incomingThreadId) return {
|
|
3406
|
+
result: void 0,
|
|
3407
|
+
newMessages: []
|
|
3408
|
+
};
|
|
3294
3409
|
const runAgentResult = await agent.connectAgent({
|
|
3295
3410
|
forwardedProps: this._internal.properties,
|
|
3296
3411
|
tools: this.buildFrontendTools(agent.agentId),
|
|
3297
3412
|
context: this._internal.getContextForAgent(agent.agentId)
|
|
3298
3413
|
}, this.createAgentErrorSubscriber(agent));
|
|
3299
|
-
if ((agent.threadId ?? null) !== incomingThreadId) return runAgentResult;
|
|
3414
|
+
if (this._connectionGenerations.get(agent) !== connection || (agent.threadId ?? null) !== incomingThreadId) return runAgentResult;
|
|
3300
3415
|
const controller = new AbortController();
|
|
3301
3416
|
const replay = this._interactionAbortControllers.get(agent) ?? {
|
|
3302
3417
|
threadId: incomingThreadId,
|
|
@@ -3353,6 +3468,12 @@ var RunHandler = class {
|
|
|
3353
3468
|
continuationHandoff?.cancel();
|
|
3354
3469
|
throw error;
|
|
3355
3470
|
}
|
|
3471
|
+
const resumedRunId = this._internal.stateManager.getContinuationRunId(agent, {
|
|
3472
|
+
threadId: agent.threadId,
|
|
3473
|
+
resume,
|
|
3474
|
+
forwardedProps
|
|
3475
|
+
});
|
|
3476
|
+
const logicalHandoff = continuationHandoff ?? (resumedRunId ? this._internal.stateManager.markNextRunAsContinuation(agent, resumedRunId) : void 0);
|
|
3356
3477
|
const isTopLevel = this._runDepth === 0;
|
|
3357
3478
|
let originalAbortRun;
|
|
3358
3479
|
if (isTopLevel) {
|
|
@@ -3370,18 +3491,19 @@ var RunHandler = class {
|
|
|
3370
3491
|
}
|
|
3371
3492
|
this._runDepth++;
|
|
3372
3493
|
try {
|
|
3373
|
-
let logicalRunId = runId;
|
|
3494
|
+
let logicalRunId = resumedRunId ?? runId;
|
|
3374
3495
|
const agentSubscriber = this.createAgentErrorSubscriber(agent);
|
|
3375
3496
|
let started = false;
|
|
3376
3497
|
const onRunStartedEvent = agentSubscriber.onRunStartedEvent;
|
|
3377
3498
|
const onRunInitialized = agentSubscriber.onRunInitialized;
|
|
3378
3499
|
agentSubscriber.onRunInitialized = async (params) => {
|
|
3379
|
-
|
|
3500
|
+
this._lastActiveThreadIdsByAgent.set(this.getConnectRestoreKey(agent), params.input.threadId);
|
|
3501
|
+
logicalHandoff?.bind(params.input);
|
|
3380
3502
|
return onRunInitialized?.(params);
|
|
3381
3503
|
};
|
|
3382
3504
|
agentSubscriber.onRunStartedEvent = async (params) => {
|
|
3383
3505
|
started = true;
|
|
3384
|
-
if (!
|
|
3506
|
+
if (!logicalHandoff) logicalRunId = params.input.runId;
|
|
3385
3507
|
return onRunStartedEvent?.(params);
|
|
3386
3508
|
};
|
|
3387
3509
|
const pinRunIdOnWire = runId !== void 0 && !continuationHandoff;
|
|
@@ -3396,14 +3518,14 @@ var RunHandler = class {
|
|
|
3396
3518
|
context: this._internal.getContextForAgent(agent.agentId)
|
|
3397
3519
|
};
|
|
3398
3520
|
const runAgentResult = await agent.runAgent(agentRunInput, agentSubscriber);
|
|
3399
|
-
if (!started)
|
|
3521
|
+
if (!started) logicalHandoff?.cancel();
|
|
3400
3522
|
return await this.processAgentResult({
|
|
3401
3523
|
runAgentResult,
|
|
3402
3524
|
agent,
|
|
3403
3525
|
runId: logicalRunId
|
|
3404
3526
|
});
|
|
3405
3527
|
} catch (error) {
|
|
3406
|
-
|
|
3528
|
+
logicalHandoff?.cancel();
|
|
3407
3529
|
const runError = error instanceof Error ? error : new Error(String(error));
|
|
3408
3530
|
const context = {};
|
|
3409
3531
|
if (agent.agentId) context.agentId = agent.agentId;
|
|
@@ -3945,6 +4067,15 @@ var StateManager = class {
|
|
|
3945
4067
|
activeRun = /* @__PURE__ */ new Map();
|
|
3946
4068
|
agentSubscriptions = /* @__PURE__ */ new Map();
|
|
3947
4069
|
pendingContinuations = /* @__PURE__ */ new WeakMap();
|
|
4070
|
+
interruptedRuns = /* @__PURE__ */ new WeakMap();
|
|
4071
|
+
/** Find the interrupted logical run without consuming its pending answers. */
|
|
4072
|
+
getContinuationRunId(agent, input) {
|
|
4073
|
+
const pending = this.interruptedRuns.get(agent)?.get(input.threadId);
|
|
4074
|
+
if (!pending) return void 0;
|
|
4075
|
+
if (pending.interruptIds === null) return input.resume === void 0 && isContinuation(input) ? pending.runId : void 0;
|
|
4076
|
+
const submitted = new Set(input.resume?.map((entry) => entry.interruptId));
|
|
4077
|
+
return submitted.size > 0 && submitted.size === input.resume?.length && submitted.size === pending.interruptIds.length && pending.interruptIds.every((id) => submitted.has(id)) ? pending.runId : void 0;
|
|
4078
|
+
}
|
|
3948
4079
|
constructor(core) {
|
|
3949
4080
|
this.core = core;
|
|
3950
4081
|
}
|
|
@@ -3988,6 +4119,7 @@ var StateManager = class {
|
|
|
3988
4119
|
}
|
|
3989
4120
|
let revoked = false;
|
|
3990
4121
|
let subRunId;
|
|
4122
|
+
let legacyInterrupted = false;
|
|
3991
4123
|
let runFinished = false;
|
|
3992
4124
|
const pendingResults = /* @__PURE__ */ new WeakMap();
|
|
3993
4125
|
const reconcilePendingResults = (historyMessages, input) => {
|
|
@@ -4053,21 +4185,43 @@ var StateManager = class {
|
|
|
4053
4185
|
if (revoked) return;
|
|
4054
4186
|
const internalContinuation = [...this.pendingContinuations.get(agent) ?? []].find((pending) => pending.expectedInput === input);
|
|
4055
4187
|
internalContinuation?.cancel();
|
|
4188
|
+
const startedInput = event.input ?? {
|
|
4189
|
+
...input,
|
|
4190
|
+
threadId: event.threadId
|
|
4191
|
+
};
|
|
4192
|
+
const resumedRunId = this.getContinuationRunId(agent, startedInput);
|
|
4193
|
+
this.interruptedRuns.get(agent)?.delete(startedInput.threadId);
|
|
4194
|
+
legacyInterrupted = false;
|
|
4056
4195
|
if (internalContinuation) subRunId = internalContinuation.expectedRunId ?? event.runId ?? input.runId;
|
|
4196
|
+
else if (resumedRunId) subRunId = resumedRunId;
|
|
4057
4197
|
else if (runFinished && input.runId === subRunId && !isContinuation(input) && (event.runId == null || event.runId === subRunId)) subRunId = (0, _ag_ui_client.randomUUID)();
|
|
4058
4198
|
else subRunId = event.runId || input.runId;
|
|
4059
4199
|
runFinished = false;
|
|
4060
4200
|
this.handleRunStarted(agent, effectiveInput(input), state);
|
|
4061
4201
|
},
|
|
4062
|
-
onRunFinishedEvent: ({ input, state, messages }) => {
|
|
4202
|
+
onRunFinishedEvent: ({ event, input, state, messages }) => {
|
|
4063
4203
|
if (revoked) return;
|
|
4064
4204
|
runFinished = true;
|
|
4065
4205
|
const effective = effectiveInput(input);
|
|
4206
|
+
let interrupted = this.interruptedRuns.get(agent);
|
|
4207
|
+
if (event.outcome?.type === "interrupt" || legacyInterrupted) {
|
|
4208
|
+
if (!interrupted) {
|
|
4209
|
+
interrupted = /* @__PURE__ */ new Map();
|
|
4210
|
+
this.interruptedRuns.set(agent, interrupted);
|
|
4211
|
+
}
|
|
4212
|
+
interrupted.set(event.threadId, {
|
|
4213
|
+
runId: effective.runId,
|
|
4214
|
+
interruptIds: event.outcome?.type === "interrupt" ? event.outcome.interrupts.map((interrupt) => interrupt.id) : null
|
|
4215
|
+
});
|
|
4216
|
+
} else interrupted?.delete(event.threadId);
|
|
4066
4217
|
const mutation = reconcilePendingResults(messages, input);
|
|
4067
4218
|
clearPendingResults(input);
|
|
4068
4219
|
this.handleRunFinished(agent, effective, state);
|
|
4069
4220
|
return mutation;
|
|
4070
4221
|
},
|
|
4222
|
+
onCustomEvent: ({ event }) => {
|
|
4223
|
+
if (!revoked && event.name === "on_interrupt") legacyInterrupted = true;
|
|
4224
|
+
},
|
|
4071
4225
|
onRunErrorEvent: ({ input, state, messages }) => {
|
|
4072
4226
|
if (revoked) return;
|
|
4073
4227
|
runFinished = true;
|
|
@@ -4124,6 +4278,7 @@ var StateManager = class {
|
|
|
4124
4278
|
unsubscribe: () => {
|
|
4125
4279
|
revoked = true;
|
|
4126
4280
|
this.pendingContinuations.delete(agent);
|
|
4281
|
+
this.interruptedRuns.delete(agent);
|
|
4127
4282
|
unsubscribe();
|
|
4128
4283
|
}
|
|
4129
4284
|
});
|
|
@@ -4284,6 +4439,8 @@ var StateManager = class {
|
|
|
4284
4439
|
* Clear all state for an agent
|
|
4285
4440
|
*/
|
|
4286
4441
|
clearAgentState(agentId) {
|
|
4442
|
+
const agent = this.agentSubscriptions.get(agentId)?.agent;
|
|
4443
|
+
if (agent) this.interruptedRuns.delete(agent);
|
|
4287
4444
|
this.stateByRun.delete(agentId);
|
|
4288
4445
|
this.messageToRun.delete(agentId);
|
|
4289
4446
|
this.rawEventByMessage.delete(agentId);
|
|
@@ -4292,6 +4449,8 @@ var StateManager = class {
|
|
|
4292
4449
|
* Clear all state for a thread
|
|
4293
4450
|
*/
|
|
4294
4451
|
clearThreadState(agentId, threadId) {
|
|
4452
|
+
const agent = this.agentSubscriptions.get(agentId)?.agent;
|
|
4453
|
+
if (agent) this.interruptedRuns.get(agent)?.delete(threadId);
|
|
4295
4454
|
this.stateByRun.get(agentId)?.delete(threadId);
|
|
4296
4455
|
this.messageToRun.get(agentId)?.delete(threadId);
|
|
4297
4456
|
this.rawEventByMessage.get(agentId)?.delete(threadId);
|
|
@@ -7407,6 +7566,7 @@ exports.ɵcreateMemoryStore = createMemoryStore;
|
|
|
7407
7566
|
exports.ɵcreateThreadSelectors = ɵcreateThreadSelectors;
|
|
7408
7567
|
exports.ɵcreateThreadStore = createThreadStore;
|
|
7409
7568
|
exports.ɵisCopilotKitFeature = ɵisCopilotKitFeature;
|
|
7569
|
+
exports.ɵisHttpAgent = ɵisHttpAgent;
|
|
7410
7570
|
exports.ɵisRetryableMemoryStatus = isRetryableStatus;
|
|
7411
7571
|
exports.ɵjoinPhoenixChannel$ = ɵjoinPhoenixChannel$;
|
|
7412
7572
|
exports.ɵmapMemoryMetadataEvent = ɵmapMemoryMetadataEvent;
|