@copilotkitnext/core 0.0.0-max-changeset-20260109174803

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