@copilotkit/core 0.0.0-fix-license-verifier-client-bundle-20260402220111

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.
@@ -0,0 +1,3592 @@
1
+ (function(global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@ag-ui/client'), require('@copilotkit/shared'), require('rxjs'), require('rxjs/operators'), require('phoenix'), require('zod-to-json-schema'), require('rxjs/fetch')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@ag-ui/client', '@copilotkit/shared', 'rxjs', 'rxjs/operators', 'phoenix', 'zod-to-json-schema', 'rxjs/fetch'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitCore = {}), global.AgUIClient,global.CopilotKitShared,global.rxjs,global.rxjs.operators,global.phoenix,global.zodToJsonSchema,global.rxjs_fetch));
5
+ })(this, function(exports, _ag_ui_client, _copilotkit_shared, rxjs, rxjs_operators, phoenix, zod_to_json_schema, rxjs_fetch) {
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
7
+
8
+ //#region src/utils/phoenix-observable.ts
9
+ /**
10
+ * Adapt Phoenix socket open/error callbacks into an observable signal stream.
11
+ *
12
+ * The returned observable is shared and replayable by the caller when needed,
13
+ * but this helper itself does not own socket connection teardown.
14
+ */
15
+ function ɵcreatePhoenixSocketSignals$(socket) {
16
+ return new rxjs.Observable((observer) => {
17
+ socket.onOpen(() => observer.next({ type: "open" }));
18
+ socket.onError((error) => observer.next({
19
+ type: "error",
20
+ error
21
+ }));
22
+ });
23
+ }
24
+ /**
25
+ * Adapt a Phoenix channel join attempt into a single-outcome observable.
26
+ */
27
+ function ɵcreatePhoenixJoinOutcome$(channel) {
28
+ return new rxjs.Observable((observer) => {
29
+ channel.join().receive("ok", () => {
30
+ observer.next({ type: "joined" });
31
+ observer.complete();
32
+ }).receive("error", (response) => {
33
+ observer.next({
34
+ type: "error",
35
+ response
36
+ });
37
+ observer.complete();
38
+ }).receive("timeout", () => {
39
+ observer.next({ type: "timeout" });
40
+ observer.complete();
41
+ });
42
+ });
43
+ }
44
+ /**
45
+ * Create a cold Phoenix socket session.
46
+ *
47
+ * The socket is constructed and connected on subscription, and disconnected on
48
+ * teardown. Each subscription creates an isolated socket instance.
49
+ */
50
+ function ɵphoenixSocket$(options) {
51
+ return (0, rxjs.defer)(() => {
52
+ const socket = new phoenix.Socket(options.url, options.options);
53
+ const signals$ = ɵcreatePhoenixSocketSignals$(socket).pipe((0, rxjs_operators.shareReplay)({
54
+ bufferSize: 1,
55
+ refCount: true
56
+ }));
57
+ socket.connect();
58
+ return (0, rxjs.concat)((0, rxjs.of)({
59
+ socket,
60
+ signals$
61
+ }), rxjs.NEVER).pipe((0, rxjs_operators.finalize)(() => socket.disconnect()));
62
+ });
63
+ }
64
+ /**
65
+ * Create a cold Phoenix channel session from a socket session stream.
66
+ *
67
+ * A channel is created and joined for each active socket session. If the
68
+ * upstream socket session changes, the previous channel is left before the
69
+ * next one becomes active.
70
+ */
71
+ function ɵphoenixChannel$(options) {
72
+ return options.socket$.pipe((0, rxjs_operators.switchMap)(({ socket }) => (0, rxjs.defer)(() => {
73
+ const channel = socket.channel(options.topic, options.params);
74
+ return (0, rxjs.concat)((0, rxjs.of)({
75
+ channel,
76
+ joinOutcome$: ɵcreatePhoenixJoinOutcome$(channel).pipe((0, rxjs_operators.shareReplay)({
77
+ bufferSize: 1,
78
+ refCount: true
79
+ }))
80
+ }), rxjs.NEVER).pipe((0, rxjs_operators.finalize)(() => {
81
+ if (options.leaveOnUnsubscribe !== false) channel.leave();
82
+ }));
83
+ })));
84
+ }
85
+ /**
86
+ * Observe a named Phoenix channel event as an observable payload stream.
87
+ */
88
+ function ɵobservePhoenixEvent$(channel, eventName) {
89
+ return new rxjs.Observable((observer) => {
90
+ const ref = channel.on(eventName, (payload) => observer.next(payload));
91
+ return () => {
92
+ channel.off(eventName, ref);
93
+ };
94
+ });
95
+ }
96
+ /**
97
+ * Flatten channel sessions into their join-outcome stream.
98
+ */
99
+ function ɵobservePhoenixJoinOutcome$(channel$) {
100
+ return channel$.pipe((0, rxjs_operators.switchMap)((session) => session.joinOutcome$));
101
+ }
102
+ /**
103
+ * Complete when a channel joins successfully, or error if the join fails.
104
+ */
105
+ function ɵjoinPhoenixChannel$(channel$) {
106
+ return ɵobservePhoenixJoinOutcome$(channel$).pipe((0, rxjs_operators.take)(1), (0, rxjs_operators.mergeMap)((outcome) => {
107
+ if (outcome.type === "joined") return rxjs.EMPTY;
108
+ throw outcome.type === "timeout" ? /* @__PURE__ */ new Error("Timed out joining channel") : /* @__PURE__ */ new Error(`Failed to join channel: ${JSON.stringify(outcome.response)}`);
109
+ }));
110
+ }
111
+ /**
112
+ * Flatten socket sessions into their lifecycle signal stream.
113
+ */
114
+ function ɵobservePhoenixSocketSignals$(socket$) {
115
+ return socket$.pipe((0, rxjs_operators.switchMap)((session) => session.signals$));
116
+ }
117
+ /**
118
+ * Error after a socket emits the configured number of consecutive error
119
+ * signals, resetting the counter after each successful open signal.
120
+ */
121
+ function ɵobservePhoenixSocketHealth$(socketSignals$, maxConsecutiveErrors) {
122
+ return socketSignals$.pipe((0, rxjs_operators.scan)((consecutiveErrors, signal) => signal.type === "open" ? 0 : consecutiveErrors + 1, 0), (0, rxjs_operators.filter)((consecutiveErrors) => consecutiveErrors >= maxConsecutiveErrors), (0, rxjs_operators.take)(1), (0, rxjs_operators.mergeMap)((consecutiveErrors) => (0, rxjs.throwError)(() => /* @__PURE__ */ new Error(`WebSocket connection failed after ${consecutiveErrors} consecutive errors`))));
123
+ }
124
+
125
+ //#endregion
126
+ //#region \0@oxc-project+runtime@0.112.0/helpers/typeof.js
127
+ function _typeof(o) {
128
+ "@babel/helpers - typeof";
129
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
130
+ return typeof o;
131
+ } : function(o) {
132
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
133
+ }, _typeof(o);
134
+ }
135
+
136
+ //#endregion
137
+ //#region \0@oxc-project+runtime@0.112.0/helpers/toPrimitive.js
138
+ function toPrimitive(t, r) {
139
+ if ("object" != _typeof(t) || !t) return t;
140
+ var e = t[Symbol.toPrimitive];
141
+ if (void 0 !== e) {
142
+ var i = e.call(t, r || "default");
143
+ if ("object" != _typeof(i)) return i;
144
+ throw new TypeError("@@toPrimitive must return a primitive value.");
145
+ }
146
+ return ("string" === r ? String : Number)(t);
147
+ }
148
+
149
+ //#endregion
150
+ //#region \0@oxc-project+runtime@0.112.0/helpers/toPropertyKey.js
151
+ function toPropertyKey(t) {
152
+ var i = toPrimitive(t, "string");
153
+ return "symbol" == _typeof(i) ? i : i + "";
154
+ }
155
+
156
+ //#endregion
157
+ //#region \0@oxc-project+runtime@0.112.0/helpers/defineProperty.js
158
+ function _defineProperty(e, r, t) {
159
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
160
+ value: t,
161
+ enumerable: !0,
162
+ configurable: !0,
163
+ writable: !0
164
+ }) : e[r] = t, e;
165
+ }
166
+
167
+ //#endregion
168
+ //#region src/intelligence-agent.ts
169
+ const CLIENT_AG_UI_EVENT = "ag_ui_event";
170
+ const STOP_RUN_EVENT = "stop_run";
171
+ var AgentThreadLockedError = class extends Error {
172
+ constructor(threadId) {
173
+ super(threadId ? `Thread ${threadId} is locked` : "Thread is locked");
174
+ this.name = "AgentThreadLockedError";
175
+ }
176
+ };
177
+ var IntelligenceAgent = class IntelligenceAgent extends _ag_ui_client.AbstractAgent {
178
+ constructor(config, sharedState = { lastSeenEventIds: /* @__PURE__ */ new Map() }) {
179
+ super();
180
+ _defineProperty(this, "config", void 0);
181
+ _defineProperty(this, "socket", null);
182
+ _defineProperty(this, "activeChannel", null);
183
+ _defineProperty(this, "runId", null);
184
+ _defineProperty(this, "sharedState", void 0);
185
+ this.config = config;
186
+ this.sharedState = sharedState;
187
+ }
188
+ clone() {
189
+ return new IntelligenceAgent(this.config, this.sharedState);
190
+ }
191
+ /**
192
+ * Override of AbstractAgent.connectAgent that removes the `verifyEvents` step.
193
+ *
194
+ * Background: AbstractAgent's connectAgent pipeline runs events through
195
+ * `verifyEvents`, which validates that the stream follows the AG-UI protocol
196
+ * lifecycle — specifically, it expects a RUN_STARTED event before any content
197
+ * events and a RUN_FINISHED/RUN_ERROR event to complete the stream.
198
+ *
199
+ * IntelligenceAgent uses long-lived WebSocket connections rather than
200
+ * request-scoped SSE streams. When connecting to replay historical messages
201
+ * for an existing thread, the connection semantics don't map to a single
202
+ * agent run start/stop cycle. The replayed events may not include
203
+ * RUN_STARTED/RUN_FINISHED bookends (or may contain events from multiple
204
+ * past runs), which causes verifyEvents to either never complete or to
205
+ * error out.
206
+ *
207
+ * This override replicates the base connectAgent implementation exactly,
208
+ * substituting only `transformChunks` (which is still needed for message
209
+ * reassembly) and omitting `verifyEvents`.
210
+ *
211
+ * TODO: Remove this override once AG-UI's AbstractAgent supports opting out
212
+ * of verifyEvents for transports with different connection life-cycles.
213
+ */
214
+ async connectAgent(parameters, subscriber) {
215
+ const self = this;
216
+ try {
217
+ var _this$agentId;
218
+ this.isRunning = true;
219
+ this.agentId = (_this$agentId = this.agentId) !== null && _this$agentId !== void 0 ? _this$agentId : (0, _ag_ui_client.randomUUID)();
220
+ const input = this.prepareRunAgentInput(parameters);
221
+ let result;
222
+ const previousMessageIds = new Set(this.messages.map((m) => m.id));
223
+ const subscribers = [
224
+ { onRunFinishedEvent: (event) => {
225
+ result = event.result;
226
+ } },
227
+ ...this.subscribers,
228
+ subscriber !== null && subscriber !== void 0 ? subscriber : {}
229
+ ];
230
+ await this.onInitialize(input, subscribers);
231
+ self.activeRunDetach$ = new rxjs.Subject();
232
+ let resolveCompletion;
233
+ self.activeRunCompletionPromise = new Promise((resolve) => {
234
+ resolveCompletion = resolve;
235
+ });
236
+ const source$ = (0, rxjs.defer)(() => this.connect(input)).pipe((0, _ag_ui_client.transformChunks)(this.debug), (0, rxjs_operators.takeUntil)(self.activeRunDetach$));
237
+ const applied$ = this.apply(input, source$, subscribers);
238
+ await (0, rxjs.lastValueFrom)(this.processApplyEvents(input, applied$, subscribers).pipe((0, rxjs_operators.catchError)((error) => {
239
+ this.isRunning = false;
240
+ return this.onError(input, error, subscribers);
241
+ }), (0, rxjs_operators.finalize)(() => {
242
+ this.isRunning = false;
243
+ this.onFinalize(input, subscribers);
244
+ resolveCompletion === null || resolveCompletion === void 0 || resolveCompletion();
245
+ resolveCompletion = void 0;
246
+ self.activeRunCompletionPromise = void 0;
247
+ self.activeRunDetach$ = void 0;
248
+ })), { defaultValue: void 0 });
249
+ const newMessages = (0, _ag_ui_client.structuredClone_)(this.messages).filter((m) => !previousMessageIds.has(m.id));
250
+ return {
251
+ result,
252
+ newMessages
253
+ };
254
+ } finally {
255
+ this.isRunning = false;
256
+ }
257
+ }
258
+ abortRun() {
259
+ if (this.activeChannel && this.runId) {
260
+ const fallback = setTimeout(() => clear(), 5e3);
261
+ const clear = () => {
262
+ clearTimeout(fallback);
263
+ this.detachActiveRun();
264
+ this.cleanup();
265
+ };
266
+ this.activeChannel.push(STOP_RUN_EVENT, { run_id: this.runId }).receive("ok", clear).receive("error", clear).receive("timeout", clear);
267
+ } else {
268
+ this.detachActiveRun();
269
+ this.cleanup();
270
+ }
271
+ }
272
+ /**
273
+ * Trigger the run via REST, then join the realtime thread channel and relay
274
+ * server-pushed AG-UI events to the Observable subscriber.
275
+ */
276
+ run(input) {
277
+ this.threadId = input.threadId;
278
+ this.runId = input.runId;
279
+ return (0, rxjs.defer)(() => this.requestJoinCredentials$("run", input)).pipe((0, rxjs.switchMap)((credentials) => this.observeThread$(input, credentials, {
280
+ completeOnRunError: false,
281
+ streamMode: "run"
282
+ })));
283
+ }
284
+ /**
285
+ * Reconnect to an existing thread by fetching websocket credentials and
286
+ * joining the realtime thread channel.
287
+ */
288
+ connect(input) {
289
+ this.threadId = input.threadId;
290
+ this.runId = input.runId;
291
+ return (0, rxjs.defer)(() => this.requestConnectPlan$(input)).pipe((0, rxjs.switchMap)((plan) => {
292
+ if (plan === null) return rxjs.EMPTY;
293
+ if (plan.mode === "bootstrap") {
294
+ this.setLastSeenEventId(input.threadId, plan.latestEventId);
295
+ for (const event of plan.events) this.updateRunIdFromEvent(event);
296
+ return (0, rxjs.from)(plan.events);
297
+ }
298
+ this.setLastSeenEventId(input.threadId, plan.joinFromEventId);
299
+ for (const event of plan.events) this.updateRunIdFromEvent(event);
300
+ return (0, rxjs.concat)((0, rxjs.from)(plan.events), this.observeThread$(input, { joinToken: plan.joinToken }, {
301
+ completeOnRunError: true,
302
+ streamMode: "connect",
303
+ replayCursor: plan.joinFromEventId
304
+ }));
305
+ }));
306
+ }
307
+ /**
308
+ * Tear down a specific channel + socket pair that belongs to one pipeline.
309
+ * Only nulls instance references when they still point to the owned resource,
310
+ * so a concurrent pipeline's resources are never clobbered.
311
+ */
312
+ cleanupOwned(ownChannel, ownSocket) {
313
+ if (ownChannel) {
314
+ ownChannel.leave();
315
+ if (this.activeChannel === ownChannel) this.activeChannel = null;
316
+ }
317
+ if (ownSocket) {
318
+ ownSocket.disconnect();
319
+ if (this.socket === ownSocket) this.socket = null;
320
+ }
321
+ if (this.threadId) this.sharedState.lastSeenEventIds.delete(this.threadId);
322
+ this.runId = null;
323
+ }
324
+ cleanup() {
325
+ this.cleanupOwned(this.activeChannel, this.socket);
326
+ }
327
+ requestJoinCredentials$(mode, input) {
328
+ return (0, rxjs.defer)(async () => {
329
+ try {
330
+ const response = await fetch(this.buildRuntimeUrl(mode), {
331
+ method: "POST",
332
+ headers: {
333
+ "Content-Type": "application/json",
334
+ ...this.config.headers
335
+ },
336
+ body: JSON.stringify({
337
+ threadId: input.threadId,
338
+ runId: input.runId,
339
+ messages: input.messages,
340
+ tools: input.tools,
341
+ context: input.context,
342
+ state: input.state,
343
+ forwardedProps: input.forwardedProps
344
+ }),
345
+ ...this.config.credentials ? { credentials: this.config.credentials } : {}
346
+ });
347
+ if (response.status === 409) throw new AgentThreadLockedError(input.threadId);
348
+ if (!response.ok) {
349
+ const text = await response.text().catch(() => "");
350
+ throw new Error(text || response.statusText || String(response.status));
351
+ }
352
+ const payload = await response.json();
353
+ if (!payload.joinToken) throw new Error("missing joinToken");
354
+ return { joinToken: payload.joinToken };
355
+ } catch (error) {
356
+ if (error instanceof AgentThreadLockedError) throw error;
357
+ throw new Error(`REST ${mode} request failed: ${error instanceof Error ? error.message : String(error)}`);
358
+ }
359
+ });
360
+ }
361
+ requestConnectPlan$(input) {
362
+ return (0, rxjs.defer)(async () => {
363
+ try {
364
+ const response = await fetch(this.buildRuntimeUrl("connect"), {
365
+ method: "POST",
366
+ headers: {
367
+ "Content-Type": "application/json",
368
+ ...this.config.headers
369
+ },
370
+ body: JSON.stringify({
371
+ threadId: input.threadId,
372
+ runId: input.runId,
373
+ messages: input.messages,
374
+ tools: input.tools,
375
+ context: input.context,
376
+ state: input.state,
377
+ forwardedProps: input.forwardedProps,
378
+ lastSeenEventId: this.getReconnectCursor(input)
379
+ }),
380
+ ...this.config.credentials ? { credentials: this.config.credentials } : {}
381
+ });
382
+ if (response.status === 204) return null;
383
+ if (!response.ok) {
384
+ const text = await response.text().catch(() => "");
385
+ throw new Error(text || response.statusText || String(response.status));
386
+ }
387
+ return this.normalizeConnectPlan(await response.json());
388
+ } catch (error) {
389
+ throw new Error(`REST connect request failed: ${error instanceof Error ? error.message : String(error)}`);
390
+ }
391
+ });
392
+ }
393
+ normalizeConnectPlan(payload) {
394
+ const envelope = payload && typeof payload === "object" ? payload : null;
395
+ if ((envelope === null || envelope === void 0 ? void 0 : envelope.mode) === "bootstrap") return {
396
+ mode: "bootstrap",
397
+ latestEventId: typeof envelope.latestEventId === "string" ? envelope.latestEventId : null,
398
+ events: Array.isArray(envelope.events) ? envelope.events : []
399
+ };
400
+ if ((envelope === null || envelope === void 0 ? void 0 : envelope.mode) === "live") {
401
+ if (typeof envelope.joinToken !== "string" || envelope.joinToken.length === 0) throw new Error("missing joinToken");
402
+ return {
403
+ mode: "live",
404
+ joinToken: envelope.joinToken,
405
+ joinFromEventId: typeof envelope.joinFromEventId === "string" ? envelope.joinFromEventId : null,
406
+ events: Array.isArray(envelope.events) ? envelope.events : []
407
+ };
408
+ }
409
+ throw new Error("invalid connect plan");
410
+ }
411
+ observeThread$(input, credentials, options) {
412
+ return (0, rxjs.defer)(() => {
413
+ var _this$config$socketPa;
414
+ let ownSocket = null;
415
+ let ownChannel = null;
416
+ const socket$ = ɵphoenixSocket$({
417
+ url: this.config.url,
418
+ options: {
419
+ params: {
420
+ ...(_this$config$socketPa = this.config.socketParams) !== null && _this$config$socketPa !== void 0 ? _this$config$socketPa : {},
421
+ join_token: credentials.joinToken
422
+ },
423
+ reconnectAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(100, 1e4),
424
+ rejoinAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(1e3, 3e4)
425
+ }
426
+ }).pipe((0, rxjs_operators.tap)(({ socket }) => {
427
+ ownSocket = socket;
428
+ this.socket = ownSocket;
429
+ }), (0, rxjs_operators.shareReplay)({
430
+ bufferSize: 1,
431
+ refCount: true
432
+ }));
433
+ const { topic, params } = this.createThreadChannelDescriptor(input, options.streamMode, options.replayCursor);
434
+ const channel$ = ɵphoenixChannel$({
435
+ socket$,
436
+ topic,
437
+ params
438
+ }).pipe((0, rxjs_operators.tap)(({ channel }) => {
439
+ ownChannel = channel;
440
+ this.activeChannel = ownChannel;
441
+ }), (0, rxjs_operators.shareReplay)({
442
+ bufferSize: 1,
443
+ refCount: true
444
+ }));
445
+ const threadEvents$ = this.observeThreadEvents$(input.threadId, channel$, options).pipe((0, rxjs_operators.share)());
446
+ const threadCompleted$ = threadEvents$.pipe((0, rxjs_operators.ignoreElements)(), (0, rxjs_operators.endWith)(null), (0, rxjs_operators.take)(1));
447
+ return (0, rxjs.merge)(this.joinThreadChannel$(channel$), this.observeSocketHealth$(socket$).pipe((0, rxjs_operators.takeUntil)(threadCompleted$)), threadEvents$).pipe((0, rxjs_operators.finalize)(() => this.cleanupOwned(ownChannel, ownSocket)));
448
+ });
449
+ }
450
+ joinThreadChannel$(channel$) {
451
+ return ɵjoinPhoenixChannel$(channel$);
452
+ }
453
+ observeSocketHealth$(socket$) {
454
+ return ɵobservePhoenixSocketHealth$(ɵobservePhoenixSocketSignals$(socket$), 5);
455
+ }
456
+ observeThreadEvents$(threadId, channel$, options) {
457
+ return channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => this.observeChannelEvent$(channel, CLIENT_AG_UI_EVENT)), (0, rxjs_operators.tap)((payload) => {
458
+ this.updateLastSeenEventId(threadId, payload);
459
+ this.updateRunIdFromEvent(payload);
460
+ }), (0, rxjs_operators.mergeMap)((payload) => (0, rxjs.from)(this.createThreadNotifications(payload, options.completeOnRunError))), (0, rxjs.dematerialize)());
461
+ }
462
+ observeChannelEvent$(channel, eventName) {
463
+ return ɵobservePhoenixEvent$(channel, eventName);
464
+ }
465
+ createThreadNotifications(payload, completeOnRunError) {
466
+ if (payload.type === _ag_ui_client.EventType.RUN_FINISHED) return [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()];
467
+ if (payload.type === _ag_ui_client.EventType.RUN_ERROR) {
468
+ var _message;
469
+ const errorMessage = (_message = payload.message) !== null && _message !== void 0 ? _message : "Run error";
470
+ return completeOnRunError ? [rxjs.Notification.createNext(payload), rxjs.Notification.createComplete()] : [rxjs.Notification.createNext(payload), rxjs.Notification.createError(new Error(errorMessage))];
471
+ }
472
+ return [rxjs.Notification.createNext(payload)];
473
+ }
474
+ buildRuntimeUrl(mode) {
475
+ const path = `${this.config.runtimeUrl}/agent/${encodeURIComponent(this.config.agentId)}/${mode}`;
476
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
477
+ return new URL(path, new URL(this.config.runtimeUrl, origin)).toString();
478
+ }
479
+ createThreadChannelDescriptor(input, streamMode, replayCursor) {
480
+ const params = streamMode === "run" ? {
481
+ stream_mode: "run",
482
+ run_id: input.runId
483
+ } : {
484
+ stream_mode: "connect",
485
+ last_seen_event_id: replayCursor === void 0 ? this.getReconnectCursor(input) : replayCursor
486
+ };
487
+ return {
488
+ topic: `thread:${input.threadId}`,
489
+ params
490
+ };
491
+ }
492
+ getLastSeenEventId(threadId) {
493
+ var _this$sharedState$las;
494
+ return (_this$sharedState$las = this.sharedState.lastSeenEventIds.get(threadId)) !== null && _this$sharedState$las !== void 0 ? _this$sharedState$las : null;
495
+ }
496
+ getReconnectCursor(input) {
497
+ return this.hasLocalThreadMessages(input) ? this.getLastSeenEventId(input.threadId) : null;
498
+ }
499
+ hasLocalThreadMessages(input) {
500
+ return Array.isArray(input.messages) && input.messages.length > 0;
501
+ }
502
+ updateLastSeenEventId(threadId, payload) {
503
+ const eventId = this.readEventId(payload);
504
+ if (!eventId) return;
505
+ this.sharedState.lastSeenEventIds.set(threadId, eventId);
506
+ }
507
+ setLastSeenEventId(threadId, eventId) {
508
+ if (!eventId) return;
509
+ this.sharedState.lastSeenEventIds.set(threadId, eventId);
510
+ }
511
+ /**
512
+ * Keep `this.runId` in sync with the backend's actual run ID.
513
+ *
514
+ * During a `connect` (resume) flow the client generates a fresh `runId`
515
+ * via `prepareRunAgentInput`, but the backend is running under its own
516
+ * run ID. If the client later sends `STOP_RUN_EVENT` with the wrong
517
+ * `runId`, the gateway's runner channel will not match it and the agent
518
+ * keeps running. Extracting the run ID from live events fixes this.
519
+ *
520
+ * The runner normalises events to `run_id` (snake_case) before pushing
521
+ * to the gateway, so we check both `runId` and `run_id`.
522
+ */
523
+ updateRunIdFromEvent(payload) {
524
+ var _record$runId;
525
+ const record = payload;
526
+ const eventRunId = (_record$runId = record.runId) !== null && _record$runId !== void 0 ? _record$runId : record.run_id;
527
+ if (typeof eventRunId === "string" && eventRunId.length > 0) this.runId = eventRunId;
528
+ }
529
+ readEventId(payload) {
530
+ const metadata = payload.metadata;
531
+ if (!metadata || typeof metadata !== "object") return null;
532
+ const runnerEventId = metadata.cpki_event_id;
533
+ return typeof runnerEventId === "string" ? runnerEventId : null;
534
+ }
535
+ };
536
+
537
+ //#endregion
538
+ //#region \0@oxc-project+runtime@0.112.0/helpers/checkPrivateRedeclaration.js
539
+ function _checkPrivateRedeclaration(e, t) {
540
+ if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
541
+ }
542
+
543
+ //#endregion
544
+ //#region \0@oxc-project+runtime@0.112.0/helpers/classPrivateMethodInitSpec.js
545
+ function _classPrivateMethodInitSpec(e, a) {
546
+ _checkPrivateRedeclaration(e, a), a.add(e);
547
+ }
548
+
549
+ //#endregion
550
+ //#region \0@oxc-project+runtime@0.112.0/helpers/assertClassBrand.js
551
+ function _assertClassBrand(e, t, n) {
552
+ if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
553
+ throw new TypeError("Private element is not present on this object");
554
+ }
555
+
556
+ //#endregion
557
+ //#region \0@oxc-project+runtime@0.112.0/helpers/getPrototypeOf.js
558
+ function _getPrototypeOf(t) {
559
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(t) {
560
+ return t.__proto__ || Object.getPrototypeOf(t);
561
+ }, _getPrototypeOf(t);
562
+ }
563
+
564
+ //#endregion
565
+ //#region \0@oxc-project+runtime@0.112.0/helpers/superPropBase.js
566
+ function _superPropBase(t, o) {
567
+ for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t)););
568
+ return t;
569
+ }
570
+
571
+ //#endregion
572
+ //#region \0@oxc-project+runtime@0.112.0/helpers/get.js
573
+ function _get() {
574
+ return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function(e, t, r) {
575
+ var p = _superPropBase(e, t);
576
+ if (p) {
577
+ var n = Object.getOwnPropertyDescriptor(p, t);
578
+ return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
579
+ }
580
+ }, _get.apply(null, arguments);
581
+ }
582
+
583
+ //#endregion
584
+ //#region \0@oxc-project+runtime@0.112.0/helpers/superPropGet.js
585
+ function _superPropGet(t, o, e, r) {
586
+ var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e);
587
+ return 2 & r && "function" == typeof p ? function(t) {
588
+ return p.apply(e, t);
589
+ } : p;
590
+ }
591
+
592
+ //#endregion
593
+ //#region src/agent.ts
594
+ var _ProxiedCopilotRuntimeAgent;
595
+ function hasHeaders(agent) {
596
+ return "headers" in agent;
597
+ }
598
+ function hasCredentials(agent) {
599
+ return "credentials" in agent;
600
+ }
601
+ function isZodError(error) {
602
+ return error !== null && typeof error === "object" && "name" in error && error.name === "ZodError";
603
+ }
604
+ function isAbortError(error) {
605
+ return (error instanceof DOMException || error instanceof Error) && error.name === "AbortError";
606
+ }
607
+ function withAbortErrorHandling(observable) {
608
+ return observable.pipe((0, rxjs_operators.catchError)((error) => {
609
+ if (isZodError(error) || isAbortError(error)) return rxjs.EMPTY;
610
+ throw error;
611
+ }));
612
+ }
613
+ var _ProxiedCopilotRuntimeAgent_brand = /* @__PURE__ */ new WeakSet();
614
+ var ProxiedCopilotRuntimeAgent = class ProxiedCopilotRuntimeAgent extends _ag_ui_client.HttpAgent {
615
+ constructor(config) {
616
+ var _config$transport, _ref, _config$agentId, _config$runtimeMode;
617
+ const normalizedRuntimeUrl = config.runtimeUrl ? config.runtimeUrl.replace(/\/$/, "") : void 0;
618
+ const transport = (_config$transport = config.transport) !== null && _config$transport !== void 0 ? _config$transport : "rest";
619
+ const runUrl = transport === "single" ? (_ref = normalizedRuntimeUrl !== null && normalizedRuntimeUrl !== void 0 ? normalizedRuntimeUrl : config.runtimeUrl) !== null && _ref !== void 0 ? _ref : "" : `${normalizedRuntimeUrl !== null && normalizedRuntimeUrl !== void 0 ? normalizedRuntimeUrl : config.runtimeUrl}/agent/${encodeURIComponent((_config$agentId = config.agentId) !== null && _config$agentId !== void 0 ? _config$agentId : "")}/run`;
620
+ if (!runUrl) throw new Error("ProxiedCopilotRuntimeAgent requires a runtimeUrl when transport is set to 'single'.");
621
+ super({
622
+ ...config,
623
+ url: runUrl
624
+ });
625
+ _classPrivateMethodInitSpec(this, _ProxiedCopilotRuntimeAgent_brand);
626
+ _defineProperty(this, "runtimeUrl", void 0);
627
+ _defineProperty(this, "credentials", void 0);
628
+ _defineProperty(this, "transport", void 0);
629
+ _defineProperty(this, "singleEndpointUrl", void 0);
630
+ _defineProperty(this, "runtimeMode", void 0);
631
+ _defineProperty(this, "intelligence", void 0);
632
+ _defineProperty(this, "delegate", void 0);
633
+ _defineProperty(this, "runtimeInfoPromise", void 0);
634
+ this.runtimeUrl = normalizedRuntimeUrl !== null && normalizedRuntimeUrl !== void 0 ? normalizedRuntimeUrl : config.runtimeUrl;
635
+ this.credentials = config.credentials;
636
+ this.transport = transport;
637
+ this.runtimeMode = (_config$runtimeMode = config.runtimeMode) !== null && _config$runtimeMode !== void 0 ? _config$runtimeMode : _copilotkit_shared.RUNTIME_MODE_SSE;
638
+ this.intelligence = config.intelligence;
639
+ if (this.transport === "single") this.singleEndpointUrl = this.runtimeUrl;
640
+ }
641
+ async detachActiveRun() {
642
+ if (this.delegate) await this.delegate.detachActiveRun();
643
+ await super.detachActiveRun();
644
+ }
645
+ abortRun() {
646
+ if (this.delegate) {
647
+ this.syncDelegate(this.delegate);
648
+ this.delegate.abortRun();
649
+ this.detachActiveRun();
650
+ return;
651
+ }
652
+ if (!this.agentId || !this.threadId) return;
653
+ if (typeof fetch === "undefined") return;
654
+ if (this.transport === "single") {
655
+ if (!this.singleEndpointUrl) return;
656
+ const headers = new Headers({
657
+ ...this.headers,
658
+ "Content-Type": "application/json"
659
+ });
660
+ fetch(this.singleEndpointUrl, {
661
+ method: "POST",
662
+ headers,
663
+ body: JSON.stringify({
664
+ method: "agent/stop",
665
+ params: {
666
+ agentId: this.agentId,
667
+ threadId: this.threadId
668
+ }
669
+ }),
670
+ ...this.credentials ? { credentials: this.credentials } : {}
671
+ }).catch((error) => {
672
+ console.error("ProxiedCopilotRuntimeAgent: stop request failed", error);
673
+ });
674
+ return;
675
+ }
676
+ if (!this.runtimeUrl) return;
677
+ const stopPath = `${this.runtimeUrl}/agent/${encodeURIComponent(this.agentId)}/stop/${encodeURIComponent(this.threadId)}`;
678
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
679
+ const base = new URL(this.runtimeUrl, origin);
680
+ const stopUrl = new URL(stopPath, base);
681
+ fetch(stopUrl.toString(), {
682
+ method: "POST",
683
+ headers: {
684
+ "Content-Type": "application/json",
685
+ ...this.headers
686
+ },
687
+ ...this.credentials ? { credentials: this.credentials } : {}
688
+ }).catch((error) => {
689
+ console.error("ProxiedCopilotRuntimeAgent: stop request failed", error);
690
+ });
691
+ }
692
+ async connectAgent(parameters, subscriber) {
693
+ if (this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return super.connectAgent(parameters, subscriber);
694
+ if (this.delegate) await this.delegate.detachActiveRun();
695
+ await this.resolveDelegate();
696
+ const delegate = this.delegate;
697
+ const bridgeSub = delegate.subscribe({
698
+ onMessagesChanged: () => {
699
+ this.setMessages([...delegate.messages]);
700
+ },
701
+ onStateChanged: () => {
702
+ this.setState({ ...delegate.state });
703
+ },
704
+ onRunInitialized: () => {
705
+ this.isRunning = true;
706
+ },
707
+ onRunFinalized: () => {
708
+ this.isRunning = false;
709
+ },
710
+ onRunFailed: () => {
711
+ this.isRunning = false;
712
+ }
713
+ });
714
+ const forwardedSubs = this.subscribers.map((s) => delegate.subscribe(s));
715
+ try {
716
+ const result = await delegate.connectAgent(parameters, subscriber);
717
+ this.setMessages([...delegate.messages]);
718
+ this.setState({ ...delegate.state });
719
+ return result;
720
+ } finally {
721
+ this.isRunning = false;
722
+ bridgeSub.unsubscribe();
723
+ for (const sub of forwardedSubs) sub.unsubscribe();
724
+ }
725
+ }
726
+ connect(input) {
727
+ if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _connectViaDelegate).call(this, input);
728
+ return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _connectViaHttp).call(this, input);
729
+ }
730
+ run(input) {
731
+ if (this.runtimeMode === _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _runViaDelegate).call(this, input);
732
+ return _assertClassBrand(_ProxiedCopilotRuntimeAgent_brand, this, _runViaHttp).call(this, input);
733
+ }
734
+ clone() {
735
+ const cloned = new ProxiedCopilotRuntimeAgent({
736
+ runtimeUrl: this.runtimeUrl,
737
+ agentId: this.agentId,
738
+ description: this.description,
739
+ headers: { ...this.headers },
740
+ credentials: this.credentials,
741
+ transport: this.transport,
742
+ runtimeMode: this.runtimeMode,
743
+ intelligence: this.intelligence
744
+ });
745
+ cloned.threadId = this.threadId;
746
+ cloned.setState(this.state);
747
+ cloned.setMessages(this.messages);
748
+ if (this.delegate) {
749
+ cloned.delegate = this.delegate.clone();
750
+ cloned.syncDelegate(cloned.delegate);
751
+ }
752
+ return cloned;
753
+ }
754
+ async resolveDelegate() {
755
+ await this.ensureRuntimeMode();
756
+ if (!this.delegate) {
757
+ if (this.runtimeMode !== _copilotkit_shared.RUNTIME_MODE_INTELLIGENCE) throw new Error("A delegate is only created for Intelligence mode");
758
+ this.delegate = this.createIntelligenceDelegate();
759
+ }
760
+ this.syncDelegate(this.delegate);
761
+ return this.delegate;
762
+ }
763
+ async ensureRuntimeMode() {
764
+ var _this$runtimeInfoProm;
765
+ if (this.runtimeMode !== "pending") return;
766
+ if (!this.runtimeUrl) throw new Error("Runtime URL is not set");
767
+ (_this$runtimeInfoProm = this.runtimeInfoPromise) !== null && _this$runtimeInfoProm !== void 0 || (this.runtimeInfoPromise = this.fetchRuntimeInfo().then((runtimeInfo) => {
768
+ var _runtimeInfo$mode;
769
+ this.runtimeMode = (_runtimeInfo$mode = runtimeInfo.mode) !== null && _runtimeInfo$mode !== void 0 ? _runtimeInfo$mode : _copilotkit_shared.RUNTIME_MODE_SSE;
770
+ this.intelligence = runtimeInfo.intelligence;
771
+ }));
772
+ await this.runtimeInfoPromise;
773
+ }
774
+ async fetchRuntimeInfo() {
775
+ const headers = { ...this.headers };
776
+ let init;
777
+ let url;
778
+ if (this.transport === "single") {
779
+ if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
780
+ if (!headers["Content-Type"]) headers["Content-Type"] = "application/json";
781
+ url = this.runtimeUrl;
782
+ init = {
783
+ method: "POST",
784
+ body: JSON.stringify({ method: "info" })
785
+ };
786
+ } else {
787
+ url = `${this.runtimeUrl}/info`;
788
+ init = {};
789
+ }
790
+ const response = await fetch(url, {
791
+ ...init,
792
+ headers,
793
+ ...this.credentials ? { credentials: this.credentials } : {}
794
+ });
795
+ if (!response.ok) throw new Error(`Runtime info request failed with status ${response.status}`);
796
+ return await response.json();
797
+ }
798
+ createSingleRouteRequestInit(input, method, params) {
799
+ var _baseInit$headers, _headers$get;
800
+ if (!this.agentId) throw new Error("ProxiedCopilotRuntimeAgent requires agentId to make runtime requests");
801
+ const baseInit = super.requestInit(input);
802
+ const headers = new Headers((_baseInit$headers = baseInit.headers) !== null && _baseInit$headers !== void 0 ? _baseInit$headers : {});
803
+ headers.set("Content-Type", "application/json");
804
+ headers.set("Accept", (_headers$get = headers.get("Accept")) !== null && _headers$get !== void 0 ? _headers$get : "text/event-stream");
805
+ let originalBody = void 0;
806
+ if (typeof baseInit.body === "string") try {
807
+ originalBody = JSON.parse(baseInit.body);
808
+ } catch (error) {
809
+ console.warn("ProxiedCopilotRuntimeAgent: failed to parse request body for single route transport", error);
810
+ }
811
+ const envelope = { method };
812
+ if (params && Object.keys(params).length > 0) envelope.params = params;
813
+ if (originalBody !== void 0) envelope.body = originalBody;
814
+ return {
815
+ ...baseInit,
816
+ headers,
817
+ body: JSON.stringify(envelope),
818
+ ...this.credentials ? { credentials: this.credentials } : {}
819
+ };
820
+ }
821
+ createIntelligenceDelegate() {
822
+ var _this$intelligence;
823
+ if (!this.runtimeUrl || !this.agentId || !((_this$intelligence = this.intelligence) === null || _this$intelligence === void 0 ? void 0 : _this$intelligence.wsUrl)) throw new Error("Intelligence mode requires runtimeUrl, agentId, and intelligence websocket metadata");
824
+ return new IntelligenceAgent({
825
+ url: this.intelligence.wsUrl,
826
+ runtimeUrl: this.runtimeUrl,
827
+ agentId: this.agentId,
828
+ headers: { ...this.headers },
829
+ credentials: this.credentials
830
+ });
831
+ }
832
+ syncDelegate(delegate) {
833
+ delegate.agentId = this.agentId;
834
+ delegate.description = this.description;
835
+ delegate.threadId = this.threadId;
836
+ delegate.setMessages(this.messages);
837
+ delegate.setState(this.state);
838
+ if (hasHeaders(delegate)) delegate.headers = { ...this.headers };
839
+ if (hasCredentials(delegate)) delegate.credentials = this.credentials;
840
+ }
841
+ };
842
+ _ProxiedCopilotRuntimeAgent = ProxiedCopilotRuntimeAgent;
843
+ function _connectViaDelegate(input) {
844
+ return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.connect(input))));
845
+ }
846
+ function _connectViaHttp(input) {
847
+ if (this.transport === "single") {
848
+ if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
849
+ const requestInit = this.createSingleRouteRequestInit(input, "agent/connect", { agentId: this.agentId });
850
+ return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(this.singleEndpointUrl, requestInit)));
851
+ }
852
+ return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(`${this.runtimeUrl}/agent/${this.agentId}/connect`, this.requestInit(input))));
853
+ }
854
+ function _runViaDelegate(input) {
855
+ return (0, rxjs.defer)(() => (0, rxjs.from)(this.resolveDelegate())).pipe((0, rxjs_operators.switchMap)((delegate) => withAbortErrorHandling(delegate.run(input))));
856
+ }
857
+ function _runViaHttp(input) {
858
+ if (this.transport === "single") {
859
+ if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
860
+ const requestInit = this.createSingleRouteRequestInit(input, "agent/run", { agentId: this.agentId });
861
+ return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(this.singleEndpointUrl, requestInit)));
862
+ }
863
+ return withAbortErrorHandling(_superPropGet(_ProxiedCopilotRuntimeAgent.prototype, "run", this, 2)([input]));
864
+ }
865
+
866
+ //#endregion
867
+ //#region src/core/agent-registry.ts
868
+ /**
869
+ * Manages agent registration, lifecycle, and runtime connectivity for CopilotKitCore.
870
+ * Handles both local development agents and remote runtime agents.
871
+ */
872
+ var AgentRegistry = class {
873
+ constructor(core) {
874
+ this.core = core;
875
+ _defineProperty(this, "_agents", {});
876
+ _defineProperty(this, "localAgents", {});
877
+ _defineProperty(this, "remoteAgents", {});
878
+ _defineProperty(this, "_runtimeUrl", void 0);
879
+ _defineProperty(this, "_runtimeVersion", void 0);
880
+ _defineProperty(this, "_runtimeConnectionStatus", CopilotKitCoreRuntimeConnectionStatus.Disconnected);
881
+ _defineProperty(this, "_runtimeTransport", "rest");
882
+ _defineProperty(this, "_audioFileTranscriptionEnabled", false);
883
+ _defineProperty(this, "_runtimeMode", _copilotkit_shared.RUNTIME_MODE_SSE);
884
+ _defineProperty(this, "_intelligence", void 0);
885
+ _defineProperty(this, "_a2uiEnabled", false);
886
+ _defineProperty(this, "_licenseStatus", void 0);
887
+ }
888
+ /**
889
+ * Get all agents as a readonly record
890
+ */
891
+ get agents() {
892
+ return this._agents;
893
+ }
894
+ get runtimeUrl() {
895
+ return this._runtimeUrl;
896
+ }
897
+ get runtimeVersion() {
898
+ return this._runtimeVersion;
899
+ }
900
+ get runtimeConnectionStatus() {
901
+ return this._runtimeConnectionStatus;
902
+ }
903
+ get runtimeTransport() {
904
+ return this._runtimeTransport;
905
+ }
906
+ get audioFileTranscriptionEnabled() {
907
+ return this._audioFileTranscriptionEnabled;
908
+ }
909
+ get runtimeMode() {
910
+ return this._runtimeMode;
911
+ }
912
+ get intelligence() {
913
+ return this._intelligence;
914
+ }
915
+ get a2uiEnabled() {
916
+ return this._a2uiEnabled;
917
+ }
918
+ get licenseStatus() {
919
+ return this._licenseStatus;
920
+ }
921
+ /**
922
+ * Initialize agents from configuration
923
+ */
924
+ initialize(agents) {
925
+ this.localAgents = this.assignAgentIds(agents);
926
+ this.applyHeadersToAgents(this.localAgents);
927
+ this._agents = this.localAgents;
928
+ }
929
+ /**
930
+ * Set the runtime URL and update connection
931
+ */
932
+ setRuntimeUrl(runtimeUrl) {
933
+ const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
934
+ if (this._runtimeUrl === normalizedRuntimeUrl) return;
935
+ this._runtimeUrl = normalizedRuntimeUrl;
936
+ this.updateRuntimeConnection();
937
+ }
938
+ setRuntimeTransport(runtimeTransport) {
939
+ if (this._runtimeTransport === runtimeTransport) return;
940
+ this._runtimeTransport = runtimeTransport;
941
+ this.updateRuntimeConnection();
942
+ }
943
+ /**
944
+ * Set all agents at once (for development use)
945
+ */
946
+ setAgents__unsafe_dev_only(agents) {
947
+ Object.entries(agents).forEach(([id, agent]) => {
948
+ if (agent) this.validateAndAssignAgentId(id, agent);
949
+ });
950
+ this.localAgents = agents;
951
+ this._agents = {
952
+ ...this.localAgents,
953
+ ...this.remoteAgents
954
+ };
955
+ this.applyHeadersToAgents(this._agents);
956
+ this.notifyAgentsChanged();
957
+ }
958
+ /**
959
+ * Add a single agent (for development use)
960
+ */
961
+ addAgent__unsafe_dev_only({ id, agent }) {
962
+ this.validateAndAssignAgentId(id, agent);
963
+ this.localAgents[id] = agent;
964
+ this.applyHeadersToAgent(agent);
965
+ this._agents = {
966
+ ...this.localAgents,
967
+ ...this.remoteAgents
968
+ };
969
+ this.notifyAgentsChanged();
970
+ }
971
+ /**
972
+ * Remove an agent by ID (for development use)
973
+ */
974
+ removeAgent__unsafe_dev_only(id) {
975
+ delete this.localAgents[id];
976
+ this._agents = {
977
+ ...this.localAgents,
978
+ ...this.remoteAgents
979
+ };
980
+ this.notifyAgentsChanged();
981
+ }
982
+ /**
983
+ * Get an agent by ID
984
+ */
985
+ getAgent(id) {
986
+ if (id in this._agents) return this._agents[id];
987
+ if (this.runtimeUrl !== void 0 && (this.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Disconnected || this.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connecting)) return;
988
+ console.warn(`Agent ${id} not found`);
989
+ }
990
+ /**
991
+ * Apply current headers to an agent
992
+ */
993
+ applyHeadersToAgent(agent) {
994
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...this.core.headers };
995
+ }
996
+ /**
997
+ * Apply current headers to all agents
998
+ */
999
+ applyHeadersToAgents(agents) {
1000
+ Object.values(agents).forEach((agent) => {
1001
+ this.applyHeadersToAgent(agent);
1002
+ });
1003
+ }
1004
+ /**
1005
+ * Apply current credentials to an agent
1006
+ */
1007
+ applyCredentialsToAgent(agent) {
1008
+ if (agent instanceof ProxiedCopilotRuntimeAgent) agent.credentials = this.core.credentials;
1009
+ }
1010
+ /**
1011
+ * Apply current credentials to all agents
1012
+ */
1013
+ applyCredentialsToAgents(agents) {
1014
+ Object.values(agents).forEach((agent) => {
1015
+ this.applyCredentialsToAgent(agent);
1016
+ });
1017
+ }
1018
+ /**
1019
+ * Update runtime connection and fetch remote agents
1020
+ */
1021
+ async updateRuntimeConnection() {
1022
+ if (typeof window === "undefined") return;
1023
+ if (!this.runtimeUrl) {
1024
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Disconnected;
1025
+ this._runtimeVersion = void 0;
1026
+ this._audioFileTranscriptionEnabled = false;
1027
+ this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
1028
+ this._intelligence = void 0;
1029
+ this._a2uiEnabled = false;
1030
+ this.remoteAgents = {};
1031
+ this._agents = this.localAgents;
1032
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Disconnected);
1033
+ await this.notifyAgentsChanged();
1034
+ return;
1035
+ }
1036
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Connecting;
1037
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connecting);
1038
+ try {
1039
+ var _runtimeInfoResponse$2, _runtimeInfoResponse$3, _runtimeInfoResponse$4;
1040
+ const runtimeInfoResponse = await this.fetchRuntimeInfo();
1041
+ const { version, ...runtimeInfo } = runtimeInfoResponse;
1042
+ const credentials = this.core.credentials;
1043
+ this.remoteAgents = Object.fromEntries(Object.entries(runtimeInfo.agents).map(([id, { description }]) => {
1044
+ var _runtimeInfoResponse$;
1045
+ const agent = new ProxiedCopilotRuntimeAgent({
1046
+ runtimeUrl: this.runtimeUrl,
1047
+ agentId: id,
1048
+ description,
1049
+ transport: this._runtimeTransport,
1050
+ credentials,
1051
+ runtimeMode: (_runtimeInfoResponse$ = runtimeInfoResponse.mode) !== null && _runtimeInfoResponse$ !== void 0 ? _runtimeInfoResponse$ : _copilotkit_shared.RUNTIME_MODE_SSE,
1052
+ intelligence: runtimeInfoResponse.intelligence
1053
+ });
1054
+ this.applyHeadersToAgent(agent);
1055
+ return [id, agent];
1056
+ }));
1057
+ this._agents = {
1058
+ ...this.localAgents,
1059
+ ...this.remoteAgents
1060
+ };
1061
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Connected;
1062
+ this._runtimeVersion = version;
1063
+ this._audioFileTranscriptionEnabled = (_runtimeInfoResponse$2 = runtimeInfoResponse.audioFileTranscriptionEnabled) !== null && _runtimeInfoResponse$2 !== void 0 ? _runtimeInfoResponse$2 : false;
1064
+ this._runtimeMode = (_runtimeInfoResponse$3 = runtimeInfoResponse.mode) !== null && _runtimeInfoResponse$3 !== void 0 ? _runtimeInfoResponse$3 : _copilotkit_shared.RUNTIME_MODE_SSE;
1065
+ this._intelligence = runtimeInfoResponse.intelligence;
1066
+ this._a2uiEnabled = (_runtimeInfoResponse$4 = runtimeInfoResponse.a2uiEnabled) !== null && _runtimeInfoResponse$4 !== void 0 ? _runtimeInfoResponse$4 : false;
1067
+ this._licenseStatus = runtimeInfoResponse.licenseStatus;
1068
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connected);
1069
+ await this.notifyAgentsChanged();
1070
+ } catch (error) {
1071
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Error;
1072
+ this._runtimeVersion = void 0;
1073
+ this._audioFileTranscriptionEnabled = false;
1074
+ this._runtimeMode = _copilotkit_shared.RUNTIME_MODE_SSE;
1075
+ this._intelligence = void 0;
1076
+ this._a2uiEnabled = false;
1077
+ this.remoteAgents = {};
1078
+ this._agents = this.localAgents;
1079
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Error);
1080
+ await this.notifyAgentsChanged();
1081
+ const message = error instanceof Error ? error.message : JSON.stringify(error);
1082
+ _copilotkit_shared.logger.warn(`Failed to load runtime info (${this.runtimeUrl}/info): ${message}`);
1083
+ const runtimeError = error instanceof Error ? error : new Error(String(error));
1084
+ await this.core.emitError({
1085
+ error: runtimeError,
1086
+ code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,
1087
+ context: { runtimeUrl: this.runtimeUrl }
1088
+ });
1089
+ }
1090
+ }
1091
+ async fetchRuntimeInfo() {
1092
+ if (!this.runtimeUrl) throw new Error("Runtime URL is not set");
1093
+ const baseHeaders = this.core.headers;
1094
+ const credentials = this.core.credentials;
1095
+ const headers = { ...baseHeaders };
1096
+ if (this._runtimeTransport === "single") {
1097
+ if (!headers["Content-Type"]) headers["Content-Type"] = "application/json";
1098
+ const response = await fetch(this.runtimeUrl, {
1099
+ method: "POST",
1100
+ headers,
1101
+ body: JSON.stringify({ method: "info" }),
1102
+ ...credentials ? { credentials } : {}
1103
+ });
1104
+ if ("ok" in response && !response.ok) throw new Error(`Runtime info request failed with status ${response.status}`);
1105
+ return await response.json();
1106
+ }
1107
+ const response = await fetch(`${this.runtimeUrl}/info`, {
1108
+ headers,
1109
+ ...credentials ? { credentials } : {}
1110
+ });
1111
+ if ("ok" in response && !response.ok) throw new Error(`Runtime info request failed with status ${response.status}`);
1112
+ return await response.json();
1113
+ }
1114
+ /**
1115
+ * Assign agent IDs to a record of agents
1116
+ */
1117
+ assignAgentIds(agents) {
1118
+ Object.entries(agents).forEach(([id, agent]) => {
1119
+ if (agent) this.validateAndAssignAgentId(id, agent);
1120
+ });
1121
+ return agents;
1122
+ }
1123
+ /**
1124
+ * Validate and assign an agent ID
1125
+ */
1126
+ validateAndAssignAgentId(registrationId, agent) {
1127
+ if (agent.agentId && agent.agentId !== registrationId) throw new Error(`Agent registration mismatch: Agent with ID "${agent.agentId}" cannot be registered under key "${registrationId}". The agent ID must match the registration key or be undefined.`);
1128
+ if (!agent.agentId) agent.agentId = registrationId;
1129
+ }
1130
+ /**
1131
+ * Notify subscribers of runtime status changes
1132
+ */
1133
+ async notifyRuntimeStatusChanged(status) {
1134
+ await this.core.notifySubscribers((subscriber) => {
1135
+ var _subscriber$onRuntime;
1136
+ return (_subscriber$onRuntime = subscriber.onRuntimeConnectionStatusChanged) === null || _subscriber$onRuntime === void 0 ? void 0 : _subscriber$onRuntime.call(subscriber, {
1137
+ copilotkit: this.core,
1138
+ status
1139
+ });
1140
+ }, "Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):");
1141
+ }
1142
+ /**
1143
+ * Notify subscribers of agent changes
1144
+ */
1145
+ async notifyAgentsChanged() {
1146
+ await this.core.notifySubscribers((subscriber) => {
1147
+ var _subscriber$onAgentsC;
1148
+ return (_subscriber$onAgentsC = subscriber.onAgentsChanged) === null || _subscriber$onAgentsC === void 0 ? void 0 : _subscriber$onAgentsC.call(subscriber, {
1149
+ copilotkit: this.core,
1150
+ agents: this._agents
1151
+ });
1152
+ }, "Subscriber onAgentsChanged error:");
1153
+ }
1154
+ };
1155
+
1156
+ //#endregion
1157
+ //#region src/core/context-store.ts
1158
+ /**
1159
+ * Manages context storage and lifecycle for CopilotKitCore.
1160
+ * Context represents additional information available to agents during execution.
1161
+ */
1162
+ var ContextStore = class {
1163
+ constructor(core) {
1164
+ this.core = core;
1165
+ _defineProperty(this, "_context", {});
1166
+ }
1167
+ /**
1168
+ * Get all context entries as a readonly record
1169
+ */
1170
+ get context() {
1171
+ return this._context;
1172
+ }
1173
+ /**
1174
+ * Add a new context entry
1175
+ * @returns The ID of the created context entry
1176
+ */
1177
+ addContext({ description, value }) {
1178
+ const id = (0, _copilotkit_shared.randomUUID)();
1179
+ this._context[id] = {
1180
+ description,
1181
+ value
1182
+ };
1183
+ this.notifySubscribers();
1184
+ return id;
1185
+ }
1186
+ /**
1187
+ * Remove a context entry by ID
1188
+ */
1189
+ removeContext(id) {
1190
+ delete this._context[id];
1191
+ this.notifySubscribers();
1192
+ }
1193
+ /**
1194
+ * Notify all subscribers of context changes
1195
+ */
1196
+ async notifySubscribers() {
1197
+ await this.core.notifySubscribers((subscriber) => {
1198
+ var _subscriber$onContext;
1199
+ return (_subscriber$onContext = subscriber.onContextChanged) === null || _subscriber$onContext === void 0 ? void 0 : _subscriber$onContext.call(subscriber, {
1200
+ copilotkit: this.core,
1201
+ context: this._context
1202
+ });
1203
+ }, "Subscriber onContextChanged error:");
1204
+ }
1205
+ };
1206
+
1207
+ //#endregion
1208
+ //#region src/core/suggestion-engine.ts
1209
+ /**
1210
+ * Manages suggestion generation, streaming, and lifecycle for CopilotKitCore.
1211
+ * Handles both dynamic (AI-generated) and static suggestions.
1212
+ */
1213
+ var SuggestionEngine = class {
1214
+ constructor(core) {
1215
+ this.core = core;
1216
+ _defineProperty(this, "_suggestionsConfig", {});
1217
+ _defineProperty(this, "_suggestions", {});
1218
+ _defineProperty(this, "_runningSuggestions", {});
1219
+ }
1220
+ /**
1221
+ * Initialize with suggestion configs
1222
+ */
1223
+ initialize(suggestionsConfig) {
1224
+ for (const config of suggestionsConfig) this._suggestionsConfig[(0, _copilotkit_shared.randomUUID)()] = config;
1225
+ }
1226
+ /**
1227
+ * Add a suggestion configuration
1228
+ * @returns The ID of the created config
1229
+ */
1230
+ addSuggestionsConfig(config) {
1231
+ const id = (0, _copilotkit_shared.randomUUID)();
1232
+ this._suggestionsConfig[id] = config;
1233
+ this.notifySuggestionsConfigChanged();
1234
+ return id;
1235
+ }
1236
+ /**
1237
+ * Remove a suggestion configuration by ID
1238
+ */
1239
+ removeSuggestionsConfig(id) {
1240
+ delete this._suggestionsConfig[id];
1241
+ this.notifySuggestionsConfigChanged();
1242
+ }
1243
+ /**
1244
+ * Reload suggestions for a specific agent
1245
+ * This triggers generation of new suggestions based on current configs
1246
+ *
1247
+ * @param agentId - The consumer agent ID
1248
+ * @param consumerAgent - Optional: the specific agent instance whose messages should be used
1249
+ * for availability filtering and context. When running with per-thread clones, the thread
1250
+ * clone holds the conversation messages; passing it here ensures dynamic suggestions fire
1251
+ * after the first message even though the registry agent has an empty message list.
1252
+ */
1253
+ reloadSuggestions(agentId, consumerAgent) {
1254
+ var _agent$messages$lengt, _agent$messages;
1255
+ this.clearSuggestions(agentId);
1256
+ const agent = consumerAgent !== null && consumerAgent !== void 0 ? consumerAgent : this.core.getAgent(agentId);
1257
+ if (!agent) return;
1258
+ const messageCount = (_agent$messages$lengt = (_agent$messages = agent.messages) === null || _agent$messages === void 0 ? void 0 : _agent$messages.length) !== null && _agent$messages$lengt !== void 0 ? _agent$messages$lengt : 0;
1259
+ let hasAnySuggestions = false;
1260
+ for (const config of Object.values(this._suggestionsConfig)) {
1261
+ if (config.consumerAgentId !== void 0 && config.consumerAgentId !== "*" && config.consumerAgentId !== agentId) continue;
1262
+ if (!this.shouldShowSuggestions(config, messageCount)) continue;
1263
+ const suggestionId = (0, _copilotkit_shared.randomUUID)();
1264
+ if (isDynamicSuggestionsConfig(config)) {
1265
+ if (!hasAnySuggestions) {
1266
+ hasAnySuggestions = true;
1267
+ this.notifySuggestionsStartedLoading(agentId);
1268
+ }
1269
+ this.generateSuggestions(suggestionId, config, agentId, agent);
1270
+ } else if (isStaticSuggestionsConfig(config)) this.addStaticSuggestions(suggestionId, config, agentId);
1271
+ }
1272
+ }
1273
+ /**
1274
+ * Clear all suggestions for a specific agent
1275
+ */
1276
+ clearSuggestions(agentId) {
1277
+ const runningAgents = this._runningSuggestions[agentId];
1278
+ if (runningAgents) {
1279
+ for (const agent of runningAgents) agent.abortRun();
1280
+ delete this._runningSuggestions[agentId];
1281
+ }
1282
+ this._suggestions[agentId] = {};
1283
+ this.notifySuggestionsChanged(agentId, []);
1284
+ }
1285
+ /**
1286
+ * Get current suggestions for an agent
1287
+ */
1288
+ getSuggestions(agentId) {
1289
+ var _this$_suggestions$ag, _this$_runningSuggest, _this$_runningSuggest2;
1290
+ return {
1291
+ suggestions: Object.values((_this$_suggestions$ag = this._suggestions[agentId]) !== null && _this$_suggestions$ag !== void 0 ? _this$_suggestions$ag : {}).flat(),
1292
+ isLoading: ((_this$_runningSuggest = (_this$_runningSuggest2 = this._runningSuggestions[agentId]) === null || _this$_runningSuggest2 === void 0 ? void 0 : _this$_runningSuggest2.length) !== null && _this$_runningSuggest !== void 0 ? _this$_runningSuggest : 0) > 0
1293
+ };
1294
+ }
1295
+ /**
1296
+ * Generate suggestions using a provider agent
1297
+ */
1298
+ async generateSuggestions(suggestionId, config, consumerAgentId, consumerAgent) {
1299
+ let agent = void 0;
1300
+ try {
1301
+ var _config$providerAgent, _this$_suggestions$co, _this$_runningSuggest3, _config$minSuggestion, _config$maxSuggestion;
1302
+ const suggestionsProviderAgent = this.core.getAgent((_config$providerAgent = config.providerAgentId) !== null && _config$providerAgent !== void 0 ? _config$providerAgent : "default");
1303
+ if (!suggestionsProviderAgent) throw new Error(`Suggestions provider agent not found: ${config.providerAgentId}`);
1304
+ const suggestionsConsumerAgent = consumerAgent !== null && consumerAgent !== void 0 ? consumerAgent : this.core.getAgent(consumerAgentId);
1305
+ if (!suggestionsConsumerAgent) throw new Error(`Suggestions consumer agent not found: ${consumerAgentId}`);
1306
+ agent = suggestionsProviderAgent.clone();
1307
+ agent.threadId = suggestionId;
1308
+ agent.messages = JSON.parse(JSON.stringify(suggestionsConsumerAgent.messages));
1309
+ agent.state = JSON.parse(JSON.stringify(suggestionsConsumerAgent.state));
1310
+ this._suggestions[consumerAgentId] = {
1311
+ ...(_this$_suggestions$co = this._suggestions[consumerAgentId]) !== null && _this$_suggestions$co !== void 0 ? _this$_suggestions$co : {},
1312
+ [suggestionId]: []
1313
+ };
1314
+ this._runningSuggestions[consumerAgentId] = [...(_this$_runningSuggest3 = this._runningSuggestions[consumerAgentId]) !== null && _this$_runningSuggest3 !== void 0 ? _this$_runningSuggest3 : [], agent];
1315
+ agent.addMessage({
1316
+ id: suggestionId,
1317
+ role: "user",
1318
+ content: [
1319
+ `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \`copilotkitSuggest\` tool.`,
1320
+ `Provide at least ${(_config$minSuggestion = config.minSuggestions) !== null && _config$minSuggestion !== void 0 ? _config$minSuggestion : 1} and at most ${(_config$maxSuggestion = config.maxSuggestions) !== null && _config$maxSuggestion !== void 0 ? _config$maxSuggestion : 3} suggestions.`,
1321
+ `The user has the following tools available: ${JSON.stringify(this.core.buildFrontendTools(consumerAgentId))}.`,
1322
+ ` ${config.instructions}`
1323
+ ].join("\n")
1324
+ });
1325
+ await agent.runAgent({
1326
+ context: Object.values(this.core.context),
1327
+ forwardedProps: {
1328
+ ...this.core.properties,
1329
+ toolChoice: {
1330
+ type: "function",
1331
+ function: { name: "copilotkitSuggest" }
1332
+ }
1333
+ },
1334
+ tools: [SUGGEST_TOOL]
1335
+ }, { onMessagesChanged: ({ messages }) => {
1336
+ this.extractSuggestions(messages, suggestionId, consumerAgentId, true);
1337
+ } });
1338
+ } catch (error) {
1339
+ console.warn("Error generating suggestions:", error);
1340
+ } finally {
1341
+ this.finalizeSuggestions(suggestionId, consumerAgentId);
1342
+ const runningAgents = this._runningSuggestions[consumerAgentId];
1343
+ if (agent && runningAgents) {
1344
+ const filteredAgents = runningAgents.filter((a) => a !== agent);
1345
+ this._runningSuggestions[consumerAgentId] = filteredAgents;
1346
+ if (filteredAgents.length === 0) {
1347
+ delete this._runningSuggestions[consumerAgentId];
1348
+ await this.notifySuggestionsFinishedLoading(consumerAgentId);
1349
+ }
1350
+ }
1351
+ }
1352
+ }
1353
+ /**
1354
+ * Finalize suggestions by marking them as no longer loading
1355
+ */
1356
+ finalizeSuggestions(suggestionId, consumerAgentId) {
1357
+ const agentSuggestions = this._suggestions[consumerAgentId];
1358
+ const currentSuggestions = agentSuggestions === null || agentSuggestions === void 0 ? void 0 : agentSuggestions[suggestionId];
1359
+ if (agentSuggestions && currentSuggestions && currentSuggestions.length > 0) {
1360
+ var _this$_suggestions$co2;
1361
+ const finalizedSuggestions = currentSuggestions.filter((suggestion) => suggestion.title !== "" || suggestion.message !== "").map((suggestion) => ({
1362
+ ...suggestion,
1363
+ isLoading: false
1364
+ }));
1365
+ if (finalizedSuggestions.length > 0) agentSuggestions[suggestionId] = finalizedSuggestions;
1366
+ else delete agentSuggestions[suggestionId];
1367
+ const allSuggestions = Object.values((_this$_suggestions$co2 = this._suggestions[consumerAgentId]) !== null && _this$_suggestions$co2 !== void 0 ? _this$_suggestions$co2 : {}).flat();
1368
+ this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "finalized");
1369
+ }
1370
+ }
1371
+ /**
1372
+ * Extract suggestions from messages (called during streaming)
1373
+ */
1374
+ extractSuggestions(messages, suggestionId, consumerAgentId, isRunning) {
1375
+ const idx = messages.findIndex((message) => message.id === suggestionId);
1376
+ if (idx == -1) return;
1377
+ const suggestions = [];
1378
+ const newMessages = messages.slice(idx + 1);
1379
+ for (const message of newMessages) if (message.role === "assistant" && message.toolCalls) {
1380
+ for (const toolCall of message.toolCalls) if (toolCall.function.name === "copilotkitSuggest") {
1381
+ const parsed = (0, _copilotkit_shared.partialJSONParse)(Array.isArray(toolCall.function.arguments) ? toolCall.function.arguments.join("") : toolCall.function.arguments);
1382
+ if (parsed && typeof parsed === "object" && "suggestions" in parsed) {
1383
+ const parsedSuggestions = parsed.suggestions;
1384
+ if (Array.isArray(parsedSuggestions)) {
1385
+ for (const item of parsedSuggestions) if (item && typeof item === "object" && "title" in item) {
1386
+ var _item$title, _item$message;
1387
+ suggestions.push({
1388
+ title: (_item$title = item.title) !== null && _item$title !== void 0 ? _item$title : "",
1389
+ message: (_item$message = item.message) !== null && _item$message !== void 0 ? _item$message : "",
1390
+ isLoading: false
1391
+ });
1392
+ }
1393
+ }
1394
+ }
1395
+ }
1396
+ }
1397
+ if (isRunning && suggestions.length > 0) suggestions[suggestions.length - 1].isLoading = true;
1398
+ const agentSuggestions = this._suggestions[consumerAgentId];
1399
+ if (agentSuggestions) {
1400
+ var _this$_suggestions$co3;
1401
+ agentSuggestions[suggestionId] = suggestions;
1402
+ const allSuggestions = Object.values((_this$_suggestions$co3 = this._suggestions[consumerAgentId]) !== null && _this$_suggestions$co3 !== void 0 ? _this$_suggestions$co3 : {}).flat();
1403
+ this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "suggestions changed");
1404
+ }
1405
+ }
1406
+ /**
1407
+ * Notify subscribers of suggestions config changes
1408
+ */
1409
+ async notifySuggestionsConfigChanged() {
1410
+ await this.core.notifySubscribers((subscriber) => {
1411
+ var _subscriber$onSuggest;
1412
+ return (_subscriber$onSuggest = subscriber.onSuggestionsConfigChanged) === null || _subscriber$onSuggest === void 0 ? void 0 : _subscriber$onSuggest.call(subscriber, {
1413
+ copilotkit: this.core,
1414
+ suggestionsConfig: this._suggestionsConfig
1415
+ });
1416
+ }, "Subscriber onSuggestionsConfigChanged error:");
1417
+ }
1418
+ /**
1419
+ * Notify subscribers of suggestions changes
1420
+ */
1421
+ async notifySuggestionsChanged(agentId, suggestions, context = "") {
1422
+ await this.core.notifySubscribers((subscriber) => {
1423
+ var _subscriber$onSuggest2;
1424
+ return (_subscriber$onSuggest2 = subscriber.onSuggestionsChanged) === null || _subscriber$onSuggest2 === void 0 ? void 0 : _subscriber$onSuggest2.call(subscriber, {
1425
+ copilotkit: this.core,
1426
+ agentId,
1427
+ suggestions
1428
+ });
1429
+ }, `Subscriber onSuggestionsChanged error: ${context}`);
1430
+ }
1431
+ /**
1432
+ * Notify subscribers that suggestions started loading
1433
+ */
1434
+ async notifySuggestionsStartedLoading(agentId) {
1435
+ await this.core.notifySubscribers((subscriber) => {
1436
+ var _subscriber$onSuggest3;
1437
+ return (_subscriber$onSuggest3 = subscriber.onSuggestionsStartedLoading) === null || _subscriber$onSuggest3 === void 0 ? void 0 : _subscriber$onSuggest3.call(subscriber, {
1438
+ copilotkit: this.core,
1439
+ agentId
1440
+ });
1441
+ }, "Subscriber onSuggestionsStartedLoading error:");
1442
+ }
1443
+ /**
1444
+ * Notify subscribers that suggestions finished loading
1445
+ */
1446
+ async notifySuggestionsFinishedLoading(agentId) {
1447
+ await this.core.notifySubscribers((subscriber) => {
1448
+ var _subscriber$onSuggest4;
1449
+ return (_subscriber$onSuggest4 = subscriber.onSuggestionsFinishedLoading) === null || _subscriber$onSuggest4 === void 0 ? void 0 : _subscriber$onSuggest4.call(subscriber, {
1450
+ copilotkit: this.core,
1451
+ agentId
1452
+ });
1453
+ }, "Subscriber onSuggestionsFinishedLoading error:");
1454
+ }
1455
+ /**
1456
+ * Check if suggestions should be shown based on availability and message count
1457
+ */
1458
+ shouldShowSuggestions(config, messageCount) {
1459
+ const availability = config.available;
1460
+ if (!availability) if (isDynamicSuggestionsConfig(config)) return messageCount > 0;
1461
+ else return messageCount === 0;
1462
+ switch (availability) {
1463
+ case "disabled": return false;
1464
+ case "before-first-message": return messageCount === 0;
1465
+ case "after-first-message": return messageCount > 0;
1466
+ case "always": return true;
1467
+ default: return false;
1468
+ }
1469
+ }
1470
+ /**
1471
+ * Add static suggestions directly without AI generation
1472
+ */
1473
+ addStaticSuggestions(suggestionId, config, consumerAgentId) {
1474
+ var _this$_suggestions$co4, _this$_suggestions$co5;
1475
+ const suggestions = config.suggestions.map((s) => ({
1476
+ ...s,
1477
+ isLoading: false
1478
+ }));
1479
+ this._suggestions[consumerAgentId] = {
1480
+ ...(_this$_suggestions$co4 = this._suggestions[consumerAgentId]) !== null && _this$_suggestions$co4 !== void 0 ? _this$_suggestions$co4 : {},
1481
+ [suggestionId]: suggestions
1482
+ };
1483
+ const allSuggestions = Object.values((_this$_suggestions$co5 = this._suggestions[consumerAgentId]) !== null && _this$_suggestions$co5 !== void 0 ? _this$_suggestions$co5 : {}).flat();
1484
+ this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "static suggestions added");
1485
+ }
1486
+ };
1487
+ /**
1488
+ * Type guard for dynamic suggestions config
1489
+ */
1490
+ function isDynamicSuggestionsConfig(config) {
1491
+ return "instructions" in config;
1492
+ }
1493
+ /**
1494
+ * Type guard for static suggestions config
1495
+ */
1496
+ function isStaticSuggestionsConfig(config) {
1497
+ return "suggestions" in config;
1498
+ }
1499
+ /**
1500
+ * The tool definition for AI-generated suggestions
1501
+ */
1502
+ const SUGGEST_TOOL = {
1503
+ name: "copilotkitSuggest",
1504
+ description: "Suggest what the user could say next",
1505
+ parameters: {
1506
+ type: "object",
1507
+ properties: { suggestions: {
1508
+ type: "array",
1509
+ description: "List of suggestions shown to the user as buttons.",
1510
+ items: {
1511
+ type: "object",
1512
+ properties: {
1513
+ title: {
1514
+ type: "string",
1515
+ description: "The title of the suggestion. This is shown as a button and should be short."
1516
+ },
1517
+ message: {
1518
+ type: "string",
1519
+ description: "The message to send when the suggestion is clicked. This should be a clear, complete sentence and will be sent as an instruction to the AI."
1520
+ }
1521
+ },
1522
+ required: ["title", "message"]
1523
+ }
1524
+ } },
1525
+ required: ["suggestions"]
1526
+ }
1527
+ };
1528
+
1529
+ //#endregion
1530
+ //#region src/core/run-handler.ts
1531
+ /**
1532
+ * Handles agent execution, tool calling, and agent connectivity for CopilotKitCore.
1533
+ * Manages the complete lifecycle of agent runs including tool execution and follow-ups.
1534
+ */
1535
+ var RunHandler = class {
1536
+ constructor(core) {
1537
+ this.core = core;
1538
+ _defineProperty(this, "_tools", []);
1539
+ _defineProperty(this, "_runAbortController", null);
1540
+ _defineProperty(this, "_runDepth", 0);
1541
+ }
1542
+ /**
1543
+ * Abort the current run. Called by `CopilotKitCore.stopAgent()` to signal
1544
+ * that in-flight tool handlers should stop and `processAgentResult` should
1545
+ * not start a follow-up run.
1546
+ */
1547
+ abortCurrentRun() {
1548
+ var _this$_runAbortContro;
1549
+ (_this$_runAbortContro = this._runAbortController) === null || _this$_runAbortContro === void 0 || _this$_runAbortContro.abort();
1550
+ }
1551
+ /**
1552
+ * Typed access to CopilotKitCore's internal ("friend") methods.
1553
+ * Centralises the single unavoidable cast so call-sites stay clean.
1554
+ */
1555
+ get _internal() {
1556
+ return this.core;
1557
+ }
1558
+ /**
1559
+ * Get all tools as a readonly array
1560
+ */
1561
+ get tools() {
1562
+ return this._tools;
1563
+ }
1564
+ /**
1565
+ * Initialize with tools
1566
+ */
1567
+ initialize(tools) {
1568
+ this._tools = tools;
1569
+ }
1570
+ /**
1571
+ * Add a tool to the registry
1572
+ */
1573
+ addTool(tool) {
1574
+ if (this._tools.findIndex((t) => t.name === tool.name && t.agentId === tool.agentId) !== -1) {
1575
+ _copilotkit_shared.logger.warn(`Tool already exists: '${tool.name}' for agent '${tool.agentId || "global"}', skipping.`);
1576
+ return;
1577
+ }
1578
+ this._tools.push(tool);
1579
+ }
1580
+ /**
1581
+ * Remove a tool by name and optionally by agentId
1582
+ */
1583
+ removeTool(id, agentId) {
1584
+ this._tools = this._tools.filter((tool) => {
1585
+ if (agentId !== void 0) return !(tool.name === id && tool.agentId === agentId);
1586
+ return !(tool.name === id && !tool.agentId);
1587
+ });
1588
+ }
1589
+ /**
1590
+ * Get a tool by name and optionally by agentId.
1591
+ * If agentId is provided, it will first look for an agent-specific tool,
1592
+ * then fall back to a global tool with the same name.
1593
+ */
1594
+ getTool(params) {
1595
+ const { toolName, agentId } = params;
1596
+ if (agentId) {
1597
+ const agentTool = this._tools.find((tool) => tool.name === toolName && tool.agentId === agentId);
1598
+ if (agentTool) return agentTool;
1599
+ }
1600
+ return this._tools.find((tool) => tool.name === toolName && !tool.agentId);
1601
+ }
1602
+ /**
1603
+ * Set all tools at once. Replaces existing tools.
1604
+ */
1605
+ setTools(tools) {
1606
+ this._tools = [...tools];
1607
+ }
1608
+ /**
1609
+ * Connect an agent (establish initial connection)
1610
+ */
1611
+ async connectAgent({ agent }) {
1612
+ try {
1613
+ await agent.detachActiveRun();
1614
+ agent.setMessages([]);
1615
+ agent.setState({});
1616
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...this._internal.headers };
1617
+ const runAgentResult = await agent.connectAgent({
1618
+ forwardedProps: this._internal.properties,
1619
+ tools: this.buildFrontendTools(agent.agentId),
1620
+ context: Object.values(this._internal.context)
1621
+ }, this.createAgentErrorSubscriber(agent));
1622
+ return this.processAgentResult({
1623
+ runAgentResult,
1624
+ agent
1625
+ });
1626
+ } catch (error) {
1627
+ const connectError = error instanceof Error ? error : new Error(String(error));
1628
+ const context = {};
1629
+ if (agent.agentId) context.agentId = agent.agentId;
1630
+ await this._internal.emitError({
1631
+ error: connectError,
1632
+ code: CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED,
1633
+ context
1634
+ });
1635
+ return { newMessages: [] };
1636
+ }
1637
+ }
1638
+ /**
1639
+ * Run an agent
1640
+ */
1641
+ async runAgent({ agent, forwardedProps }) {
1642
+ if (agent.agentId) this._internal.suggestionEngine.clearSuggestions(agent.agentId);
1643
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...this._internal.headers };
1644
+ if (agent.detachActiveRun) await agent.detachActiveRun();
1645
+ this._internal.subscribeAgentToStateManager(agent);
1646
+ const isTopLevel = this._runDepth === 0;
1647
+ let originalAbortRun;
1648
+ if (isTopLevel) {
1649
+ this._runAbortController = new AbortController();
1650
+ const controller = this._runAbortController;
1651
+ originalAbortRun = agent.abortRun.bind(agent);
1652
+ agent.abortRun = () => {
1653
+ controller.abort();
1654
+ originalAbortRun();
1655
+ };
1656
+ }
1657
+ this._runDepth++;
1658
+ try {
1659
+ const runAgentResult = await agent.runAgent({
1660
+ forwardedProps: {
1661
+ ...this._internal.properties,
1662
+ ...forwardedProps
1663
+ },
1664
+ tools: this.buildFrontendTools(agent.agentId),
1665
+ context: Object.values(this._internal.context)
1666
+ }, this.createAgentErrorSubscriber(agent));
1667
+ return await this.processAgentResult({
1668
+ runAgentResult,
1669
+ agent
1670
+ });
1671
+ } catch (error) {
1672
+ const runError = error instanceof Error ? error : new Error(String(error));
1673
+ const context = {};
1674
+ if (agent.agentId) context.agentId = agent.agentId;
1675
+ await this._internal.emitError({
1676
+ error: runError,
1677
+ code: CopilotKitCoreErrorCode.AGENT_RUN_FAILED,
1678
+ context
1679
+ });
1680
+ return { newMessages: [] };
1681
+ } finally {
1682
+ this._runDepth--;
1683
+ if (isTopLevel && originalAbortRun) agent.abortRun = originalAbortRun;
1684
+ }
1685
+ }
1686
+ /**
1687
+ * Process agent result and execute tools
1688
+ */
1689
+ async processAgentResult({ runAgentResult, agent }) {
1690
+ var _this$_runAbortContro2;
1691
+ const { newMessages } = runAgentResult;
1692
+ const agentId = agent.agentId;
1693
+ let needsFollowUp = false;
1694
+ for (const message of newMessages) if (message.role === "assistant") {
1695
+ for (const toolCall of message.toolCalls || []) if (newMessages.findIndex((m) => m.role === "tool" && m.toolCallId === toolCall.id) === -1) {
1696
+ const tool = this.getTool({
1697
+ toolName: toolCall.function.name,
1698
+ agentId: agent.agentId
1699
+ });
1700
+ if (tool) {
1701
+ if (await this.executeSpecificTool(tool, toolCall, message, agent, agentId)) needsFollowUp = true;
1702
+ } else {
1703
+ const wildcardTool = this.getTool({
1704
+ toolName: "*",
1705
+ agentId: agent.agentId
1706
+ });
1707
+ if (wildcardTool) {
1708
+ if (await this.executeWildcardTool(wildcardTool, toolCall, message, agent, agentId)) needsFollowUp = true;
1709
+ }
1710
+ }
1711
+ }
1712
+ }
1713
+ if (needsFollowUp && !((_this$_runAbortContro2 = this._runAbortController) === null || _this$_runAbortContro2 === void 0 ? void 0 : _this$_runAbortContro2.signal.aborted)) {
1714
+ await this._internal.waitForPendingFrameworkUpdates();
1715
+ return await this.runAgent({ agent });
1716
+ }
1717
+ this._internal.suggestionEngine.reloadSuggestions(agentId, agent);
1718
+ return runAgentResult;
1719
+ }
1720
+ /**
1721
+ * Shared handler execution logic used by executeSpecificTool, executeWildcardTool, and runTool.
1722
+ * Handles arg parsing, subscriber notifications, handler invocation, result stringification,
1723
+ * and error handling.
1724
+ */
1725
+ async executeToolHandler({ tool, toolCall, agent, agentId, handlerArgs, toolType, messageId }) {
1726
+ let toolCallResult = "";
1727
+ let errorMessage;
1728
+ let isArgumentError = false;
1729
+ let parsedArgs;
1730
+ try {
1731
+ parsedArgs = parseToolArguments(handlerArgs, toolCall.function.name);
1732
+ } catch (error) {
1733
+ const parseError = error instanceof Error ? error : new Error(String(error));
1734
+ errorMessage = parseError.message;
1735
+ isArgumentError = true;
1736
+ await this._internal.emitError({
1737
+ error: parseError,
1738
+ code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,
1739
+ context: {
1740
+ agentId,
1741
+ toolCallId: toolCall.id,
1742
+ toolName: toolCall.function.name,
1743
+ rawArguments: handlerArgs,
1744
+ toolType,
1745
+ ...messageId ? { messageId } : {}
1746
+ }
1747
+ });
1748
+ }
1749
+ await this._internal.notifySubscribers((subscriber) => {
1750
+ var _subscriber$onToolExe;
1751
+ return (_subscriber$onToolExe = subscriber.onToolExecutionStart) === null || _subscriber$onToolExe === void 0 ? void 0 : _subscriber$onToolExe.call(subscriber, {
1752
+ copilotkit: this.core,
1753
+ toolCallId: toolCall.id,
1754
+ agentId,
1755
+ toolName: toolCall.function.name,
1756
+ args: parsedArgs
1757
+ });
1758
+ }, "Subscriber onToolExecutionStart error:");
1759
+ if (!errorMessage) try {
1760
+ var _this$_runAbortContro3;
1761
+ const result = await tool.handler(parsedArgs, {
1762
+ toolCall,
1763
+ agent,
1764
+ signal: (_this$_runAbortContro3 = this._runAbortController) === null || _this$_runAbortContro3 === void 0 ? void 0 : _this$_runAbortContro3.signal
1765
+ });
1766
+ if (result === void 0 || result === null) toolCallResult = "";
1767
+ else if (typeof result === "string") toolCallResult = result;
1768
+ else toolCallResult = JSON.stringify(result);
1769
+ } catch (error) {
1770
+ const handlerError = error instanceof Error ? error : new Error(String(error));
1771
+ errorMessage = handlerError.message;
1772
+ await this._internal.emitError({
1773
+ error: handlerError,
1774
+ code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,
1775
+ context: {
1776
+ agentId,
1777
+ toolCallId: toolCall.id,
1778
+ toolName: toolCall.function.name,
1779
+ parsedArgs,
1780
+ toolType,
1781
+ ...messageId ? { messageId } : {}
1782
+ }
1783
+ });
1784
+ }
1785
+ if (errorMessage) toolCallResult = `Error: ${errorMessage}`;
1786
+ await this._internal.notifySubscribers((subscriber) => {
1787
+ var _subscriber$onToolExe2;
1788
+ return (_subscriber$onToolExe2 = subscriber.onToolExecutionEnd) === null || _subscriber$onToolExe2 === void 0 ? void 0 : _subscriber$onToolExe2.call(subscriber, {
1789
+ copilotkit: this.core,
1790
+ toolCallId: toolCall.id,
1791
+ agentId,
1792
+ toolName: toolCall.function.name,
1793
+ result: errorMessage ? "" : toolCallResult,
1794
+ error: errorMessage
1795
+ });
1796
+ }, "Subscriber onToolExecutionEnd error:");
1797
+ return {
1798
+ result: toolCallResult,
1799
+ error: errorMessage,
1800
+ isArgumentError
1801
+ };
1802
+ }
1803
+ /**
1804
+ * Execute a specific tool
1805
+ */
1806
+ async executeSpecificTool(tool, toolCall, message, agent, agentId) {
1807
+ if ((tool === null || tool === void 0 ? void 0 : tool.agentId) && tool.agentId !== agent.agentId) return false;
1808
+ let handlerResult = {
1809
+ result: "",
1810
+ error: void 0,
1811
+ isArgumentError: false
1812
+ };
1813
+ if (tool === null || tool === void 0 ? void 0 : tool.handler) handlerResult = await this.executeToolHandler({
1814
+ tool,
1815
+ toolCall,
1816
+ agent,
1817
+ agentId,
1818
+ handlerArgs: toolCall.function.arguments,
1819
+ toolType: "specific",
1820
+ messageId: message.id
1821
+ });
1822
+ {
1823
+ const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
1824
+ if (messageIndex === -1) return false;
1825
+ const toolMessage = {
1826
+ id: (0, _copilotkit_shared.randomUUID)(),
1827
+ role: "tool",
1828
+ toolCallId: toolCall.id,
1829
+ content: handlerResult.result
1830
+ };
1831
+ agent.messages.splice(messageIndex + 1, 0, toolMessage);
1832
+ if (!handlerResult.error && (tool === null || tool === void 0 ? void 0 : tool.followUp) !== false) return true;
1833
+ }
1834
+ return false;
1835
+ }
1836
+ /**
1837
+ * Execute a wildcard tool.
1838
+ * Wildcard tools receive args wrapped as `{toolName, args}`, which differs from
1839
+ * specific tools, so this method keeps its own arg-wrapping logic rather than
1840
+ * delegating to `executeToolHandler`.
1841
+ */
1842
+ async executeWildcardTool(wildcardTool, toolCall, message, agent, agentId) {
1843
+ if ((wildcardTool === null || wildcardTool === void 0 ? void 0 : wildcardTool.agentId) && wildcardTool.agentId !== agent.agentId) return false;
1844
+ let toolCallResult = "";
1845
+ let errorMessage;
1846
+ if (wildcardTool === null || wildcardTool === void 0 ? void 0 : wildcardTool.handler) {
1847
+ let parsedArgs;
1848
+ try {
1849
+ parsedArgs = parseToolArguments(toolCall.function.arguments, toolCall.function.name);
1850
+ } catch (error) {
1851
+ const parseError = error instanceof Error ? error : new Error(String(error));
1852
+ errorMessage = parseError.message;
1853
+ await this._internal.emitError({
1854
+ error: parseError,
1855
+ code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,
1856
+ context: {
1857
+ agentId,
1858
+ toolCallId: toolCall.id,
1859
+ toolName: toolCall.function.name,
1860
+ rawArguments: toolCall.function.arguments,
1861
+ toolType: "wildcard",
1862
+ messageId: message.id
1863
+ }
1864
+ });
1865
+ }
1866
+ const wildcardArgs = {
1867
+ toolName: toolCall.function.name,
1868
+ args: parsedArgs
1869
+ };
1870
+ await this._internal.notifySubscribers((subscriber) => {
1871
+ var _subscriber$onToolExe3;
1872
+ return (_subscriber$onToolExe3 = subscriber.onToolExecutionStart) === null || _subscriber$onToolExe3 === void 0 ? void 0 : _subscriber$onToolExe3.call(subscriber, {
1873
+ copilotkit: this.core,
1874
+ toolCallId: toolCall.id,
1875
+ agentId,
1876
+ toolName: toolCall.function.name,
1877
+ args: wildcardArgs
1878
+ });
1879
+ }, "Subscriber onToolExecutionStart error:");
1880
+ if (!errorMessage) try {
1881
+ const result = await wildcardTool.handler(wildcardArgs, {
1882
+ toolCall,
1883
+ agent
1884
+ });
1885
+ if (result === void 0 || result === null) toolCallResult = "";
1886
+ else if (typeof result === "string") toolCallResult = result;
1887
+ else toolCallResult = JSON.stringify(result);
1888
+ } catch (error) {
1889
+ const handlerError = error instanceof Error ? error : new Error(String(error));
1890
+ errorMessage = handlerError.message;
1891
+ await this._internal.emitError({
1892
+ error: handlerError,
1893
+ code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,
1894
+ context: {
1895
+ agentId,
1896
+ toolCallId: toolCall.id,
1897
+ toolName: toolCall.function.name,
1898
+ parsedArgs: wildcardArgs,
1899
+ toolType: "wildcard",
1900
+ messageId: message.id
1901
+ }
1902
+ });
1903
+ }
1904
+ if (errorMessage) toolCallResult = `Error: ${errorMessage}`;
1905
+ await this._internal.notifySubscribers((subscriber) => {
1906
+ var _subscriber$onToolExe4;
1907
+ return (_subscriber$onToolExe4 = subscriber.onToolExecutionEnd) === null || _subscriber$onToolExe4 === void 0 ? void 0 : _subscriber$onToolExe4.call(subscriber, {
1908
+ copilotkit: this.core,
1909
+ toolCallId: toolCall.id,
1910
+ agentId,
1911
+ toolName: toolCall.function.name,
1912
+ result: errorMessage ? "" : toolCallResult,
1913
+ error: errorMessage
1914
+ });
1915
+ }, "Subscriber onToolExecutionEnd error:");
1916
+ }
1917
+ {
1918
+ const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
1919
+ if (messageIndex === -1) return false;
1920
+ const toolMessage = {
1921
+ id: (0, _copilotkit_shared.randomUUID)(),
1922
+ role: "tool",
1923
+ toolCallId: toolCall.id,
1924
+ content: toolCallResult
1925
+ };
1926
+ agent.messages.splice(messageIndex + 1, 0, toolMessage);
1927
+ if (!errorMessage && (wildcardTool === null || wildcardTool === void 0 ? void 0 : wildcardTool.followUp) !== false) return true;
1928
+ }
1929
+ return false;
1930
+ }
1931
+ /**
1932
+ * Programmatically execute a registered frontend tool without going through an LLM turn.
1933
+ * The handler runs, render components show up in the UI, and both the tool call and
1934
+ * result messages are added to `agent.messages`.
1935
+ */
1936
+ async runTool(params) {
1937
+ const { name, agentId, parameters = {}, followUp = false } = params;
1938
+ const tool = this.getTool({
1939
+ toolName: name,
1940
+ agentId
1941
+ });
1942
+ if (!tool) {
1943
+ const error = /* @__PURE__ */ new Error(`Tool not found: ${name}`);
1944
+ await this._internal.emitError({
1945
+ error,
1946
+ code: CopilotKitCoreErrorCode.TOOL_NOT_FOUND,
1947
+ context: {
1948
+ toolName: name,
1949
+ agentId
1950
+ }
1951
+ });
1952
+ throw error;
1953
+ }
1954
+ const resolvedAgentId = agentId !== null && agentId !== void 0 ? agentId : "default";
1955
+ const agent = this._internal.getAgent(resolvedAgentId);
1956
+ if (!agent) {
1957
+ const error = /* @__PURE__ */ new Error(`Agent not found: ${resolvedAgentId}`);
1958
+ await this._internal.emitError({
1959
+ error,
1960
+ code: CopilotKitCoreErrorCode.AGENT_NOT_FOUND,
1961
+ context: { agentId: resolvedAgentId }
1962
+ });
1963
+ throw error;
1964
+ }
1965
+ const toolCallId = (0, _copilotkit_shared.randomUUID)();
1966
+ const assistantMessage = {
1967
+ id: (0, _copilotkit_shared.randomUUID)(),
1968
+ role: "assistant",
1969
+ content: "",
1970
+ toolCalls: [{
1971
+ id: toolCallId,
1972
+ type: "function",
1973
+ function: {
1974
+ name,
1975
+ arguments: JSON.stringify(parameters)
1976
+ }
1977
+ }]
1978
+ };
1979
+ agent.messages.push(assistantMessage);
1980
+ let handlerResult = {
1981
+ result: "",
1982
+ error: void 0,
1983
+ isArgumentError: false
1984
+ };
1985
+ if (tool.handler) handlerResult = await this.executeToolHandler({
1986
+ tool,
1987
+ toolCall: assistantMessage.toolCalls[0],
1988
+ agent,
1989
+ agentId: resolvedAgentId,
1990
+ handlerArgs: parameters,
1991
+ toolType: "runTool"
1992
+ });
1993
+ const toolResultMessage = {
1994
+ id: (0, _copilotkit_shared.randomUUID)(),
1995
+ role: "tool",
1996
+ toolCallId,
1997
+ content: handlerResult.result
1998
+ };
1999
+ const assistantIndex = agent.messages.findIndex((m) => m.id === assistantMessage.id);
2000
+ if (assistantIndex !== -1) agent.messages.splice(assistantIndex + 1, 0, toolResultMessage);
2001
+ else agent.messages.push(toolResultMessage);
2002
+ if (!handlerResult.error && followUp !== false) {
2003
+ if (typeof followUp === "string" && followUp !== "generate") {
2004
+ const userMessage = {
2005
+ id: (0, _copilotkit_shared.randomUUID)(),
2006
+ role: "user",
2007
+ content: followUp
2008
+ };
2009
+ agent.messages.push(userMessage);
2010
+ }
2011
+ await this._internal.waitForPendingFrameworkUpdates();
2012
+ await this.runAgent({ agent });
2013
+ }
2014
+ return {
2015
+ toolCallId,
2016
+ result: handlerResult.result,
2017
+ error: handlerResult.error
2018
+ };
2019
+ }
2020
+ /**
2021
+ * Build frontend tools for an agent
2022
+ */
2023
+ buildFrontendTools(agentId) {
2024
+ return this._tools.filter((tool) => tool.available !== false && (!tool.agentId || tool.agentId === agentId)).map((tool) => {
2025
+ var _tool$description;
2026
+ return {
2027
+ name: tool.name,
2028
+ description: (_tool$description = tool.description) !== null && _tool$description !== void 0 ? _tool$description : "",
2029
+ parameters: createToolSchema(tool)
2030
+ };
2031
+ });
2032
+ }
2033
+ /**
2034
+ * Create an agent error subscriber
2035
+ */
2036
+ createAgentErrorSubscriber(agent) {
2037
+ const emitAgentError = async (error, code, extraContext = {}) => {
2038
+ const context = { ...extraContext };
2039
+ if (agent.agentId) context.agentId = agent.agentId;
2040
+ await this._internal.emitError({
2041
+ error,
2042
+ code,
2043
+ context
2044
+ });
2045
+ };
2046
+ return {
2047
+ onRunFailed: async ({ error }) => {
2048
+ await emitAgentError(error, error instanceof AgentThreadLockedError ? CopilotKitCoreErrorCode.AGENT_THREAD_LOCKED : CopilotKitCoreErrorCode.AGENT_RUN_FAILED_EVENT, { source: "onRunFailed" });
2049
+ },
2050
+ onRunErrorEvent: async ({ event }) => {
2051
+ var _event$rawEvent, _event$rawEvent2, _event$message;
2052
+ const eventError = (event === null || event === void 0 ? void 0 : event.rawEvent) instanceof Error ? event.rawEvent : (event === null || event === void 0 || (_event$rawEvent = event.rawEvent) === null || _event$rawEvent === void 0 ? void 0 : _event$rawEvent.error) instanceof Error ? event.rawEvent.error : void 0;
2053
+ const errorMessage = typeof (event === null || event === void 0 || (_event$rawEvent2 = event.rawEvent) === null || _event$rawEvent2 === void 0 ? void 0 : _event$rawEvent2.error) === "string" ? event.rawEvent.error : (_event$message = event === null || event === void 0 ? void 0 : event.message) !== null && _event$message !== void 0 ? _event$message : "Agent run error";
2054
+ const rawError = eventError !== null && eventError !== void 0 ? eventError : new Error(errorMessage);
2055
+ if ((event === null || event === void 0 ? void 0 : event.code) && !rawError.code) rawError.code = event.code;
2056
+ await emitAgentError(rawError, CopilotKitCoreErrorCode.AGENT_RUN_ERROR_EVENT, {
2057
+ source: "onRunErrorEvent",
2058
+ event,
2059
+ runtimeErrorCode: event === null || event === void 0 ? void 0 : event.code
2060
+ });
2061
+ }
2062
+ };
2063
+ }
2064
+ };
2065
+ /**
2066
+ * Empty tool schema constant
2067
+ */
2068
+ const EMPTY_TOOL_SCHEMA = {
2069
+ type: "object",
2070
+ properties: {}
2071
+ };
2072
+ /**
2073
+ * Create a JSON schema from a tool's parameters
2074
+ */
2075
+ function createToolSchema(tool) {
2076
+ if (!tool.parameters) return { ...EMPTY_TOOL_SCHEMA };
2077
+ const rawSchema = (0, _copilotkit_shared.schemaToJsonSchema)(tool.parameters, { zodToJsonSchema: zod_to_json_schema.zodToJsonSchema });
2078
+ if (!rawSchema || typeof rawSchema !== "object") return { ...EMPTY_TOOL_SCHEMA };
2079
+ const { $schema, ...schema } = rawSchema;
2080
+ if (typeof schema.type !== "string") schema.type = "object";
2081
+ if (typeof schema.properties !== "object" || schema.properties === null) schema.properties = {};
2082
+ stripAdditionalProperties(schema);
2083
+ return schema;
2084
+ }
2085
+ function stripAdditionalProperties(schema) {
2086
+ if (!schema || typeof schema !== "object") return;
2087
+ if (Array.isArray(schema)) {
2088
+ schema.forEach(stripAdditionalProperties);
2089
+ return;
2090
+ }
2091
+ const record = schema;
2092
+ if (record.additionalProperties !== void 0) delete record.additionalProperties;
2093
+ for (const value of Object.values(record)) stripAdditionalProperties(value);
2094
+ }
2095
+ /**
2096
+ * Ensures parsed tool arguments are a plain object.
2097
+ * Throws for non-object values so the caller's catch block can emit
2098
+ * a structured TOOL_ARGUMENT_PARSE_FAILED error.
2099
+ *
2100
+ * @internal Exported for testing only.
2101
+ */
2102
+ function ensureObjectArgs(parsed, toolName) {
2103
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed;
2104
+ throw new Error(`Tool arguments for ${toolName} parsed to non-object (${typeof parsed})`);
2105
+ }
2106
+ /**
2107
+ * Parses raw tool call arguments into a validated object.
2108
+ *
2109
+ * Some LLM providers (e.g. @ai-sdk/openai-compatible) may send empty string "",
2110
+ * null, or undefined instead of "{}". This function normalises those cases to an
2111
+ * empty object so callers don't crash on JSON.parse("").
2112
+ *
2113
+ * A debug-level warning is emitted when the fallback triggers so silent coercion
2114
+ * is observable in logs.
2115
+ *
2116
+ * @internal Exported for testing only.
2117
+ */
2118
+ function parseToolArguments(rawArgs, toolName) {
2119
+ if (rawArgs === "" || rawArgs === null || rawArgs === void 0) {
2120
+ _copilotkit_shared.logger.debug(`[parseToolArguments] Tool "${toolName}" received empty/null/undefined arguments — defaulting to {}`);
2121
+ return {};
2122
+ }
2123
+ return ensureObjectArgs(typeof rawArgs === "string" ? JSON.parse(rawArgs) : rawArgs, toolName);
2124
+ }
2125
+
2126
+ //#endregion
2127
+ //#region src/core/state-manager.ts
2128
+ /**
2129
+ * Manages state and message tracking by run for CopilotKitCore.
2130
+ * Tracks agent state snapshots and message-to-run associations.
2131
+ */
2132
+ var StateManager = class {
2133
+ constructor(core) {
2134
+ this.core = core;
2135
+ _defineProperty(this, "stateByRun", /* @__PURE__ */ new Map());
2136
+ _defineProperty(this, "messageToRun", /* @__PURE__ */ new Map());
2137
+ _defineProperty(this, "activeRun", /* @__PURE__ */ new Map());
2138
+ _defineProperty(this, "agentSubscriptions", /* @__PURE__ */ new Map());
2139
+ }
2140
+ /**
2141
+ * Initialize state tracking for an agent
2142
+ */
2143
+ initialize() {}
2144
+ /**
2145
+ * Subscribe to an agent's events to track state and messages.
2146
+ *
2147
+ * Registry agents (subscribed via `onAgentsChanged`) use the bare `agentId`
2148
+ * key so that `unsubscribeFromAgent(agentId)` can remove them when they
2149
+ * are replaced. Per-thread clones (subscribed via `subscribeAgentToStateManager`)
2150
+ * pass `{ isClone: true }` to use a composite `agentId:threadId` key, keeping
2151
+ * their subscription independent of the registry agent's.
2152
+ */
2153
+ subscribeToAgent(agent, { isClone = false } = {}) {
2154
+ if (!agent.agentId) return;
2155
+ const agentId = agent.agentId;
2156
+ const subscriptionKey = isClone && agent.threadId ? `${agentId}:${agent.threadId}` : agentId;
2157
+ const existingUnsubscribe = this.agentSubscriptions.get(subscriptionKey);
2158
+ if (existingUnsubscribe) {
2159
+ existingUnsubscribe();
2160
+ this.agentSubscriptions.delete(subscriptionKey);
2161
+ }
2162
+ let revoked = false;
2163
+ let subRunId;
2164
+ let runFinished = false;
2165
+ const effectiveInput = (input) => {
2166
+ var _subRunId;
2167
+ return {
2168
+ ...input,
2169
+ runId: (_subRunId = subRunId) !== null && _subRunId !== void 0 ? _subRunId : input.runId
2170
+ };
2171
+ };
2172
+ const { unsubscribe } = agent.subscribe({
2173
+ onRunStartedEvent: ({ input, state }) => {
2174
+ if (revoked) return;
2175
+ if (runFinished && input.runId === subRunId) subRunId = (0, _ag_ui_client.randomUUID)();
2176
+ else subRunId = input.runId;
2177
+ runFinished = false;
2178
+ this.handleRunStarted(agent, effectiveInput(input), state);
2179
+ },
2180
+ onRunFinishedEvent: ({ input, state }) => {
2181
+ if (revoked) return;
2182
+ runFinished = true;
2183
+ this.handleRunFinished(agent, effectiveInput(input), state);
2184
+ },
2185
+ onStateSnapshotEvent: ({ event, input, state }) => {
2186
+ if (revoked) return;
2187
+ this.handleStateSnapshot(agent, event, effectiveInput(input), state);
2188
+ },
2189
+ onStateDeltaEvent: ({ event, input, state }) => {
2190
+ if (revoked) return;
2191
+ this.handleStateDelta(agent, event, effectiveInput(input), state);
2192
+ },
2193
+ onMessagesSnapshotEvent: ({ event, input, messages }) => {
2194
+ if (revoked) return;
2195
+ this.handleMessagesSnapshot(agent, event, effectiveInput(input), messages);
2196
+ },
2197
+ onNewMessage: ({ message, input }) => {
2198
+ if (revoked) return;
2199
+ this.handleNewMessage(agent, message, input ? effectiveInput(input) : void 0);
2200
+ }
2201
+ });
2202
+ this.agentSubscriptions.set(subscriptionKey, () => {
2203
+ revoked = true;
2204
+ unsubscribe();
2205
+ });
2206
+ }
2207
+ /**
2208
+ * Unsubscribe a registry agent's subscription (bare `agentId` key).
2209
+ * Per-thread clone subscriptions use composite `agentId:threadId` keys and
2210
+ * are replaced (not removed) by subsequent subscribeToAgent(agent, { isClone: true })
2211
+ * calls for the same (agentId, threadId) pair.
2212
+ */
2213
+ unsubscribeFromAgent(agentId) {
2214
+ const unsubscribe = this.agentSubscriptions.get(agentId);
2215
+ if (unsubscribe) {
2216
+ unsubscribe();
2217
+ this.agentSubscriptions.delete(agentId);
2218
+ }
2219
+ }
2220
+ /**
2221
+ * Get state for a specific run
2222
+ * Returns a deep copy to prevent external mutations
2223
+ */
2224
+ getStateByRun(agentId, threadId, runId) {
2225
+ var _this$stateByRun$get;
2226
+ const state = (_this$stateByRun$get = this.stateByRun.get(agentId)) === null || _this$stateByRun$get === void 0 || (_this$stateByRun$get = _this$stateByRun$get.get(threadId)) === null || _this$stateByRun$get === void 0 ? void 0 : _this$stateByRun$get.get(runId);
2227
+ if (!state) return void 0;
2228
+ return JSON.parse(JSON.stringify(state));
2229
+ }
2230
+ /**
2231
+ * Get runId associated with a message
2232
+ */
2233
+ getRunIdForMessage(agentId, threadId, messageId) {
2234
+ var _this$messageToRun$ge;
2235
+ return (_this$messageToRun$ge = this.messageToRun.get(agentId)) === null || _this$messageToRun$ge === void 0 || (_this$messageToRun$ge = _this$messageToRun$ge.get(threadId)) === null || _this$messageToRun$ge === void 0 ? void 0 : _this$messageToRun$ge.get(messageId);
2236
+ }
2237
+ /**
2238
+ * Get all states for an agent's thread
2239
+ */
2240
+ getStatesForThread(agentId, threadId) {
2241
+ var _this$stateByRun$get$, _this$stateByRun$get2;
2242
+ return (_this$stateByRun$get$ = (_this$stateByRun$get2 = this.stateByRun.get(agentId)) === null || _this$stateByRun$get2 === void 0 ? void 0 : _this$stateByRun$get2.get(threadId)) !== null && _this$stateByRun$get$ !== void 0 ? _this$stateByRun$get$ : /* @__PURE__ */ new Map();
2243
+ }
2244
+ /**
2245
+ * Get all run IDs for an agent's thread
2246
+ */
2247
+ getRunIdsForThread(agentId, threadId) {
2248
+ var _this$stateByRun$get3;
2249
+ const threadStates = (_this$stateByRun$get3 = this.stateByRun.get(agentId)) === null || _this$stateByRun$get3 === void 0 ? void 0 : _this$stateByRun$get3.get(threadId);
2250
+ return threadStates ? Array.from(threadStates.keys()) : [];
2251
+ }
2252
+ /**
2253
+ * Handle run started event
2254
+ */
2255
+ handleRunStarted(agent, input, state) {
2256
+ if (!agent.agentId) return;
2257
+ const { threadId, runId } = input;
2258
+ this.activeRun.set(`${agent.agentId}:${threadId}`, runId);
2259
+ if (state && Object.keys(state).length > 0) this.saveState(agent.agentId, threadId, runId, state);
2260
+ }
2261
+ /**
2262
+ * Handle run finished event
2263
+ */
2264
+ handleRunFinished(agent, input, state) {
2265
+ if (!agent.agentId) return;
2266
+ const { threadId, runId } = input;
2267
+ this.activeRun.delete(`${agent.agentId}:${threadId}`);
2268
+ if (state && Object.keys(state).length > 0) this.saveState(agent.agentId, threadId, runId, state);
2269
+ }
2270
+ /**
2271
+ * Handle state snapshot event
2272
+ */
2273
+ handleStateSnapshot(agent, event, input, state) {
2274
+ if (!agent.agentId) return;
2275
+ const { threadId, runId } = input;
2276
+ const mergedState = {
2277
+ ...state,
2278
+ ...event.snapshot
2279
+ };
2280
+ this.saveState(agent.agentId, threadId, runId, mergedState);
2281
+ }
2282
+ /**
2283
+ * Handle state delta event
2284
+ */
2285
+ handleStateDelta(agent, event, input, state) {
2286
+ if (!agent.agentId) return;
2287
+ const { threadId, runId } = input;
2288
+ this.saveState(agent.agentId, threadId, runId, state);
2289
+ }
2290
+ /**
2291
+ * Handle messages snapshot event
2292
+ */
2293
+ handleMessagesSnapshot(agent, event, input, messages) {
2294
+ if (!agent.agentId) return;
2295
+ const { threadId, runId } = input;
2296
+ for (const message of event.messages) this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);
2297
+ }
2298
+ /**
2299
+ * Handle new message event
2300
+ */
2301
+ handleNewMessage(agent, message, input) {
2302
+ if (!agent.agentId) return;
2303
+ if (!input) {
2304
+ var _agent$threadId;
2305
+ const threadId = (_agent$threadId = agent.threadId) !== null && _agent$threadId !== void 0 ? _agent$threadId : "";
2306
+ const runId = this.activeRun.get(`${agent.agentId}:${threadId}`);
2307
+ if (runId) this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);
2308
+ return;
2309
+ }
2310
+ const { threadId, runId } = input;
2311
+ this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);
2312
+ }
2313
+ /**
2314
+ * Save state for a specific run
2315
+ */
2316
+ saveState(agentId, threadId, runId, state) {
2317
+ if (!this.stateByRun.has(agentId)) this.stateByRun.set(agentId, /* @__PURE__ */ new Map());
2318
+ const agentStates = this.stateByRun.get(agentId);
2319
+ if (!agentStates.has(threadId)) agentStates.set(threadId, /* @__PURE__ */ new Map());
2320
+ agentStates.get(threadId).set(runId, JSON.parse(JSON.stringify(state)));
2321
+ }
2322
+ /**
2323
+ * Associate a message with a run
2324
+ */
2325
+ associateMessageWithRun(agentId, threadId, messageId, runId) {
2326
+ if (!this.messageToRun.has(agentId)) this.messageToRun.set(agentId, /* @__PURE__ */ new Map());
2327
+ const agentMessages = this.messageToRun.get(agentId);
2328
+ if (!agentMessages.has(threadId)) agentMessages.set(threadId, /* @__PURE__ */ new Map());
2329
+ agentMessages.get(threadId).set(messageId, runId);
2330
+ }
2331
+ /**
2332
+ * Clear all state for an agent
2333
+ */
2334
+ clearAgentState(agentId) {
2335
+ this.stateByRun.delete(agentId);
2336
+ this.messageToRun.delete(agentId);
2337
+ }
2338
+ /**
2339
+ * Clear all state for a thread
2340
+ */
2341
+ clearThreadState(agentId, threadId) {
2342
+ var _this$stateByRun$get4, _this$messageToRun$ge2;
2343
+ (_this$stateByRun$get4 = this.stateByRun.get(agentId)) === null || _this$stateByRun$get4 === void 0 || _this$stateByRun$get4.delete(threadId);
2344
+ (_this$messageToRun$ge2 = this.messageToRun.get(agentId)) === null || _this$messageToRun$ge2 === void 0 || _this$messageToRun$ge2.delete(threadId);
2345
+ }
2346
+ };
2347
+
2348
+ //#endregion
2349
+ //#region src/core/core.ts
2350
+ let CopilotKitCoreErrorCode = /* @__PURE__ */ function(CopilotKitCoreErrorCode) {
2351
+ CopilotKitCoreErrorCode["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
2352
+ CopilotKitCoreErrorCode["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
2353
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED"] = "agent_run_failed";
2354
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
2355
+ CopilotKitCoreErrorCode["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
2356
+ CopilotKitCoreErrorCode["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
2357
+ CopilotKitCoreErrorCode["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
2358
+ CopilotKitCoreErrorCode["TOOL_NOT_FOUND"] = "tool_not_found";
2359
+ CopilotKitCoreErrorCode["AGENT_NOT_FOUND"] = "agent_not_found";
2360
+ /**
2361
+ * Emitted when an agent run fails because the thread is already locked
2362
+ * by another active run.
2363
+ *
2364
+ * @example
2365
+ * ```tsx
2366
+ * <CopilotKitProvider
2367
+ * onError={({ code, error, context }) => {
2368
+ * if (code === "agent_thread_locked") {
2369
+ * // Show "Agent is busy, retry?" UI
2370
+ * }
2371
+ * }}
2372
+ * />
2373
+ * ```
2374
+ */
2375
+ CopilotKitCoreErrorCode["AGENT_THREAD_LOCKED"] = "agent_thread_locked";
2376
+ CopilotKitCoreErrorCode["TRANSCRIPTION_FAILED"] = "transcription_failed";
2377
+ CopilotKitCoreErrorCode["TRANSCRIPTION_SERVICE_NOT_CONFIGURED"] = "transcription_service_not_configured";
2378
+ CopilotKitCoreErrorCode["TRANSCRIPTION_INVALID_AUDIO"] = "transcription_invalid_audio";
2379
+ CopilotKitCoreErrorCode["TRANSCRIPTION_RATE_LIMITED"] = "transcription_rate_limited";
2380
+ CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
2381
+ CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
2382
+ return CopilotKitCoreErrorCode;
2383
+ }({});
2384
+ let CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ function(CopilotKitCoreRuntimeConnectionStatus) {
2385
+ CopilotKitCoreRuntimeConnectionStatus["Disconnected"] = "disconnected";
2386
+ CopilotKitCoreRuntimeConnectionStatus["Connected"] = "connected";
2387
+ CopilotKitCoreRuntimeConnectionStatus["Connecting"] = "connecting";
2388
+ CopilotKitCoreRuntimeConnectionStatus["Error"] = "error";
2389
+ return CopilotKitCoreRuntimeConnectionStatus;
2390
+ }({});
2391
+ var CopilotKitCore = class {
2392
+ constructor({ runtimeUrl, runtimeTransport = "rest", headers = {}, credentials, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [] }) {
2393
+ _defineProperty(this, "_headers", void 0);
2394
+ _defineProperty(this, "_credentials", void 0);
2395
+ _defineProperty(this, "_properties", void 0);
2396
+ _defineProperty(this, "subscribers", /* @__PURE__ */ new Set());
2397
+ _defineProperty(this, "agentRegistry", void 0);
2398
+ _defineProperty(this, "contextStore", void 0);
2399
+ _defineProperty(this, "suggestionEngine", void 0);
2400
+ _defineProperty(this, "runHandler", void 0);
2401
+ _defineProperty(this, "stateManager", void 0);
2402
+ this._headers = headers;
2403
+ this._credentials = credentials;
2404
+ this._properties = properties;
2405
+ this.agentRegistry = new AgentRegistry(this);
2406
+ this.contextStore = new ContextStore(this);
2407
+ this.suggestionEngine = new SuggestionEngine(this);
2408
+ this.runHandler = new RunHandler(this);
2409
+ this.stateManager = new StateManager(this);
2410
+ this.agentRegistry.initialize(agents__unsafe_dev_only);
2411
+ this.runHandler.initialize(tools);
2412
+ this.suggestionEngine.initialize(suggestionsConfig);
2413
+ this.stateManager.initialize();
2414
+ this.agentRegistry.setRuntimeTransport(runtimeTransport);
2415
+ this.agentRegistry.setRuntimeUrl(runtimeUrl);
2416
+ this.subscribe({ onAgentsChanged: ({ agents }) => {
2417
+ Object.values(agents).forEach((agent) => {
2418
+ if (agent.agentId) this.stateManager.subscribeToAgent(agent);
2419
+ });
2420
+ } });
2421
+ }
2422
+ /**
2423
+ * Internal method used by delegate classes and subclasses to notify subscribers
2424
+ */
2425
+ async notifySubscribers(handler, errorMessage) {
2426
+ await Promise.all(Array.from(this.subscribers).map(async (subscriber) => {
2427
+ try {
2428
+ await handler(subscriber);
2429
+ } catch (error) {
2430
+ console.error(errorMessage, error);
2431
+ }
2432
+ }));
2433
+ }
2434
+ /**
2435
+ * Internal method used by delegate classes to emit errors
2436
+ */
2437
+ async emitError({ error, code, context = {} }) {
2438
+ await this.notifySubscribers((subscriber) => {
2439
+ var _subscriber$onError;
2440
+ return (_subscriber$onError = subscriber.onError) === null || _subscriber$onError === void 0 ? void 0 : _subscriber$onError.call(subscriber, {
2441
+ copilotkit: this,
2442
+ error,
2443
+ code,
2444
+ context
2445
+ });
2446
+ }, "Subscriber onError error:");
2447
+ }
2448
+ /**
2449
+ * Snapshot accessors
2450
+ */
2451
+ get context() {
2452
+ return this.contextStore.context;
2453
+ }
2454
+ get agents() {
2455
+ return this.agentRegistry.agents;
2456
+ }
2457
+ get tools() {
2458
+ return this.runHandler.tools;
2459
+ }
2460
+ get runtimeUrl() {
2461
+ return this.agentRegistry.runtimeUrl;
2462
+ }
2463
+ setRuntimeUrl(runtimeUrl) {
2464
+ this.agentRegistry.setRuntimeUrl(runtimeUrl);
2465
+ }
2466
+ get runtimeTransport() {
2467
+ return this.agentRegistry.runtimeTransport;
2468
+ }
2469
+ setRuntimeTransport(runtimeTransport) {
2470
+ this.agentRegistry.setRuntimeTransport(runtimeTransport);
2471
+ }
2472
+ get runtimeVersion() {
2473
+ return this.agentRegistry.runtimeVersion;
2474
+ }
2475
+ get headers() {
2476
+ return this._headers;
2477
+ }
2478
+ get credentials() {
2479
+ return this._credentials;
2480
+ }
2481
+ get properties() {
2482
+ return this._properties;
2483
+ }
2484
+ get runtimeConnectionStatus() {
2485
+ return this.agentRegistry.runtimeConnectionStatus;
2486
+ }
2487
+ get audioFileTranscriptionEnabled() {
2488
+ return this.agentRegistry.audioFileTranscriptionEnabled;
2489
+ }
2490
+ get runtimeMode() {
2491
+ return this.agentRegistry.runtimeMode;
2492
+ }
2493
+ get intelligence() {
2494
+ return this.agentRegistry.intelligence;
2495
+ }
2496
+ get a2uiEnabled() {
2497
+ return this.agentRegistry.a2uiEnabled;
2498
+ }
2499
+ get licenseStatus() {
2500
+ return this.agentRegistry.licenseStatus;
2501
+ }
2502
+ /**
2503
+ * Configuration updates
2504
+ */
2505
+ setHeaders(headers) {
2506
+ this._headers = headers;
2507
+ this.agentRegistry.applyHeadersToAgents(this.agentRegistry.agents);
2508
+ this.notifySubscribers((subscriber) => {
2509
+ var _subscriber$onHeaders;
2510
+ return (_subscriber$onHeaders = subscriber.onHeadersChanged) === null || _subscriber$onHeaders === void 0 ? void 0 : _subscriber$onHeaders.call(subscriber, {
2511
+ copilotkit: this,
2512
+ headers: this.headers
2513
+ });
2514
+ }, "Subscriber onHeadersChanged error:");
2515
+ }
2516
+ setCredentials(credentials) {
2517
+ this._credentials = credentials;
2518
+ this.agentRegistry.applyCredentialsToAgents(this.agentRegistry.agents);
2519
+ }
2520
+ setProperties(properties) {
2521
+ this._properties = properties;
2522
+ this.notifySubscribers((subscriber) => {
2523
+ var _subscriber$onPropert;
2524
+ return (_subscriber$onPropert = subscriber.onPropertiesChanged) === null || _subscriber$onPropert === void 0 ? void 0 : _subscriber$onPropert.call(subscriber, {
2525
+ copilotkit: this,
2526
+ properties: this.properties
2527
+ });
2528
+ }, "Subscriber onPropertiesChanged error:");
2529
+ }
2530
+ /**
2531
+ * Agent management (delegated to AgentRegistry)
2532
+ */
2533
+ setAgents__unsafe_dev_only(agents) {
2534
+ this.agentRegistry.setAgents__unsafe_dev_only(agents);
2535
+ }
2536
+ addAgent__unsafe_dev_only(params) {
2537
+ this.agentRegistry.addAgent__unsafe_dev_only(params);
2538
+ }
2539
+ removeAgent__unsafe_dev_only(id) {
2540
+ this.agentRegistry.removeAgent__unsafe_dev_only(id);
2541
+ }
2542
+ getAgent(id) {
2543
+ return this.agentRegistry.getAgent(id);
2544
+ }
2545
+ /**
2546
+ * Context management (delegated to ContextStore)
2547
+ */
2548
+ addContext(context) {
2549
+ return this.contextStore.addContext(context);
2550
+ }
2551
+ removeContext(id) {
2552
+ this.contextStore.removeContext(id);
2553
+ }
2554
+ /**
2555
+ * Suggestions management (delegated to SuggestionEngine)
2556
+ */
2557
+ addSuggestionsConfig(config) {
2558
+ return this.suggestionEngine.addSuggestionsConfig(config);
2559
+ }
2560
+ removeSuggestionsConfig(id) {
2561
+ this.suggestionEngine.removeSuggestionsConfig(id);
2562
+ }
2563
+ reloadSuggestions(agentId) {
2564
+ this.suggestionEngine.reloadSuggestions(agentId);
2565
+ }
2566
+ clearSuggestions(agentId) {
2567
+ this.suggestionEngine.clearSuggestions(agentId);
2568
+ }
2569
+ getSuggestions(agentId) {
2570
+ return this.suggestionEngine.getSuggestions(agentId);
2571
+ }
2572
+ /**
2573
+ * Tool management (delegated to RunHandler)
2574
+ */
2575
+ addTool(tool) {
2576
+ this.runHandler.addTool(tool);
2577
+ }
2578
+ removeTool(id, agentId) {
2579
+ this.runHandler.removeTool(id, agentId);
2580
+ }
2581
+ getTool(params) {
2582
+ return this.runHandler.getTool(params);
2583
+ }
2584
+ setTools(tools) {
2585
+ this.runHandler.setTools(tools);
2586
+ }
2587
+ /**
2588
+ * Subscription lifecycle
2589
+ */
2590
+ subscribe(subscriber) {
2591
+ this.subscribers.add(subscriber);
2592
+ return { unsubscribe: () => {
2593
+ this.subscribers.delete(subscriber);
2594
+ } };
2595
+ }
2596
+ /**
2597
+ * Agent connectivity (delegated to RunHandler)
2598
+ */
2599
+ async connectAgent(params) {
2600
+ return this.runHandler.connectAgent(params);
2601
+ }
2602
+ stopAgent(params) {
2603
+ this.runHandler.abortCurrentRun();
2604
+ params.agent.abortRun();
2605
+ }
2606
+ async runAgent(params) {
2607
+ return this.runHandler.runAgent(params);
2608
+ }
2609
+ /**
2610
+ * Programmatically execute a registered frontend tool without going through an LLM turn.
2611
+ * The handler runs, render components show up in the UI, and both the tool call and
2612
+ * result messages are added to `agent.messages`.
2613
+ */
2614
+ async runTool(params) {
2615
+ return this.runHandler.runTool(params);
2616
+ }
2617
+ /**
2618
+ * State management (delegated to StateManager)
2619
+ */
2620
+ getStateByRun(agentId, threadId, runId) {
2621
+ return this.stateManager.getStateByRun(agentId, threadId, runId);
2622
+ }
2623
+ getRunIdForMessage(agentId, threadId, messageId) {
2624
+ return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);
2625
+ }
2626
+ getRunIdsForThread(agentId, threadId) {
2627
+ return this.stateManager.getRunIdsForThread(agentId, threadId);
2628
+ }
2629
+ subscribeAgentToStateManager(agent) {
2630
+ this.stateManager.subscribeToAgent(agent, { isClone: true });
2631
+ }
2632
+ /**
2633
+ * Internal method used by RunHandler to build frontend tools
2634
+ */
2635
+ buildFrontendTools(agentId) {
2636
+ return this.runHandler.buildFrontendTools(agentId);
2637
+ }
2638
+ /**
2639
+ * Called before each follow-up agent run (after tool execution).
2640
+ *
2641
+ * When a frontend tool handler calls framework state setters (e.g. React's
2642
+ * setState), those updates are batched and deferred — they do not take effect
2643
+ * until the framework's scheduler runs (React uses MessageChannel).
2644
+ * useAgentContext registers context via useLayoutEffect, which runs
2645
+ * synchronously after React commits that deferred batch.
2646
+ *
2647
+ * Without yielding here, the follow-up runAgent reads the context store
2648
+ * synchronously while the deferred updates are still pending, producing stale
2649
+ * context for the next agent turn.
2650
+ *
2651
+ * Override in framework-specific subclasses to yield to the framework
2652
+ * scheduler before the follow-up run. The base implementation is a no-op
2653
+ * because non-React environments have no deferred state to flush.
2654
+ */
2655
+ async waitForPendingFrameworkUpdates() {}
2656
+ };
2657
+
2658
+ //#endregion
2659
+ //#region src/types.ts
2660
+ /**
2661
+ * Status of a tool call execution
2662
+ */
2663
+ let ToolCallStatus = /* @__PURE__ */ function(ToolCallStatus) {
2664
+ ToolCallStatus["InProgress"] = "inProgress";
2665
+ ToolCallStatus["Executing"] = "executing";
2666
+ ToolCallStatus["Complete"] = "complete";
2667
+ return ToolCallStatus;
2668
+ }({});
2669
+
2670
+ //#endregion
2671
+ //#region src/utils/markdown.ts
2672
+ function completePartialMarkdown(input) {
2673
+ let s = input;
2674
+ const fenceMatches = Array.from(s.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
2675
+ if (fenceMatches.length % 2 === 1) {
2676
+ const [, indent, fence] = fenceMatches[0];
2677
+ s += `\n${indent}${fence}`;
2678
+ }
2679
+ if (s.match(/\[([^\]]*)\]\(([^)]*)$/)) s += ")";
2680
+ const openElements = [];
2681
+ const chars = Array.from(s);
2682
+ const codeBlockRanges = [];
2683
+ const inlineCodeRanges = [];
2684
+ let tempCodeFenceCount = 0;
2685
+ let currentCodeBlockStart = -1;
2686
+ for (let i = 0; i < chars.length; i++) if (i === 0 || chars[i - 1] === "\n") {
2687
+ const lineMatch = s.substring(i).match(/^(\s*)(`{3,}|~{3,})/);
2688
+ if (lineMatch) {
2689
+ tempCodeFenceCount++;
2690
+ if (tempCodeFenceCount % 2 === 1) currentCodeBlockStart = i;
2691
+ else if (currentCodeBlockStart !== -1) {
2692
+ codeBlockRanges.push({
2693
+ start: currentCodeBlockStart,
2694
+ end: i + lineMatch[0].length
2695
+ });
2696
+ currentCodeBlockStart = -1;
2697
+ }
2698
+ i += lineMatch[0].length - 1;
2699
+ }
2700
+ }
2701
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`") {
2702
+ let backslashCount = 0;
2703
+ for (let j = i - 1; j >= 0 && chars[j] === "\\"; j--) backslashCount++;
2704
+ if (backslashCount % 2 === 0) {
2705
+ for (let j = i + 1; j < chars.length; j++) if (chars[j] === "`") {
2706
+ let closingBackslashCount = 0;
2707
+ for (let k = j - 1; k >= 0 && chars[k] === "\\"; k--) closingBackslashCount++;
2708
+ if (closingBackslashCount % 2 === 0) {
2709
+ inlineCodeRanges.push({
2710
+ start: i,
2711
+ end: j + 1
2712
+ });
2713
+ i = j;
2714
+ break;
2715
+ }
2716
+ }
2717
+ }
2718
+ }
2719
+ const isInCode = (pos) => {
2720
+ return codeBlockRanges.some((range) => pos >= range.start && pos < range.end) || inlineCodeRanges.some((range) => pos >= range.start && pos < range.end);
2721
+ };
2722
+ for (let i = 0; i < chars.length; i++) {
2723
+ const char = chars[i];
2724
+ const nextChar = chars[i + 1];
2725
+ const prevChar = chars[i - 1];
2726
+ if (isInCode(i)) continue;
2727
+ if (char === "[") {
2728
+ let isCompleteLink = false;
2729
+ let bracketDepth = 1;
2730
+ let j = i + 1;
2731
+ while (j < chars.length && bracketDepth > 0) {
2732
+ if (chars[j] === "[" && !isInCode(j)) bracketDepth++;
2733
+ if (chars[j] === "]" && !isInCode(j)) bracketDepth--;
2734
+ j++;
2735
+ }
2736
+ if (bracketDepth === 0 && chars[j] === "(") {
2737
+ let parenDepth = 1;
2738
+ j++;
2739
+ while (j < chars.length && parenDepth > 0) {
2740
+ if (chars[j] === "(" && !isInCode(j)) parenDepth++;
2741
+ if (chars[j] === ")" && !isInCode(j)) parenDepth--;
2742
+ j++;
2743
+ }
2744
+ if (parenDepth === 0) {
2745
+ isCompleteLink = true;
2746
+ i = j - 1;
2747
+ continue;
2748
+ }
2749
+ }
2750
+ if (!isCompleteLink) {
2751
+ const existingIndex = openElements.findIndex((el) => el.type === "bracket");
2752
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
2753
+ else openElements.push({
2754
+ type: "bracket",
2755
+ marker: "[",
2756
+ position: i
2757
+ });
2758
+ }
2759
+ } else if (char === "*" && nextChar === "*") {
2760
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_star");
2761
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
2762
+ else openElements.push({
2763
+ type: "bold_star",
2764
+ marker: "**",
2765
+ position: i
2766
+ });
2767
+ i++;
2768
+ } else if (char === "_" && nextChar === "_") {
2769
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_underscore");
2770
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
2771
+ else openElements.push({
2772
+ type: "bold_underscore",
2773
+ marker: "__",
2774
+ position: i
2775
+ });
2776
+ i++;
2777
+ } else if (char === "~" && nextChar === "~") {
2778
+ const existingIndex = openElements.findIndex((el) => el.type === "strike");
2779
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
2780
+ else openElements.push({
2781
+ type: "strike",
2782
+ marker: "~~",
2783
+ position: i
2784
+ });
2785
+ i++;
2786
+ } else if (char === "*" && prevChar !== "*" && nextChar !== "*") {
2787
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_star");
2788
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
2789
+ else openElements.push({
2790
+ type: "italic_star",
2791
+ marker: "*",
2792
+ position: i
2793
+ });
2794
+ } else if (char === "_" && prevChar !== "_" && nextChar !== "_") {
2795
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_underscore");
2796
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
2797
+ else openElements.push({
2798
+ type: "italic_underscore",
2799
+ marker: "_",
2800
+ position: i
2801
+ });
2802
+ }
2803
+ }
2804
+ let backtickCount = 0;
2805
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`" && !isInCode(i)) backtickCount++;
2806
+ if (backtickCount % 2 === 1) s += "`";
2807
+ openElements.sort((a, b) => b.position - a.position);
2808
+ const closers = openElements.map((el) => {
2809
+ switch (el.type) {
2810
+ case "bracket": return "]";
2811
+ case "bold_star": return "**";
2812
+ case "bold_underscore": return "__";
2813
+ case "strike": return "~~";
2814
+ case "italic_star": return "*";
2815
+ case "italic_underscore": return "_";
2816
+ default: return "";
2817
+ }
2818
+ });
2819
+ let result = s + closers.join("");
2820
+ const finalFenceMatches = Array.from(result.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
2821
+ const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;
2822
+ const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;
2823
+ let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;
2824
+ if (shouldCloseParens) {
2825
+ const lastOpenParen = result.lastIndexOf("(");
2826
+ if (lastOpenParen !== -1) {
2827
+ if ((result.substring(0, lastOpenParen).match(/`/g) || []).length % 2 === 1) shouldCloseParens = false;
2828
+ }
2829
+ }
2830
+ if (shouldCloseParens) {
2831
+ const openParens = (result.match(/\(/g) || []).length;
2832
+ const closeParens = (result.match(/\)/g) || []).length;
2833
+ if (openParens > closeParens) result += ")".repeat(openParens - closeParens);
2834
+ }
2835
+ return result;
2836
+ }
2837
+
2838
+ //#endregion
2839
+ //#region src/utils/micro-redux.ts
2840
+ const INTERNAL_ACTION_TYPES = {
2841
+ boot: "@@micro-redux/boot",
2842
+ init: "@@micro-redux/init",
2843
+ stop: "@@micro-redux/stop"
2844
+ };
2845
+ const INTERNAL_BOOT_ACTION = { type: INTERNAL_ACTION_TYPES.boot };
2846
+ /**
2847
+ * Builds a typed action creator from a type string and payload factory.
2848
+ */
2849
+ function createTypedActionCreator(type, factory) {
2850
+ const creator = ((...args) => ({
2851
+ ...factory(...args),
2852
+ type
2853
+ }));
2854
+ creator.type = type;
2855
+ creator.match = (action) => action.type === type;
2856
+ return creator;
2857
+ }
2858
+ /**
2859
+ * Declares a payload-based action config for `createActionGroup`.
2860
+ *
2861
+ * @example
2862
+ * ```ts
2863
+ * const actions = createActionGroup("User", {
2864
+ * loaded: props<{ id: string }>(),
2865
+ * });
2866
+ * ```
2867
+ */
2868
+ function props() {
2869
+ return { kind: "props" };
2870
+ }
2871
+ /**
2872
+ * Declares a no-payload action config for `createActionGroup`.
2873
+ *
2874
+ * @example
2875
+ * ```ts
2876
+ * const actions = createActionGroup("User", {
2877
+ * reset: empty(),
2878
+ * });
2879
+ * ```
2880
+ */
2881
+ function empty() {
2882
+ return { kind: "empty" };
2883
+ }
2884
+ /**
2885
+ * Creates a namespaced group of typed action creators.
2886
+ *
2887
+ * Action types are formatted as: `[Source] actionName`.
2888
+ */
2889
+ function createActionGroup(source, config) {
2890
+ const group = {};
2891
+ for (const eventName of Object.keys(config)) {
2892
+ const eventConfig = config[eventName];
2893
+ if (!eventConfig) continue;
2894
+ const actionType = `[${source}] ${eventName}`;
2895
+ if (eventConfig.kind === "props") {
2896
+ group[eventName] = createTypedActionCreator(actionType, (payload) => ({ ...payload }));
2897
+ continue;
2898
+ }
2899
+ group[eventName] = createTypedActionCreator(actionType, () => ({}));
2900
+ }
2901
+ return group;
2902
+ }
2903
+ /**
2904
+ * Registers one reducer handler for one or more action creators.
2905
+ *
2906
+ * @throws Error when called without at least one action creator and reducer.
2907
+ */
2908
+ function on(...args) {
2909
+ if (args.length < 2) throw new Error("on requires at least one action creator and one reducer");
2910
+ const reducer = args[args.length - 1];
2911
+ return {
2912
+ creators: args.slice(0, -1),
2913
+ reducer
2914
+ };
2915
+ }
2916
+ /**
2917
+ * Creates a reducer from an initial state and `on(...)` handler entries.
2918
+ *
2919
+ * Unknown action types return the current state unchanged.
2920
+ */
2921
+ function createReducer(initialState, ...entries) {
2922
+ const reducerMap = /* @__PURE__ */ new Map();
2923
+ for (const entry of entries) for (const creator of entry.creators) {
2924
+ var _reducerMap$get;
2925
+ const handlers = (_reducerMap$get = reducerMap.get(creator.type)) !== null && _reducerMap$get !== void 0 ? _reducerMap$get : [];
2926
+ handlers.push(entry.reducer);
2927
+ reducerMap.set(creator.type, handlers);
2928
+ }
2929
+ return (state, action) => {
2930
+ const currentState = state !== null && state !== void 0 ? state : initialState;
2931
+ const handlers = reducerMap.get(action.type);
2932
+ if (!handlers || handlers.length === 0) return currentState;
2933
+ let nextState = currentState;
2934
+ for (const handler of handlers) nextState = handler(nextState, action);
2935
+ return nextState;
2936
+ };
2937
+ }
2938
+ /**
2939
+ * Creates a selector that caches and reuses the last computed result
2940
+ * when all input references are unchanged.
2941
+ */
2942
+ function createSelector(...args) {
2943
+ if (args.length === 1) {
2944
+ const projector = args[0];
2945
+ let hasCached = false;
2946
+ let lastState;
2947
+ let lastResult;
2948
+ return (state) => {
2949
+ if (hasCached && state === lastState) return lastResult;
2950
+ lastState = state;
2951
+ lastResult = projector(state);
2952
+ hasCached = true;
2953
+ return lastResult;
2954
+ };
2955
+ }
2956
+ const projector = args[args.length - 1];
2957
+ const selectors = args.slice(0, -1);
2958
+ let hasCached = false;
2959
+ let lastInputs = [];
2960
+ let lastResult;
2961
+ return (state) => {
2962
+ const inputs = selectors.map((selector) => selector(state));
2963
+ if (hasCached && inputs.length === lastInputs.length && inputs.every((value, index) => value === lastInputs[index])) return lastResult;
2964
+ lastInputs = inputs;
2965
+ lastResult = projector(...inputs);
2966
+ hasCached = true;
2967
+ return lastResult;
2968
+ };
2969
+ }
2970
+ /**
2971
+ * RxJS operator that maps state emissions through a selector and suppresses
2972
+ * unchanged projected values via reference equality.
2973
+ */
2974
+ function select(selector) {
2975
+ return (source$) => source$.pipe((0, rxjs_operators.map)(selector), (0, rxjs_operators.distinctUntilChanged)());
2976
+ }
2977
+ /**
2978
+ * RxJS operator that filters an action stream by action creators and narrows
2979
+ * the output action type to the matched creator union.
2980
+ *
2981
+ * @throws Error when called without at least one action creator.
2982
+ */
2983
+ function ofType(...creators) {
2984
+ if (creators.length === 0) throw new Error("ofType requires at least one action creator");
2985
+ const actionTypes = new Set(creators.map((creator) => creator.type));
2986
+ return (source$) => {
2987
+ return source$.pipe((0, rxjs_operators.filter)((action) => {
2988
+ return actionTypes.has(action.type);
2989
+ }));
2990
+ };
2991
+ }
2992
+ /**
2993
+ * Creates an effect descriptor consumed by `createStore`.
2994
+ */
2995
+ function createEffect(factory, options = {}) {
2996
+ if (options.dispatch === false) return {
2997
+ run: factory,
2998
+ dispatch: false
2999
+ };
3000
+ return {
3001
+ run: factory,
3002
+ dispatch: true
3003
+ };
3004
+ }
3005
+ /**
3006
+ * Creates a small observable store with reducer + effects.
3007
+ *
3008
+ * Behavior:
3009
+ * - `init()` starts effects and dispatches `@@micro-redux/init`.
3010
+ * - `stop()` dispatches `@@micro-redux/stop` and unsubscribes all effects.
3011
+ * - Effect action observation is scheduled on `asapScheduler` to avoid
3012
+ * synchronous re-entrancy in the effect loop.
3013
+ * - Any effect error triggers fail-fast teardown and errors both `actions$`
3014
+ * and `state$`.
3015
+ */
3016
+ function createStore(options) {
3017
+ var _options$effects;
3018
+ const reducer = options.reducer;
3019
+ const effects = (_options$effects = options.effects) !== null && _options$effects !== void 0 ? _options$effects : [];
3020
+ let hasFatalError = false;
3021
+ let isRunning = false;
3022
+ let effectSubscriptions = new rxjs.Subscription();
3023
+ let currentState = reducer(void 0, INTERNAL_BOOT_ACTION);
3024
+ const stateSubject = new rxjs.BehaviorSubject(currentState);
3025
+ const actionsSubject = new rxjs.Subject();
3026
+ const dispatchInternal = (action) => {
3027
+ if (hasFatalError) throw new Error("Store is in a failed state due to an effect error");
3028
+ currentState = reducer(currentState, action);
3029
+ stateSubject.next(currentState);
3030
+ actionsSubject.next(action);
3031
+ };
3032
+ const failFast = (error) => {
3033
+ if (hasFatalError) return;
3034
+ hasFatalError = true;
3035
+ isRunning = false;
3036
+ effectSubscriptions.unsubscribe();
3037
+ effectSubscriptions = new rxjs.Subscription();
3038
+ actionsSubject.error(error);
3039
+ stateSubject.error(error);
3040
+ };
3041
+ const startEffects = () => {
3042
+ for (const effect of effects) {
3043
+ const scheduledActions$ = actionsSubject.asObservable().pipe((0, rxjs_operators.observeOn)(rxjs.asapScheduler));
3044
+ const state$ = stateSubject.asObservable();
3045
+ if (effect.dispatch) {
3046
+ const subscription = effect.run(scheduledActions$, state$).subscribe({
3047
+ next: (effectAction) => {
3048
+ if (hasFatalError) return;
3049
+ dispatchInternal(effectAction);
3050
+ },
3051
+ error: (error) => {
3052
+ failFast(error);
3053
+ }
3054
+ });
3055
+ effectSubscriptions.add(subscription);
3056
+ continue;
3057
+ }
3058
+ const subscription = effect.run(scheduledActions$, state$).subscribe({ error: (error) => {
3059
+ failFast(error);
3060
+ } });
3061
+ effectSubscriptions.add(subscription);
3062
+ }
3063
+ };
3064
+ return {
3065
+ dispatch(action) {
3066
+ dispatchInternal(action);
3067
+ },
3068
+ getState() {
3069
+ return currentState;
3070
+ },
3071
+ get state$() {
3072
+ return stateSubject.asObservable();
3073
+ },
3074
+ get actions$() {
3075
+ return actionsSubject.asObservable();
3076
+ },
3077
+ select(selector) {
3078
+ return stateSubject.asObservable().pipe(select(selector));
3079
+ },
3080
+ init() {
3081
+ if (hasFatalError || isRunning) return;
3082
+ isRunning = true;
3083
+ startEffects();
3084
+ if (hasFatalError) return;
3085
+ dispatchInternal({ type: INTERNAL_ACTION_TYPES.init });
3086
+ },
3087
+ stop() {
3088
+ if (hasFatalError || !isRunning) return;
3089
+ dispatchInternal({ type: INTERNAL_ACTION_TYPES.stop });
3090
+ effectSubscriptions.unsubscribe();
3091
+ effectSubscriptions = new rxjs.Subscription();
3092
+ isRunning = false;
3093
+ }
3094
+ };
3095
+ }
3096
+
3097
+ //#endregion
3098
+ //#region src/threads.ts
3099
+ const THREADS_CHANNEL_EVENT = "thread_metadata";
3100
+ const THREAD_SUBSCRIBE_PATH = "/threads/subscribe";
3101
+ const MAX_SOCKET_RETRIES = 5;
3102
+ const REQUEST_TIMEOUT_MS = 15e3;
3103
+ const initialThreadState = {
3104
+ threads: [],
3105
+ isLoading: false,
3106
+ isFetchingNextPage: false,
3107
+ error: null,
3108
+ context: null,
3109
+ sessionId: 0,
3110
+ metadataCredentialsRequested: false,
3111
+ metadataJoinCode: null,
3112
+ nextCursor: null
3113
+ };
3114
+ const threadAdapterEvents = createActionGroup("Thread Adapter", {
3115
+ started: empty(),
3116
+ stopped: empty(),
3117
+ contextChanged: props(),
3118
+ fetchNextPageRequested: empty(),
3119
+ renameRequested: props(),
3120
+ archiveRequested: props(),
3121
+ deleteRequested: props()
3122
+ });
3123
+ const threadRestEvents = createActionGroup("Thread REST", {
3124
+ listRequested: props(),
3125
+ listSucceeded: props(),
3126
+ listFailed: props(),
3127
+ nextPageSucceeded: props(),
3128
+ nextPageFailed: props(),
3129
+ metadataCredentialsRequested: props(),
3130
+ metadataCredentialsSucceeded: props(),
3131
+ metadataCredentialsFailed: props(),
3132
+ mutationFinished: props()
3133
+ });
3134
+ const threadSocketEvents = createActionGroup("Thread Socket", {
3135
+ opened: props(),
3136
+ errored: props(),
3137
+ joinFailed: props(),
3138
+ joinTimedOut: props(),
3139
+ metadataReceived: props()
3140
+ });
3141
+ const threadDomainEvents = createActionGroup("Thread Domain", {
3142
+ threadUpserted: props(),
3143
+ threadDeleted: props()
3144
+ });
3145
+ function sortThreadsByUpdatedAt(threads) {
3146
+ return [...threads].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
3147
+ }
3148
+ function upsertThread(threads, thread) {
3149
+ const existingIndex = threads.findIndex((item) => item.id === thread.id);
3150
+ if (existingIndex === -1) return sortThreadsByUpdatedAt([...threads, thread]);
3151
+ const next = [...threads];
3152
+ next[existingIndex] = thread;
3153
+ return sortThreadsByUpdatedAt(next);
3154
+ }
3155
+ const threadReducer = createReducer(initialThreadState, on(threadAdapterEvents.contextChanged, (state, { context }) => ({
3156
+ ...state,
3157
+ context,
3158
+ sessionId: state.sessionId + 1,
3159
+ threads: [],
3160
+ isLoading: Boolean(context),
3161
+ isFetchingNextPage: false,
3162
+ error: null,
3163
+ metadataCredentialsRequested: false,
3164
+ metadataJoinCode: null,
3165
+ nextCursor: null
3166
+ })), on(threadAdapterEvents.stopped, (state) => ({
3167
+ ...state,
3168
+ threads: [],
3169
+ isLoading: false,
3170
+ isFetchingNextPage: false,
3171
+ error: null,
3172
+ metadataCredentialsRequested: false,
3173
+ metadataJoinCode: null,
3174
+ nextCursor: null
3175
+ })), on(threadRestEvents.listRequested, (state, { sessionId }) => {
3176
+ if (sessionId !== state.sessionId || !state.context) return state;
3177
+ return {
3178
+ ...state,
3179
+ isLoading: true,
3180
+ error: null
3181
+ };
3182
+ }), on(threadRestEvents.listSucceeded, (state, { sessionId, threads, joinCode, nextCursor }) => {
3183
+ if (sessionId !== state.sessionId) return state;
3184
+ return {
3185
+ ...state,
3186
+ threads: sortThreadsByUpdatedAt(threads),
3187
+ isLoading: false,
3188
+ error: null,
3189
+ metadataJoinCode: joinCode,
3190
+ nextCursor
3191
+ };
3192
+ }), on(threadRestEvents.listFailed, (state, { sessionId, error }) => {
3193
+ if (sessionId !== state.sessionId) return state;
3194
+ return {
3195
+ ...state,
3196
+ isLoading: false,
3197
+ error
3198
+ };
3199
+ }), on(threadRestEvents.nextPageSucceeded, (state, { sessionId, threads, nextCursor }) => {
3200
+ if (sessionId !== state.sessionId) return state;
3201
+ let merged = state.threads;
3202
+ for (const thread of threads) merged = upsertThread(merged, thread);
3203
+ return {
3204
+ ...state,
3205
+ threads: merged,
3206
+ isFetchingNextPage: false,
3207
+ nextCursor
3208
+ };
3209
+ }), on(threadRestEvents.nextPageFailed, (state, { sessionId, error }) => {
3210
+ if (sessionId !== state.sessionId) return state;
3211
+ return {
3212
+ ...state,
3213
+ isFetchingNextPage: false,
3214
+ error
3215
+ };
3216
+ }), on(threadRestEvents.metadataCredentialsFailed, (state, { sessionId, error }) => {
3217
+ if (sessionId !== state.sessionId) return state;
3218
+ return {
3219
+ ...state,
3220
+ error
3221
+ };
3222
+ }), on(threadRestEvents.metadataCredentialsRequested, (state, { sessionId }) => {
3223
+ if (sessionId !== state.sessionId) return state;
3224
+ return {
3225
+ ...state,
3226
+ metadataCredentialsRequested: true
3227
+ };
3228
+ }), on(threadAdapterEvents.fetchNextPageRequested, (state) => {
3229
+ if (!state.nextCursor || state.isFetchingNextPage) return state;
3230
+ return {
3231
+ ...state,
3232
+ isFetchingNextPage: true
3233
+ };
3234
+ }), on(threadRestEvents.mutationFinished, (state, { outcome }) => ({
3235
+ ...state,
3236
+ error: outcome.ok ? state.error : outcome.error
3237
+ })), on(threadDomainEvents.threadUpserted, (state, { sessionId, thread }) => {
3238
+ if (sessionId !== state.sessionId) return state;
3239
+ return {
3240
+ ...state,
3241
+ threads: upsertThread(state.threads, thread)
3242
+ };
3243
+ }), on(threadDomainEvents.threadDeleted, (state, { sessionId, threadId }) => {
3244
+ if (sessionId !== state.sessionId) return state;
3245
+ return {
3246
+ ...state,
3247
+ threads: state.threads.filter((thread) => thread.id !== threadId)
3248
+ };
3249
+ }));
3250
+ const selectThreads = createSelector((state) => state.threads);
3251
+ const selectThreadsIsLoading = createSelector((state) => state.isLoading);
3252
+ const selectThreadsError = createSelector((state) => state.error);
3253
+ const selectHasNextPage = createSelector((state) => state.nextCursor != null);
3254
+ const selectIsFetchingNextPage = createSelector((state) => state.isFetchingNextPage);
3255
+ let threadRequestId = 0;
3256
+ function createThreadRequestId() {
3257
+ threadRequestId += 1;
3258
+ return `thread-request-${threadRequestId}`;
3259
+ }
3260
+ function createThreadFetchObservable(environment, context, sessionId) {
3261
+ return (0, rxjs.defer)(() => {
3262
+ const params = { agentId: context.agentId };
3263
+ if (context.includeArchived) params.includeArchived = "true";
3264
+ if (context.limit != null) params.limit = String(context.limit);
3265
+ const qs = new URLSearchParams(params);
3266
+ return (0, rxjs_fetch.fromFetch)(`${context.runtimeUrl}/threads?${qs.toString()}`, {
3267
+ selector: (response) => {
3268
+ if (!response.ok) throw new Error(`Failed to fetch threads: ${response.status}`);
3269
+ return response.json();
3270
+ },
3271
+ fetch: environment.fetch,
3272
+ method: "GET",
3273
+ headers: { ...context.headers }
3274
+ }).pipe((0, rxjs_operators.timeout)({
3275
+ first: REQUEST_TIMEOUT_MS,
3276
+ with: () => {
3277
+ throw new Error("Request timed out");
3278
+ }
3279
+ }), (0, rxjs_operators.map)((data) => {
3280
+ var _data$nextCursor;
3281
+ return threadRestEvents.listSucceeded({
3282
+ sessionId,
3283
+ threads: data.threads,
3284
+ joinCode: typeof data.joinCode === "string" && data.joinCode.length > 0 ? data.joinCode : null,
3285
+ nextCursor: (_data$nextCursor = data.nextCursor) !== null && _data$nextCursor !== void 0 ? _data$nextCursor : null
3286
+ });
3287
+ }), (0, rxjs_operators.catchError)((error) => {
3288
+ return (0, rxjs.of)(threadRestEvents.listFailed({
3289
+ sessionId,
3290
+ error: error instanceof Error ? error : new Error(String(error))
3291
+ }));
3292
+ }));
3293
+ });
3294
+ }
3295
+ function createThreadMetadataCredentialsObservable(environment, context, sessionId) {
3296
+ return (0, rxjs.defer)(() => {
3297
+ return (0, rxjs_fetch.fromFetch)(`${context.runtimeUrl}${THREAD_SUBSCRIBE_PATH}`, {
3298
+ selector: async (response) => {
3299
+ if (!response.ok) throw new Error(`Failed to fetch thread metadata credentials: ${response.status}`);
3300
+ return response.json();
3301
+ },
3302
+ fetch: environment.fetch,
3303
+ method: "POST",
3304
+ headers: {
3305
+ ...context.headers,
3306
+ "Content-Type": "application/json"
3307
+ },
3308
+ body: JSON.stringify({})
3309
+ }).pipe((0, rxjs_operators.timeout)({
3310
+ first: REQUEST_TIMEOUT_MS,
3311
+ with: () => {
3312
+ throw new Error("Request timed out");
3313
+ }
3314
+ }), (0, rxjs_operators.map)((data) => {
3315
+ if (typeof data.joinToken !== "string" || data.joinToken.length === 0) throw new Error("missing joinToken");
3316
+ return threadRestEvents.metadataCredentialsSucceeded({
3317
+ sessionId,
3318
+ joinToken: data.joinToken
3319
+ });
3320
+ }), (0, rxjs_operators.catchError)((error) => {
3321
+ return (0, rxjs.of)(threadRestEvents.metadataCredentialsFailed({
3322
+ sessionId,
3323
+ error: error instanceof Error ? error : new Error(String(error))
3324
+ }));
3325
+ }));
3326
+ });
3327
+ }
3328
+ function createThreadMutationObservable(environment, context, request) {
3329
+ return (0, rxjs.defer)(() => {
3330
+ return (0, rxjs_fetch.fromFetch)(`${context.runtimeUrl}${request.path}`, {
3331
+ selector: async (response) => {
3332
+ if (!response.ok) throw new Error(`Request failed: ${response.status}`);
3333
+ return null;
3334
+ },
3335
+ fetch: environment.fetch,
3336
+ method: request.method,
3337
+ headers: {
3338
+ ...context.headers,
3339
+ "Content-Type": "application/json"
3340
+ },
3341
+ body: JSON.stringify(request.body)
3342
+ }).pipe((0, rxjs_operators.map)(() => threadRestEvents.mutationFinished({ outcome: {
3343
+ requestId: request.requestId,
3344
+ ok: true
3345
+ } })), (0, rxjs_operators.catchError)((error) => {
3346
+ return (0, rxjs.of)(threadRestEvents.mutationFinished({ outcome: {
3347
+ requestId: request.requestId,
3348
+ ok: false,
3349
+ error: error instanceof Error ? error : new Error(String(error))
3350
+ } }));
3351
+ }));
3352
+ });
3353
+ }
3354
+ function createThreadStore(environment) {
3355
+ const store = createStore({
3356
+ reducer: threadReducer,
3357
+ effects: [
3358
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.contextChanged), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([, state]) => Boolean(state.context)), (0, rxjs_operators.map)(([, state]) => threadRestEvents.listRequested({ sessionId: state.sessionId })))),
3359
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.listRequested), (0, rxjs_operators.switchMap)((action) => state$.pipe((0, rxjs_operators.map)((state) => state.context), (0, rxjs_operators.filter)((context) => Boolean(context)), (0, rxjs_operators.take)(1), (0, rxjs_operators.map)((context) => ({
3360
+ action,
3361
+ context
3362
+ })), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createThreadFetchObservable(environment, context, currentAction.sessionId)))))),
3363
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.listSucceeded), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => {
3364
+ var _state$context;
3365
+ return action.sessionId === state.sessionId && !state.metadataCredentialsRequested && Boolean((_state$context = state.context) === null || _state$context === void 0 ? void 0 : _state$context.wsUrl) && Boolean(state.metadataJoinCode);
3366
+ }), (0, rxjs_operators.map)(([action]) => threadRestEvents.metadataCredentialsRequested({ sessionId: action.sessionId })))),
3367
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.metadataCredentialsRequested), (0, rxjs_operators.switchMap)((action) => state$.pipe((0, rxjs_operators.map)((state) => state.context), (0, rxjs_operators.filter)((context) => Boolean(context)), (0, rxjs_operators.take)(1), (0, rxjs_operators.map)((context) => ({
3368
+ action,
3369
+ context
3370
+ })), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped))), (0, rxjs_operators.switchMap)(({ action: currentAction, context }) => createThreadMetadataCredentialsObservable(environment, context, currentAction.sessionId)))))),
3371
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadRestEvents.metadataCredentialsSucceeded), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => {
3372
+ var _state$context2;
3373
+ return action.sessionId === state.sessionId && Boolean((_state$context2 = state.context) === null || _state$context2 === void 0 ? void 0 : _state$context2.wsUrl);
3374
+ }), (0, rxjs_operators.switchMap)(([action, state]) => {
3375
+ const context = state.context;
3376
+ const joinToken = action.joinToken;
3377
+ const joinCode = state.metadataJoinCode;
3378
+ const shutdown$ = actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped));
3379
+ return (0, rxjs.defer)(() => {
3380
+ const socket$ = ɵphoenixSocket$({
3381
+ url: context.wsUrl,
3382
+ options: {
3383
+ params: { join_token: joinToken },
3384
+ reconnectAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(100, 1e4),
3385
+ rejoinAfterMs: (0, _copilotkit_shared.phoenixExponentialBackoff)(1e3, 3e4)
3386
+ }
3387
+ }).pipe((0, rxjs_operators.shareReplay)({
3388
+ bufferSize: 1,
3389
+ refCount: true
3390
+ }));
3391
+ const channel$ = ɵphoenixChannel$({
3392
+ socket$,
3393
+ topic: `user_meta:${joinCode}`
3394
+ }).pipe((0, rxjs_operators.shareReplay)({
3395
+ bufferSize: 1,
3396
+ refCount: true
3397
+ }));
3398
+ const socketSignals$ = ɵobservePhoenixSocketSignals$(socket$).pipe((0, rxjs_operators.share)());
3399
+ const fatalSocketShutdown$ = ɵobservePhoenixSocketHealth$(socketSignals$, MAX_SOCKET_RETRIES).pipe((0, rxjs_operators.catchError)(() => {
3400
+ console.warn(`[threads] WebSocket failed after ${MAX_SOCKET_RETRIES} attempts, giving up`);
3401
+ return (0, rxjs.of)(void 0);
3402
+ }), (0, rxjs_operators.share)());
3403
+ return (0, rxjs.merge)(socketSignals$.pipe((0, rxjs_operators.map)((signal) => signal.type === "open" ? threadSocketEvents.opened({ sessionId: action.sessionId }) : threadSocketEvents.errored({ sessionId: action.sessionId }))), channel$.pipe((0, rxjs_operators.switchMap)(({ channel }) => ɵobservePhoenixEvent$(channel, THREADS_CHANNEL_EVENT)), (0, rxjs_operators.map)((payload) => threadSocketEvents.metadataReceived({
3404
+ sessionId: action.sessionId,
3405
+ payload
3406
+ }))), ɵobservePhoenixJoinOutcome$(channel$).pipe((0, rxjs_operators.filter)((outcome) => outcome.type !== "joined"), (0, rxjs_operators.map)((outcome) => outcome.type === "timeout" ? threadSocketEvents.joinTimedOut({ sessionId: action.sessionId }) : threadSocketEvents.joinFailed({ sessionId: action.sessionId })))).pipe((0, rxjs_operators.takeUntil)((0, rxjs.merge)(shutdown$, fatalSocketShutdown$)));
3407
+ });
3408
+ }))),
3409
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadSocketEvents.metadataReceived), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([action, state]) => action.sessionId === state.sessionId), (0, rxjs_operators.map)(([action, state]) => {
3410
+ var _state$context3;
3411
+ if (action.payload.operation === "deleted") return threadDomainEvents.threadDeleted({
3412
+ sessionId: action.sessionId,
3413
+ threadId: action.payload.deleted.id
3414
+ });
3415
+ if (action.payload.operation === "archived" && !((_state$context3 = state.context) === null || _state$context3 === void 0 ? void 0 : _state$context3.includeArchived)) return threadDomainEvents.threadDeleted({
3416
+ sessionId: action.sessionId,
3417
+ threadId: action.payload.threadId
3418
+ });
3419
+ return threadDomainEvents.threadUpserted({
3420
+ sessionId: action.sessionId,
3421
+ thread: action.payload.thread
3422
+ });
3423
+ }))),
3424
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.fetchNextPageRequested), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.filter)(([, state]) => Boolean(state.context) && Boolean(state.nextCursor)), (0, rxjs_operators.switchMap)(([, state]) => {
3425
+ const context = state.context;
3426
+ const params = {
3427
+ agentId: context.agentId,
3428
+ cursor: state.nextCursor
3429
+ };
3430
+ if (context.includeArchived) params.includeArchived = "true";
3431
+ if (context.limit != null) params.limit = String(context.limit);
3432
+ return (0, rxjs_fetch.fromFetch)(`${context.runtimeUrl}/threads?${new URLSearchParams(params).toString()}`, {
3433
+ selector: (response) => {
3434
+ if (!response.ok) throw new Error(`Failed to fetch next page: ${response.status}`);
3435
+ return response.json();
3436
+ },
3437
+ fetch: environment.fetch,
3438
+ method: "GET",
3439
+ headers: { ...context.headers }
3440
+ }).pipe((0, rxjs_operators.timeout)({
3441
+ first: REQUEST_TIMEOUT_MS,
3442
+ with: () => {
3443
+ throw new Error("Request timed out");
3444
+ }
3445
+ }), (0, rxjs_operators.map)((data) => {
3446
+ var _data$nextCursor2;
3447
+ return threadRestEvents.nextPageSucceeded({
3448
+ sessionId: state.sessionId,
3449
+ threads: data.threads,
3450
+ nextCursor: (_data$nextCursor2 = data.nextCursor) !== null && _data$nextCursor2 !== void 0 ? _data$nextCursor2 : null
3451
+ });
3452
+ }), (0, rxjs_operators.catchError)((error) => (0, rxjs.of)(threadRestEvents.nextPageFailed({
3453
+ sessionId: state.sessionId,
3454
+ error: error instanceof Error ? error : new Error(String(error))
3455
+ }))), (0, rxjs_operators.takeUntil)(actions$.pipe(ofType(threadAdapterEvents.contextChanged, threadAdapterEvents.stopped))));
3456
+ }))),
3457
+ createEffect((actions$, state$) => actions$.pipe(ofType(threadAdapterEvents.renameRequested, threadAdapterEvents.archiveRequested, threadAdapterEvents.deleteRequested), (0, rxjs_operators.withLatestFrom)(state$), (0, rxjs_operators.mergeMap)(([action, state]) => {
3458
+ const context = state.context;
3459
+ if (!(context === null || context === void 0 ? void 0 : context.runtimeUrl)) {
3460
+ const requestId = action.requestId;
3461
+ return (0, rxjs.of)(threadRestEvents.mutationFinished({ outcome: {
3462
+ requestId,
3463
+ ok: false,
3464
+ error: /* @__PURE__ */ new Error("Runtime URL is not configured")
3465
+ } }));
3466
+ }
3467
+ const commonBody = { agentId: context.agentId };
3468
+ if (threadAdapterEvents.renameRequested.match(action)) return createThreadMutationObservable(environment, context, {
3469
+ requestId: action.requestId,
3470
+ method: "PATCH",
3471
+ path: `/threads/${encodeURIComponent(action.threadId)}`,
3472
+ body: {
3473
+ ...commonBody,
3474
+ name: action.name
3475
+ }
3476
+ });
3477
+ if (threadAdapterEvents.archiveRequested.match(action)) return createThreadMutationObservable(environment, context, {
3478
+ requestId: action.requestId,
3479
+ method: "POST",
3480
+ path: `/threads/${encodeURIComponent(action.threadId)}/archive`,
3481
+ body: commonBody
3482
+ });
3483
+ return createThreadMutationObservable(environment, context, {
3484
+ requestId: action.requestId,
3485
+ method: "DELETE",
3486
+ path: `/threads/${encodeURIComponent(action.threadId)}`,
3487
+ body: commonBody
3488
+ });
3489
+ })))
3490
+ ]
3491
+ });
3492
+ function trackMutation(dispatchAction) {
3493
+ const resultPromise = (0, rxjs.firstValueFrom)((0, rxjs.merge)(store.actions$.pipe(ofType(threadRestEvents.mutationFinished), (0, rxjs_operators.filter)((action) => action.outcome.requestId === dispatchAction.requestId), (0, rxjs_operators.map)((action) => action.outcome)), store.actions$.pipe(ofType(threadAdapterEvents.stopped), (0, rxjs_operators.map)(() => ({
3494
+ requestId: dispatchAction.requestId,
3495
+ ok: false,
3496
+ error: /* @__PURE__ */ new Error("Thread store stopped before mutation completed")
3497
+ })))).pipe((0, rxjs_operators.take)(1))).then((outcome) => {
3498
+ if (outcome.ok) return;
3499
+ throw outcome.error;
3500
+ });
3501
+ store.dispatch(dispatchAction);
3502
+ return resultPromise;
3503
+ }
3504
+ return {
3505
+ start() {
3506
+ store.init();
3507
+ store.dispatch(threadAdapterEvents.started());
3508
+ },
3509
+ stop() {
3510
+ store.dispatch(threadAdapterEvents.stopped());
3511
+ store.stop();
3512
+ },
3513
+ setContext(context) {
3514
+ store.dispatch(threadAdapterEvents.contextChanged({ context }));
3515
+ },
3516
+ fetchNextPage() {
3517
+ store.dispatch(threadAdapterEvents.fetchNextPageRequested());
3518
+ },
3519
+ renameThread(threadId, name) {
3520
+ return trackMutation(threadAdapterEvents.renameRequested({
3521
+ requestId: createThreadRequestId(),
3522
+ threadId,
3523
+ name
3524
+ }));
3525
+ },
3526
+ archiveThread(threadId) {
3527
+ return trackMutation(threadAdapterEvents.archiveRequested({
3528
+ requestId: createThreadRequestId(),
3529
+ threadId
3530
+ }));
3531
+ },
3532
+ deleteThread(threadId) {
3533
+ return trackMutation(threadAdapterEvents.deleteRequested({
3534
+ requestId: createThreadRequestId(),
3535
+ threadId
3536
+ }));
3537
+ },
3538
+ getState() {
3539
+ return store.getState();
3540
+ },
3541
+ select: store.select.bind(store)
3542
+ };
3543
+ }
3544
+ const ɵthreadAdapterEvents = threadAdapterEvents;
3545
+ const ɵselectThreads = selectThreads;
3546
+ const ɵselectThreadsIsLoading = selectThreadsIsLoading;
3547
+ const ɵselectThreadsError = selectThreadsError;
3548
+ const ɵselectHasNextPage = selectHasNextPage;
3549
+ const ɵselectIsFetchingNextPage = selectIsFetchingNextPage;
3550
+
3551
+ //#endregion
3552
+ exports.AgentRegistry = AgentRegistry;
3553
+ exports.AgentThreadLockedError = AgentThreadLockedError;
3554
+ exports.ContextStore = ContextStore;
3555
+ exports.CopilotKitCore = CopilotKitCore;
3556
+ exports.CopilotKitCoreErrorCode = CopilotKitCoreErrorCode;
3557
+ exports.CopilotKitCoreRuntimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus;
3558
+ exports.IntelligenceAgent = IntelligenceAgent;
3559
+ exports.ProxiedCopilotRuntimeAgent = ProxiedCopilotRuntimeAgent;
3560
+ exports.RunHandler = RunHandler;
3561
+ exports.StateManager = StateManager;
3562
+ exports.SuggestionEngine = SuggestionEngine;
3563
+ exports.ToolCallStatus = ToolCallStatus;
3564
+ exports.completePartialMarkdown = completePartialMarkdown;
3565
+ exports.createActionGroup = createActionGroup;
3566
+ exports.createEffect = createEffect;
3567
+ exports.createReducer = createReducer;
3568
+ exports.createSelector = createSelector;
3569
+ exports.createStore = createStore;
3570
+ exports.empty = empty;
3571
+ exports.ensureObjectArgs = ensureObjectArgs;
3572
+ exports.ofType = ofType;
3573
+ exports.on = on;
3574
+ exports.parseToolArguments = parseToolArguments;
3575
+ exports.props = props;
3576
+ exports.select = select;
3577
+ exports.ɵcreateThreadStore = createThreadStore;
3578
+ exports.ɵjoinPhoenixChannel$ = ɵjoinPhoenixChannel$;
3579
+ exports.ɵobservePhoenixEvent$ = ɵobservePhoenixEvent$;
3580
+ exports.ɵobservePhoenixJoinOutcome$ = ɵobservePhoenixJoinOutcome$;
3581
+ exports.ɵobservePhoenixSocketHealth$ = ɵobservePhoenixSocketHealth$;
3582
+ exports.ɵobservePhoenixSocketSignals$ = ɵobservePhoenixSocketSignals$;
3583
+ exports.ɵphoenixChannel$ = ɵphoenixChannel$;
3584
+ exports.ɵphoenixSocket$ = ɵphoenixSocket$;
3585
+ exports.ɵselectHasNextPage = ɵselectHasNextPage;
3586
+ exports.ɵselectIsFetchingNextPage = ɵselectIsFetchingNextPage;
3587
+ exports.ɵselectThreads = ɵselectThreads;
3588
+ exports.ɵselectThreadsError = ɵselectThreadsError;
3589
+ exports.ɵselectThreadsIsLoading = ɵselectThreadsIsLoading;
3590
+ exports.ɵthreadAdapterEvents = ɵthreadAdapterEvents;
3591
+ });
3592
+ //# sourceMappingURL=index.umd.js.map