@copilotkitnext/core 0.0.7 → 0.0.9-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/index.d.mts +131 -24
  2. package/dist/index.d.ts +131 -24
  3. package/dist/index.js +676 -153
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +678 -153
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +4 -3
  8. package/coverage/base.css +0 -224
  9. package/coverage/block-navigation.js +0 -87
  10. package/coverage/favicon.png +0 -0
  11. package/coverage/index.html +0 -131
  12. package/coverage/lcov-report/base.css +0 -224
  13. package/coverage/lcov-report/block-navigation.js +0 -87
  14. package/coverage/lcov-report/favicon.png +0 -0
  15. package/coverage/lcov-report/index.html +0 -131
  16. package/coverage/lcov-report/prettify.css +0 -1
  17. package/coverage/lcov-report/prettify.js +0 -2
  18. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  19. package/coverage/lcov-report/sorter.js +0 -210
  20. package/coverage/lcov-report/src/agent.ts.html +0 -193
  21. package/coverage/lcov-report/src/core.ts.html +0 -919
  22. package/coverage/lcov-report/src/index.html +0 -146
  23. package/coverage/lcov-report/src/types.ts.html +0 -112
  24. package/coverage/lcov-report/src/utils/index.html +0 -116
  25. package/coverage/lcov-report/src/utils/markdown.ts.html +0 -895
  26. package/coverage/lcov.info +0 -556
  27. package/coverage/prettify.css +0 -1
  28. package/coverage/prettify.js +0 -2
  29. package/coverage/sort-arrow-sprite.png +0 -0
  30. package/coverage/sorter.js +0 -210
  31. package/coverage/src/agent.ts.html +0 -193
  32. package/coverage/src/core.ts.html +0 -919
  33. package/coverage/src/index.html +0 -146
  34. package/coverage/src/types.ts.html +0 -112
  35. package/coverage/src/utils/index.html +0 -116
  36. package/coverage/src/utils/markdown.ts.html +0 -895
package/dist/index.mjs CHANGED
@@ -1,8 +1,12 @@
1
1
  // src/core.ts
2
2
  import {
3
- randomUUID
3
+ DEFAULT_AGENT_ID,
4
+ randomUUID,
5
+ logger
4
6
  } from "@copilotkitnext/shared";
5
- import { logger } from "@copilotkitnext/shared";
7
+ import {
8
+ HttpAgent as HttpAgent2
9
+ } from "@ag-ui/client";
6
10
 
7
11
  // src/agent.ts
8
12
  import {
@@ -10,8 +14,7 @@ import {
10
14
  runHttpRequest,
11
15
  transformHttpEventStream
12
16
  } from "@ag-ui/client";
13
- var CopilotKitHttpAgent = class extends HttpAgent {
14
- isCopilotKitAgent = true;
17
+ var ProxiedCopilotRuntimeAgent = class extends HttpAgent {
15
18
  runtimeUrl;
16
19
  constructor(config) {
17
20
  super({
@@ -20,144 +23,387 @@ var CopilotKitHttpAgent = class extends HttpAgent {
20
23
  });
21
24
  this.runtimeUrl = config.runtimeUrl;
22
25
  }
23
- run(input) {
24
- const url = input.forwardedProps.__copilotkitConnect === true ? `${this.runtimeUrl}/agent/${this.agentId}/connect` : this.url;
25
- const httpEvents = runHttpRequest(url, this.requestInit(input));
26
+ connect(input) {
27
+ const httpEvents = runHttpRequest(
28
+ `${this.runtimeUrl}/agent/${this.agentId}/connect`,
29
+ this.requestInit(input)
30
+ );
26
31
  return transformHttpEventStream(httpEvents);
27
32
  }
28
33
  };
29
34
 
30
35
  // src/core.ts
36
+ import { zodToJsonSchema } from "zod-to-json-schema";
37
+ var CopilotKitCoreErrorCode = /* @__PURE__ */ ((CopilotKitCoreErrorCode2) => {
38
+ CopilotKitCoreErrorCode2["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
39
+ CopilotKitCoreErrorCode2["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
40
+ CopilotKitCoreErrorCode2["AGENT_RUN_FAILED"] = "agent_run_failed";
41
+ CopilotKitCoreErrorCode2["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
42
+ CopilotKitCoreErrorCode2["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
43
+ CopilotKitCoreErrorCode2["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
44
+ CopilotKitCoreErrorCode2["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
45
+ return CopilotKitCoreErrorCode2;
46
+ })(CopilotKitCoreErrorCode || {});
47
+ var CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ ((CopilotKitCoreRuntimeConnectionStatus2) => {
48
+ CopilotKitCoreRuntimeConnectionStatus2["Disconnected"] = "disconnected";
49
+ CopilotKitCoreRuntimeConnectionStatus2["Connected"] = "connected";
50
+ CopilotKitCoreRuntimeConnectionStatus2["Connecting"] = "connecting";
51
+ CopilotKitCoreRuntimeConnectionStatus2["Error"] = "error";
52
+ return CopilotKitCoreRuntimeConnectionStatus2;
53
+ })(CopilotKitCoreRuntimeConnectionStatus || {});
31
54
  var CopilotKitCore = class {
32
- runtimeUrl;
33
- didLoadRuntime = false;
34
- context = {};
35
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
- tools = {};
37
- agents = {};
38
55
  headers;
39
56
  properties;
40
- version;
57
+ _context = {};
58
+ _agents = {};
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+ _tools = [];
41
61
  localAgents = {};
42
62
  remoteAgents = {};
43
63
  subscribers = /* @__PURE__ */ new Set();
64
+ _runtimeUrl;
65
+ _runtimeVersion;
66
+ _runtimeConnectionStatus = "disconnected" /* Disconnected */;
44
67
  constructor({
45
68
  runtimeUrl,
46
69
  headers = {},
47
70
  properties = {},
48
71
  agents = {},
49
- tools = {}
72
+ tools = []
50
73
  }) {
51
74
  this.headers = headers;
52
75
  this.properties = properties;
53
- this.localAgents = agents;
54
- this.agents = this.localAgents;
55
- this.tools = tools;
76
+ this.localAgents = this.assignAgentIds(agents);
77
+ this._agents = this.localAgents;
78
+ this._tools = tools;
56
79
  this.setRuntimeUrl(runtimeUrl);
57
80
  }
58
- async getRuntimeInfo() {
59
- const response = await fetch(`${this.runtimeUrl}/info`, {
60
- headers: this.headers
81
+ assignAgentIds(agents) {
82
+ Object.entries(agents).forEach(([id, agent]) => {
83
+ if (agent && !agent.agentId) {
84
+ agent.agentId = id;
85
+ }
61
86
  });
62
- const {
63
- version,
64
- ...runtimeInfo
65
- } = await response.json();
66
- const agents = Object.fromEntries(
67
- Object.entries(runtimeInfo.agents).map(([id, { description }]) => {
68
- const agent = new CopilotKitHttpAgent({
69
- runtimeUrl: this.runtimeUrl,
70
- agentId: id,
71
- description
72
- });
73
- return [id, agent];
87
+ return agents;
88
+ }
89
+ async notifySubscribers(handler, errorMessage) {
90
+ await Promise.all(
91
+ Array.from(this.subscribers).map(async (subscriber) => {
92
+ try {
93
+ await handler(subscriber);
94
+ } catch (error) {
95
+ logger.error(errorMessage, error);
96
+ }
74
97
  })
75
98
  );
76
- return { agents, version };
77
- }
78
- async fetchRemoteAgents() {
79
- if (this.runtimeUrl) {
80
- this.getRuntimeInfo().then(({ agents, version }) => {
81
- this.remoteAgents = agents;
82
- this.agents = { ...this.localAgents, ...this.remoteAgents };
83
- this.didLoadRuntime = true;
84
- this.version = version;
85
- this.subscribers.forEach(async (subscriber) => {
86
- try {
87
- await subscriber.onRuntimeLoaded?.({ copilotkit: this });
88
- } catch (error) {
89
- logger.error(
90
- "Error in CopilotKitCore subscriber (onRuntimeLoaded):",
91
- error
92
- );
93
- }
94
- });
95
- }).catch((error) => {
96
- this.subscribers.forEach(async (subscriber) => {
97
- try {
98
- await subscriber.onRuntimeLoadError?.({ copilotkit: this });
99
- } catch (error2) {
100
- logger.error(
101
- "Error in CopilotKitCore subscriber (onRuntimeLoadError):",
102
- error2
103
- );
104
- }
105
- });
106
- logger.warn(`Failed to load runtime info: ${error.message}`);
99
+ }
100
+ async emitError({
101
+ error,
102
+ code,
103
+ context = {}
104
+ }) {
105
+ await this.notifySubscribers(
106
+ (subscriber) => subscriber.onError?.({
107
+ copilotkit: this,
108
+ error,
109
+ code,
110
+ context
111
+ }),
112
+ "Subscriber onError error:"
113
+ );
114
+ }
115
+ resolveAgentId(agent, providedAgentId) {
116
+ if (providedAgentId) {
117
+ return providedAgentId;
118
+ }
119
+ if (agent.agentId) {
120
+ return agent.agentId;
121
+ }
122
+ const found = Object.entries(this._agents).find(([, storedAgent]) => {
123
+ return storedAgent === agent;
124
+ });
125
+ if (found) {
126
+ agent.agentId = found[0];
127
+ return found[0];
128
+ }
129
+ agent.agentId = DEFAULT_AGENT_ID;
130
+ return DEFAULT_AGENT_ID;
131
+ }
132
+ /**
133
+ * Snapshot accessors
134
+ */
135
+ get context() {
136
+ return this._context;
137
+ }
138
+ get agents() {
139
+ return this._agents;
140
+ }
141
+ get tools() {
142
+ return this._tools;
143
+ }
144
+ get runtimeUrl() {
145
+ return this._runtimeUrl;
146
+ }
147
+ setRuntimeUrl(runtimeUrl) {
148
+ const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
149
+ if (this._runtimeUrl === normalizedRuntimeUrl) {
150
+ return;
151
+ }
152
+ this._runtimeUrl = normalizedRuntimeUrl;
153
+ void this.updateRuntimeConnection();
154
+ }
155
+ get runtimeVersion() {
156
+ return this._runtimeVersion;
157
+ }
158
+ get runtimeConnectionStatus() {
159
+ return this._runtimeConnectionStatus;
160
+ }
161
+ /**
162
+ * Runtime connection
163
+ */
164
+ async updateRuntimeConnection() {
165
+ if (!this.runtimeUrl) {
166
+ this._runtimeConnectionStatus = "disconnected" /* Disconnected */;
167
+ this._runtimeVersion = void 0;
168
+ this.remoteAgents = {};
169
+ this._agents = this.localAgents;
170
+ await this.notifySubscribers(
171
+ (subscriber) => subscriber.onRuntimeConnectionStatusChanged?.({
172
+ copilotkit: this,
173
+ status: "disconnected" /* Disconnected */
174
+ }),
175
+ "Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
176
+ );
177
+ await this.notifySubscribers(
178
+ (subscriber) => subscriber.onAgentsChanged?.({
179
+ copilotkit: this,
180
+ agents: this._agents
181
+ }),
182
+ "Subscriber onAgentsChanged error:"
183
+ );
184
+ return;
185
+ }
186
+ this._runtimeConnectionStatus = "connecting" /* Connecting */;
187
+ await this.notifySubscribers(
188
+ (subscriber) => subscriber.onRuntimeConnectionStatusChanged?.({
189
+ copilotkit: this,
190
+ status: "connecting" /* Connecting */
191
+ }),
192
+ "Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
193
+ );
194
+ try {
195
+ const response = await fetch(`${this.runtimeUrl}/info`, {
196
+ headers: this.headers
197
+ });
198
+ const {
199
+ version,
200
+ ...runtimeInfo
201
+ } = await response.json();
202
+ const agents = Object.fromEntries(
203
+ Object.entries(runtimeInfo.agents).map(([id, { description }]) => {
204
+ const agent = new ProxiedCopilotRuntimeAgent({
205
+ runtimeUrl: this.runtimeUrl,
206
+ agentId: id,
207
+ description
208
+ });
209
+ return [id, agent];
210
+ })
211
+ );
212
+ this.remoteAgents = agents;
213
+ this._agents = { ...this.localAgents, ...this.remoteAgents };
214
+ this._runtimeConnectionStatus = "connected" /* Connected */;
215
+ this._runtimeVersion = version;
216
+ await this.notifySubscribers(
217
+ (subscriber) => subscriber.onRuntimeConnectionStatusChanged?.({
218
+ copilotkit: this,
219
+ status: "connected" /* Connected */
220
+ }),
221
+ "Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
222
+ );
223
+ await this.notifySubscribers(
224
+ (subscriber) => subscriber.onAgentsChanged?.({
225
+ copilotkit: this,
226
+ agents: this._agents
227
+ }),
228
+ "Subscriber onAgentsChanged error:"
229
+ );
230
+ } catch (error) {
231
+ this._runtimeConnectionStatus = "error" /* Error */;
232
+ this._runtimeVersion = void 0;
233
+ this.remoteAgents = {};
234
+ this._agents = this.localAgents;
235
+ await this.notifySubscribers(
236
+ (subscriber) => subscriber.onRuntimeConnectionStatusChanged?.({
237
+ copilotkit: this,
238
+ status: "error" /* Error */
239
+ }),
240
+ "Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
241
+ );
242
+ await this.notifySubscribers(
243
+ (subscriber) => subscriber.onAgentsChanged?.({
244
+ copilotkit: this,
245
+ agents: this._agents
246
+ }),
247
+ "Subscriber onAgentsChanged error:"
248
+ );
249
+ const message = error instanceof Error ? error.message : JSON.stringify(error);
250
+ logger.warn(
251
+ `Failed to load runtime info (${this.runtimeUrl}/info): ${message}`
252
+ );
253
+ const runtimeError = error instanceof Error ? error : new Error(String(error));
254
+ await this.emitError({
255
+ error: runtimeError,
256
+ code: "runtime_info_fetch_failed" /* RUNTIME_INFO_FETCH_FAILED */,
257
+ context: {
258
+ runtimeUrl: this.runtimeUrl
259
+ }
107
260
  });
108
261
  }
109
262
  }
263
+ /**
264
+ * Configuration updates
265
+ */
266
+ setHeaders(headers) {
267
+ this.headers = headers;
268
+ void this.notifySubscribers(
269
+ (subscriber) => subscriber.onHeadersChanged?.({
270
+ copilotkit: this,
271
+ headers: this.headers
272
+ }),
273
+ "Subscriber onHeadersChanged error:"
274
+ );
275
+ }
276
+ setProperties(properties) {
277
+ this.properties = properties;
278
+ void this.notifySubscribers(
279
+ (subscriber) => subscriber.onPropertiesChanged?.({
280
+ copilotkit: this,
281
+ properties: this.properties
282
+ }),
283
+ "Subscriber onPropertiesChanged error:"
284
+ );
285
+ }
110
286
  setAgents(agents) {
111
- this.localAgents = agents;
112
- this.agents = { ...this.localAgents, ...this.remoteAgents };
287
+ this.localAgents = this.assignAgentIds(agents);
288
+ this._agents = { ...this.localAgents, ...this.remoteAgents };
289
+ void this.notifySubscribers(
290
+ (subscriber) => subscriber.onAgentsChanged?.({
291
+ copilotkit: this,
292
+ agents: this._agents
293
+ }),
294
+ "Subscriber onAgentsChanged error:"
295
+ );
113
296
  }
114
297
  addAgent({ id, agent }) {
115
298
  this.localAgents[id] = agent;
116
- this.agents = { ...this.localAgents, ...this.remoteAgents };
299
+ if (!agent.agentId) {
300
+ agent.agentId = id;
301
+ }
302
+ this._agents = { ...this.localAgents, ...this.remoteAgents };
303
+ void this.notifySubscribers(
304
+ (subscriber) => subscriber.onAgentsChanged?.({
305
+ copilotkit: this,
306
+ agents: this._agents
307
+ }),
308
+ "Subscriber onAgentsChanged error:"
309
+ );
117
310
  }
118
311
  removeAgent(id) {
119
312
  delete this.localAgents[id];
120
- this.agents = { ...this.localAgents, ...this.remoteAgents };
313
+ this._agents = { ...this.localAgents, ...this.remoteAgents };
314
+ void this.notifySubscribers(
315
+ (subscriber) => subscriber.onAgentsChanged?.({
316
+ copilotkit: this,
317
+ agents: this._agents
318
+ }),
319
+ "Subscriber onAgentsChanged error:"
320
+ );
121
321
  }
122
322
  getAgent(id) {
123
- if (id in this.agents) {
124
- return this.agents[id];
323
+ if (id in this._agents) {
324
+ return this._agents[id];
325
+ }
326
+ if (this.runtimeUrl !== void 0 && (this.runtimeConnectionStatus === "disconnected" /* Disconnected */ || this.runtimeConnectionStatus === "connecting" /* Connecting */)) {
327
+ return void 0;
125
328
  } else {
126
- if (!this.didLoadRuntime) {
127
- return void 0;
128
- } else {
129
- throw new Error(`Agent ${id} not found`);
130
- }
329
+ console.warn(`Agent ${id} not found`);
330
+ return void 0;
131
331
  }
132
332
  }
333
+ /**
334
+ * Context management
335
+ */
133
336
  addContext({ description, value }) {
134
337
  const id = randomUUID();
135
- this.context[id] = { description, value };
338
+ this._context[id] = { description, value };
339
+ void this.notifySubscribers(
340
+ (subscriber) => subscriber.onContextChanged?.({
341
+ copilotkit: this,
342
+ context: this._context
343
+ }),
344
+ "Subscriber onContextChanged error:"
345
+ );
136
346
  return id;
137
347
  }
138
348
  removeContext(id) {
139
- delete this.context[id];
140
- }
141
- setRuntimeUrl(runtimeUrl) {
142
- this.runtimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
143
- this.fetchRemoteAgents();
349
+ delete this._context[id];
350
+ void this.notifySubscribers(
351
+ (subscriber) => subscriber.onContextChanged?.({
352
+ copilotkit: this,
353
+ context: this._context
354
+ }),
355
+ "Subscriber onContextChanged error:"
356
+ );
144
357
  }
358
+ /**
359
+ * Tool management
360
+ */
145
361
  addTool(tool) {
146
- if (tool.name in this.tools) {
147
- logger.warn(`Tool already exists: '${tool.name}', skipping.`);
362
+ const existingToolIndex = this._tools.findIndex(
363
+ (t) => t.name === tool.name && t.agentId === tool.agentId
364
+ );
365
+ if (existingToolIndex !== -1) {
366
+ logger.warn(
367
+ `Tool already exists: '${tool.name}' for agent '${tool.agentId || "global"}', skipping.`
368
+ );
148
369
  return;
149
370
  }
150
- this.tools[tool.name] = tool;
371
+ this._tools.push(tool);
151
372
  }
152
- removeTool(id) {
153
- delete this.tools[id];
373
+ removeTool(id, agentId) {
374
+ this._tools = this._tools.filter((tool) => {
375
+ if (agentId !== void 0) {
376
+ return !(tool.name === id && tool.agentId === agentId);
377
+ }
378
+ return !(tool.name === id && !tool.agentId);
379
+ });
154
380
  }
155
- setHeaders(headers) {
156
- this.headers = headers;
381
+ /**
382
+ * Get a tool by name and optionally by agentId.
383
+ * If agentId is provided, it will first look for an agent-specific tool,
384
+ * then fall back to a global tool with the same name.
385
+ */
386
+ getTool(params) {
387
+ const { toolName, agentId } = params;
388
+ if (agentId) {
389
+ const agentTool = this._tools.find(
390
+ (tool) => tool.name === toolName && tool.agentId === agentId
391
+ );
392
+ if (agentTool) {
393
+ return agentTool;
394
+ }
395
+ }
396
+ return this._tools.find((tool) => tool.name === toolName && !tool.agentId);
157
397
  }
158
- setProperties(properties) {
159
- this.properties = properties;
398
+ /**
399
+ * Set all tools at once. Replaces existing tools.
400
+ */
401
+ setTools(tools) {
402
+ this._tools = [...tools];
160
403
  }
404
+ /**
405
+ * Subscription lifecycle
406
+ */
161
407
  subscribe(subscriber) {
162
408
  this.subscribers.add(subscriber);
163
409
  return () => {
@@ -167,19 +413,83 @@ var CopilotKitCore = class {
167
413
  unsubscribe(subscriber) {
168
414
  this.subscribers.delete(subscriber);
169
415
  }
170
- // TODO: AG-UI needs to expose the runAgent result type
416
+ /**
417
+ * Agent connectivity
418
+ */
419
+ async connectAgent({
420
+ agent,
421
+ agentId
422
+ }) {
423
+ try {
424
+ if (agent instanceof HttpAgent2) {
425
+ agent.headers = { ...this.headers };
426
+ }
427
+ const runAgentResult = await agent.connectAgent(
428
+ {
429
+ forwardedProps: this.properties,
430
+ tools: this.buildFrontendTools(agentId)
431
+ },
432
+ this.createAgentErrorSubscriber(agent, agentId)
433
+ );
434
+ return this.processAgentResult({ runAgentResult, agent, agentId });
435
+ } catch (error) {
436
+ const connectError = error instanceof Error ? error : new Error(String(error));
437
+ const context = {};
438
+ if (agentId ?? agent.agentId) {
439
+ context.agentId = agentId ?? agent.agentId;
440
+ }
441
+ await this.emitError({
442
+ error: connectError,
443
+ code: "agent_connect_failed" /* AGENT_CONNECT_FAILED */,
444
+ context
445
+ });
446
+ throw error;
447
+ }
448
+ }
171
449
  async runAgent({
172
450
  agent,
173
451
  withMessages,
174
452
  agentId
175
453
  }) {
454
+ if (agent instanceof HttpAgent2) {
455
+ agent.headers = { ...this.headers };
456
+ }
176
457
  if (withMessages) {
177
458
  agent.addMessages(withMessages);
178
459
  }
179
- const runAgentResult = await agent.runAgent({
180
- forwardedProps: this.properties
181
- });
460
+ try {
461
+ const runAgentResult = await agent.runAgent(
462
+ {
463
+ forwardedProps: this.properties,
464
+ tools: this.buildFrontendTools(agentId)
465
+ },
466
+ this.createAgentErrorSubscriber(agent, agentId)
467
+ );
468
+ return this.processAgentResult({ runAgentResult, agent, agentId });
469
+ } catch (error) {
470
+ const runError = error instanceof Error ? error : new Error(String(error));
471
+ const context = {};
472
+ if (agentId ?? agent.agentId) {
473
+ context.agentId = agentId ?? agent.agentId;
474
+ }
475
+ if (withMessages) {
476
+ context.messageCount = withMessages.length;
477
+ }
478
+ await this.emitError({
479
+ error: runError,
480
+ code: "agent_run_failed" /* AGENT_RUN_FAILED */,
481
+ context
482
+ });
483
+ throw error;
484
+ }
485
+ }
486
+ async processAgentResult({
487
+ runAgentResult,
488
+ agent,
489
+ agentId
490
+ }) {
182
491
  const { newMessages } = runAgentResult;
492
+ const effectiveAgentId = this.resolveAgentId(agent, agentId);
183
493
  let needsFollowUp = false;
184
494
  for (const message of newMessages) {
185
495
  if (message.role === "assistant") {
@@ -187,76 +497,214 @@ var CopilotKitCore = class {
187
497
  if (newMessages.findIndex(
188
498
  (m) => m.role === "tool" && m.toolCallId === toolCall.id
189
499
  ) === -1) {
190
- if (toolCall.function.name in this.tools) {
191
- const tool = this.tools[toolCall.function.name];
500
+ const tool = this.getTool({
501
+ toolName: toolCall.function.name,
502
+ agentId
503
+ });
504
+ if (tool) {
192
505
  if (tool?.agentId && tool.agentId !== agentId) {
193
506
  continue;
194
507
  }
195
508
  let toolCallResult = "";
509
+ let errorMessage;
510
+ let isArgumentError = false;
196
511
  if (tool?.handler) {
197
- const args = JSON.parse(toolCall.function.arguments);
512
+ let parsedArgs;
198
513
  try {
199
- const result = await tool.handler(args);
200
- if (result === void 0 || result === null) {
201
- toolCallResult = "";
202
- } else if (typeof result === "string") {
203
- toolCallResult = result;
204
- } else {
205
- toolCallResult = JSON.stringify(result);
206
- }
514
+ parsedArgs = JSON.parse(toolCall.function.arguments);
207
515
  } catch (error) {
208
- toolCallResult = `Error: ${error instanceof Error ? error.message : String(error)}`;
516
+ const parseError = error instanceof Error ? error : new Error(String(error));
517
+ errorMessage = parseError.message;
518
+ isArgumentError = true;
519
+ await this.emitError({
520
+ error: parseError,
521
+ code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
522
+ context: {
523
+ agentId: effectiveAgentId,
524
+ toolCallId: toolCall.id,
525
+ toolName: toolCall.function.name,
526
+ rawArguments: toolCall.function.arguments,
527
+ toolType: "specific",
528
+ messageId: message.id
529
+ }
530
+ });
531
+ }
532
+ await this.notifySubscribers(
533
+ (subscriber) => subscriber.onToolExecutionStart?.({
534
+ copilotkit: this,
535
+ toolCallId: toolCall.id,
536
+ agentId: effectiveAgentId,
537
+ toolName: toolCall.function.name,
538
+ args: parsedArgs
539
+ }),
540
+ "Subscriber onToolExecutionStart error:"
541
+ );
542
+ if (!errorMessage) {
543
+ try {
544
+ const result = await tool.handler(parsedArgs);
545
+ if (result === void 0 || result === null) {
546
+ toolCallResult = "";
547
+ } else if (typeof result === "string") {
548
+ toolCallResult = result;
549
+ } else {
550
+ toolCallResult = JSON.stringify(result);
551
+ }
552
+ } catch (error) {
553
+ const handlerError = error instanceof Error ? error : new Error(String(error));
554
+ errorMessage = handlerError.message;
555
+ await this.emitError({
556
+ error: handlerError,
557
+ code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
558
+ context: {
559
+ agentId: effectiveAgentId,
560
+ toolCallId: toolCall.id,
561
+ toolName: toolCall.function.name,
562
+ parsedArgs,
563
+ toolType: "specific",
564
+ messageId: message.id
565
+ }
566
+ });
567
+ }
568
+ }
569
+ if (errorMessage) {
570
+ toolCallResult = `Error: ${errorMessage}`;
571
+ }
572
+ await this.notifySubscribers(
573
+ (subscriber) => subscriber.onToolExecutionEnd?.({
574
+ copilotkit: this,
575
+ toolCallId: toolCall.id,
576
+ agentId: effectiveAgentId,
577
+ toolName: toolCall.function.name,
578
+ result: errorMessage ? "" : toolCallResult,
579
+ error: errorMessage
580
+ }),
581
+ "Subscriber onToolExecutionEnd error:"
582
+ );
583
+ if (isArgumentError) {
584
+ throw new Error(errorMessage ?? "Tool execution failed");
209
585
  }
210
586
  }
211
- const messageIndex = agent.messages.findIndex(
212
- (m) => m.id === message.id
213
- );
214
- const toolMessage = {
215
- id: randomUUID(),
216
- role: "tool",
217
- toolCallId: toolCall.id,
218
- content: toolCallResult
219
- };
220
- agent.messages.splice(messageIndex + 1, 0, toolMessage);
221
- if (tool?.followUp !== false) {
222
- needsFollowUp = true;
223
- }
224
- } else if ("*" in this.tools) {
225
- const wildcardTool = this.tools["*"];
226
- if (wildcardTool?.agentId && wildcardTool.agentId !== agentId) {
227
- continue;
228
- }
229
- let toolCallResult = "";
230
- if (wildcardTool?.handler) {
231
- const wildcardArgs = {
232
- toolName: toolCall.function.name,
233
- args: JSON.parse(toolCall.function.arguments)
587
+ if (!errorMessage || !isArgumentError) {
588
+ const messageIndex = agent.messages.findIndex(
589
+ (m) => m.id === message.id
590
+ );
591
+ const toolMessage = {
592
+ id: randomUUID(),
593
+ role: "tool",
594
+ toolCallId: toolCall.id,
595
+ content: toolCallResult
234
596
  };
235
- try {
236
- const result = await wildcardTool.handler(wildcardArgs);
237
- if (result === void 0 || result === null) {
238
- toolCallResult = "";
239
- } else if (typeof result === "string") {
240
- toolCallResult = result;
241
- } else {
242
- toolCallResult = JSON.stringify(result);
243
- }
244
- } catch (error) {
245
- toolCallResult = `Error: ${error instanceof Error ? error.message : String(error)}`;
597
+ agent.messages.splice(messageIndex + 1, 0, toolMessage);
598
+ if (!errorMessage && tool?.followUp !== false) {
599
+ needsFollowUp = true;
246
600
  }
247
601
  }
248
- const messageIndex = agent.messages.findIndex(
249
- (m) => m.id === message.id
250
- );
251
- const toolMessage = {
252
- id: randomUUID(),
253
- role: "tool",
254
- toolCallId: toolCall.id,
255
- content: toolCallResult
256
- };
257
- agent.messages.splice(messageIndex + 1, 0, toolMessage);
258
- if (wildcardTool?.followUp !== false) {
259
- needsFollowUp = true;
602
+ } else {
603
+ const wildcardTool = this.getTool({ toolName: "*", agentId });
604
+ if (wildcardTool) {
605
+ if (wildcardTool?.agentId && wildcardTool.agentId !== agentId) {
606
+ continue;
607
+ }
608
+ let toolCallResult = "";
609
+ let errorMessage;
610
+ let isArgumentError = false;
611
+ if (wildcardTool?.handler) {
612
+ let parsedArgs;
613
+ try {
614
+ parsedArgs = JSON.parse(toolCall.function.arguments);
615
+ } catch (error) {
616
+ const parseError = error instanceof Error ? error : new Error(String(error));
617
+ errorMessage = parseError.message;
618
+ isArgumentError = true;
619
+ await this.emitError({
620
+ error: parseError,
621
+ code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
622
+ context: {
623
+ agentId: effectiveAgentId,
624
+ toolCallId: toolCall.id,
625
+ toolName: toolCall.function.name,
626
+ rawArguments: toolCall.function.arguments,
627
+ toolType: "wildcard",
628
+ messageId: message.id
629
+ }
630
+ });
631
+ }
632
+ const wildcardArgs = {
633
+ toolName: toolCall.function.name,
634
+ args: parsedArgs
635
+ };
636
+ await this.notifySubscribers(
637
+ (subscriber) => subscriber.onToolExecutionStart?.({
638
+ copilotkit: this,
639
+ toolCallId: toolCall.id,
640
+ agentId: effectiveAgentId,
641
+ toolName: toolCall.function.name,
642
+ args: wildcardArgs
643
+ }),
644
+ "Subscriber onToolExecutionStart error:"
645
+ );
646
+ if (!errorMessage) {
647
+ try {
648
+ const result = await wildcardTool.handler(
649
+ wildcardArgs
650
+ );
651
+ if (result === void 0 || result === null) {
652
+ toolCallResult = "";
653
+ } else if (typeof result === "string") {
654
+ toolCallResult = result;
655
+ } else {
656
+ toolCallResult = JSON.stringify(result);
657
+ }
658
+ } catch (error) {
659
+ const handlerError = error instanceof Error ? error : new Error(String(error));
660
+ errorMessage = handlerError.message;
661
+ await this.emitError({
662
+ error: handlerError,
663
+ code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
664
+ context: {
665
+ agentId: effectiveAgentId,
666
+ toolCallId: toolCall.id,
667
+ toolName: toolCall.function.name,
668
+ parsedArgs: wildcardArgs,
669
+ toolType: "wildcard",
670
+ messageId: message.id
671
+ }
672
+ });
673
+ }
674
+ }
675
+ if (errorMessage) {
676
+ toolCallResult = `Error: ${errorMessage}`;
677
+ }
678
+ await this.notifySubscribers(
679
+ (subscriber) => subscriber.onToolExecutionEnd?.({
680
+ copilotkit: this,
681
+ toolCallId: toolCall.id,
682
+ agentId: effectiveAgentId,
683
+ toolName: toolCall.function.name,
684
+ result: errorMessage ? "" : toolCallResult,
685
+ error: errorMessage
686
+ }),
687
+ "Subscriber onToolExecutionEnd error:"
688
+ );
689
+ if (isArgumentError) {
690
+ throw new Error(errorMessage ?? "Tool execution failed");
691
+ }
692
+ }
693
+ if (!errorMessage || !isArgumentError) {
694
+ const messageIndex = agent.messages.findIndex(
695
+ (m) => m.id === message.id
696
+ );
697
+ const toolMessage = {
698
+ id: randomUUID(),
699
+ role: "tool",
700
+ toolCallId: toolCall.id,
701
+ content: toolCallResult
702
+ };
703
+ agent.messages.splice(messageIndex + 1, 0, toolMessage);
704
+ if (!errorMessage && wildcardTool?.followUp !== false) {
705
+ needsFollowUp = true;
706
+ }
707
+ }
260
708
  }
261
709
  }
262
710
  }
@@ -268,7 +716,82 @@ var CopilotKitCore = class {
268
716
  }
269
717
  return runAgentResult;
270
718
  }
719
+ buildFrontendTools(agentId) {
720
+ return this._tools.filter((tool) => !tool.agentId || tool.agentId === agentId).map((tool) => ({
721
+ name: tool.name,
722
+ description: tool.description ?? "",
723
+ parameters: createToolSchema(tool)
724
+ }));
725
+ }
726
+ createAgentErrorSubscriber(agent, agentId) {
727
+ const emitAgentError = async (error, code, extraContext = {}) => {
728
+ const context = { ...extraContext };
729
+ if (agentId ?? agent.agentId) {
730
+ context.agentId = agentId ?? agent.agentId;
731
+ }
732
+ await this.emitError({
733
+ error,
734
+ code,
735
+ context
736
+ });
737
+ };
738
+ return {
739
+ onRunFailed: async ({ error }) => {
740
+ await emitAgentError(
741
+ error,
742
+ "agent_run_failed_event" /* AGENT_RUN_FAILED_EVENT */,
743
+ {
744
+ source: "onRunFailed"
745
+ }
746
+ );
747
+ },
748
+ onRunErrorEvent: async ({ event }) => {
749
+ const eventError = event?.rawEvent instanceof Error ? event.rawEvent : event?.rawEvent?.error instanceof Error ? event.rawEvent.error : void 0;
750
+ const errorMessage = typeof event?.rawEvent?.error === "string" ? event.rawEvent.error : event?.message ?? "Agent run error";
751
+ const rawError = eventError ?? new Error(errorMessage);
752
+ if (event?.code && !rawError.code) {
753
+ rawError.code = event.code;
754
+ }
755
+ await emitAgentError(
756
+ rawError,
757
+ "agent_run_error_event" /* AGENT_RUN_ERROR_EVENT */,
758
+ {
759
+ source: "onRunErrorEvent",
760
+ event,
761
+ runtimeErrorCode: event?.code
762
+ }
763
+ );
764
+ }
765
+ };
766
+ }
271
767
  };
768
+ var EMPTY_TOOL_SCHEMA = {
769
+ type: "object",
770
+ properties: {},
771
+ additionalProperties: false
772
+ };
773
+ function createToolSchema(tool) {
774
+ if (!tool.parameters) {
775
+ return EMPTY_TOOL_SCHEMA;
776
+ }
777
+ const rawSchema = zodToJsonSchema(tool.parameters, {
778
+ $refStrategy: "none"
779
+ });
780
+ if (!rawSchema || typeof rawSchema !== "object") {
781
+ return { ...EMPTY_TOOL_SCHEMA };
782
+ }
783
+ const { $schema, ...schema } = rawSchema;
784
+ if (typeof schema.type !== "string") {
785
+ schema.type = "object";
786
+ }
787
+ if (typeof schema.properties !== "object" || schema.properties === null) {
788
+ schema.properties = {};
789
+ }
790
+ if (schema.additionalProperties === void 0) {
791
+ schema.additionalProperties = false;
792
+ }
793
+ return schema;
794
+ }
272
795
 
273
796
  // src/types.ts
274
797
  var ToolCallStatus = /* @__PURE__ */ ((ToolCallStatus2) => {
@@ -495,7 +1018,9 @@ ${indent}${fence}`;
495
1018
  }
496
1019
  export {
497
1020
  CopilotKitCore,
498
- CopilotKitHttpAgent,
1021
+ CopilotKitCoreErrorCode,
1022
+ CopilotKitCoreRuntimeConnectionStatus,
1023
+ ProxiedCopilotRuntimeAgent,
499
1024
  ToolCallStatus,
500
1025
  completePartialMarkdown
501
1026
  };