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