@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.umd.js CHANGED
@@ -5,6 +5,23 @@
5
5
  })(this, function(exports, _tanstack_pacer, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema) {
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7
7
 
8
+ //#region src/utils/http-agent.ts
9
+ /**
10
+ * Whether an agent is an `HttpAgent`, including one built from another copy of
11
+ * `@ag-ui/client` (an app that pins its own 0.x version next to CopilotKit's
12
+ * 1.0, for example). `instanceof` is false across package copies, which made
13
+ * CopilotKit silently skip headers and abort wiring for those agents. The
14
+ * fallback checks the public fields CopilotKit uses, which every published
15
+ * `HttpAgent` has.
16
+ */
17
+ function ɵisHttpAgent(agent) {
18
+ if (agent instanceof _ag_ui_client.HttpAgent) return true;
19
+ if (typeof agent !== "object" || agent === null) return false;
20
+ const candidate = agent;
21
+ return typeof candidate.url === "string" && typeof candidate.headers === "object" && candidate.headers !== null && candidate.abortController instanceof AbortController && typeof candidate.runAgent === "function";
22
+ }
23
+
24
+ //#endregion
8
25
  //#region src/utils/connect-replay.ts
9
26
  /**
10
27
  * Runs an agent's `connect()` stream through the AbstractAgent apply pipeline
@@ -21,18 +38,27 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
21
38
  * Cannot send event type 'RUN_STARTED': The run has already errored with
22
39
  * 'RUN_ERROR'. No further events can be sent.
23
40
  *
24
- * `transformChunks` is still applied — message reassembly is needed either way.
41
+ * The AG-UI 1.0 compatibility boundary still runs first, so stored 0.x history
42
+ * is translated (THINKING_* events, `binary` parts, legacy nulls) exactly as in
43
+ * the base pipeline. `enforceEvents` is omitted too: a replay is stored
44
+ * history, and one event that the 1.0 schema rejects (the Intelligence gateway
45
+ * replays RUN_STARTED without `runId`, for example) must not stop the whole
46
+ * thread from hydrating. That keeps the leniency this path had before 1.0.
25
47
  *
26
48
  * Connection-local replay hooks track the phase before applying events. An
27
49
  * explicitly live RUN_ERROR clears busy without closing the connection;
28
50
  * historical errors remain data. Connections without hooks retain the existing
29
- * completion behavior. Subscriber, detach, and result contracts are preserved.
51
+ * completion behavior.
52
+ *
53
+ * Apart from the above, this mirrors the base `AbstractAgent.connectAgent`
54
+ * implementation, so callers keep the same subscriber notifications, detach
55
+ * semantics, and `{ result, newMessages }` return shape.
30
56
  *
31
57
  * TODO: Remove this in favour of the base implementation once AG-UI's
32
58
  * AbstractAgent supports opting out of `verifyEvents` for transports whose
33
59
  * connection life-cycle isn't a single run AND preserves the connection-local
34
60
  * replay lifecycle and running-state behavior below. Skipping verification alone
35
- * is insufficient. As of `@ag-ui/client@0.0.57`
61
+ * is insufficient. As of `@ag-ui/client@1.0.1`
36
62
  * `connectAgent(parameters?, subscriber?)` takes no such option.
37
63
  *
38
64
  * @param agent - The agent whose `connect()` stream should be consumed.
@@ -41,6 +67,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
41
67
  */
42
68
  async function ɵconnectWithoutEventVerification(agent, parameters, subscriber, connect) {
43
69
  const self = agent;
70
+ let finalizeRun = () => {
71
+ agent.isRunning = false;
72
+ };
44
73
  try {
45
74
  var _agent$agentId;
46
75
  agent.isRunning = true;
@@ -65,12 +94,35 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
65
94
  ...agent.subscribers,
66
95
  subscriber !== null && subscriber !== void 0 ? subscriber : {}
67
96
  ];
68
- await self.onInitialize(input, subscribers);
69
- self.activeRunDetach$ = new rxjs.Subject();
97
+ const activeRunDetach$ = new rxjs.Subject();
98
+ self.activeRunDetach$ = activeRunDetach$;
70
99
  let resolveCompletion;
71
100
  self.activeRunCompletionPromise = new Promise((resolve) => {
72
101
  resolveCompletion = resolve;
73
102
  });
103
+ let detached = false;
104
+ let finalized = false;
105
+ const detachSubscription = activeRunDetach$.subscribe(() => {
106
+ detached = true;
107
+ });
108
+ finalizeRun = () => {
109
+ if (finalized) return;
110
+ finalized = true;
111
+ detachSubscription.unsubscribe();
112
+ if (self.activeRunDetach$ === activeRunDetach$) {
113
+ agent.isRunning = false;
114
+ self.activeRunCompletionPromise = void 0;
115
+ self.activeRunDetach$ = void 0;
116
+ self.onFinalize(input, subscribers);
117
+ }
118
+ resolveCompletion === null || resolveCompletion === void 0 || resolveCompletion();
119
+ resolveCompletion = void 0;
120
+ };
121
+ await self.onInitialize(input, subscribers);
122
+ if (detached) return {
123
+ result: void 0,
124
+ newMessages: []
125
+ };
74
126
  const lifecycle = {
75
127
  onReplayStarted: () => {
76
128
  isReplaying = true;
@@ -80,29 +132,23 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
80
132
  isReplaying = false;
81
133
  }
82
134
  };
83
- const source$ = (0, rxjs.defer)(() => connect ? connect(input, lifecycle) : self.connect(input)).pipe((0, rxjs_operators.tap)((event) => {
135
+ 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) => {
84
136
  if (!isReplaying && event.type === _ag_ui_client.EventType.RUN_ERROR) liveErrors.add(event);
85
- }), (0, _ag_ui_client.transformChunks)(self.debugLogger), (0, rxjs_operators.takeUntil)(self.activeRunDetach$));
137
+ }), (0, _ag_ui_client.transformChunks)(self.debugLogger), (0, rxjs_operators.takeUntil)(activeRunDetach$));
86
138
  const applied$ = self.apply(input, source$, subscribers);
87
139
  await (0, rxjs.lastValueFrom)(self.processApplyEvents(input, applied$, subscribers).pipe((0, rxjs_operators.catchError)((error) => {
140
+ if (self.activeRunDetach$ !== activeRunDetach$) return rxjs.EMPTY;
88
141
  agent.isRunning = false;
89
142
  if (error instanceof _ag_ui_client.AGUIConnectNotImplementedError) return rxjs.EMPTY;
90
143
  return self.onError(input, error, subscribers);
91
- }), (0, rxjs_operators.finalize)(() => {
92
- agent.isRunning = false;
93
- self.onFinalize(input, subscribers);
94
- resolveCompletion === null || resolveCompletion === void 0 || resolveCompletion();
95
- resolveCompletion = void 0;
96
- self.activeRunCompletionPromise = void 0;
97
- self.activeRunDetach$ = void 0;
98
- })), { defaultValue: void 0 });
144
+ }), (0, rxjs_operators.finalize)(() => finalizeRun())), { defaultValue: void 0 });
99
145
  const newMessages = (0, _ag_ui_client.structuredClone_)(agent.messages).filter((m) => !previousMessageIds.has(m.id));
100
146
  return {
101
147
  result,
102
148
  newMessages
103
149
  };
104
150
  } finally {
105
- agent.isRunning = false;
151
+ finalizeRun();
106
152
  }
107
153
  }
108
154
 
@@ -635,7 +681,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
635
681
  observeThreadEvents$(threadId, channel$, options) {
636
682
  return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, CLIENT_AG_UI_EVENT)), (0, rxjs_operators.tap)((payload) => {
637
683
  this.updateLastSeenEventId(threadId, payload);
638
- }), (0, rxjs_operators.mergeMap)((payload) => this.createThreadNotifications(payload, {
684
+ }), (0, rxjs_operators.map)((payload) => options.streamMode === "run" ? (0, _copilotkit_shared.stripIntelligenceRoutingFields)(payload) : payload), (0, rxjs_operators.mergeMap)((payload) => this.createThreadNotifications(payload, {
639
685
  completeOnRunError: options.completeOnRunError,
640
686
  completeOnRunFinished: options.streamMode === "run",
641
687
  errorOnRunError: options.streamMode === "run"
@@ -957,6 +1003,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
957
1003
  _defineProperty(this, "_capabilities", void 0);
958
1004
  _defineProperty(this, "delegate", void 0);
959
1005
  _defineProperty(this, "runtimeInfoPromise", void 0);
1006
+ _defineProperty(this, "connectionAttempt", void 0);
960
1007
  _defineProperty(this, "_messageFilter", void 0);
961
1008
  _defineProperty(this, "activeRun", void 0);
962
1009
  this.runtimeUrl = normalizedRuntimeUrl !== null && normalizedRuntimeUrl !== void 0 ? normalizedRuntimeUrl : config.runtimeUrl;
@@ -1000,13 +1047,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1000
1047
  this.runtimeMode = runtimeMode;
1001
1048
  this.intelligence = intelligence;
1002
1049
  if (unchanged) return;
1050
+ this.connectionAttempt = void 0;
1003
1051
  this.runtimeInfoPromise = void 0;
1004
1052
  const staleDelegate = this.delegate;
1005
1053
  this.delegate = void 0;
1006
- if (staleDelegate) {
1007
- staleDelegate.abortRun();
1008
- this.detachActiveRun();
1009
- }
1054
+ if (staleDelegate) staleDelegate.abortRun();
1055
+ this.detachActiveRun();
1010
1056
  }
1011
1057
  /**
1012
1058
  * The agent id used for outbound runtime requests — `runtimeAgentId` when
@@ -1052,8 +1098,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1052
1098
  return (_this$_capabilities = this._capabilities) !== null && _this$_capabilities !== void 0 ? _this$_capabilities : {};
1053
1099
  }
1054
1100
  async detachActiveRun() {
1055
- if (this.delegate) await this.delegate.detachActiveRun();
1056
- await super.detachActiveRun();
1101
+ var _this$delegate;
1102
+ this.connectionAttempt = void 0;
1103
+ this.isRunning = false;
1104
+ const delegateDetach = (_this$delegate = this.delegate) === null || _this$delegate === void 0 ? void 0 : _this$delegate.detachActiveRun();
1105
+ const proxyDetach = super.detachActiveRun();
1106
+ await Promise.all([delegateDetach, proxyDetach]);
1057
1107
  }
1058
1108
  abortRun() {
1059
1109
  var _this$activeRun;
@@ -1108,41 +1158,74 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1108
1158
  });
1109
1159
  }
1110
1160
  async connectAgent(parameters, subscriber) {
1161
+ const detached = this.detachActiveRun();
1162
+ const connection = {};
1163
+ const threadId = this.threadId;
1164
+ this.connectionAttempt = connection;
1165
+ const isCurrentConnection = () => this.connectionAttempt === connection && this.threadId === threadId;
1166
+ await detached;
1167
+ if (!isCurrentConnection()) return {
1168
+ result: void 0,
1169
+ newMessages: []
1170
+ };
1171
+ await this.ensureRuntimeConfiguration();
1172
+ if (!isCurrentConnection()) return {
1173
+ result: void 0,
1174
+ newMessages: []
1175
+ };
1111
1176
  if (this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return ɵconnectWithoutEventVerification(this, parameters, subscriber, (input, lifecycle) => this.connect(input, lifecycle));
1112
- if (this.delegate) await this.delegate.detachActiveRun();
1113
1177
  await this.resolveDelegate();
1178
+ if (!isCurrentConnection()) return {
1179
+ result: void 0,
1180
+ newMessages: []
1181
+ };
1114
1182
  const delegate = this.delegate;
1115
1183
  const bridgeSub = delegate.subscribe({
1116
1184
  onMessagesChanged: () => {
1185
+ if (!isCurrentConnection()) return;
1117
1186
  this.setMessages([...delegate.messages]);
1118
1187
  },
1119
1188
  onStateChanged: () => {
1189
+ if (!isCurrentConnection()) return;
1120
1190
  this.setState({ ...delegate.state });
1121
1191
  },
1122
1192
  onRunInitialized: () => {
1193
+ if (!isCurrentConnection()) return;
1123
1194
  this.isRunning = true;
1124
1195
  },
1125
1196
  onRunFinalized: () => {
1197
+ if (!isCurrentConnection()) return;
1198
+ this.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(delegate.pendingInterrupts);
1126
1199
  this.isRunning = false;
1127
1200
  },
1128
1201
  onRunFailed: () => {
1202
+ if (!isCurrentConnection()) return;
1129
1203
  this.isRunning = false;
1130
1204
  },
1131
1205
  onRunErrorEvent: () => {
1206
+ if (!isCurrentConnection()) return;
1132
1207
  this.isRunning = delegate.isRunning;
1133
1208
  },
1134
1209
  onRunStartedEvent: () => {
1210
+ if (!isCurrentConnection()) return;
1135
1211
  this.isRunning = delegate.isRunning;
1136
1212
  }
1137
1213
  });
1138
- const forwardedSubs = this.subscribers.map((s) => delegate.subscribe(s));
1214
+ const forwardedSubs = [...this.subscribers, ...subscriber ? [subscriber] : []].map((subscriber) => delegate.subscribe(new Proxy(subscriber, { get(target, property, receiver) {
1215
+ const callback = Reflect.get(target, property, receiver);
1216
+ if (typeof callback !== "function") return callback;
1217
+ return (...args) => isCurrentConnection() ? Reflect.apply(callback, target, args) : void 0;
1218
+ } })));
1139
1219
  try {
1140
- const result = await delegate.connectAgent(parameters, subscriber);
1141
- this.setMessages([...delegate.messages]);
1142
- this.setState({ ...delegate.state });
1220
+ const result = await delegate.connectAgent(parameters);
1221
+ if (isCurrentConnection()) {
1222
+ this.setMessages([...delegate.messages]);
1223
+ this.setState({ ...delegate.state });
1224
+ this.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(delegate.pendingInterrupts);
1225
+ }
1143
1226
  return result;
1144
1227
  } finally {
1145
- this.isRunning = false;
1228
+ if (isCurrentConnection()) this.isRunning = false;
1146
1229
  bridgeSub.unsubscribe();
1147
1230
  for (const sub of forwardedSubs) sub.unsubscribe();
1148
1231
  }
@@ -1177,6 +1260,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1177
1260
  cloned.threadId = this.threadId;
1178
1261
  cloned.setState(this.state);
1179
1262
  cloned.setMessages(this.messages);
1263
+ cloned.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(this.pendingInterrupts);
1180
1264
  if (this.delegate) {
1181
1265
  const clonedDelegate = this.delegate.clone();
1182
1266
  cloned.delegate = clonedDelegate;
@@ -1218,6 +1302,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1218
1302
  if (!this.runtimeUrl) throw new Error("Runtime URL is not set");
1219
1303
  const runtimeInfoPromise = (_this$runtimeInfoProm = this.runtimeInfoPromise) !== null && _this$runtimeInfoProm !== void 0 ? _this$runtimeInfoProm : this.fetchRuntimeInfo().then((runtimeInfo) => {
1220
1304
  var _runtimeInfo$mode;
1305
+ if (this.runtimeInfoPromise !== runtimeInfoPromise) return;
1221
1306
  this.runtimeMode = (_runtimeInfo$mode = runtimeInfo.mode) !== null && _runtimeInfo$mode !== void 0 ? _runtimeInfo$mode : _copilotkit_shared.RUNTIME_MODE_SSE;
1222
1307
  this.intelligence = runtimeInfo.intelligence;
1223
1308
  });
@@ -1325,6 +1410,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1325
1410
  delegate.debugLogger = this.debugLogger;
1326
1411
  delegate.setMessages(this.messages);
1327
1412
  delegate.setState(this.state);
1413
+ delegate.pendingInterrupts = (0, _ag_ui_client.structuredClone_)(this.pendingInterrupts);
1328
1414
  if (hasHeaders(delegate)) delegate.headers = { ...this.headers };
1329
1415
  if (hasCredentials(delegate)) delegate.credentials = this.credentials;
1330
1416
  }
@@ -1385,14 +1471,31 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1385
1471
  const input = _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _applyMessageFilter).call(this, unfiltered);
1386
1472
  this.activeRun = void 0;
1387
1473
  const routedId = this.routedAgentId();
1474
+ let httpEvents;
1388
1475
  if (this.transport === "single") {
1389
1476
  if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
1390
1477
  const requestInit = this.createSingleRouteRequestInit(input, "agent/connect", { agentId: routedId });
1391
- return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(() => this.fetch(this.singleEndpointUrl, requestInit))));
1392
- }
1393
- const connectUrl = `${this.runtimeUrl}/agent/${routedId}/connect`;
1394
- const connectRequestInit = this.requestInit(input);
1395
- return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(() => this.fetch(connectUrl, connectRequestInit))));
1478
+ httpEvents = (0, _ag_ui_client.runHttpRequest)(() => this.fetch(this.singleEndpointUrl, requestInit));
1479
+ } else {
1480
+ const connectUrl = `${this.runtimeUrl}/agent/${routedId}/connect`;
1481
+ const connectRequestInit = this.requestInit(input);
1482
+ httpEvents = (0, _ag_ui_client.runHttpRequest)(() => this.fetch(connectUrl, connectRequestInit));
1483
+ }
1484
+ return withAbortErrorHandling((0, rxjs.defer)(() => {
1485
+ let replayStarted = false;
1486
+ const emptyHistory = [{
1487
+ type: _ag_ui_client.EventType.MESSAGES_SNAPSHOT,
1488
+ messages: []
1489
+ }, {
1490
+ type: _ag_ui_client.EventType.STATE_SNAPSHOT,
1491
+ snapshot: {}
1492
+ }];
1493
+ return (0, _ag_ui_client.transformHttpEventStream)(httpEvents).pipe((0, rxjs_operators.concatMap)((event) => {
1494
+ if (replayStarted) return (0, rxjs.of)(event);
1495
+ replayStarted = true;
1496
+ return (0, rxjs.from)([...emptyHistory, event]);
1497
+ }), (0, rxjs_operators.concatWith)((0, rxjs.defer)(() => replayStarted ? rxjs.EMPTY : (0, rxjs.from)(emptyHistory))));
1498
+ }));
1396
1499
  }
1397
1500
  function _runViaDelegate(input) {
1398
1501
  return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.run(input))));
@@ -1840,7 +1943,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1840
1943
  * because only `HttpAgent` carries a `headers` field. See #5635.
1841
1944
  */
1842
1945
  applyHeadersToAgent(agent) {
1843
- if (agent instanceof _ag_ui_client.HttpAgent) {
1946
+ if (ɵisHttpAgent(agent)) {
1844
1947
  if (!this.agentOwnHeaders.has(agent)) this.agentOwnHeaders.set(agent, { ...agent.headers });
1845
1948
  agent.headers = {
1846
1949
  ...this.agentOwnHeaders.get(agent),
@@ -3166,6 +3269,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3166
3269
  _defineProperty(this, "_runDepth", 0);
3167
3270
  _defineProperty(this, "_webmcpRegistry", new WebMCPRegistry());
3168
3271
  _defineProperty(this, "_lastConnectedThreadIdsByAgent", /* @__PURE__ */ new Map());
3272
+ _defineProperty(this, "_lastActiveThreadIdsByAgent", /* @__PURE__ */ new Map());
3169
3273
  _defineProperty(this, "_anonymousAgentIds", /* @__PURE__ */ new WeakMap());
3170
3274
  _defineProperty(this, "_nextAnonymousAgentId", 0);
3171
3275
  _defineProperty(this, "_executingToolCalls", /* @__PURE__ */ new WeakMap());
@@ -3342,7 +3446,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3342
3446
  */
3343
3447
  async connectAgent({ agent }) {
3344
3448
  var _agent$threadId;
3345
- this._connectionGenerations.set(agent, {});
3449
+ const connection = {};
3450
+ this._connectionGenerations.set(agent, connection);
3346
3451
  const incomingThreadId = (_agent$threadId = agent.threadId) !== null && _agent$threadId !== void 0 ? _agent$threadId : null;
3347
3452
  const previousReplay = this._interactionAbortControllers.get(agent);
3348
3453
  if (previousReplay && previousReplay.threadId !== incomingThreadId) {
@@ -3351,14 +3456,21 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3351
3456
  this._executingToolCalls.delete(agent);
3352
3457
  }
3353
3458
  try {
3354
- var _this$_lastConnectedT, _agent$threadId2, _this$_interactionAbo;
3459
+ var _ref, _agent$threadId2, _agent$threadId3, _agent$threadId4, _this$_interactionAbo;
3355
3460
  const restoreKey = this.getConnectRestoreKey(agent);
3356
- const isFreshRestore = incomingThreadId !== ((_this$_lastConnectedT = this._lastConnectedThreadIdsByAgent.get(restoreKey)) !== null && _this$_lastConnectedT !== void 0 ? _this$_lastConnectedT : null);
3357
- this._lastConnectedThreadIdsByAgent.set(restoreKey, incomingThreadId);
3461
+ const previousThreadId = this._lastActiveThreadIdsByAgent.get(restoreKey);
3462
+ const isFreshRestore = incomingThreadId !== ((_ref = previousThreadId !== null && previousThreadId !== void 0 ? previousThreadId : this._lastConnectedThreadIdsByAgent.get(restoreKey)) !== null && _ref !== void 0 ? _ref : null);
3358
3463
  await agent.detachActiveRun();
3464
+ if (this._connectionGenerations.get(agent) !== connection || ((_agent$threadId2 = agent.threadId) !== null && _agent$threadId2 !== void 0 ? _agent$threadId2 : null) !== incomingThreadId) return {
3465
+ result: void 0,
3466
+ newMessages: []
3467
+ };
3468
+ this._lastConnectedThreadIdsByAgent.set(restoreKey, incomingThreadId);
3469
+ this._lastActiveThreadIdsByAgent.set(restoreKey, incomingThreadId);
3359
3470
  if (isFreshRestore) {
3360
3471
  agent.setMessages([]);
3361
3472
  agent.setState({});
3473
+ if (previousThreadId !== void 0 && previousThreadId !== incomingThreadId) agent.pendingInterrupts = [];
3362
3474
  const cursorAware = agent;
3363
3475
  if (incomingThreadId) {
3364
3476
  if (typeof cursorAware.clearReplayCursor === "function") cursorAware.clearReplayCursor(incomingThreadId);
@@ -3373,12 +3485,16 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3373
3485
  agent
3374
3486
  });
3375
3487
  }, "Subscriber onAgentRunStarted error:");
3488
+ if (this._connectionGenerations.get(agent) !== connection || ((_agent$threadId3 = agent.threadId) !== null && _agent$threadId3 !== void 0 ? _agent$threadId3 : null) !== incomingThreadId) return {
3489
+ result: void 0,
3490
+ newMessages: []
3491
+ };
3376
3492
  const runAgentResult = await agent.connectAgent({
3377
3493
  forwardedProps: this._internal.properties,
3378
3494
  tools: this.buildFrontendTools(agent.agentId),
3379
3495
  context: this._internal.getContextForAgent(agent.agentId)
3380
3496
  }, this.createAgentErrorSubscriber(agent));
3381
- if (((_agent$threadId2 = agent.threadId) !== null && _agent$threadId2 !== void 0 ? _agent$threadId2 : null) !== incomingThreadId) return runAgentResult;
3497
+ if (this._connectionGenerations.get(agent) !== connection || ((_agent$threadId4 = agent.threadId) !== null && _agent$threadId4 !== void 0 ? _agent$threadId4 : null) !== incomingThreadId) return runAgentResult;
3382
3498
  const controller = new AbortController();
3383
3499
  const replay = (_this$_interactionAbo = this._interactionAbortControllers.get(agent)) !== null && _this$_interactionAbo !== void 0 ? _this$_interactionAbo : {
3384
3500
  threadId: incomingThreadId,
@@ -3435,6 +3551,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3435
3551
  continuationHandoff === null || continuationHandoff === void 0 || continuationHandoff.cancel();
3436
3552
  throw error;
3437
3553
  }
3554
+ const resumedRunId = this._internal.stateManager.getContinuationRunId(agent, {
3555
+ threadId: agent.threadId,
3556
+ resume,
3557
+ forwardedProps
3558
+ });
3559
+ const logicalHandoff = continuationHandoff !== null && continuationHandoff !== void 0 ? continuationHandoff : resumedRunId ? this._internal.stateManager.markNextRunAsContinuation(agent, resumedRunId) : void 0;
3438
3560
  const isTopLevel = this._runDepth === 0;
3439
3561
  let originalAbortRun;
3440
3562
  if (isTopLevel) {
@@ -3455,18 +3577,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3455
3577
  }
3456
3578
  this._runDepth++;
3457
3579
  try {
3458
- let logicalRunId = runId;
3580
+ let logicalRunId = resumedRunId !== null && resumedRunId !== void 0 ? resumedRunId : runId;
3459
3581
  const agentSubscriber = this.createAgentErrorSubscriber(agent);
3460
3582
  let started = false;
3461
3583
  const onRunStartedEvent = agentSubscriber.onRunStartedEvent;
3462
3584
  const onRunInitialized = agentSubscriber.onRunInitialized;
3463
3585
  agentSubscriber.onRunInitialized = async (params) => {
3464
- continuationHandoff === null || continuationHandoff === void 0 || continuationHandoff.bind(params.input);
3586
+ this._lastActiveThreadIdsByAgent.set(this.getConnectRestoreKey(agent), params.input.threadId);
3587
+ logicalHandoff === null || logicalHandoff === void 0 || logicalHandoff.bind(params.input);
3465
3588
  return onRunInitialized === null || onRunInitialized === void 0 ? void 0 : onRunInitialized(params);
3466
3589
  };
3467
3590
  agentSubscriber.onRunStartedEvent = async (params) => {
3468
3591
  started = true;
3469
- if (!continuationHandoff) logicalRunId = params.input.runId;
3592
+ if (!logicalHandoff) logicalRunId = params.input.runId;
3470
3593
  return onRunStartedEvent === null || onRunStartedEvent === void 0 ? void 0 : onRunStartedEvent(params);
3471
3594
  };
3472
3595
  const pinRunIdOnWire = runId !== void 0 && !continuationHandoff;
@@ -3481,14 +3604,14 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3481
3604
  context: this._internal.getContextForAgent(agent.agentId)
3482
3605
  };
3483
3606
  const runAgentResult = await agent.runAgent(agentRunInput, agentSubscriber);
3484
- if (!started) continuationHandoff === null || continuationHandoff === void 0 || continuationHandoff.cancel();
3607
+ if (!started) logicalHandoff === null || logicalHandoff === void 0 || logicalHandoff.cancel();
3485
3608
  return await this.processAgentResult({
3486
3609
  runAgentResult,
3487
3610
  agent,
3488
3611
  runId: logicalRunId
3489
3612
  });
3490
3613
  } catch (error) {
3491
- continuationHandoff === null || continuationHandoff === void 0 || continuationHandoff.cancel();
3614
+ logicalHandoff === null || logicalHandoff === void 0 || logicalHandoff.cancel();
3492
3615
  const runError = error instanceof Error ? error : new Error(String(error));
3493
3616
  const context = {};
3494
3617
  if (agent.agentId) context.agentId = agent.agentId;
@@ -4057,6 +4180,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4057
4180
  * Tracks agent state snapshots and message-to-run associations.
4058
4181
  */
4059
4182
  var StateManager = class {
4183
+ /** Find the interrupted logical run without consuming its pending answers. */
4184
+ getContinuationRunId(agent, input) {
4185
+ var _this$interruptedRuns, _input$resume, _input$resume2;
4186
+ const pending = (_this$interruptedRuns = this.interruptedRuns.get(agent)) === null || _this$interruptedRuns === void 0 ? void 0 : _this$interruptedRuns.get(input.threadId);
4187
+ if (!pending) return void 0;
4188
+ if (pending.interruptIds === null) return input.resume === void 0 && isContinuation(input) ? pending.runId : void 0;
4189
+ const submitted = new Set((_input$resume = input.resume) === null || _input$resume === void 0 ? void 0 : _input$resume.map((entry) => entry.interruptId));
4190
+ return submitted.size > 0 && submitted.size === ((_input$resume2 = input.resume) === null || _input$resume2 === void 0 ? void 0 : _input$resume2.length) && submitted.size === pending.interruptIds.length && pending.interruptIds.every((id) => submitted.has(id)) ? pending.runId : void 0;
4191
+ }
4060
4192
  constructor(core) {
4061
4193
  this.core = core;
4062
4194
  _defineProperty(this, "stateByRun", /* @__PURE__ */ new Map());
@@ -4065,6 +4197,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4065
4197
  _defineProperty(this, "activeRun", /* @__PURE__ */ new Map());
4066
4198
  _defineProperty(this, "agentSubscriptions", /* @__PURE__ */ new Map());
4067
4199
  _defineProperty(this, "pendingContinuations", /* @__PURE__ */ new WeakMap());
4200
+ _defineProperty(this, "interruptedRuns", /* @__PURE__ */ new WeakMap());
4068
4201
  }
4069
4202
  /**
4070
4203
  * Initialize state tracking for an agent
@@ -4106,6 +4239,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4106
4239
  }
4107
4240
  let revoked = false;
4108
4241
  let subRunId;
4242
+ let legacyInterrupted = false;
4109
4243
  let runFinished = false;
4110
4244
  const pendingResults = /* @__PURE__ */ new WeakMap();
4111
4245
  const reconcilePendingResults = (historyMessages, input) => {
@@ -4184,27 +4318,52 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4184
4318
  };
4185
4319
  const { unsubscribe } = agent.subscribe({
4186
4320
  onRunStartedEvent: ({ event, input, state }) => {
4321
+ var _event$input, _this$interruptedRuns2;
4187
4322
  if (revoked) return;
4188
4323
  const pendingForAgent = this.pendingContinuations.get(agent);
4189
4324
  const internalContinuation = [...pendingForAgent !== null && pendingForAgent !== void 0 ? pendingForAgent : []].find((pending) => pending.expectedInput === input);
4190
4325
  internalContinuation === null || internalContinuation === void 0 || internalContinuation.cancel();
4326
+ const startedInput = (_event$input = event.input) !== null && _event$input !== void 0 ? _event$input : {
4327
+ ...input,
4328
+ threadId: event.threadId
4329
+ };
4330
+ const resumedRunId = this.getContinuationRunId(agent, startedInput);
4331
+ (_this$interruptedRuns2 = this.interruptedRuns.get(agent)) === null || _this$interruptedRuns2 === void 0 || _this$interruptedRuns2.delete(startedInput.threadId);
4332
+ legacyInterrupted = false;
4191
4333
  if (internalContinuation) {
4192
4334
  var _ref, _internalContinuation;
4193
4335
  subRunId = (_ref = (_internalContinuation = internalContinuation.expectedRunId) !== null && _internalContinuation !== void 0 ? _internalContinuation : event.runId) !== null && _ref !== void 0 ? _ref : input.runId;
4194
- } else if (runFinished && input.runId === subRunId && !isContinuation(input) && (event.runId == null || event.runId === subRunId)) subRunId = (0, _ag_ui_client.randomUUID)();
4336
+ } else if (resumedRunId) subRunId = resumedRunId;
4337
+ else if (runFinished && input.runId === subRunId && !isContinuation(input) && (event.runId == null || event.runId === subRunId)) subRunId = (0, _ag_ui_client.randomUUID)();
4195
4338
  else subRunId = event.runId || input.runId;
4196
4339
  runFinished = false;
4197
4340
  this.handleRunStarted(agent, effectiveInput(input), state);
4198
4341
  },
4199
- onRunFinishedEvent: ({ input, state, messages }) => {
4342
+ onRunFinishedEvent: ({ event, input, state, messages }) => {
4343
+ var _event$outcome;
4200
4344
  if (revoked) return;
4201
4345
  runFinished = true;
4202
4346
  const effective = effectiveInput(input);
4347
+ let interrupted = this.interruptedRuns.get(agent);
4348
+ if (((_event$outcome = event.outcome) === null || _event$outcome === void 0 ? void 0 : _event$outcome.type) === "interrupt" || legacyInterrupted) {
4349
+ var _event$outcome2;
4350
+ if (!interrupted) {
4351
+ interrupted = /* @__PURE__ */ new Map();
4352
+ this.interruptedRuns.set(agent, interrupted);
4353
+ }
4354
+ interrupted.set(event.threadId, {
4355
+ runId: effective.runId,
4356
+ interruptIds: ((_event$outcome2 = event.outcome) === null || _event$outcome2 === void 0 ? void 0 : _event$outcome2.type) === "interrupt" ? event.outcome.interrupts.map((interrupt) => interrupt.id) : null
4357
+ });
4358
+ } else interrupted === null || interrupted === void 0 || interrupted.delete(event.threadId);
4203
4359
  const mutation = reconcilePendingResults(messages, input);
4204
4360
  clearPendingResults(input);
4205
4361
  this.handleRunFinished(agent, effective, state);
4206
4362
  return mutation;
4207
4363
  },
4364
+ onCustomEvent: ({ event }) => {
4365
+ if (!revoked && event.name === "on_interrupt") legacyInterrupted = true;
4366
+ },
4208
4367
  onRunErrorEvent: ({ input, state, messages }) => {
4209
4368
  if (revoked) return;
4210
4369
  runFinished = true;
@@ -4261,6 +4420,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4261
4420
  unsubscribe: () => {
4262
4421
  revoked = true;
4263
4422
  this.pendingContinuations.delete(agent);
4423
+ this.interruptedRuns.delete(agent);
4264
4424
  unsubscribe();
4265
4425
  }
4266
4426
  });
@@ -4435,6 +4595,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4435
4595
  * Clear all state for an agent
4436
4596
  */
4437
4597
  clearAgentState(agentId) {
4598
+ var _this$agentSubscripti;
4599
+ const agent = (_this$agentSubscripti = this.agentSubscriptions.get(agentId)) === null || _this$agentSubscripti === void 0 ? void 0 : _this$agentSubscripti.agent;
4600
+ if (agent) this.interruptedRuns.delete(agent);
4438
4601
  this.stateByRun.delete(agentId);
4439
4602
  this.messageToRun.delete(agentId);
4440
4603
  this.rawEventByMessage.delete(agentId);
@@ -4443,7 +4606,9 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4443
4606
  * Clear all state for a thread
4444
4607
  */
4445
4608
  clearThreadState(agentId, threadId) {
4446
- var _this$stateByRun$get4, _this$messageToRun$ge2, _this$rawEventByMessa8;
4609
+ var _this$agentSubscripti2, _this$interruptedRuns3, _this$stateByRun$get4, _this$messageToRun$ge2, _this$rawEventByMessa8;
4610
+ const agent = (_this$agentSubscripti2 = this.agentSubscriptions.get(agentId)) === null || _this$agentSubscripti2 === void 0 ? void 0 : _this$agentSubscripti2.agent;
4611
+ if (agent) (_this$interruptedRuns3 = this.interruptedRuns.get(agent)) === null || _this$interruptedRuns3 === void 0 || _this$interruptedRuns3.delete(threadId);
4447
4612
  (_this$stateByRun$get4 = this.stateByRun.get(agentId)) === null || _this$stateByRun$get4 === void 0 || _this$stateByRun$get4.delete(threadId);
4448
4613
  (_this$messageToRun$ge2 = this.messageToRun.get(agentId)) === null || _this$messageToRun$ge2 === void 0 || _this$messageToRun$ge2.delete(threadId);
4449
4614
  (_this$rawEventByMessa8 = this.rawEventByMessage.get(agentId)) === null || _this$rawEventByMessa8 === void 0 || _this$rawEventByMessa8.delete(threadId);
@@ -7621,6 +7786,7 @@ exports.ɵcreateMemoryStore = createMemoryStore;
7621
7786
  exports.ɵcreateThreadSelectors = ɵcreateThreadSelectors;
7622
7787
  exports.ɵcreateThreadStore = createThreadStore;
7623
7788
  exports.ɵisCopilotKitFeature = ɵisCopilotKitFeature;
7789
+ exports.ɵisHttpAgent = ɵisHttpAgent;
7624
7790
  exports.ɵisRetryableMemoryStatus = isRetryableStatus;
7625
7791
  exports.ɵjoinPhoenixChannel$ = ɵjoinPhoenixChannel$;
7626
7792
  exports.ɵmapMemoryMetadataEvent = ɵmapMemoryMetadataEvent;