@copilotkitnext/core 1.51.5-next.0 → 1.51.5-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1729 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let _ag_ui_client = require("@ag-ui/client");
3
+ let _copilotkitnext_shared = require("@copilotkitnext/shared");
4
+ let rxjs = require("rxjs");
5
+ let rxjs_operators = require("rxjs/operators");
6
+ let zod_to_json_schema = require("zod-to-json-schema");
7
+
8
+ //#region src/agent.ts
9
+ /**
10
+ * Check if an error is a ZodError (validation error).
11
+ * These can occur when the SSE stream is aborted/truncated mid-event.
12
+ */
13
+ function isZodError(error) {
14
+ return error !== null && typeof error === "object" && "name" in error && error.name === "ZodError";
15
+ }
16
+ /**
17
+ * Wrap an Observable to catch and suppress ZodErrors that occur during stream abort.
18
+ * These errors are expected when the connection is cancelled mid-stream.
19
+ */
20
+ function withAbortErrorHandling(observable) {
21
+ return observable.pipe((0, rxjs_operators.catchError)((error) => {
22
+ if (isZodError(error)) return rxjs.EMPTY;
23
+ throw error;
24
+ }));
25
+ }
26
+ var ProxiedCopilotRuntimeAgent = class extends _ag_ui_client.HttpAgent {
27
+ runtimeUrl;
28
+ credentials;
29
+ transport;
30
+ singleEndpointUrl;
31
+ constructor(config) {
32
+ const normalizedRuntimeUrl = config.runtimeUrl ? config.runtimeUrl.replace(/\/$/, "") : void 0;
33
+ const transport = config.transport ?? "rest";
34
+ const runUrl = transport === "single" ? normalizedRuntimeUrl ?? config.runtimeUrl ?? "" : `${normalizedRuntimeUrl ?? config.runtimeUrl}/agent/${encodeURIComponent(config.agentId ?? "")}/run`;
35
+ if (!runUrl) throw new Error("ProxiedCopilotRuntimeAgent requires a runtimeUrl when transport is set to 'single'.");
36
+ super({
37
+ ...config,
38
+ url: runUrl
39
+ });
40
+ this.runtimeUrl = normalizedRuntimeUrl ?? config.runtimeUrl;
41
+ this.credentials = config.credentials;
42
+ this.transport = transport;
43
+ if (this.transport === "single") this.singleEndpointUrl = this.runtimeUrl;
44
+ }
45
+ abortRun() {
46
+ if (!this.agentId || !this.threadId) return;
47
+ if (typeof fetch === "undefined") return;
48
+ if (this.transport === "single") {
49
+ if (!this.singleEndpointUrl) return;
50
+ const headers = new Headers({
51
+ ...this.headers,
52
+ "Content-Type": "application/json"
53
+ });
54
+ fetch(this.singleEndpointUrl, {
55
+ method: "POST",
56
+ headers,
57
+ body: JSON.stringify({
58
+ method: "agent/stop",
59
+ params: {
60
+ agentId: this.agentId,
61
+ threadId: this.threadId
62
+ }
63
+ }),
64
+ ...this.credentials ? { credentials: this.credentials } : {}
65
+ }).catch((error) => {
66
+ console.error("ProxiedCopilotRuntimeAgent: stop request failed", error);
67
+ });
68
+ return;
69
+ }
70
+ if (!this.runtimeUrl) return;
71
+ const stopPath = `${this.runtimeUrl}/agent/${encodeURIComponent(this.agentId)}/stop/${encodeURIComponent(this.threadId)}`;
72
+ const origin = typeof window !== "undefined" && window.location ? window.location.origin : "http://localhost";
73
+ const base = new URL(this.runtimeUrl, origin);
74
+ const stopUrl = new URL(stopPath, base);
75
+ fetch(stopUrl.toString(), {
76
+ method: "POST",
77
+ headers: {
78
+ "Content-Type": "application/json",
79
+ ...this.headers
80
+ },
81
+ ...this.credentials ? { credentials: this.credentials } : {}
82
+ }).catch((error) => {
83
+ console.error("ProxiedCopilotRuntimeAgent: stop request failed", error);
84
+ });
85
+ }
86
+ connect(input) {
87
+ if (this.transport === "single") {
88
+ if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
89
+ const requestInit = this.createSingleRouteRequestInit(input, "agent/connect", { agentId: this.agentId });
90
+ return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(this.singleEndpointUrl, requestInit)));
91
+ }
92
+ return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(`${this.runtimeUrl}/agent/${this.agentId}/connect`, this.requestInit(input))));
93
+ }
94
+ run(input) {
95
+ if (this.transport === "single") {
96
+ if (!this.singleEndpointUrl) throw new Error("Single endpoint transport requires a runtimeUrl");
97
+ const requestInit = this.createSingleRouteRequestInit(input, "agent/run", { agentId: this.agentId });
98
+ return withAbortErrorHandling((0, _ag_ui_client.transformHttpEventStream)((0, _ag_ui_client.runHttpRequest)(this.singleEndpointUrl, requestInit)));
99
+ }
100
+ return withAbortErrorHandling(super.run(input));
101
+ }
102
+ clone() {
103
+ const cloned = super.clone();
104
+ cloned.runtimeUrl = this.runtimeUrl;
105
+ cloned.credentials = this.credentials;
106
+ cloned.transport = this.transport;
107
+ cloned.singleEndpointUrl = this.singleEndpointUrl;
108
+ return cloned;
109
+ }
110
+ createSingleRouteRequestInit(input, method, params) {
111
+ if (!this.agentId) throw new Error("ProxiedCopilotRuntimeAgent requires agentId to make runtime requests");
112
+ const baseInit = super.requestInit(input);
113
+ const headers = new Headers(baseInit.headers ?? {});
114
+ headers.set("Content-Type", "application/json");
115
+ headers.set("Accept", headers.get("Accept") ?? "text/event-stream");
116
+ let originalBody = void 0;
117
+ if (typeof baseInit.body === "string") try {
118
+ originalBody = JSON.parse(baseInit.body);
119
+ } catch (error) {
120
+ console.warn("ProxiedCopilotRuntimeAgent: failed to parse request body for single route transport", error);
121
+ originalBody = void 0;
122
+ }
123
+ const envelope = { method };
124
+ if (params && Object.keys(params).length > 0) envelope.params = params;
125
+ if (originalBody !== void 0) envelope.body = originalBody;
126
+ return {
127
+ ...baseInit,
128
+ headers,
129
+ body: JSON.stringify(envelope),
130
+ ...this.credentials ? { credentials: this.credentials } : {}
131
+ };
132
+ }
133
+ };
134
+
135
+ //#endregion
136
+ //#region src/core/agent-registry.ts
137
+ /**
138
+ * Manages agent registration, lifecycle, and runtime connectivity for CopilotKitCore.
139
+ * Handles both local development agents and remote runtime agents.
140
+ */
141
+ var AgentRegistry = class {
142
+ _agents = {};
143
+ localAgents = {};
144
+ remoteAgents = {};
145
+ _runtimeUrl;
146
+ _runtimeVersion;
147
+ _runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Disconnected;
148
+ _runtimeTransport = "rest";
149
+ _audioFileTranscriptionEnabled = false;
150
+ constructor(core) {
151
+ this.core = core;
152
+ }
153
+ /**
154
+ * Get all agents as a readonly record
155
+ */
156
+ get agents() {
157
+ return this._agents;
158
+ }
159
+ get runtimeUrl() {
160
+ return this._runtimeUrl;
161
+ }
162
+ get runtimeVersion() {
163
+ return this._runtimeVersion;
164
+ }
165
+ get runtimeConnectionStatus() {
166
+ return this._runtimeConnectionStatus;
167
+ }
168
+ get runtimeTransport() {
169
+ return this._runtimeTransport;
170
+ }
171
+ get audioFileTranscriptionEnabled() {
172
+ return this._audioFileTranscriptionEnabled;
173
+ }
174
+ /**
175
+ * Initialize agents from configuration
176
+ */
177
+ initialize(agents) {
178
+ this.localAgents = this.assignAgentIds(agents);
179
+ this.applyHeadersToAgents(this.localAgents);
180
+ this._agents = this.localAgents;
181
+ }
182
+ /**
183
+ * Set the runtime URL and update connection
184
+ */
185
+ setRuntimeUrl(runtimeUrl) {
186
+ const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
187
+ if (this._runtimeUrl === normalizedRuntimeUrl) return;
188
+ this._runtimeUrl = normalizedRuntimeUrl;
189
+ this.updateRuntimeConnection();
190
+ }
191
+ setRuntimeTransport(runtimeTransport) {
192
+ if (this._runtimeTransport === runtimeTransport) return;
193
+ this._runtimeTransport = runtimeTransport;
194
+ this.updateRuntimeConnection();
195
+ }
196
+ /**
197
+ * Set all agents at once (for development use)
198
+ */
199
+ setAgents__unsafe_dev_only(agents) {
200
+ Object.entries(agents).forEach(([id, agent]) => {
201
+ if (agent) this.validateAndAssignAgentId(id, agent);
202
+ });
203
+ this.localAgents = agents;
204
+ this._agents = {
205
+ ...this.localAgents,
206
+ ...this.remoteAgents
207
+ };
208
+ this.applyHeadersToAgents(this._agents);
209
+ this.notifyAgentsChanged();
210
+ }
211
+ /**
212
+ * Add a single agent (for development use)
213
+ */
214
+ addAgent__unsafe_dev_only({ id, agent }) {
215
+ this.validateAndAssignAgentId(id, agent);
216
+ this.localAgents[id] = agent;
217
+ this.applyHeadersToAgent(agent);
218
+ this._agents = {
219
+ ...this.localAgents,
220
+ ...this.remoteAgents
221
+ };
222
+ this.notifyAgentsChanged();
223
+ }
224
+ /**
225
+ * Remove an agent by ID (for development use)
226
+ */
227
+ removeAgent__unsafe_dev_only(id) {
228
+ delete this.localAgents[id];
229
+ this._agents = {
230
+ ...this.localAgents,
231
+ ...this.remoteAgents
232
+ };
233
+ this.notifyAgentsChanged();
234
+ }
235
+ /**
236
+ * Get an agent by ID
237
+ */
238
+ getAgent(id) {
239
+ if (id in this._agents) return this._agents[id];
240
+ if (this.runtimeUrl !== void 0 && (this.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Disconnected || this.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connecting)) return;
241
+ console.warn(`Agent ${id} not found`);
242
+ }
243
+ /**
244
+ * Apply current headers to an agent
245
+ */
246
+ applyHeadersToAgent(agent) {
247
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...this.core.headers };
248
+ }
249
+ /**
250
+ * Apply current headers to all agents
251
+ */
252
+ applyHeadersToAgents(agents) {
253
+ Object.values(agents).forEach((agent) => {
254
+ this.applyHeadersToAgent(agent);
255
+ });
256
+ }
257
+ /**
258
+ * Apply current credentials to an agent
259
+ */
260
+ applyCredentialsToAgent(agent) {
261
+ if (agent instanceof ProxiedCopilotRuntimeAgent) agent.credentials = this.core.credentials;
262
+ }
263
+ /**
264
+ * Apply current credentials to all agents
265
+ */
266
+ applyCredentialsToAgents(agents) {
267
+ Object.values(agents).forEach((agent) => {
268
+ this.applyCredentialsToAgent(agent);
269
+ });
270
+ }
271
+ /**
272
+ * Update runtime connection and fetch remote agents
273
+ */
274
+ async updateRuntimeConnection() {
275
+ if (typeof window === "undefined") return;
276
+ if (!this.runtimeUrl) {
277
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Disconnected;
278
+ this._runtimeVersion = void 0;
279
+ this._audioFileTranscriptionEnabled = false;
280
+ this.remoteAgents = {};
281
+ this._agents = this.localAgents;
282
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Disconnected);
283
+ await this.notifyAgentsChanged();
284
+ return;
285
+ }
286
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Connecting;
287
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connecting);
288
+ try {
289
+ const runtimeInfoResponse = await this.fetchRuntimeInfo();
290
+ const { version, ...runtimeInfo } = runtimeInfoResponse;
291
+ const credentials = this.core.credentials;
292
+ this.remoteAgents = Object.fromEntries(Object.entries(runtimeInfo.agents).map(([id, { description }]) => {
293
+ const agent = new ProxiedCopilotRuntimeAgent({
294
+ runtimeUrl: this.runtimeUrl,
295
+ agentId: id,
296
+ description,
297
+ transport: this._runtimeTransport,
298
+ credentials
299
+ });
300
+ this.applyHeadersToAgent(agent);
301
+ return [id, agent];
302
+ }));
303
+ this._agents = {
304
+ ...this.localAgents,
305
+ ...this.remoteAgents
306
+ };
307
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Connected;
308
+ this._runtimeVersion = version;
309
+ this._audioFileTranscriptionEnabled = runtimeInfoResponse.audioFileTranscriptionEnabled ?? false;
310
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Connected);
311
+ await this.notifyAgentsChanged();
312
+ } catch (error) {
313
+ this._runtimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus.Error;
314
+ this._runtimeVersion = void 0;
315
+ this._audioFileTranscriptionEnabled = false;
316
+ this.remoteAgents = {};
317
+ this._agents = this.localAgents;
318
+ await this.notifyRuntimeStatusChanged(CopilotKitCoreRuntimeConnectionStatus.Error);
319
+ await this.notifyAgentsChanged();
320
+ const message = error instanceof Error ? error.message : JSON.stringify(error);
321
+ _copilotkitnext_shared.logger.warn(`Failed to load runtime info (${this.runtimeUrl}/info): ${message}`);
322
+ const runtimeError = error instanceof Error ? error : new Error(String(error));
323
+ await this.core.emitError({
324
+ error: runtimeError,
325
+ code: CopilotKitCoreErrorCode.RUNTIME_INFO_FETCH_FAILED,
326
+ context: { runtimeUrl: this.runtimeUrl }
327
+ });
328
+ }
329
+ }
330
+ async fetchRuntimeInfo() {
331
+ if (!this.runtimeUrl) throw new Error("Runtime URL is not set");
332
+ const baseHeaders = this.core.headers;
333
+ const credentials = this.core.credentials;
334
+ const headers = { ...baseHeaders };
335
+ if (this._runtimeTransport === "single") {
336
+ if (!headers["Content-Type"]) headers["Content-Type"] = "application/json";
337
+ const response = await fetch(this.runtimeUrl, {
338
+ method: "POST",
339
+ headers,
340
+ body: JSON.stringify({ method: "info" }),
341
+ ...credentials ? { credentials } : {}
342
+ });
343
+ if ("ok" in response && !response.ok) throw new Error(`Runtime info request failed with status ${response.status}`);
344
+ return await response.json();
345
+ }
346
+ const response = await fetch(`${this.runtimeUrl}/info`, {
347
+ headers,
348
+ ...credentials ? { credentials } : {}
349
+ });
350
+ if ("ok" in response && !response.ok) throw new Error(`Runtime info request failed with status ${response.status}`);
351
+ return await response.json();
352
+ }
353
+ /**
354
+ * Assign agent IDs to a record of agents
355
+ */
356
+ assignAgentIds(agents) {
357
+ Object.entries(agents).forEach(([id, agent]) => {
358
+ if (agent) this.validateAndAssignAgentId(id, agent);
359
+ });
360
+ return agents;
361
+ }
362
+ /**
363
+ * Validate and assign an agent ID
364
+ */
365
+ validateAndAssignAgentId(registrationId, agent) {
366
+ 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.`);
367
+ if (!agent.agentId) agent.agentId = registrationId;
368
+ }
369
+ /**
370
+ * Notify subscribers of runtime status changes
371
+ */
372
+ async notifyRuntimeStatusChanged(status) {
373
+ await this.core.notifySubscribers((subscriber) => subscriber.onRuntimeConnectionStatusChanged?.({
374
+ copilotkit: this.core,
375
+ status
376
+ }), "Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):");
377
+ }
378
+ /**
379
+ * Notify subscribers of agent changes
380
+ */
381
+ async notifyAgentsChanged() {
382
+ await this.core.notifySubscribers((subscriber) => subscriber.onAgentsChanged?.({
383
+ copilotkit: this.core,
384
+ agents: this._agents
385
+ }), "Subscriber onAgentsChanged error:");
386
+ }
387
+ };
388
+
389
+ //#endregion
390
+ //#region src/core/context-store.ts
391
+ /**
392
+ * Manages context storage and lifecycle for CopilotKitCore.
393
+ * Context represents additional information available to agents during execution.
394
+ */
395
+ var ContextStore = class {
396
+ _context = {};
397
+ constructor(core) {
398
+ this.core = core;
399
+ }
400
+ /**
401
+ * Get all context entries as a readonly record
402
+ */
403
+ get context() {
404
+ return this._context;
405
+ }
406
+ /**
407
+ * Add a new context entry
408
+ * @returns The ID of the created context entry
409
+ */
410
+ addContext({ description, value }) {
411
+ const id = (0, _copilotkitnext_shared.randomUUID)();
412
+ this._context[id] = {
413
+ description,
414
+ value
415
+ };
416
+ this.notifySubscribers();
417
+ return id;
418
+ }
419
+ /**
420
+ * Remove a context entry by ID
421
+ */
422
+ removeContext(id) {
423
+ delete this._context[id];
424
+ this.notifySubscribers();
425
+ }
426
+ /**
427
+ * Notify all subscribers of context changes
428
+ */
429
+ async notifySubscribers() {
430
+ await this.core.notifySubscribers((subscriber) => subscriber.onContextChanged?.({
431
+ copilotkit: this.core,
432
+ context: this._context
433
+ }), "Subscriber onContextChanged error:");
434
+ }
435
+ };
436
+
437
+ //#endregion
438
+ //#region src/core/suggestion-engine.ts
439
+ /**
440
+ * Manages suggestion generation, streaming, and lifecycle for CopilotKitCore.
441
+ * Handles both dynamic (AI-generated) and static suggestions.
442
+ */
443
+ var SuggestionEngine = class {
444
+ _suggestionsConfig = {};
445
+ _suggestions = {};
446
+ _runningSuggestions = {};
447
+ constructor(core) {
448
+ this.core = core;
449
+ }
450
+ /**
451
+ * Initialize with suggestion configs
452
+ */
453
+ initialize(suggestionsConfig) {
454
+ for (const config of suggestionsConfig) this._suggestionsConfig[(0, _copilotkitnext_shared.randomUUID)()] = config;
455
+ }
456
+ /**
457
+ * Add a suggestion configuration
458
+ * @returns The ID of the created config
459
+ */
460
+ addSuggestionsConfig(config) {
461
+ const id = (0, _copilotkitnext_shared.randomUUID)();
462
+ this._suggestionsConfig[id] = config;
463
+ this.notifySuggestionsConfigChanged();
464
+ return id;
465
+ }
466
+ /**
467
+ * Remove a suggestion configuration by ID
468
+ */
469
+ removeSuggestionsConfig(id) {
470
+ delete this._suggestionsConfig[id];
471
+ this.notifySuggestionsConfigChanged();
472
+ }
473
+ /**
474
+ * Reload suggestions for a specific agent
475
+ * This triggers generation of new suggestions based on current configs
476
+ */
477
+ reloadSuggestions(agentId) {
478
+ this.clearSuggestions(agentId);
479
+ const agent = this.core.getAgent(agentId);
480
+ if (!agent) return;
481
+ const messageCount = agent.messages?.length ?? 0;
482
+ let hasAnySuggestions = false;
483
+ for (const config of Object.values(this._suggestionsConfig)) {
484
+ if (config.consumerAgentId !== void 0 && config.consumerAgentId !== "*" && config.consumerAgentId !== agentId) continue;
485
+ if (!this.shouldShowSuggestions(config, messageCount)) continue;
486
+ const suggestionId = (0, _copilotkitnext_shared.randomUUID)();
487
+ if (isDynamicSuggestionsConfig(config)) {
488
+ if (!hasAnySuggestions) {
489
+ hasAnySuggestions = true;
490
+ this.notifySuggestionsStartedLoading(agentId);
491
+ }
492
+ this.generateSuggestions(suggestionId, config, agentId);
493
+ } else if (isStaticSuggestionsConfig(config)) this.addStaticSuggestions(suggestionId, config, agentId);
494
+ }
495
+ }
496
+ /**
497
+ * Clear all suggestions for a specific agent
498
+ */
499
+ clearSuggestions(agentId) {
500
+ const runningAgents = this._runningSuggestions[agentId];
501
+ if (runningAgents) {
502
+ for (const agent of runningAgents) agent.abortRun();
503
+ delete this._runningSuggestions[agentId];
504
+ }
505
+ this._suggestions[agentId] = {};
506
+ this.notifySuggestionsChanged(agentId, []);
507
+ }
508
+ /**
509
+ * Get current suggestions for an agent
510
+ */
511
+ getSuggestions(agentId) {
512
+ return {
513
+ suggestions: Object.values(this._suggestions[agentId] ?? {}).flat(),
514
+ isLoading: (this._runningSuggestions[agentId]?.length ?? 0) > 0
515
+ };
516
+ }
517
+ /**
518
+ * Generate suggestions using a provider agent
519
+ */
520
+ async generateSuggestions(suggestionId, config, consumerAgentId) {
521
+ let agent = void 0;
522
+ try {
523
+ const suggestionsProviderAgent = this.core.getAgent(config.providerAgentId ?? "default");
524
+ if (!suggestionsProviderAgent) throw new Error(`Suggestions provider agent not found: ${config.providerAgentId}`);
525
+ const suggestionsConsumerAgent = this.core.getAgent(consumerAgentId);
526
+ if (!suggestionsConsumerAgent) throw new Error(`Suggestions consumer agent not found: ${consumerAgentId}`);
527
+ agent = suggestionsProviderAgent.clone();
528
+ agent.threadId = suggestionId;
529
+ agent.messages = JSON.parse(JSON.stringify(suggestionsConsumerAgent.messages));
530
+ agent.state = JSON.parse(JSON.stringify(suggestionsConsumerAgent.state));
531
+ this._suggestions[consumerAgentId] = {
532
+ ...this._suggestions[consumerAgentId] ?? {},
533
+ [suggestionId]: []
534
+ };
535
+ this._runningSuggestions[consumerAgentId] = [...this._runningSuggestions[consumerAgentId] ?? [], agent];
536
+ agent.addMessage({
537
+ id: suggestionId,
538
+ role: "user",
539
+ content: [
540
+ `Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \`copilotkitSuggest\` tool.`,
541
+ `Provide at least ${config.minSuggestions ?? 1} and at most ${config.maxSuggestions ?? 3} suggestions.`,
542
+ `The user has the following tools available: ${JSON.stringify(this.core.buildFrontendTools(consumerAgentId))}.`,
543
+ ` ${config.instructions}`
544
+ ].join("\n")
545
+ });
546
+ await agent.runAgent({
547
+ context: Object.values(this.core.context),
548
+ forwardedProps: {
549
+ ...this.core.properties,
550
+ toolChoice: {
551
+ type: "function",
552
+ function: { name: "copilotkitSuggest" }
553
+ }
554
+ },
555
+ tools: [SUGGEST_TOOL]
556
+ }, { onMessagesChanged: ({ messages }) => {
557
+ this.extractSuggestions(messages, suggestionId, consumerAgentId, true);
558
+ } });
559
+ } catch (error) {
560
+ console.warn("Error generating suggestions:", error);
561
+ } finally {
562
+ this.finalizeSuggestions(suggestionId, consumerAgentId);
563
+ const runningAgents = this._runningSuggestions[consumerAgentId];
564
+ if (agent && runningAgents) {
565
+ const filteredAgents = runningAgents.filter((a) => a !== agent);
566
+ this._runningSuggestions[consumerAgentId] = filteredAgents;
567
+ if (filteredAgents.length === 0) {
568
+ delete this._runningSuggestions[consumerAgentId];
569
+ await this.notifySuggestionsFinishedLoading(consumerAgentId);
570
+ }
571
+ }
572
+ }
573
+ }
574
+ /**
575
+ * Finalize suggestions by marking them as no longer loading
576
+ */
577
+ finalizeSuggestions(suggestionId, consumerAgentId) {
578
+ const agentSuggestions = this._suggestions[consumerAgentId];
579
+ const currentSuggestions = agentSuggestions?.[suggestionId];
580
+ if (agentSuggestions && currentSuggestions && currentSuggestions.length > 0) {
581
+ const finalizedSuggestions = currentSuggestions.filter((suggestion) => suggestion.title !== "" || suggestion.message !== "").map((suggestion) => ({
582
+ ...suggestion,
583
+ isLoading: false
584
+ }));
585
+ if (finalizedSuggestions.length > 0) agentSuggestions[suggestionId] = finalizedSuggestions;
586
+ else delete agentSuggestions[suggestionId];
587
+ const allSuggestions = Object.values(this._suggestions[consumerAgentId] ?? {}).flat();
588
+ this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "finalized");
589
+ }
590
+ }
591
+ /**
592
+ * Extract suggestions from messages (called during streaming)
593
+ */
594
+ extractSuggestions(messages, suggestionId, consumerAgentId, isRunning) {
595
+ const idx = messages.findIndex((message) => message.id === suggestionId);
596
+ if (idx == -1) return;
597
+ const suggestions = [];
598
+ const newMessages = messages.slice(idx + 1);
599
+ for (const message of newMessages) if (message.role === "assistant" && message.toolCalls) {
600
+ for (const toolCall of message.toolCalls) if (toolCall.function.name === "copilotkitSuggest") {
601
+ const parsed = (0, _copilotkitnext_shared.partialJSONParse)(Array.isArray(toolCall.function.arguments) ? toolCall.function.arguments.join("") : toolCall.function.arguments);
602
+ if (parsed && typeof parsed === "object" && "suggestions" in parsed) {
603
+ const parsedSuggestions = parsed.suggestions;
604
+ if (Array.isArray(parsedSuggestions)) {
605
+ for (const item of parsedSuggestions) if (item && typeof item === "object" && "title" in item) suggestions.push({
606
+ title: item.title ?? "",
607
+ message: item.message ?? "",
608
+ isLoading: false
609
+ });
610
+ }
611
+ }
612
+ }
613
+ }
614
+ if (isRunning && suggestions.length > 0) suggestions[suggestions.length - 1].isLoading = true;
615
+ const agentSuggestions = this._suggestions[consumerAgentId];
616
+ if (agentSuggestions) {
617
+ agentSuggestions[suggestionId] = suggestions;
618
+ const allSuggestions = Object.values(this._suggestions[consumerAgentId] ?? {}).flat();
619
+ this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "suggestions changed");
620
+ }
621
+ }
622
+ /**
623
+ * Notify subscribers of suggestions config changes
624
+ */
625
+ async notifySuggestionsConfigChanged() {
626
+ await this.core.notifySubscribers((subscriber) => subscriber.onSuggestionsConfigChanged?.({
627
+ copilotkit: this.core,
628
+ suggestionsConfig: this._suggestionsConfig
629
+ }), "Subscriber onSuggestionsConfigChanged error:");
630
+ }
631
+ /**
632
+ * Notify subscribers of suggestions changes
633
+ */
634
+ async notifySuggestionsChanged(agentId, suggestions, context = "") {
635
+ await this.core.notifySubscribers((subscriber) => subscriber.onSuggestionsChanged?.({
636
+ copilotkit: this.core,
637
+ agentId,
638
+ suggestions
639
+ }), `Subscriber onSuggestionsChanged error: ${context}`);
640
+ }
641
+ /**
642
+ * Notify subscribers that suggestions started loading
643
+ */
644
+ async notifySuggestionsStartedLoading(agentId) {
645
+ await this.core.notifySubscribers((subscriber) => subscriber.onSuggestionsStartedLoading?.({
646
+ copilotkit: this.core,
647
+ agentId
648
+ }), "Subscriber onSuggestionsStartedLoading error:");
649
+ }
650
+ /**
651
+ * Notify subscribers that suggestions finished loading
652
+ */
653
+ async notifySuggestionsFinishedLoading(agentId) {
654
+ await this.core.notifySubscribers((subscriber) => subscriber.onSuggestionsFinishedLoading?.({
655
+ copilotkit: this.core,
656
+ agentId
657
+ }), "Subscriber onSuggestionsFinishedLoading error:");
658
+ }
659
+ /**
660
+ * Check if suggestions should be shown based on availability and message count
661
+ */
662
+ shouldShowSuggestions(config, messageCount) {
663
+ const availability = config.available;
664
+ if (!availability) if (isDynamicSuggestionsConfig(config)) return messageCount > 0;
665
+ else return messageCount === 0;
666
+ switch (availability) {
667
+ case "disabled": return false;
668
+ case "before-first-message": return messageCount === 0;
669
+ case "after-first-message": return messageCount > 0;
670
+ case "always": return true;
671
+ default: return false;
672
+ }
673
+ }
674
+ /**
675
+ * Add static suggestions directly without AI generation
676
+ */
677
+ addStaticSuggestions(suggestionId, config, consumerAgentId) {
678
+ const suggestions = config.suggestions.map((s) => ({
679
+ ...s,
680
+ isLoading: false
681
+ }));
682
+ this._suggestions[consumerAgentId] = {
683
+ ...this._suggestions[consumerAgentId] ?? {},
684
+ [suggestionId]: suggestions
685
+ };
686
+ const allSuggestions = Object.values(this._suggestions[consumerAgentId] ?? {}).flat();
687
+ this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "static suggestions added");
688
+ }
689
+ };
690
+ /**
691
+ * Type guard for dynamic suggestions config
692
+ */
693
+ function isDynamicSuggestionsConfig(config) {
694
+ return "instructions" in config;
695
+ }
696
+ /**
697
+ * Type guard for static suggestions config
698
+ */
699
+ function isStaticSuggestionsConfig(config) {
700
+ return "suggestions" in config;
701
+ }
702
+ /**
703
+ * The tool definition for AI-generated suggestions
704
+ */
705
+ const SUGGEST_TOOL = {
706
+ name: "copilotkitSuggest",
707
+ description: "Suggest what the user could say next",
708
+ parameters: {
709
+ type: "object",
710
+ properties: { suggestions: {
711
+ type: "array",
712
+ description: "List of suggestions shown to the user as buttons.",
713
+ items: {
714
+ type: "object",
715
+ properties: {
716
+ title: {
717
+ type: "string",
718
+ description: "The title of the suggestion. This is shown as a button and should be short."
719
+ },
720
+ message: {
721
+ type: "string",
722
+ 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."
723
+ }
724
+ },
725
+ required: ["title", "message"]
726
+ }
727
+ } },
728
+ required: ["suggestions"]
729
+ }
730
+ };
731
+
732
+ //#endregion
733
+ //#region src/core/run-handler.ts
734
+ /**
735
+ * Handles agent execution, tool calling, and agent connectivity for CopilotKitCore.
736
+ * Manages the complete lifecycle of agent runs including tool execution and follow-ups.
737
+ */
738
+ var RunHandler = class {
739
+ _tools = [];
740
+ constructor(core) {
741
+ this.core = core;
742
+ }
743
+ /**
744
+ * Get all tools as a readonly array
745
+ */
746
+ get tools() {
747
+ return this._tools;
748
+ }
749
+ /**
750
+ * Initialize with tools
751
+ */
752
+ initialize(tools) {
753
+ this._tools = tools;
754
+ }
755
+ /**
756
+ * Add a tool to the registry
757
+ */
758
+ addTool(tool) {
759
+ if (this._tools.findIndex((t) => t.name === tool.name && t.agentId === tool.agentId) !== -1) {
760
+ _copilotkitnext_shared.logger.warn(`Tool already exists: '${tool.name}' for agent '${tool.agentId || "global"}', skipping.`);
761
+ return;
762
+ }
763
+ this._tools.push(tool);
764
+ }
765
+ /**
766
+ * Remove a tool by name and optionally by agentId
767
+ */
768
+ removeTool(id, agentId) {
769
+ this._tools = this._tools.filter((tool) => {
770
+ if (agentId !== void 0) return !(tool.name === id && tool.agentId === agentId);
771
+ return !(tool.name === id && !tool.agentId);
772
+ });
773
+ }
774
+ /**
775
+ * Get a tool by name and optionally by agentId.
776
+ * If agentId is provided, it will first look for an agent-specific tool,
777
+ * then fall back to a global tool with the same name.
778
+ */
779
+ getTool(params) {
780
+ const { toolName, agentId } = params;
781
+ if (agentId) {
782
+ const agentTool = this._tools.find((tool) => tool.name === toolName && tool.agentId === agentId);
783
+ if (agentTool) return agentTool;
784
+ }
785
+ return this._tools.find((tool) => tool.name === toolName && !tool.agentId);
786
+ }
787
+ /**
788
+ * Set all tools at once. Replaces existing tools.
789
+ */
790
+ setTools(tools) {
791
+ this._tools = [...tools];
792
+ }
793
+ /**
794
+ * Connect an agent (establish initial connection)
795
+ */
796
+ async connectAgent({ agent }) {
797
+ try {
798
+ await agent.detachActiveRun();
799
+ agent.setMessages([]);
800
+ agent.setState({});
801
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...this.core.headers };
802
+ const runAgentResult = await agent.connectAgent({
803
+ forwardedProps: this.core.properties,
804
+ tools: this.buildFrontendTools(agent.agentId)
805
+ }, this.createAgentErrorSubscriber(agent));
806
+ return this.processAgentResult({
807
+ runAgentResult,
808
+ agent
809
+ });
810
+ } catch (error) {
811
+ const connectError = error instanceof Error ? error : new Error(String(error));
812
+ const context = {};
813
+ if (agent.agentId) context.agentId = agent.agentId;
814
+ await this.core.emitError({
815
+ error: connectError,
816
+ code: CopilotKitCoreErrorCode.AGENT_CONNECT_FAILED,
817
+ context
818
+ });
819
+ throw error;
820
+ }
821
+ }
822
+ /**
823
+ * Run an agent
824
+ */
825
+ async runAgent({ agent }) {
826
+ if (agent.agentId) this.core.suggestionEngine.clearSuggestions(agent.agentId);
827
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.headers = { ...this.core.headers };
828
+ try {
829
+ const runAgentResult = await agent.runAgent({
830
+ forwardedProps: this.core.properties,
831
+ tools: this.buildFrontendTools(agent.agentId),
832
+ context: Object.values(this.core.context)
833
+ }, this.createAgentErrorSubscriber(agent));
834
+ return this.processAgentResult({
835
+ runAgentResult,
836
+ agent
837
+ });
838
+ } catch (error) {
839
+ const runError = error instanceof Error ? error : new Error(String(error));
840
+ const context = {};
841
+ if (agent.agentId) context.agentId = agent.agentId;
842
+ await this.core.emitError({
843
+ error: runError,
844
+ code: CopilotKitCoreErrorCode.AGENT_RUN_FAILED,
845
+ context
846
+ });
847
+ throw error;
848
+ }
849
+ }
850
+ /**
851
+ * Process agent result and execute tools
852
+ */
853
+ async processAgentResult({ runAgentResult, agent }) {
854
+ const { newMessages } = runAgentResult;
855
+ const agentId = agent.agentId;
856
+ let needsFollowUp = false;
857
+ for (const message of newMessages) if (message.role === "assistant") {
858
+ for (const toolCall of message.toolCalls || []) if (newMessages.findIndex((m) => m.role === "tool" && m.toolCallId === toolCall.id) === -1) {
859
+ const tool = this.getTool({
860
+ toolName: toolCall.function.name,
861
+ agentId: agent.agentId
862
+ });
863
+ if (tool) {
864
+ if (await this.executeSpecificTool(tool, toolCall, message, agent, agentId)) needsFollowUp = true;
865
+ } else {
866
+ const wildcardTool = this.getTool({
867
+ toolName: "*",
868
+ agentId: agent.agentId
869
+ });
870
+ if (wildcardTool) {
871
+ if (await this.executeWildcardTool(wildcardTool, toolCall, message, agent, agentId)) needsFollowUp = true;
872
+ }
873
+ }
874
+ }
875
+ }
876
+ if (needsFollowUp) return await this.runAgent({ agent });
877
+ this.core.suggestionEngine.reloadSuggestions(agentId);
878
+ return runAgentResult;
879
+ }
880
+ /**
881
+ * Execute a specific tool
882
+ */
883
+ async executeSpecificTool(tool, toolCall, message, agent, agentId) {
884
+ if (tool?.agentId && tool.agentId !== agent.agentId) return false;
885
+ let toolCallResult = "";
886
+ let errorMessage;
887
+ let isArgumentError = false;
888
+ if (tool?.handler) {
889
+ let parsedArgs;
890
+ try {
891
+ parsedArgs = JSON.parse(toolCall.function.arguments);
892
+ } catch (error) {
893
+ const parseError = error instanceof Error ? error : new Error(String(error));
894
+ errorMessage = parseError.message;
895
+ isArgumentError = true;
896
+ await this.core.emitError({
897
+ error: parseError,
898
+ code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,
899
+ context: {
900
+ agentId,
901
+ toolCallId: toolCall.id,
902
+ toolName: toolCall.function.name,
903
+ rawArguments: toolCall.function.arguments,
904
+ toolType: "specific",
905
+ messageId: message.id
906
+ }
907
+ });
908
+ }
909
+ await this.core.notifySubscribers((subscriber) => subscriber.onToolExecutionStart?.({
910
+ copilotkit: this.core,
911
+ toolCallId: toolCall.id,
912
+ agentId,
913
+ toolName: toolCall.function.name,
914
+ args: parsedArgs
915
+ }), "Subscriber onToolExecutionStart error:");
916
+ if (!errorMessage) try {
917
+ const result = await tool.handler(parsedArgs, {
918
+ toolCall,
919
+ agent
920
+ });
921
+ if (result === void 0 || result === null) toolCallResult = "";
922
+ else if (typeof result === "string") toolCallResult = result;
923
+ else toolCallResult = JSON.stringify(result);
924
+ } catch (error) {
925
+ const handlerError = error instanceof Error ? error : new Error(String(error));
926
+ errorMessage = handlerError.message;
927
+ await this.core.emitError({
928
+ error: handlerError,
929
+ code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,
930
+ context: {
931
+ agentId,
932
+ toolCallId: toolCall.id,
933
+ toolName: toolCall.function.name,
934
+ parsedArgs,
935
+ toolType: "specific",
936
+ messageId: message.id
937
+ }
938
+ });
939
+ }
940
+ if (errorMessage) toolCallResult = `Error: ${errorMessage}`;
941
+ await this.core.notifySubscribers((subscriber) => subscriber.onToolExecutionEnd?.({
942
+ copilotkit: this.core,
943
+ toolCallId: toolCall.id,
944
+ agentId,
945
+ toolName: toolCall.function.name,
946
+ result: errorMessage ? "" : toolCallResult,
947
+ error: errorMessage
948
+ }), "Subscriber onToolExecutionEnd error:");
949
+ if (isArgumentError) throw new Error(errorMessage ?? "Tool execution failed");
950
+ }
951
+ if (!errorMessage || !isArgumentError) {
952
+ const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
953
+ if (messageIndex === -1) return false;
954
+ const toolMessage = {
955
+ id: (0, _copilotkitnext_shared.randomUUID)(),
956
+ role: "tool",
957
+ toolCallId: toolCall.id,
958
+ content: toolCallResult
959
+ };
960
+ agent.messages.splice(messageIndex + 1, 0, toolMessage);
961
+ if (!errorMessage && tool?.followUp !== false) return true;
962
+ }
963
+ return false;
964
+ }
965
+ /**
966
+ * Execute a wildcard tool
967
+ */
968
+ async executeWildcardTool(wildcardTool, toolCall, message, agent, agentId) {
969
+ if (wildcardTool?.agentId && wildcardTool.agentId !== agent.agentId) return false;
970
+ let toolCallResult = "";
971
+ let errorMessage;
972
+ let isArgumentError = false;
973
+ if (wildcardTool?.handler) {
974
+ let parsedArgs;
975
+ try {
976
+ parsedArgs = JSON.parse(toolCall.function.arguments);
977
+ } catch (error) {
978
+ const parseError = error instanceof Error ? error : new Error(String(error));
979
+ errorMessage = parseError.message;
980
+ isArgumentError = true;
981
+ await this.core.emitError({
982
+ error: parseError,
983
+ code: CopilotKitCoreErrorCode.TOOL_ARGUMENT_PARSE_FAILED,
984
+ context: {
985
+ agentId,
986
+ toolCallId: toolCall.id,
987
+ toolName: toolCall.function.name,
988
+ rawArguments: toolCall.function.arguments,
989
+ toolType: "wildcard",
990
+ messageId: message.id
991
+ }
992
+ });
993
+ }
994
+ const wildcardArgs = {
995
+ toolName: toolCall.function.name,
996
+ args: parsedArgs
997
+ };
998
+ await this.core.notifySubscribers((subscriber) => subscriber.onToolExecutionStart?.({
999
+ copilotkit: this.core,
1000
+ toolCallId: toolCall.id,
1001
+ agentId,
1002
+ toolName: toolCall.function.name,
1003
+ args: wildcardArgs
1004
+ }), "Subscriber onToolExecutionStart error:");
1005
+ if (!errorMessage) try {
1006
+ const result = await wildcardTool.handler(wildcardArgs, {
1007
+ toolCall,
1008
+ agent
1009
+ });
1010
+ if (result === void 0 || result === null) toolCallResult = "";
1011
+ else if (typeof result === "string") toolCallResult = result;
1012
+ else toolCallResult = JSON.stringify(result);
1013
+ } catch (error) {
1014
+ const handlerError = error instanceof Error ? error : new Error(String(error));
1015
+ errorMessage = handlerError.message;
1016
+ await this.core.emitError({
1017
+ error: handlerError,
1018
+ code: CopilotKitCoreErrorCode.TOOL_HANDLER_FAILED,
1019
+ context: {
1020
+ agentId,
1021
+ toolCallId: toolCall.id,
1022
+ toolName: toolCall.function.name,
1023
+ parsedArgs: wildcardArgs,
1024
+ toolType: "wildcard",
1025
+ messageId: message.id
1026
+ }
1027
+ });
1028
+ }
1029
+ if (errorMessage) toolCallResult = `Error: ${errorMessage}`;
1030
+ await this.core.notifySubscribers((subscriber) => subscriber.onToolExecutionEnd?.({
1031
+ copilotkit: this.core,
1032
+ toolCallId: toolCall.id,
1033
+ agentId,
1034
+ toolName: toolCall.function.name,
1035
+ result: errorMessage ? "" : toolCallResult,
1036
+ error: errorMessage
1037
+ }), "Subscriber onToolExecutionEnd error:");
1038
+ if (isArgumentError) throw new Error(errorMessage ?? "Tool execution failed");
1039
+ }
1040
+ if (!errorMessage || !isArgumentError) {
1041
+ const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
1042
+ if (messageIndex === -1) return false;
1043
+ const toolMessage = {
1044
+ id: (0, _copilotkitnext_shared.randomUUID)(),
1045
+ role: "tool",
1046
+ toolCallId: toolCall.id,
1047
+ content: toolCallResult
1048
+ };
1049
+ agent.messages.splice(messageIndex + 1, 0, toolMessage);
1050
+ if (!errorMessage && wildcardTool?.followUp !== false) return true;
1051
+ }
1052
+ return false;
1053
+ }
1054
+ /**
1055
+ * Build frontend tools for an agent
1056
+ */
1057
+ buildFrontendTools(agentId) {
1058
+ return this._tools.filter((tool) => tool.available !== false && (!tool.agentId || tool.agentId === agentId)).map((tool) => ({
1059
+ name: tool.name,
1060
+ description: tool.description ?? "",
1061
+ parameters: createToolSchema(tool)
1062
+ }));
1063
+ }
1064
+ /**
1065
+ * Create an agent error subscriber
1066
+ */
1067
+ createAgentErrorSubscriber(agent) {
1068
+ const emitAgentError = async (error, code, extraContext = {}) => {
1069
+ const context = { ...extraContext };
1070
+ if (agent.agentId) context.agentId = agent.agentId;
1071
+ await this.core.emitError({
1072
+ error,
1073
+ code,
1074
+ context
1075
+ });
1076
+ };
1077
+ return {
1078
+ onRunFailed: async ({ error }) => {
1079
+ await emitAgentError(error, CopilotKitCoreErrorCode.AGENT_RUN_FAILED_EVENT, { source: "onRunFailed" });
1080
+ },
1081
+ onRunErrorEvent: async ({ event }) => {
1082
+ const eventError = event?.rawEvent instanceof Error ? event.rawEvent : event?.rawEvent?.error instanceof Error ? event.rawEvent.error : void 0;
1083
+ const errorMessage = typeof event?.rawEvent?.error === "string" ? event.rawEvent.error : event?.message ?? "Agent run error";
1084
+ const rawError = eventError ?? new Error(errorMessage);
1085
+ if (event?.code && !rawError.code) rawError.code = event.code;
1086
+ await emitAgentError(rawError, CopilotKitCoreErrorCode.AGENT_RUN_ERROR_EVENT, {
1087
+ source: "onRunErrorEvent",
1088
+ event,
1089
+ runtimeErrorCode: event?.code
1090
+ });
1091
+ }
1092
+ };
1093
+ }
1094
+ };
1095
+ /**
1096
+ * Empty tool schema constant
1097
+ */
1098
+ const EMPTY_TOOL_SCHEMA = {
1099
+ type: "object",
1100
+ properties: {}
1101
+ };
1102
+ /**
1103
+ * Create a JSON schema from a tool's parameters
1104
+ */
1105
+ function createToolSchema(tool) {
1106
+ if (!tool.parameters) return { ...EMPTY_TOOL_SCHEMA };
1107
+ const rawSchema = (0, zod_to_json_schema.zodToJsonSchema)(tool.parameters, { $refStrategy: "none" });
1108
+ if (!rawSchema || typeof rawSchema !== "object") return { ...EMPTY_TOOL_SCHEMA };
1109
+ const { $schema, ...schema } = rawSchema;
1110
+ if (typeof schema.type !== "string") schema.type = "object";
1111
+ if (typeof schema.properties !== "object" || schema.properties === null) schema.properties = {};
1112
+ stripAdditionalProperties(schema);
1113
+ return schema;
1114
+ }
1115
+ function stripAdditionalProperties(schema) {
1116
+ if (!schema || typeof schema !== "object") return;
1117
+ if (Array.isArray(schema)) {
1118
+ schema.forEach(stripAdditionalProperties);
1119
+ return;
1120
+ }
1121
+ const record = schema;
1122
+ if (record.additionalProperties !== void 0) delete record.additionalProperties;
1123
+ for (const value of Object.values(record)) stripAdditionalProperties(value);
1124
+ }
1125
+
1126
+ //#endregion
1127
+ //#region src/core/state-manager.ts
1128
+ /**
1129
+ * Manages state and message tracking by run for CopilotKitCore.
1130
+ * Tracks agent state snapshots and message-to-run associations.
1131
+ */
1132
+ var StateManager = class {
1133
+ stateByRun = /* @__PURE__ */ new Map();
1134
+ messageToRun = /* @__PURE__ */ new Map();
1135
+ agentSubscriptions = /* @__PURE__ */ new Map();
1136
+ constructor(core) {
1137
+ this.core = core;
1138
+ }
1139
+ /**
1140
+ * Initialize state tracking for an agent
1141
+ */
1142
+ initialize() {}
1143
+ /**
1144
+ * Subscribe to an agent's events to track state and messages
1145
+ */
1146
+ subscribeToAgent(agent) {
1147
+ if (!agent.agentId) return;
1148
+ const agentId = agent.agentId;
1149
+ this.unsubscribeFromAgent(agentId);
1150
+ const { unsubscribe } = agent.subscribe({
1151
+ onRunStartedEvent: ({ event, state }) => {
1152
+ this.handleRunStarted(agent, event, state);
1153
+ },
1154
+ onRunFinishedEvent: ({ event, state }) => {
1155
+ this.handleRunFinished(agent, event, state);
1156
+ },
1157
+ onStateSnapshotEvent: ({ event, input, state }) => {
1158
+ this.handleStateSnapshot(agent, event, input, state);
1159
+ },
1160
+ onStateDeltaEvent: ({ event, input, state }) => {
1161
+ this.handleStateDelta(agent, event, input, state);
1162
+ },
1163
+ onMessagesSnapshotEvent: ({ event, input, messages }) => {
1164
+ this.handleMessagesSnapshot(agent, event, input, messages);
1165
+ },
1166
+ onNewMessage: ({ message, input }) => {
1167
+ this.handleNewMessage(agent, message, input);
1168
+ }
1169
+ });
1170
+ this.agentSubscriptions.set(agentId, unsubscribe);
1171
+ }
1172
+ /**
1173
+ * Unsubscribe from an agent's events
1174
+ */
1175
+ unsubscribeFromAgent(agentId) {
1176
+ const unsubscribe = this.agentSubscriptions.get(agentId);
1177
+ if (unsubscribe) {
1178
+ unsubscribe();
1179
+ this.agentSubscriptions.delete(agentId);
1180
+ }
1181
+ }
1182
+ /**
1183
+ * Get state for a specific run
1184
+ * Returns a deep copy to prevent external mutations
1185
+ */
1186
+ getStateByRun(agentId, threadId, runId) {
1187
+ const state = this.stateByRun.get(agentId)?.get(threadId)?.get(runId);
1188
+ if (!state) return void 0;
1189
+ return JSON.parse(JSON.stringify(state));
1190
+ }
1191
+ /**
1192
+ * Get runId associated with a message
1193
+ */
1194
+ getRunIdForMessage(agentId, threadId, messageId) {
1195
+ return this.messageToRun.get(agentId)?.get(threadId)?.get(messageId);
1196
+ }
1197
+ /**
1198
+ * Get all states for an agent's thread
1199
+ */
1200
+ getStatesForThread(agentId, threadId) {
1201
+ return this.stateByRun.get(agentId)?.get(threadId) ?? /* @__PURE__ */ new Map();
1202
+ }
1203
+ /**
1204
+ * Get all run IDs for an agent's thread
1205
+ */
1206
+ getRunIdsForThread(agentId, threadId) {
1207
+ const threadStates = this.stateByRun.get(agentId)?.get(threadId);
1208
+ return threadStates ? Array.from(threadStates.keys()) : [];
1209
+ }
1210
+ /**
1211
+ * Handle run started event
1212
+ */
1213
+ handleRunStarted(agent, event, state) {
1214
+ if (!agent.agentId) return;
1215
+ const { threadId, runId } = event;
1216
+ this.saveState(agent.agentId, threadId, runId, state);
1217
+ }
1218
+ /**
1219
+ * Handle run finished event
1220
+ */
1221
+ handleRunFinished(agent, event, state) {
1222
+ if (!agent.agentId) return;
1223
+ const { threadId, runId } = event;
1224
+ this.saveState(agent.agentId, threadId, runId, state);
1225
+ }
1226
+ /**
1227
+ * Handle state snapshot event
1228
+ */
1229
+ handleStateSnapshot(agent, event, input, state) {
1230
+ if (!agent.agentId) return;
1231
+ const { threadId, runId } = input;
1232
+ const mergedState = {
1233
+ ...state,
1234
+ ...event.snapshot
1235
+ };
1236
+ this.saveState(agent.agentId, threadId, runId, mergedState);
1237
+ }
1238
+ /**
1239
+ * Handle state delta event
1240
+ */
1241
+ handleStateDelta(agent, event, input, state) {
1242
+ if (!agent.agentId) return;
1243
+ const { threadId, runId } = input;
1244
+ this.saveState(agent.agentId, threadId, runId, state);
1245
+ }
1246
+ /**
1247
+ * Handle messages snapshot event
1248
+ */
1249
+ handleMessagesSnapshot(agent, event, input, messages) {
1250
+ if (!agent.agentId) return;
1251
+ const { threadId, runId } = input;
1252
+ for (const message of event.messages) this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);
1253
+ }
1254
+ /**
1255
+ * Handle new message event
1256
+ */
1257
+ handleNewMessage(agent, message, input) {
1258
+ if (!agent.agentId || !input) return;
1259
+ const { threadId, runId } = input;
1260
+ this.associateMessageWithRun(agent.agentId, threadId, message.id, runId);
1261
+ }
1262
+ /**
1263
+ * Save state for a specific run
1264
+ */
1265
+ saveState(agentId, threadId, runId, state) {
1266
+ if (!this.stateByRun.has(agentId)) this.stateByRun.set(agentId, /* @__PURE__ */ new Map());
1267
+ const agentStates = this.stateByRun.get(agentId);
1268
+ if (!agentStates.has(threadId)) agentStates.set(threadId, /* @__PURE__ */ new Map());
1269
+ agentStates.get(threadId).set(runId, JSON.parse(JSON.stringify(state)));
1270
+ }
1271
+ /**
1272
+ * Associate a message with a run
1273
+ */
1274
+ associateMessageWithRun(agentId, threadId, messageId, runId) {
1275
+ if (!this.messageToRun.has(agentId)) this.messageToRun.set(agentId, /* @__PURE__ */ new Map());
1276
+ const agentMessages = this.messageToRun.get(agentId);
1277
+ if (!agentMessages.has(threadId)) agentMessages.set(threadId, /* @__PURE__ */ new Map());
1278
+ agentMessages.get(threadId).set(messageId, runId);
1279
+ }
1280
+ /**
1281
+ * Clear all state for an agent
1282
+ */
1283
+ clearAgentState(agentId) {
1284
+ this.stateByRun.delete(agentId);
1285
+ this.messageToRun.delete(agentId);
1286
+ }
1287
+ /**
1288
+ * Clear all state for a thread
1289
+ */
1290
+ clearThreadState(agentId, threadId) {
1291
+ this.stateByRun.get(agentId)?.delete(threadId);
1292
+ this.messageToRun.get(agentId)?.delete(threadId);
1293
+ }
1294
+ };
1295
+
1296
+ //#endregion
1297
+ //#region src/core/core.ts
1298
+ let CopilotKitCoreErrorCode = /* @__PURE__ */ function(CopilotKitCoreErrorCode) {
1299
+ CopilotKitCoreErrorCode["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
1300
+ CopilotKitCoreErrorCode["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
1301
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED"] = "agent_run_failed";
1302
+ CopilotKitCoreErrorCode["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
1303
+ CopilotKitCoreErrorCode["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
1304
+ CopilotKitCoreErrorCode["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
1305
+ CopilotKitCoreErrorCode["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
1306
+ CopilotKitCoreErrorCode["TRANSCRIPTION_FAILED"] = "transcription_failed";
1307
+ CopilotKitCoreErrorCode["TRANSCRIPTION_SERVICE_NOT_CONFIGURED"] = "transcription_service_not_configured";
1308
+ CopilotKitCoreErrorCode["TRANSCRIPTION_INVALID_AUDIO"] = "transcription_invalid_audio";
1309
+ CopilotKitCoreErrorCode["TRANSCRIPTION_RATE_LIMITED"] = "transcription_rate_limited";
1310
+ CopilotKitCoreErrorCode["TRANSCRIPTION_AUTH_FAILED"] = "transcription_auth_failed";
1311
+ CopilotKitCoreErrorCode["TRANSCRIPTION_NETWORK_ERROR"] = "transcription_network_error";
1312
+ return CopilotKitCoreErrorCode;
1313
+ }({});
1314
+ let CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ function(CopilotKitCoreRuntimeConnectionStatus) {
1315
+ CopilotKitCoreRuntimeConnectionStatus["Disconnected"] = "disconnected";
1316
+ CopilotKitCoreRuntimeConnectionStatus["Connected"] = "connected";
1317
+ CopilotKitCoreRuntimeConnectionStatus["Connecting"] = "connecting";
1318
+ CopilotKitCoreRuntimeConnectionStatus["Error"] = "error";
1319
+ return CopilotKitCoreRuntimeConnectionStatus;
1320
+ }({});
1321
+ var CopilotKitCore = class {
1322
+ _headers;
1323
+ _credentials;
1324
+ _properties;
1325
+ subscribers = /* @__PURE__ */ new Set();
1326
+ agentRegistry;
1327
+ contextStore;
1328
+ suggestionEngine;
1329
+ runHandler;
1330
+ stateManager;
1331
+ constructor({ runtimeUrl, runtimeTransport = "rest", headers = {}, credentials, properties = {}, agents__unsafe_dev_only = {}, tools = [], suggestionsConfig = [] }) {
1332
+ this._headers = headers;
1333
+ this._credentials = credentials;
1334
+ this._properties = properties;
1335
+ this.agentRegistry = new AgentRegistry(this);
1336
+ this.contextStore = new ContextStore(this);
1337
+ this.suggestionEngine = new SuggestionEngine(this);
1338
+ this.runHandler = new RunHandler(this);
1339
+ this.stateManager = new StateManager(this);
1340
+ this.agentRegistry.initialize(agents__unsafe_dev_only);
1341
+ this.runHandler.initialize(tools);
1342
+ this.suggestionEngine.initialize(suggestionsConfig);
1343
+ this.stateManager.initialize();
1344
+ this.agentRegistry.setRuntimeTransport(runtimeTransport);
1345
+ this.agentRegistry.setRuntimeUrl(runtimeUrl);
1346
+ this.subscribe({ onAgentsChanged: ({ agents }) => {
1347
+ Object.values(agents).forEach((agent) => {
1348
+ if (agent.agentId) this.stateManager.subscribeToAgent(agent);
1349
+ });
1350
+ } });
1351
+ }
1352
+ /**
1353
+ * Internal method used by delegate classes and subclasses to notify subscribers
1354
+ */
1355
+ async notifySubscribers(handler, errorMessage) {
1356
+ await Promise.all(Array.from(this.subscribers).map(async (subscriber) => {
1357
+ try {
1358
+ await handler(subscriber);
1359
+ } catch (error) {
1360
+ console.error(errorMessage, error);
1361
+ }
1362
+ }));
1363
+ }
1364
+ /**
1365
+ * Internal method used by delegate classes to emit errors
1366
+ */
1367
+ async emitError({ error, code, context = {} }) {
1368
+ await this.notifySubscribers((subscriber) => subscriber.onError?.({
1369
+ copilotkit: this,
1370
+ error,
1371
+ code,
1372
+ context
1373
+ }), "Subscriber onError error:");
1374
+ }
1375
+ /**
1376
+ * Snapshot accessors
1377
+ */
1378
+ get context() {
1379
+ return this.contextStore.context;
1380
+ }
1381
+ get agents() {
1382
+ return this.agentRegistry.agents;
1383
+ }
1384
+ get tools() {
1385
+ return this.runHandler.tools;
1386
+ }
1387
+ get runtimeUrl() {
1388
+ return this.agentRegistry.runtimeUrl;
1389
+ }
1390
+ setRuntimeUrl(runtimeUrl) {
1391
+ this.agentRegistry.setRuntimeUrl(runtimeUrl);
1392
+ }
1393
+ get runtimeTransport() {
1394
+ return this.agentRegistry.runtimeTransport;
1395
+ }
1396
+ setRuntimeTransport(runtimeTransport) {
1397
+ this.agentRegistry.setRuntimeTransport(runtimeTransport);
1398
+ }
1399
+ get runtimeVersion() {
1400
+ return this.agentRegistry.runtimeVersion;
1401
+ }
1402
+ get headers() {
1403
+ return this._headers;
1404
+ }
1405
+ get credentials() {
1406
+ return this._credentials;
1407
+ }
1408
+ get properties() {
1409
+ return this._properties;
1410
+ }
1411
+ get runtimeConnectionStatus() {
1412
+ return this.agentRegistry.runtimeConnectionStatus;
1413
+ }
1414
+ get audioFileTranscriptionEnabled() {
1415
+ return this.agentRegistry.audioFileTranscriptionEnabled;
1416
+ }
1417
+ /**
1418
+ * Configuration updates
1419
+ */
1420
+ setHeaders(headers) {
1421
+ this._headers = headers;
1422
+ this.agentRegistry.applyHeadersToAgents(this.agentRegistry.agents);
1423
+ this.notifySubscribers((subscriber) => subscriber.onHeadersChanged?.({
1424
+ copilotkit: this,
1425
+ headers: this.headers
1426
+ }), "Subscriber onHeadersChanged error:");
1427
+ }
1428
+ setCredentials(credentials) {
1429
+ this._credentials = credentials;
1430
+ this.agentRegistry.applyCredentialsToAgents(this.agentRegistry.agents);
1431
+ }
1432
+ setProperties(properties) {
1433
+ this._properties = properties;
1434
+ this.notifySubscribers((subscriber) => subscriber.onPropertiesChanged?.({
1435
+ copilotkit: this,
1436
+ properties: this.properties
1437
+ }), "Subscriber onPropertiesChanged error:");
1438
+ }
1439
+ /**
1440
+ * Agent management (delegated to AgentRegistry)
1441
+ */
1442
+ setAgents__unsafe_dev_only(agents) {
1443
+ this.agentRegistry.setAgents__unsafe_dev_only(agents);
1444
+ }
1445
+ addAgent__unsafe_dev_only(params) {
1446
+ this.agentRegistry.addAgent__unsafe_dev_only(params);
1447
+ }
1448
+ removeAgent__unsafe_dev_only(id) {
1449
+ this.agentRegistry.removeAgent__unsafe_dev_only(id);
1450
+ }
1451
+ getAgent(id) {
1452
+ return this.agentRegistry.getAgent(id);
1453
+ }
1454
+ /**
1455
+ * Context management (delegated to ContextStore)
1456
+ */
1457
+ addContext(context) {
1458
+ return this.contextStore.addContext(context);
1459
+ }
1460
+ removeContext(id) {
1461
+ this.contextStore.removeContext(id);
1462
+ }
1463
+ /**
1464
+ * Suggestions management (delegated to SuggestionEngine)
1465
+ */
1466
+ addSuggestionsConfig(config) {
1467
+ return this.suggestionEngine.addSuggestionsConfig(config);
1468
+ }
1469
+ removeSuggestionsConfig(id) {
1470
+ this.suggestionEngine.removeSuggestionsConfig(id);
1471
+ }
1472
+ reloadSuggestions(agentId) {
1473
+ this.suggestionEngine.reloadSuggestions(agentId);
1474
+ }
1475
+ clearSuggestions(agentId) {
1476
+ this.suggestionEngine.clearSuggestions(agentId);
1477
+ }
1478
+ getSuggestions(agentId) {
1479
+ return this.suggestionEngine.getSuggestions(agentId);
1480
+ }
1481
+ /**
1482
+ * Tool management (delegated to RunHandler)
1483
+ */
1484
+ addTool(tool) {
1485
+ this.runHandler.addTool(tool);
1486
+ }
1487
+ removeTool(id, agentId) {
1488
+ this.runHandler.removeTool(id, agentId);
1489
+ }
1490
+ getTool(params) {
1491
+ return this.runHandler.getTool(params);
1492
+ }
1493
+ setTools(tools) {
1494
+ this.runHandler.setTools(tools);
1495
+ }
1496
+ /**
1497
+ * Subscription lifecycle
1498
+ */
1499
+ subscribe(subscriber) {
1500
+ this.subscribers.add(subscriber);
1501
+ return { unsubscribe: () => {
1502
+ this.subscribers.delete(subscriber);
1503
+ } };
1504
+ }
1505
+ /**
1506
+ * Agent connectivity (delegated to RunHandler)
1507
+ */
1508
+ async connectAgent(params) {
1509
+ return this.runHandler.connectAgent(params);
1510
+ }
1511
+ stopAgent(params) {
1512
+ params.agent.abortRun();
1513
+ }
1514
+ async runAgent(params) {
1515
+ return this.runHandler.runAgent(params);
1516
+ }
1517
+ /**
1518
+ * State management (delegated to StateManager)
1519
+ */
1520
+ getStateByRun(agentId, threadId, runId) {
1521
+ return this.stateManager.getStateByRun(agentId, threadId, runId);
1522
+ }
1523
+ getRunIdForMessage(agentId, threadId, messageId) {
1524
+ return this.stateManager.getRunIdForMessage(agentId, threadId, messageId);
1525
+ }
1526
+ getRunIdsForThread(agentId, threadId) {
1527
+ return this.stateManager.getRunIdsForThread(agentId, threadId);
1528
+ }
1529
+ /**
1530
+ * Internal method used by RunHandler to build frontend tools
1531
+ */
1532
+ buildFrontendTools(agentId) {
1533
+ return this.runHandler.buildFrontendTools(agentId);
1534
+ }
1535
+ };
1536
+
1537
+ //#endregion
1538
+ //#region src/types.ts
1539
+ /**
1540
+ * Status of a tool call execution
1541
+ */
1542
+ let ToolCallStatus = /* @__PURE__ */ function(ToolCallStatus) {
1543
+ ToolCallStatus["InProgress"] = "inProgress";
1544
+ ToolCallStatus["Executing"] = "executing";
1545
+ ToolCallStatus["Complete"] = "complete";
1546
+ return ToolCallStatus;
1547
+ }({});
1548
+
1549
+ //#endregion
1550
+ //#region src/utils/markdown.ts
1551
+ function completePartialMarkdown(input) {
1552
+ let s = input;
1553
+ const fenceMatches = Array.from(s.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
1554
+ if (fenceMatches.length % 2 === 1) {
1555
+ const [, indent, fence] = fenceMatches[0];
1556
+ s += `\n${indent}${fence}`;
1557
+ }
1558
+ if (s.match(/\[([^\]]*)\]\(([^)]*)$/)) s += ")";
1559
+ const openElements = [];
1560
+ const chars = Array.from(s);
1561
+ const codeBlockRanges = [];
1562
+ const inlineCodeRanges = [];
1563
+ let tempCodeFenceCount = 0;
1564
+ let currentCodeBlockStart = -1;
1565
+ for (let i = 0; i < chars.length; i++) if (i === 0 || chars[i - 1] === "\n") {
1566
+ const lineMatch = s.substring(i).match(/^(\s*)(`{3,}|~{3,})/);
1567
+ if (lineMatch) {
1568
+ tempCodeFenceCount++;
1569
+ if (tempCodeFenceCount % 2 === 1) currentCodeBlockStart = i;
1570
+ else if (currentCodeBlockStart !== -1) {
1571
+ codeBlockRanges.push({
1572
+ start: currentCodeBlockStart,
1573
+ end: i + lineMatch[0].length
1574
+ });
1575
+ currentCodeBlockStart = -1;
1576
+ }
1577
+ i += lineMatch[0].length - 1;
1578
+ }
1579
+ }
1580
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`") {
1581
+ let backslashCount = 0;
1582
+ for (let j = i - 1; j >= 0 && chars[j] === "\\"; j--) backslashCount++;
1583
+ if (backslashCount % 2 === 0) {
1584
+ for (let j = i + 1; j < chars.length; j++) if (chars[j] === "`") {
1585
+ let closingBackslashCount = 0;
1586
+ for (let k = j - 1; k >= 0 && chars[k] === "\\"; k--) closingBackslashCount++;
1587
+ if (closingBackslashCount % 2 === 0) {
1588
+ inlineCodeRanges.push({
1589
+ start: i,
1590
+ end: j + 1
1591
+ });
1592
+ i = j;
1593
+ break;
1594
+ }
1595
+ }
1596
+ }
1597
+ }
1598
+ const isInCode = (pos) => {
1599
+ return codeBlockRanges.some((range) => pos >= range.start && pos < range.end) || inlineCodeRanges.some((range) => pos >= range.start && pos < range.end);
1600
+ };
1601
+ for (let i = 0; i < chars.length; i++) {
1602
+ const char = chars[i];
1603
+ const nextChar = chars[i + 1];
1604
+ const prevChar = chars[i - 1];
1605
+ if (isInCode(i)) continue;
1606
+ if (char === "[") {
1607
+ let isCompleteLink = false;
1608
+ let bracketDepth = 1;
1609
+ let j = i + 1;
1610
+ while (j < chars.length && bracketDepth > 0) {
1611
+ if (chars[j] === "[" && !isInCode(j)) bracketDepth++;
1612
+ if (chars[j] === "]" && !isInCode(j)) bracketDepth--;
1613
+ j++;
1614
+ }
1615
+ if (bracketDepth === 0 && chars[j] === "(") {
1616
+ let parenDepth = 1;
1617
+ j++;
1618
+ while (j < chars.length && parenDepth > 0) {
1619
+ if (chars[j] === "(" && !isInCode(j)) parenDepth++;
1620
+ if (chars[j] === ")" && !isInCode(j)) parenDepth--;
1621
+ j++;
1622
+ }
1623
+ if (parenDepth === 0) {
1624
+ isCompleteLink = true;
1625
+ i = j - 1;
1626
+ continue;
1627
+ }
1628
+ }
1629
+ if (!isCompleteLink) {
1630
+ const existingIndex = openElements.findIndex((el) => el.type === "bracket");
1631
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
1632
+ else openElements.push({
1633
+ type: "bracket",
1634
+ marker: "[",
1635
+ position: i
1636
+ });
1637
+ }
1638
+ } else if (char === "*" && nextChar === "*") {
1639
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_star");
1640
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
1641
+ else openElements.push({
1642
+ type: "bold_star",
1643
+ marker: "**",
1644
+ position: i
1645
+ });
1646
+ i++;
1647
+ } else if (char === "_" && nextChar === "_") {
1648
+ const existingIndex = openElements.findIndex((el) => el.type === "bold_underscore");
1649
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
1650
+ else openElements.push({
1651
+ type: "bold_underscore",
1652
+ marker: "__",
1653
+ position: i
1654
+ });
1655
+ i++;
1656
+ } else if (char === "~" && nextChar === "~") {
1657
+ const existingIndex = openElements.findIndex((el) => el.type === "strike");
1658
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
1659
+ else openElements.push({
1660
+ type: "strike",
1661
+ marker: "~~",
1662
+ position: i
1663
+ });
1664
+ i++;
1665
+ } else if (char === "*" && prevChar !== "*" && nextChar !== "*") {
1666
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_star");
1667
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
1668
+ else openElements.push({
1669
+ type: "italic_star",
1670
+ marker: "*",
1671
+ position: i
1672
+ });
1673
+ } else if (char === "_" && prevChar !== "_" && nextChar !== "_") {
1674
+ const existingIndex = openElements.findIndex((el) => el.type === "italic_underscore");
1675
+ if (existingIndex !== -1) openElements.splice(existingIndex, 1);
1676
+ else openElements.push({
1677
+ type: "italic_underscore",
1678
+ marker: "_",
1679
+ position: i
1680
+ });
1681
+ }
1682
+ }
1683
+ let backtickCount = 0;
1684
+ for (let i = 0; i < chars.length; i++) if (chars[i] === "`" && !isInCode(i)) backtickCount++;
1685
+ if (backtickCount % 2 === 1) s += "`";
1686
+ openElements.sort((a, b) => b.position - a.position);
1687
+ const closers = openElements.map((el) => {
1688
+ switch (el.type) {
1689
+ case "bracket": return "]";
1690
+ case "bold_star": return "**";
1691
+ case "bold_underscore": return "__";
1692
+ case "strike": return "~~";
1693
+ case "italic_star": return "*";
1694
+ case "italic_underscore": return "_";
1695
+ default: return "";
1696
+ }
1697
+ });
1698
+ let result = s + closers.join("");
1699
+ const finalFenceMatches = Array.from(result.matchAll(/^(\s*)(`{3,}|~{3,})/gm));
1700
+ const hasUnclosedBacktick = (result.match(/`/g) || []).length % 2 === 1;
1701
+ const hasUnclosedCodeFence = finalFenceMatches.length % 2 === 1;
1702
+ let shouldCloseParens = !hasUnclosedBacktick && !hasUnclosedCodeFence;
1703
+ if (shouldCloseParens) {
1704
+ const lastOpenParen = result.lastIndexOf("(");
1705
+ if (lastOpenParen !== -1) {
1706
+ if ((result.substring(0, lastOpenParen).match(/`/g) || []).length % 2 === 1) shouldCloseParens = false;
1707
+ }
1708
+ }
1709
+ if (shouldCloseParens) {
1710
+ const openParens = (result.match(/\(/g) || []).length;
1711
+ const closeParens = (result.match(/\)/g) || []).length;
1712
+ if (openParens > closeParens) result += ")".repeat(openParens - closeParens);
1713
+ }
1714
+ return result;
1715
+ }
1716
+
1717
+ //#endregion
1718
+ exports.AgentRegistry = AgentRegistry;
1719
+ exports.ContextStore = ContextStore;
1720
+ exports.CopilotKitCore = CopilotKitCore;
1721
+ exports.CopilotKitCoreErrorCode = CopilotKitCoreErrorCode;
1722
+ exports.CopilotKitCoreRuntimeConnectionStatus = CopilotKitCoreRuntimeConnectionStatus;
1723
+ exports.ProxiedCopilotRuntimeAgent = ProxiedCopilotRuntimeAgent;
1724
+ exports.RunHandler = RunHandler;
1725
+ exports.StateManager = StateManager;
1726
+ exports.SuggestionEngine = SuggestionEngine;
1727
+ exports.ToolCallStatus = ToolCallStatus;
1728
+ exports.completePartialMarkdown = completePartialMarkdown;
1729
+ //# sourceMappingURL=index.cjs.map