@copilotkitnext/core 0.0.11 → 0.0.13-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.
- package/dist/index.d.mts +367 -55
- package/dist/index.d.ts +367 -55
- package/dist/index.js +1026 -518
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1022 -524
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
// src/core.ts
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
randomUUID,
|
|
5
|
-
logger
|
|
6
|
-
} from "@copilotkitnext/shared";
|
|
7
|
-
import {
|
|
8
|
-
HttpAgent as HttpAgent2
|
|
9
|
-
} from "@ag-ui/client";
|
|
1
|
+
// src/core/agent-registry.ts
|
|
2
|
+
import { HttpAgent as HttpAgent2 } from "@ag-ui/client";
|
|
3
|
+
import { logger } from "@copilotkitnext/shared";
|
|
10
4
|
|
|
11
5
|
// src/agent.ts
|
|
12
6
|
import {
|
|
@@ -32,179 +26,133 @@ var ProxiedCopilotRuntimeAgent = class extends HttpAgent {
|
|
|
32
26
|
}
|
|
33
27
|
};
|
|
34
28
|
|
|
35
|
-
// src/core.ts
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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 || {});
|
|
54
|
-
var CopilotKitCore = class {
|
|
55
|
-
headers;
|
|
56
|
-
properties;
|
|
57
|
-
_context = {};
|
|
29
|
+
// src/core/agent-registry.ts
|
|
30
|
+
var AgentRegistry = class {
|
|
31
|
+
constructor(core) {
|
|
32
|
+
this.core = core;
|
|
33
|
+
}
|
|
58
34
|
_agents = {};
|
|
59
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
60
|
-
_tools = [];
|
|
61
35
|
localAgents = {};
|
|
62
36
|
remoteAgents = {};
|
|
63
|
-
subscribers = /* @__PURE__ */ new Set();
|
|
64
37
|
_runtimeUrl;
|
|
65
38
|
_runtimeVersion;
|
|
66
39
|
_runtimeConnectionStatus = "disconnected" /* Disconnected */;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
this.
|
|
75
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Get all agents as a readonly record
|
|
42
|
+
*/
|
|
43
|
+
get agents() {
|
|
44
|
+
return this._agents;
|
|
45
|
+
}
|
|
46
|
+
get runtimeUrl() {
|
|
47
|
+
return this._runtimeUrl;
|
|
48
|
+
}
|
|
49
|
+
get runtimeVersion() {
|
|
50
|
+
return this._runtimeVersion;
|
|
51
|
+
}
|
|
52
|
+
get runtimeConnectionStatus() {
|
|
53
|
+
return this._runtimeConnectionStatus;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Initialize agents from configuration
|
|
57
|
+
*/
|
|
58
|
+
initialize(agents) {
|
|
76
59
|
this.localAgents = this.assignAgentIds(agents);
|
|
77
60
|
this.applyHeadersToAgents(this.localAgents);
|
|
78
61
|
this._agents = this.localAgents;
|
|
79
|
-
this._tools = tools;
|
|
80
|
-
this.setRuntimeUrl(runtimeUrl);
|
|
81
62
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Set the runtime URL and update connection
|
|
65
|
+
*/
|
|
66
|
+
setRuntimeUrl(runtimeUrl) {
|
|
67
|
+
const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
|
|
68
|
+
if (this._runtimeUrl === normalizedRuntimeUrl) {
|
|
69
|
+
return;
|
|
85
70
|
}
|
|
71
|
+
this._runtimeUrl = normalizedRuntimeUrl;
|
|
72
|
+
void this.updateRuntimeConnection();
|
|
86
73
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
assignAgentIds(agents) {
|
|
74
|
+
/**
|
|
75
|
+
* Set all agents at once (for development use)
|
|
76
|
+
*/
|
|
77
|
+
setAgents__unsafe_dev_only(agents) {
|
|
93
78
|
Object.entries(agents).forEach(([id, agent]) => {
|
|
94
|
-
if (agent
|
|
95
|
-
|
|
79
|
+
if (agent) {
|
|
80
|
+
this.validateAndAssignAgentId(id, agent);
|
|
96
81
|
}
|
|
97
82
|
});
|
|
98
|
-
|
|
83
|
+
this.localAgents = agents;
|
|
84
|
+
this._agents = { ...this.localAgents, ...this.remoteAgents };
|
|
85
|
+
this.applyHeadersToAgents(this._agents);
|
|
86
|
+
void this.notifyAgentsChanged();
|
|
99
87
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
);
|
|
88
|
+
/**
|
|
89
|
+
* Add a single agent (for development use)
|
|
90
|
+
*/
|
|
91
|
+
addAgent__unsafe_dev_only({ id, agent }) {
|
|
92
|
+
this.validateAndAssignAgentId(id, agent);
|
|
93
|
+
this.localAgents[id] = agent;
|
|
94
|
+
this.applyHeadersToAgent(agent);
|
|
95
|
+
this._agents = { ...this.localAgents, ...this.remoteAgents };
|
|
96
|
+
void this.notifyAgentsChanged();
|
|
110
97
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
copilotkit: this,
|
|
119
|
-
error,
|
|
120
|
-
code,
|
|
121
|
-
context
|
|
122
|
-
}),
|
|
123
|
-
"Subscriber onError error:"
|
|
124
|
-
);
|
|
98
|
+
/**
|
|
99
|
+
* Remove an agent by ID (for development use)
|
|
100
|
+
*/
|
|
101
|
+
removeAgent__unsafe_dev_only(id) {
|
|
102
|
+
delete this.localAgents[id];
|
|
103
|
+
this._agents = { ...this.localAgents, ...this.remoteAgents };
|
|
104
|
+
void this.notifyAgentsChanged();
|
|
125
105
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
return
|
|
106
|
+
/**
|
|
107
|
+
* Get an agent by ID
|
|
108
|
+
*/
|
|
109
|
+
getAgent(id) {
|
|
110
|
+
if (id in this._agents) {
|
|
111
|
+
return this._agents[id];
|
|
132
112
|
}
|
|
133
|
-
|
|
134
|
-
return
|
|
135
|
-
});
|
|
136
|
-
if (found) {
|
|
137
|
-
agent.agentId = found[0];
|
|
138
|
-
return found[0];
|
|
113
|
+
if (this.runtimeUrl !== void 0 && (this.runtimeConnectionStatus === "disconnected" /* Disconnected */ || this.runtimeConnectionStatus === "connecting" /* Connecting */)) {
|
|
114
|
+
return void 0;
|
|
139
115
|
}
|
|
140
|
-
|
|
141
|
-
return
|
|
116
|
+
console.warn(`Agent ${id} not found`);
|
|
117
|
+
return void 0;
|
|
142
118
|
}
|
|
143
119
|
/**
|
|
144
|
-
*
|
|
120
|
+
* Apply current headers to an agent
|
|
145
121
|
*/
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
get agents() {
|
|
150
|
-
return this._agents;
|
|
151
|
-
}
|
|
152
|
-
get tools() {
|
|
153
|
-
return this._tools;
|
|
154
|
-
}
|
|
155
|
-
get runtimeUrl() {
|
|
156
|
-
return this._runtimeUrl;
|
|
157
|
-
}
|
|
158
|
-
setRuntimeUrl(runtimeUrl) {
|
|
159
|
-
const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
|
|
160
|
-
if (this._runtimeUrl === normalizedRuntimeUrl) {
|
|
161
|
-
return;
|
|
122
|
+
applyHeadersToAgent(agent) {
|
|
123
|
+
if (agent instanceof HttpAgent2) {
|
|
124
|
+
agent.headers = { ...this.core.headers };
|
|
162
125
|
}
|
|
163
|
-
this._runtimeUrl = normalizedRuntimeUrl;
|
|
164
|
-
void this.updateRuntimeConnection();
|
|
165
126
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Apply current headers to all agents
|
|
129
|
+
*/
|
|
130
|
+
applyHeadersToAgents(agents) {
|
|
131
|
+
Object.values(agents).forEach((agent) => {
|
|
132
|
+
this.applyHeadersToAgent(agent);
|
|
133
|
+
});
|
|
171
134
|
}
|
|
172
135
|
/**
|
|
173
|
-
*
|
|
136
|
+
* Update runtime connection and fetch remote agents
|
|
174
137
|
*/
|
|
175
138
|
async updateRuntimeConnection() {
|
|
139
|
+
if (typeof window === "undefined") {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
176
142
|
if (!this.runtimeUrl) {
|
|
177
143
|
this._runtimeConnectionStatus = "disconnected" /* Disconnected */;
|
|
178
144
|
this._runtimeVersion = void 0;
|
|
179
145
|
this.remoteAgents = {};
|
|
180
146
|
this._agents = this.localAgents;
|
|
181
|
-
await this.
|
|
182
|
-
|
|
183
|
-
copilotkit: this,
|
|
184
|
-
status: "disconnected" /* Disconnected */
|
|
185
|
-
}),
|
|
186
|
-
"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
|
|
187
|
-
);
|
|
188
|
-
await this.notifySubscribers(
|
|
189
|
-
(subscriber) => subscriber.onAgentsChanged?.({
|
|
190
|
-
copilotkit: this,
|
|
191
|
-
agents: this._agents
|
|
192
|
-
}),
|
|
193
|
-
"Subscriber onAgentsChanged error:"
|
|
194
|
-
);
|
|
147
|
+
await this.notifyRuntimeStatusChanged("disconnected" /* Disconnected */);
|
|
148
|
+
await this.notifyAgentsChanged();
|
|
195
149
|
return;
|
|
196
150
|
}
|
|
197
151
|
this._runtimeConnectionStatus = "connecting" /* Connecting */;
|
|
198
|
-
await this.
|
|
199
|
-
(subscriber) => subscriber.onRuntimeConnectionStatusChanged?.({
|
|
200
|
-
copilotkit: this,
|
|
201
|
-
status: "connecting" /* Connecting */
|
|
202
|
-
}),
|
|
203
|
-
"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
|
|
204
|
-
);
|
|
152
|
+
await this.notifyRuntimeStatusChanged("connecting" /* Connecting */);
|
|
205
153
|
try {
|
|
206
154
|
const response = await fetch(`${this.runtimeUrl}/info`, {
|
|
207
|
-
headers: this.headers
|
|
155
|
+
headers: this.core.headers
|
|
208
156
|
});
|
|
209
157
|
const {
|
|
210
158
|
version,
|
|
@@ -215,6 +163,7 @@ var CopilotKitCore = class {
|
|
|
215
163
|
const agent = new ProxiedCopilotRuntimeAgent({
|
|
216
164
|
runtimeUrl: this.runtimeUrl,
|
|
217
165
|
agentId: id,
|
|
166
|
+
// Runtime agents always have their ID set correctly
|
|
218
167
|
description
|
|
219
168
|
});
|
|
220
169
|
this.applyHeadersToAgent(agent);
|
|
@@ -225,45 +174,19 @@ var CopilotKitCore = class {
|
|
|
225
174
|
this._agents = { ...this.localAgents, ...this.remoteAgents };
|
|
226
175
|
this._runtimeConnectionStatus = "connected" /* Connected */;
|
|
227
176
|
this._runtimeVersion = version;
|
|
228
|
-
await this.
|
|
229
|
-
|
|
230
|
-
copilotkit: this,
|
|
231
|
-
status: "connected" /* Connected */
|
|
232
|
-
}),
|
|
233
|
-
"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
|
|
234
|
-
);
|
|
235
|
-
await this.notifySubscribers(
|
|
236
|
-
(subscriber) => subscriber.onAgentsChanged?.({
|
|
237
|
-
copilotkit: this,
|
|
238
|
-
agents: this._agents
|
|
239
|
-
}),
|
|
240
|
-
"Subscriber onAgentsChanged error:"
|
|
241
|
-
);
|
|
177
|
+
await this.notifyRuntimeStatusChanged("connected" /* Connected */);
|
|
178
|
+
await this.notifyAgentsChanged();
|
|
242
179
|
} catch (error) {
|
|
243
180
|
this._runtimeConnectionStatus = "error" /* Error */;
|
|
244
181
|
this._runtimeVersion = void 0;
|
|
245
182
|
this.remoteAgents = {};
|
|
246
183
|
this._agents = this.localAgents;
|
|
247
|
-
await this.
|
|
248
|
-
|
|
249
|
-
copilotkit: this,
|
|
250
|
-
status: "error" /* Error */
|
|
251
|
-
}),
|
|
252
|
-
"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
|
|
253
|
-
);
|
|
254
|
-
await this.notifySubscribers(
|
|
255
|
-
(subscriber) => subscriber.onAgentsChanged?.({
|
|
256
|
-
copilotkit: this,
|
|
257
|
-
agents: this._agents
|
|
258
|
-
}),
|
|
259
|
-
"Subscriber onAgentsChanged error:"
|
|
260
|
-
);
|
|
184
|
+
await this.notifyRuntimeStatusChanged("error" /* Error */);
|
|
185
|
+
await this.notifyAgentsChanged();
|
|
261
186
|
const message = error instanceof Error ? error.message : JSON.stringify(error);
|
|
262
|
-
logger.warn(
|
|
263
|
-
`Failed to load runtime info (${this.runtimeUrl}/info): ${message}`
|
|
264
|
-
);
|
|
187
|
+
logger.warn(`Failed to load runtime info (${this.runtimeUrl}/info): ${message}`);
|
|
265
188
|
const runtimeError = error instanceof Error ? error : new Error(String(error));
|
|
266
|
-
await this.emitError({
|
|
189
|
+
await this.core.emitError({
|
|
267
190
|
error: runtimeError,
|
|
268
191
|
code: "runtime_info_fetch_failed" /* RUNTIME_INFO_FETCH_FAILED */,
|
|
269
192
|
context: {
|
|
@@ -273,118 +196,479 @@ var CopilotKitCore = class {
|
|
|
273
196
|
}
|
|
274
197
|
}
|
|
275
198
|
/**
|
|
276
|
-
*
|
|
199
|
+
* Assign agent IDs to a record of agents
|
|
277
200
|
*/
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}),
|
|
286
|
-
"Subscriber onHeadersChanged error:"
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
setProperties(properties) {
|
|
290
|
-
this.properties = properties;
|
|
291
|
-
void this.notifySubscribers(
|
|
292
|
-
(subscriber) => subscriber.onPropertiesChanged?.({
|
|
293
|
-
copilotkit: this,
|
|
294
|
-
properties: this.properties
|
|
295
|
-
}),
|
|
296
|
-
"Subscriber onPropertiesChanged error:"
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
setAgents(agents) {
|
|
300
|
-
this.localAgents = this.assignAgentIds(agents);
|
|
301
|
-
this._agents = { ...this.localAgents, ...this.remoteAgents };
|
|
302
|
-
this.applyHeadersToAgents(this._agents);
|
|
303
|
-
void this.notifySubscribers(
|
|
304
|
-
(subscriber) => subscriber.onAgentsChanged?.({
|
|
305
|
-
copilotkit: this,
|
|
306
|
-
agents: this._agents
|
|
307
|
-
}),
|
|
308
|
-
"Subscriber onAgentsChanged error:"
|
|
309
|
-
);
|
|
201
|
+
assignAgentIds(agents) {
|
|
202
|
+
Object.entries(agents).forEach(([id, agent]) => {
|
|
203
|
+
if (agent) {
|
|
204
|
+
this.validateAndAssignAgentId(id, agent);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
return agents;
|
|
310
208
|
}
|
|
311
|
-
|
|
312
|
-
|
|
209
|
+
/**
|
|
210
|
+
* Validate and assign an agent ID
|
|
211
|
+
*/
|
|
212
|
+
validateAndAssignAgentId(registrationId, agent) {
|
|
213
|
+
if (agent.agentId && agent.agentId !== registrationId) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
`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.`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
313
218
|
if (!agent.agentId) {
|
|
314
|
-
agent.agentId =
|
|
219
|
+
agent.agentId = registrationId;
|
|
315
220
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Notify subscribers of runtime status changes
|
|
224
|
+
*/
|
|
225
|
+
async notifyRuntimeStatusChanged(status) {
|
|
226
|
+
await this.core.notifySubscribers(
|
|
227
|
+
(subscriber) => subscriber.onRuntimeConnectionStatusChanged?.({
|
|
228
|
+
copilotkit: this.core,
|
|
229
|
+
status
|
|
322
230
|
}),
|
|
323
|
-
"
|
|
231
|
+
"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
|
|
324
232
|
);
|
|
325
233
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Notify subscribers of agent changes
|
|
236
|
+
*/
|
|
237
|
+
async notifyAgentsChanged() {
|
|
238
|
+
await this.core.notifySubscribers(
|
|
330
239
|
(subscriber) => subscriber.onAgentsChanged?.({
|
|
331
|
-
copilotkit: this,
|
|
240
|
+
copilotkit: this.core,
|
|
332
241
|
agents: this._agents
|
|
333
242
|
}),
|
|
334
243
|
"Subscriber onAgentsChanged error:"
|
|
335
244
|
);
|
|
336
245
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// src/core/context-store.ts
|
|
249
|
+
import { randomUUID } from "@copilotkitnext/shared";
|
|
250
|
+
var ContextStore = class {
|
|
251
|
+
constructor(core) {
|
|
252
|
+
this.core = core;
|
|
253
|
+
}
|
|
254
|
+
_context = {};
|
|
255
|
+
/**
|
|
256
|
+
* Get all context entries as a readonly record
|
|
257
|
+
*/
|
|
258
|
+
get context() {
|
|
259
|
+
return this._context;
|
|
347
260
|
}
|
|
348
261
|
/**
|
|
349
|
-
*
|
|
262
|
+
* Add a new context entry
|
|
263
|
+
* @returns The ID of the created context entry
|
|
350
264
|
*/
|
|
351
265
|
addContext({ description, value }) {
|
|
352
266
|
const id = randomUUID();
|
|
353
267
|
this._context[id] = { description, value };
|
|
354
|
-
void this.notifySubscribers(
|
|
355
|
-
(subscriber) => subscriber.onContextChanged?.({
|
|
356
|
-
copilotkit: this,
|
|
357
|
-
context: this._context
|
|
358
|
-
}),
|
|
359
|
-
"Subscriber onContextChanged error:"
|
|
360
|
-
);
|
|
268
|
+
void this.notifySubscribers();
|
|
361
269
|
return id;
|
|
362
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Remove a context entry by ID
|
|
273
|
+
*/
|
|
363
274
|
removeContext(id) {
|
|
364
275
|
delete this._context[id];
|
|
365
|
-
void this.notifySubscribers(
|
|
276
|
+
void this.notifySubscribers();
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Notify all subscribers of context changes
|
|
280
|
+
*/
|
|
281
|
+
async notifySubscribers() {
|
|
282
|
+
await this.core.notifySubscribers(
|
|
366
283
|
(subscriber) => subscriber.onContextChanged?.({
|
|
367
|
-
copilotkit: this,
|
|
284
|
+
copilotkit: this.core,
|
|
368
285
|
context: this._context
|
|
369
286
|
}),
|
|
370
287
|
"Subscriber onContextChanged error:"
|
|
371
288
|
);
|
|
372
289
|
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// src/core/suggestion-engine.ts
|
|
293
|
+
import { randomUUID as randomUUID2, partialJSONParse } from "@copilotkitnext/shared";
|
|
294
|
+
var SuggestionEngine = class {
|
|
295
|
+
constructor(core) {
|
|
296
|
+
this.core = core;
|
|
297
|
+
}
|
|
298
|
+
_suggestionsConfig = {};
|
|
299
|
+
_suggestions = {};
|
|
300
|
+
_runningSuggestions = {};
|
|
301
|
+
/**
|
|
302
|
+
* Initialize with suggestion configs
|
|
303
|
+
*/
|
|
304
|
+
initialize(suggestionsConfig) {
|
|
305
|
+
for (const config of suggestionsConfig) {
|
|
306
|
+
this._suggestionsConfig[randomUUID2()] = config;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Add a suggestion configuration
|
|
311
|
+
* @returns The ID of the created config
|
|
312
|
+
*/
|
|
313
|
+
addSuggestionsConfig(config) {
|
|
314
|
+
const id = randomUUID2();
|
|
315
|
+
this._suggestionsConfig[id] = config;
|
|
316
|
+
void this.notifySuggestionsConfigChanged();
|
|
317
|
+
return id;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Remove a suggestion configuration by ID
|
|
321
|
+
*/
|
|
322
|
+
removeSuggestionsConfig(id) {
|
|
323
|
+
delete this._suggestionsConfig[id];
|
|
324
|
+
void this.notifySuggestionsConfigChanged();
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Reload suggestions for a specific agent
|
|
328
|
+
* This triggers generation of new suggestions based on current configs
|
|
329
|
+
*/
|
|
330
|
+
reloadSuggestions(agentId) {
|
|
331
|
+
this.clearSuggestions(agentId);
|
|
332
|
+
const agent = this.core.getAgent(agentId);
|
|
333
|
+
if (!agent) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const messageCount = agent.messages?.length ?? 0;
|
|
337
|
+
let hasAnySuggestions = false;
|
|
338
|
+
for (const config of Object.values(this._suggestionsConfig)) {
|
|
339
|
+
if (config.consumerAgentId !== void 0 && config.consumerAgentId !== "*" && config.consumerAgentId !== agentId) {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (!this.shouldShowSuggestions(config, messageCount)) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
const suggestionId = randomUUID2();
|
|
346
|
+
if (isDynamicSuggestionsConfig(config)) {
|
|
347
|
+
if (!hasAnySuggestions) {
|
|
348
|
+
hasAnySuggestions = true;
|
|
349
|
+
void this.notifySuggestionsStartedLoading(agentId);
|
|
350
|
+
}
|
|
351
|
+
void this.generateSuggestions(suggestionId, config, agentId);
|
|
352
|
+
} else if (isStaticSuggestionsConfig(config)) {
|
|
353
|
+
this.addStaticSuggestions(suggestionId, config, agentId);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Clear all suggestions for a specific agent
|
|
359
|
+
*/
|
|
360
|
+
clearSuggestions(agentId) {
|
|
361
|
+
const runningAgents = this._runningSuggestions[agentId];
|
|
362
|
+
if (runningAgents) {
|
|
363
|
+
for (const agent of runningAgents) {
|
|
364
|
+
agent.abortRun();
|
|
365
|
+
}
|
|
366
|
+
delete this._runningSuggestions[agentId];
|
|
367
|
+
}
|
|
368
|
+
this._suggestions[agentId] = {};
|
|
369
|
+
void this.notifySuggestionsChanged(agentId, []);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get current suggestions for an agent
|
|
373
|
+
*/
|
|
374
|
+
getSuggestions(agentId) {
|
|
375
|
+
const suggestions = Object.values(this._suggestions[agentId] ?? {}).flat();
|
|
376
|
+
const isLoading = (this._runningSuggestions[agentId]?.length ?? 0) > 0;
|
|
377
|
+
return { suggestions, isLoading };
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Generate suggestions using a provider agent
|
|
381
|
+
*/
|
|
382
|
+
async generateSuggestions(suggestionId, config, consumerAgentId) {
|
|
383
|
+
let agent = void 0;
|
|
384
|
+
try {
|
|
385
|
+
const suggestionsProviderAgent = this.core.getAgent(config.providerAgentId ?? "default");
|
|
386
|
+
if (!suggestionsProviderAgent) {
|
|
387
|
+
throw new Error(`Suggestions provider agent not found: ${config.providerAgentId}`);
|
|
388
|
+
}
|
|
389
|
+
const suggestionsConsumerAgent = this.core.getAgent(consumerAgentId);
|
|
390
|
+
if (!suggestionsConsumerAgent) {
|
|
391
|
+
throw new Error(`Suggestions consumer agent not found: ${consumerAgentId}`);
|
|
392
|
+
}
|
|
393
|
+
const clonedAgent = suggestionsProviderAgent.clone();
|
|
394
|
+
agent = clonedAgent;
|
|
395
|
+
agent.agentId = suggestionId;
|
|
396
|
+
agent.threadId = suggestionId;
|
|
397
|
+
agent.messages = JSON.parse(JSON.stringify(suggestionsConsumerAgent.messages));
|
|
398
|
+
agent.state = JSON.parse(JSON.stringify(suggestionsConsumerAgent.state));
|
|
399
|
+
this._suggestions[consumerAgentId] = {
|
|
400
|
+
...this._suggestions[consumerAgentId] ?? {},
|
|
401
|
+
[suggestionId]: []
|
|
402
|
+
};
|
|
403
|
+
this._runningSuggestions[consumerAgentId] = [...this._runningSuggestions[consumerAgentId] ?? [], agent];
|
|
404
|
+
agent.addMessage({
|
|
405
|
+
id: suggestionId,
|
|
406
|
+
role: "user",
|
|
407
|
+
content: [
|
|
408
|
+
`Suggest what the user could say next. Provide clear, highly relevant suggestions by calling the \`copilotkitSuggest\` tool.`,
|
|
409
|
+
`Provide at least ${config.minSuggestions ?? 1} and at most ${config.maxSuggestions ?? 3} suggestions.`,
|
|
410
|
+
`The user has the following tools available: ${JSON.stringify(this.core.buildFrontendTools(consumerAgentId))}.`,
|
|
411
|
+
` ${config.instructions}`
|
|
412
|
+
].join("\n")
|
|
413
|
+
});
|
|
414
|
+
await agent.runAgent(
|
|
415
|
+
{
|
|
416
|
+
context: Object.values(this.core.context),
|
|
417
|
+
forwardedProps: {
|
|
418
|
+
...this.core.properties,
|
|
419
|
+
toolChoice: { type: "function", function: { name: "copilotkitSuggest" } }
|
|
420
|
+
},
|
|
421
|
+
tools: [SUGGEST_TOOL]
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
onMessagesChanged: ({ messages }) => {
|
|
425
|
+
this.extractSuggestions(messages, suggestionId, consumerAgentId, true);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
);
|
|
429
|
+
} catch (error) {
|
|
430
|
+
console.warn("Error generating suggestions:", error);
|
|
431
|
+
} finally {
|
|
432
|
+
this.finalizeSuggestions(suggestionId, consumerAgentId);
|
|
433
|
+
const runningAgents = this._runningSuggestions[consumerAgentId];
|
|
434
|
+
if (agent && runningAgents) {
|
|
435
|
+
const filteredAgents = runningAgents.filter((a) => a !== agent);
|
|
436
|
+
this._runningSuggestions[consumerAgentId] = filteredAgents;
|
|
437
|
+
if (filteredAgents.length === 0) {
|
|
438
|
+
delete this._runningSuggestions[consumerAgentId];
|
|
439
|
+
await this.notifySuggestionsFinishedLoading(consumerAgentId);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Finalize suggestions by marking them as no longer loading
|
|
446
|
+
*/
|
|
447
|
+
finalizeSuggestions(suggestionId, consumerAgentId) {
|
|
448
|
+
const agentSuggestions = this._suggestions[consumerAgentId];
|
|
449
|
+
const currentSuggestions = agentSuggestions?.[suggestionId];
|
|
450
|
+
if (agentSuggestions && currentSuggestions && currentSuggestions.length > 0) {
|
|
451
|
+
const finalizedSuggestions = currentSuggestions.filter((suggestion) => suggestion.title !== "" || suggestion.message !== "").map((suggestion) => ({
|
|
452
|
+
...suggestion,
|
|
453
|
+
isLoading: false
|
|
454
|
+
}));
|
|
455
|
+
if (finalizedSuggestions.length > 0) {
|
|
456
|
+
agentSuggestions[suggestionId] = finalizedSuggestions;
|
|
457
|
+
} else {
|
|
458
|
+
delete agentSuggestions[suggestionId];
|
|
459
|
+
}
|
|
460
|
+
const allSuggestions = Object.values(this._suggestions[consumerAgentId] ?? {}).flat();
|
|
461
|
+
void this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "finalized");
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Extract suggestions from messages (called during streaming)
|
|
466
|
+
*/
|
|
467
|
+
extractSuggestions(messages, suggestionId, consumerAgentId, isRunning) {
|
|
468
|
+
const idx = messages.findIndex((message) => message.id === suggestionId);
|
|
469
|
+
if (idx == -1) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const suggestions = [];
|
|
473
|
+
const newMessages = messages.slice(idx + 1);
|
|
474
|
+
for (const message of newMessages) {
|
|
475
|
+
if (message.role === "assistant" && message.toolCalls) {
|
|
476
|
+
for (const toolCall of message.toolCalls) {
|
|
477
|
+
if (toolCall.function.name === "copilotkitSuggest") {
|
|
478
|
+
const fullArgs = Array.isArray(toolCall.function.arguments) ? toolCall.function.arguments.join("") : toolCall.function.arguments;
|
|
479
|
+
const parsed = partialJSONParse(fullArgs);
|
|
480
|
+
if (parsed && typeof parsed === "object" && "suggestions" in parsed) {
|
|
481
|
+
const parsedSuggestions = parsed.suggestions;
|
|
482
|
+
if (Array.isArray(parsedSuggestions)) {
|
|
483
|
+
for (const item of parsedSuggestions) {
|
|
484
|
+
if (item && typeof item === "object" && "title" in item) {
|
|
485
|
+
suggestions.push({
|
|
486
|
+
title: item.title ?? "",
|
|
487
|
+
message: item.message ?? "",
|
|
488
|
+
isLoading: false
|
|
489
|
+
// Will be set correctly below
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
if (isRunning && suggestions.length > 0) {
|
|
500
|
+
suggestions[suggestions.length - 1].isLoading = true;
|
|
501
|
+
}
|
|
502
|
+
const agentSuggestions = this._suggestions[consumerAgentId];
|
|
503
|
+
if (agentSuggestions) {
|
|
504
|
+
agentSuggestions[suggestionId] = suggestions;
|
|
505
|
+
const allSuggestions = Object.values(this._suggestions[consumerAgentId] ?? {}).flat();
|
|
506
|
+
void this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "suggestions changed");
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Notify subscribers of suggestions config changes
|
|
511
|
+
*/
|
|
512
|
+
async notifySuggestionsConfigChanged() {
|
|
513
|
+
await this.core.notifySubscribers(
|
|
514
|
+
(subscriber) => subscriber.onSuggestionsConfigChanged?.({
|
|
515
|
+
copilotkit: this.core,
|
|
516
|
+
suggestionsConfig: this._suggestionsConfig
|
|
517
|
+
}),
|
|
518
|
+
"Subscriber onSuggestionsConfigChanged error:"
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Notify subscribers of suggestions changes
|
|
523
|
+
*/
|
|
524
|
+
async notifySuggestionsChanged(agentId, suggestions, context = "") {
|
|
525
|
+
await this.core.notifySubscribers(
|
|
526
|
+
(subscriber) => subscriber.onSuggestionsChanged?.({
|
|
527
|
+
copilotkit: this.core,
|
|
528
|
+
agentId,
|
|
529
|
+
suggestions
|
|
530
|
+
}),
|
|
531
|
+
`Subscriber onSuggestionsChanged error: ${context}`
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Notify subscribers that suggestions started loading
|
|
536
|
+
*/
|
|
537
|
+
async notifySuggestionsStartedLoading(agentId) {
|
|
538
|
+
await this.core.notifySubscribers(
|
|
539
|
+
(subscriber) => subscriber.onSuggestionsStartedLoading?.({
|
|
540
|
+
copilotkit: this.core,
|
|
541
|
+
agentId
|
|
542
|
+
}),
|
|
543
|
+
"Subscriber onSuggestionsStartedLoading error:"
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Notify subscribers that suggestions finished loading
|
|
548
|
+
*/
|
|
549
|
+
async notifySuggestionsFinishedLoading(agentId) {
|
|
550
|
+
await this.core.notifySubscribers(
|
|
551
|
+
(subscriber) => subscriber.onSuggestionsFinishedLoading?.({
|
|
552
|
+
copilotkit: this.core,
|
|
553
|
+
agentId
|
|
554
|
+
}),
|
|
555
|
+
"Subscriber onSuggestionsFinishedLoading error:"
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Check if suggestions should be shown based on availability and message count
|
|
560
|
+
*/
|
|
561
|
+
shouldShowSuggestions(config, messageCount) {
|
|
562
|
+
const availability = config.available;
|
|
563
|
+
if (!availability) {
|
|
564
|
+
if (isDynamicSuggestionsConfig(config)) {
|
|
565
|
+
return messageCount > 0;
|
|
566
|
+
} else {
|
|
567
|
+
return messageCount === 0;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
switch (availability) {
|
|
571
|
+
case "disabled":
|
|
572
|
+
return false;
|
|
573
|
+
case "before-first-message":
|
|
574
|
+
return messageCount === 0;
|
|
575
|
+
case "after-first-message":
|
|
576
|
+
return messageCount > 0;
|
|
577
|
+
case "always":
|
|
578
|
+
return true;
|
|
579
|
+
default:
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Add static suggestions directly without AI generation
|
|
585
|
+
*/
|
|
586
|
+
addStaticSuggestions(suggestionId, config, consumerAgentId) {
|
|
587
|
+
const suggestions = config.suggestions.map((s) => ({
|
|
588
|
+
...s,
|
|
589
|
+
isLoading: false
|
|
590
|
+
}));
|
|
591
|
+
this._suggestions[consumerAgentId] = {
|
|
592
|
+
...this._suggestions[consumerAgentId] ?? {},
|
|
593
|
+
[suggestionId]: suggestions
|
|
594
|
+
};
|
|
595
|
+
const allSuggestions = Object.values(this._suggestions[consumerAgentId] ?? {}).flat();
|
|
596
|
+
void this.notifySuggestionsChanged(consumerAgentId, allSuggestions, "static suggestions added");
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
function isDynamicSuggestionsConfig(config) {
|
|
600
|
+
return "instructions" in config;
|
|
601
|
+
}
|
|
602
|
+
function isStaticSuggestionsConfig(config) {
|
|
603
|
+
return "suggestions" in config;
|
|
604
|
+
}
|
|
605
|
+
var SUGGEST_TOOL = {
|
|
606
|
+
name: "copilotkitSuggest",
|
|
607
|
+
description: "Suggest what the user could say next",
|
|
608
|
+
parameters: {
|
|
609
|
+
type: "object",
|
|
610
|
+
properties: {
|
|
611
|
+
suggestions: {
|
|
612
|
+
type: "array",
|
|
613
|
+
description: "List of suggestions shown to the user as buttons.",
|
|
614
|
+
items: {
|
|
615
|
+
type: "object",
|
|
616
|
+
properties: {
|
|
617
|
+
title: {
|
|
618
|
+
type: "string",
|
|
619
|
+
description: "The title of the suggestion. This is shown as a button and should be short."
|
|
620
|
+
},
|
|
621
|
+
message: {
|
|
622
|
+
type: "string",
|
|
623
|
+
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."
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
required: ["title", "message"],
|
|
627
|
+
additionalProperties: false
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
required: ["suggestions"],
|
|
632
|
+
additionalProperties: false
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
// src/core/run-handler.ts
|
|
637
|
+
import { HttpAgent as HttpAgent3 } from "@ag-ui/client";
|
|
638
|
+
import { randomUUID as randomUUID3, logger as logger2 } from "@copilotkitnext/shared";
|
|
639
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
640
|
+
var RunHandler = class {
|
|
641
|
+
constructor(core) {
|
|
642
|
+
this.core = core;
|
|
643
|
+
}
|
|
644
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
645
|
+
_tools = [];
|
|
646
|
+
/**
|
|
647
|
+
* Get all tools as a readonly array
|
|
648
|
+
*/
|
|
649
|
+
get tools() {
|
|
650
|
+
return this._tools;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Initialize with tools
|
|
654
|
+
*/
|
|
655
|
+
initialize(tools) {
|
|
656
|
+
this._tools = tools;
|
|
657
|
+
}
|
|
373
658
|
/**
|
|
374
|
-
*
|
|
659
|
+
* Add a tool to the registry
|
|
375
660
|
*/
|
|
376
661
|
addTool(tool) {
|
|
377
|
-
const existingToolIndex = this._tools.findIndex(
|
|
378
|
-
(t) => t.name === tool.name && t.agentId === tool.agentId
|
|
379
|
-
);
|
|
662
|
+
const existingToolIndex = this._tools.findIndex((t) => t.name === tool.name && t.agentId === tool.agentId);
|
|
380
663
|
if (existingToolIndex !== -1) {
|
|
381
|
-
|
|
382
|
-
`Tool already exists: '${tool.name}' for agent '${tool.agentId || "global"}', skipping.`
|
|
383
|
-
);
|
|
664
|
+
logger2.warn(`Tool already exists: '${tool.name}' for agent '${tool.agentId || "global"}', skipping.`);
|
|
384
665
|
return;
|
|
385
666
|
}
|
|
386
667
|
this._tools.push(tool);
|
|
387
668
|
}
|
|
669
|
+
/**
|
|
670
|
+
* Remove a tool by name and optionally by agentId
|
|
671
|
+
*/
|
|
388
672
|
removeTool(id, agentId) {
|
|
389
673
|
this._tools = this._tools.filter((tool) => {
|
|
390
674
|
if (agentId !== void 0) {
|
|
@@ -401,9 +685,7 @@ var CopilotKitCore = class {
|
|
|
401
685
|
getTool(params) {
|
|
402
686
|
const { toolName, agentId } = params;
|
|
403
687
|
if (agentId) {
|
|
404
|
-
const agentTool = this._tools.find(
|
|
405
|
-
(tool) => tool.name === toolName && tool.agentId === agentId
|
|
406
|
-
);
|
|
688
|
+
const agentTool = this._tools.find((tool) => tool.name === toolName && tool.agentId === agentId);
|
|
407
689
|
if (agentTool) {
|
|
408
690
|
return agentTool;
|
|
409
691
|
}
|
|
@@ -417,43 +699,28 @@ var CopilotKitCore = class {
|
|
|
417
699
|
this._tools = [...tools];
|
|
418
700
|
}
|
|
419
701
|
/**
|
|
420
|
-
*
|
|
421
|
-
*/
|
|
422
|
-
subscribe(subscriber) {
|
|
423
|
-
this.subscribers.add(subscriber);
|
|
424
|
-
return () => {
|
|
425
|
-
this.unsubscribe(subscriber);
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
unsubscribe(subscriber) {
|
|
429
|
-
this.subscribers.delete(subscriber);
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Agent connectivity
|
|
702
|
+
* Connect an agent (establish initial connection)
|
|
433
703
|
*/
|
|
434
|
-
async connectAgent({
|
|
435
|
-
agent,
|
|
436
|
-
agentId
|
|
437
|
-
}) {
|
|
704
|
+
async connectAgent({ agent }) {
|
|
438
705
|
try {
|
|
439
|
-
if (agent instanceof
|
|
440
|
-
agent.headers = { ...this.headers };
|
|
706
|
+
if (agent instanceof HttpAgent3) {
|
|
707
|
+
agent.headers = { ...this.core.headers };
|
|
441
708
|
}
|
|
442
709
|
const runAgentResult = await agent.connectAgent(
|
|
443
710
|
{
|
|
444
|
-
forwardedProps: this.properties,
|
|
445
|
-
tools: this.buildFrontendTools(agentId)
|
|
711
|
+
forwardedProps: this.core.properties,
|
|
712
|
+
tools: this.buildFrontendTools(agent.agentId)
|
|
446
713
|
},
|
|
447
|
-
this.createAgentErrorSubscriber(agent
|
|
714
|
+
this.createAgentErrorSubscriber(agent)
|
|
448
715
|
);
|
|
449
|
-
return this.processAgentResult({ runAgentResult, agent
|
|
716
|
+
return this.processAgentResult({ runAgentResult, agent });
|
|
450
717
|
} catch (error) {
|
|
451
718
|
const connectError = error instanceof Error ? error : new Error(String(error));
|
|
452
719
|
const context = {};
|
|
453
|
-
if (
|
|
454
|
-
context.agentId =
|
|
720
|
+
if (agent.agentId) {
|
|
721
|
+
context.agentId = agent.agentId;
|
|
455
722
|
}
|
|
456
|
-
await this.emitError({
|
|
723
|
+
await this.core.emitError({
|
|
457
724
|
error: connectError,
|
|
458
725
|
code: "agent_connect_failed" /* AGENT_CONNECT_FAILED */,
|
|
459
726
|
context
|
|
@@ -461,13 +728,13 @@ var CopilotKitCore = class {
|
|
|
461
728
|
throw error;
|
|
462
729
|
}
|
|
463
730
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
if (agent instanceof
|
|
470
|
-
agent.headers = { ...this.headers };
|
|
731
|
+
/**
|
|
732
|
+
* Run an agent
|
|
733
|
+
*/
|
|
734
|
+
async runAgent({ agent, withMessages }) {
|
|
735
|
+
void this.core.suggestionEngine.clearSuggestions(agent.agentId);
|
|
736
|
+
if (agent instanceof HttpAgent3) {
|
|
737
|
+
agent.headers = { ...this.core.headers };
|
|
471
738
|
}
|
|
472
739
|
if (withMessages) {
|
|
473
740
|
agent.addMessages(withMessages);
|
|
@@ -475,22 +742,22 @@ var CopilotKitCore = class {
|
|
|
475
742
|
try {
|
|
476
743
|
const runAgentResult = await agent.runAgent(
|
|
477
744
|
{
|
|
478
|
-
forwardedProps: this.properties,
|
|
479
|
-
tools: this.buildFrontendTools(agentId)
|
|
745
|
+
forwardedProps: this.core.properties,
|
|
746
|
+
tools: this.buildFrontendTools(agent.agentId)
|
|
480
747
|
},
|
|
481
|
-
this.createAgentErrorSubscriber(agent
|
|
748
|
+
this.createAgentErrorSubscriber(agent)
|
|
482
749
|
);
|
|
483
|
-
return this.processAgentResult({ runAgentResult, agent
|
|
750
|
+
return this.processAgentResult({ runAgentResult, agent });
|
|
484
751
|
} catch (error) {
|
|
485
752
|
const runError = error instanceof Error ? error : new Error(String(error));
|
|
486
753
|
const context = {};
|
|
487
|
-
if (
|
|
488
|
-
context.agentId =
|
|
754
|
+
if (agent.agentId) {
|
|
755
|
+
context.agentId = agent.agentId;
|
|
489
756
|
}
|
|
490
757
|
if (withMessages) {
|
|
491
758
|
context.messageCount = withMessages.length;
|
|
492
759
|
}
|
|
493
|
-
await this.emitError({
|
|
760
|
+
await this.core.emitError({
|
|
494
761
|
error: runError,
|
|
495
762
|
code: "agent_run_failed" /* AGENT_RUN_FAILED */,
|
|
496
763
|
context
|
|
@@ -498,231 +765,35 @@ var CopilotKitCore = class {
|
|
|
498
765
|
throw error;
|
|
499
766
|
}
|
|
500
767
|
}
|
|
768
|
+
/**
|
|
769
|
+
* Process agent result and execute tools
|
|
770
|
+
*/
|
|
501
771
|
async processAgentResult({
|
|
502
772
|
runAgentResult,
|
|
503
|
-
agent
|
|
504
|
-
agentId
|
|
773
|
+
agent
|
|
505
774
|
}) {
|
|
506
775
|
const { newMessages } = runAgentResult;
|
|
507
|
-
const
|
|
776
|
+
const agentId = agent.agentId;
|
|
508
777
|
let needsFollowUp = false;
|
|
509
778
|
for (const message of newMessages) {
|
|
510
779
|
if (message.role === "assistant") {
|
|
511
780
|
for (const toolCall of message.toolCalls || []) {
|
|
512
|
-
if (newMessages.findIndex(
|
|
513
|
-
(m) => m.role === "tool" && m.toolCallId === toolCall.id
|
|
514
|
-
) === -1) {
|
|
781
|
+
if (newMessages.findIndex((m) => m.role === "tool" && m.toolCallId === toolCall.id) === -1) {
|
|
515
782
|
const tool = this.getTool({
|
|
516
783
|
toolName: toolCall.function.name,
|
|
517
|
-
agentId
|
|
784
|
+
agentId: agent.agentId
|
|
518
785
|
});
|
|
519
786
|
if (tool) {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
let toolCallResult = "";
|
|
524
|
-
let errorMessage;
|
|
525
|
-
let isArgumentError = false;
|
|
526
|
-
if (tool?.handler) {
|
|
527
|
-
let parsedArgs;
|
|
528
|
-
try {
|
|
529
|
-
parsedArgs = JSON.parse(toolCall.function.arguments);
|
|
530
|
-
} catch (error) {
|
|
531
|
-
const parseError = error instanceof Error ? error : new Error(String(error));
|
|
532
|
-
errorMessage = parseError.message;
|
|
533
|
-
isArgumentError = true;
|
|
534
|
-
await this.emitError({
|
|
535
|
-
error: parseError,
|
|
536
|
-
code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
|
|
537
|
-
context: {
|
|
538
|
-
agentId: effectiveAgentId,
|
|
539
|
-
toolCallId: toolCall.id,
|
|
540
|
-
toolName: toolCall.function.name,
|
|
541
|
-
rawArguments: toolCall.function.arguments,
|
|
542
|
-
toolType: "specific",
|
|
543
|
-
messageId: message.id
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
await this.notifySubscribers(
|
|
548
|
-
(subscriber) => subscriber.onToolExecutionStart?.({
|
|
549
|
-
copilotkit: this,
|
|
550
|
-
toolCallId: toolCall.id,
|
|
551
|
-
agentId: effectiveAgentId,
|
|
552
|
-
toolName: toolCall.function.name,
|
|
553
|
-
args: parsedArgs
|
|
554
|
-
}),
|
|
555
|
-
"Subscriber onToolExecutionStart error:"
|
|
556
|
-
);
|
|
557
|
-
if (!errorMessage) {
|
|
558
|
-
try {
|
|
559
|
-
const result = await tool.handler(
|
|
560
|
-
parsedArgs,
|
|
561
|
-
toolCall
|
|
562
|
-
);
|
|
563
|
-
if (result === void 0 || result === null) {
|
|
564
|
-
toolCallResult = "";
|
|
565
|
-
} else if (typeof result === "string") {
|
|
566
|
-
toolCallResult = result;
|
|
567
|
-
} else {
|
|
568
|
-
toolCallResult = JSON.stringify(result);
|
|
569
|
-
}
|
|
570
|
-
} catch (error) {
|
|
571
|
-
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
572
|
-
errorMessage = handlerError.message;
|
|
573
|
-
await this.emitError({
|
|
574
|
-
error: handlerError,
|
|
575
|
-
code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
|
|
576
|
-
context: {
|
|
577
|
-
agentId: effectiveAgentId,
|
|
578
|
-
toolCallId: toolCall.id,
|
|
579
|
-
toolName: toolCall.function.name,
|
|
580
|
-
parsedArgs,
|
|
581
|
-
toolType: "specific",
|
|
582
|
-
messageId: message.id
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
if (errorMessage) {
|
|
588
|
-
toolCallResult = `Error: ${errorMessage}`;
|
|
589
|
-
}
|
|
590
|
-
await this.notifySubscribers(
|
|
591
|
-
(subscriber) => subscriber.onToolExecutionEnd?.({
|
|
592
|
-
copilotkit: this,
|
|
593
|
-
toolCallId: toolCall.id,
|
|
594
|
-
agentId: effectiveAgentId,
|
|
595
|
-
toolName: toolCall.function.name,
|
|
596
|
-
result: errorMessage ? "" : toolCallResult,
|
|
597
|
-
error: errorMessage
|
|
598
|
-
}),
|
|
599
|
-
"Subscriber onToolExecutionEnd error:"
|
|
600
|
-
);
|
|
601
|
-
if (isArgumentError) {
|
|
602
|
-
throw new Error(errorMessage ?? "Tool execution failed");
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
if (!errorMessage || !isArgumentError) {
|
|
606
|
-
const messageIndex = agent.messages.findIndex(
|
|
607
|
-
(m) => m.id === message.id
|
|
608
|
-
);
|
|
609
|
-
const toolMessage = {
|
|
610
|
-
id: randomUUID(),
|
|
611
|
-
role: "tool",
|
|
612
|
-
toolCallId: toolCall.id,
|
|
613
|
-
content: toolCallResult
|
|
614
|
-
};
|
|
615
|
-
agent.messages.splice(messageIndex + 1, 0, toolMessage);
|
|
616
|
-
if (!errorMessage && tool?.followUp !== false) {
|
|
617
|
-
needsFollowUp = true;
|
|
618
|
-
}
|
|
787
|
+
const followUp = await this.executeSpecificTool(tool, toolCall, message, agent, agentId);
|
|
788
|
+
if (followUp) {
|
|
789
|
+
needsFollowUp = true;
|
|
619
790
|
}
|
|
620
791
|
} else {
|
|
621
|
-
const wildcardTool = this.getTool({ toolName: "*", agentId });
|
|
792
|
+
const wildcardTool = this.getTool({ toolName: "*", agentId: agent.agentId });
|
|
622
793
|
if (wildcardTool) {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
let toolCallResult = "";
|
|
627
|
-
let errorMessage;
|
|
628
|
-
let isArgumentError = false;
|
|
629
|
-
if (wildcardTool?.handler) {
|
|
630
|
-
let parsedArgs;
|
|
631
|
-
try {
|
|
632
|
-
parsedArgs = JSON.parse(toolCall.function.arguments);
|
|
633
|
-
} catch (error) {
|
|
634
|
-
const parseError = error instanceof Error ? error : new Error(String(error));
|
|
635
|
-
errorMessage = parseError.message;
|
|
636
|
-
isArgumentError = true;
|
|
637
|
-
await this.emitError({
|
|
638
|
-
error: parseError,
|
|
639
|
-
code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
|
|
640
|
-
context: {
|
|
641
|
-
agentId: effectiveAgentId,
|
|
642
|
-
toolCallId: toolCall.id,
|
|
643
|
-
toolName: toolCall.function.name,
|
|
644
|
-
rawArguments: toolCall.function.arguments,
|
|
645
|
-
toolType: "wildcard",
|
|
646
|
-
messageId: message.id
|
|
647
|
-
}
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
const wildcardArgs = {
|
|
651
|
-
toolName: toolCall.function.name,
|
|
652
|
-
args: parsedArgs
|
|
653
|
-
};
|
|
654
|
-
await this.notifySubscribers(
|
|
655
|
-
(subscriber) => subscriber.onToolExecutionStart?.({
|
|
656
|
-
copilotkit: this,
|
|
657
|
-
toolCallId: toolCall.id,
|
|
658
|
-
agentId: effectiveAgentId,
|
|
659
|
-
toolName: toolCall.function.name,
|
|
660
|
-
args: wildcardArgs
|
|
661
|
-
}),
|
|
662
|
-
"Subscriber onToolExecutionStart error:"
|
|
663
|
-
);
|
|
664
|
-
if (!errorMessage) {
|
|
665
|
-
try {
|
|
666
|
-
const result = await wildcardTool.handler(
|
|
667
|
-
wildcardArgs,
|
|
668
|
-
toolCall
|
|
669
|
-
);
|
|
670
|
-
if (result === void 0 || result === null) {
|
|
671
|
-
toolCallResult = "";
|
|
672
|
-
} else if (typeof result === "string") {
|
|
673
|
-
toolCallResult = result;
|
|
674
|
-
} else {
|
|
675
|
-
toolCallResult = JSON.stringify(result);
|
|
676
|
-
}
|
|
677
|
-
} catch (error) {
|
|
678
|
-
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
679
|
-
errorMessage = handlerError.message;
|
|
680
|
-
await this.emitError({
|
|
681
|
-
error: handlerError,
|
|
682
|
-
code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
|
|
683
|
-
context: {
|
|
684
|
-
agentId: effectiveAgentId,
|
|
685
|
-
toolCallId: toolCall.id,
|
|
686
|
-
toolName: toolCall.function.name,
|
|
687
|
-
parsedArgs: wildcardArgs,
|
|
688
|
-
toolType: "wildcard",
|
|
689
|
-
messageId: message.id
|
|
690
|
-
}
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
if (errorMessage) {
|
|
695
|
-
toolCallResult = `Error: ${errorMessage}`;
|
|
696
|
-
}
|
|
697
|
-
await this.notifySubscribers(
|
|
698
|
-
(subscriber) => subscriber.onToolExecutionEnd?.({
|
|
699
|
-
copilotkit: this,
|
|
700
|
-
toolCallId: toolCall.id,
|
|
701
|
-
agentId: effectiveAgentId,
|
|
702
|
-
toolName: toolCall.function.name,
|
|
703
|
-
result: errorMessage ? "" : toolCallResult,
|
|
704
|
-
error: errorMessage
|
|
705
|
-
}),
|
|
706
|
-
"Subscriber onToolExecutionEnd error:"
|
|
707
|
-
);
|
|
708
|
-
if (isArgumentError) {
|
|
709
|
-
throw new Error(errorMessage ?? "Tool execution failed");
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
if (!errorMessage || !isArgumentError) {
|
|
713
|
-
const messageIndex = agent.messages.findIndex(
|
|
714
|
-
(m) => m.id === message.id
|
|
715
|
-
);
|
|
716
|
-
const toolMessage = {
|
|
717
|
-
id: randomUUID(),
|
|
718
|
-
role: "tool",
|
|
719
|
-
toolCallId: toolCall.id,
|
|
720
|
-
content: toolCallResult
|
|
721
|
-
};
|
|
722
|
-
agent.messages.splice(messageIndex + 1, 0, toolMessage);
|
|
723
|
-
if (!errorMessage && wildcardTool?.followUp !== false) {
|
|
724
|
-
needsFollowUp = true;
|
|
725
|
-
}
|
|
794
|
+
const followUp = await this.executeWildcardTool(wildcardTool, toolCall, message, agent, agentId);
|
|
795
|
+
if (followUp) {
|
|
796
|
+
needsFollowUp = true;
|
|
726
797
|
}
|
|
727
798
|
}
|
|
728
799
|
}
|
|
@@ -731,10 +802,220 @@ var CopilotKitCore = class {
|
|
|
731
802
|
}
|
|
732
803
|
}
|
|
733
804
|
if (needsFollowUp) {
|
|
734
|
-
return await this.runAgent({ agent
|
|
805
|
+
return await this.runAgent({ agent });
|
|
735
806
|
}
|
|
807
|
+
void this.core.suggestionEngine.reloadSuggestions(agentId);
|
|
736
808
|
return runAgentResult;
|
|
737
809
|
}
|
|
810
|
+
/**
|
|
811
|
+
* Execute a specific tool
|
|
812
|
+
*/
|
|
813
|
+
async executeSpecificTool(tool, toolCall, message, agent, agentId) {
|
|
814
|
+
if (tool?.agentId && tool.agentId !== agent.agentId) {
|
|
815
|
+
return false;
|
|
816
|
+
}
|
|
817
|
+
let toolCallResult = "";
|
|
818
|
+
let errorMessage;
|
|
819
|
+
let isArgumentError = false;
|
|
820
|
+
if (tool?.handler) {
|
|
821
|
+
let parsedArgs;
|
|
822
|
+
try {
|
|
823
|
+
parsedArgs = JSON.parse(toolCall.function.arguments);
|
|
824
|
+
} catch (error) {
|
|
825
|
+
const parseError = error instanceof Error ? error : new Error(String(error));
|
|
826
|
+
errorMessage = parseError.message;
|
|
827
|
+
isArgumentError = true;
|
|
828
|
+
await this.core.emitError({
|
|
829
|
+
error: parseError,
|
|
830
|
+
code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
|
|
831
|
+
context: {
|
|
832
|
+
agentId,
|
|
833
|
+
toolCallId: toolCall.id,
|
|
834
|
+
toolName: toolCall.function.name,
|
|
835
|
+
rawArguments: toolCall.function.arguments,
|
|
836
|
+
toolType: "specific",
|
|
837
|
+
messageId: message.id
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
await this.core.notifySubscribers(
|
|
842
|
+
(subscriber) => subscriber.onToolExecutionStart?.({
|
|
843
|
+
copilotkit: this.core,
|
|
844
|
+
toolCallId: toolCall.id,
|
|
845
|
+
agentId,
|
|
846
|
+
toolName: toolCall.function.name,
|
|
847
|
+
args: parsedArgs
|
|
848
|
+
}),
|
|
849
|
+
"Subscriber onToolExecutionStart error:"
|
|
850
|
+
);
|
|
851
|
+
if (!errorMessage) {
|
|
852
|
+
try {
|
|
853
|
+
const result = await tool.handler(parsedArgs, toolCall);
|
|
854
|
+
if (result === void 0 || result === null) {
|
|
855
|
+
toolCallResult = "";
|
|
856
|
+
} else if (typeof result === "string") {
|
|
857
|
+
toolCallResult = result;
|
|
858
|
+
} else {
|
|
859
|
+
toolCallResult = JSON.stringify(result);
|
|
860
|
+
}
|
|
861
|
+
} catch (error) {
|
|
862
|
+
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
863
|
+
errorMessage = handlerError.message;
|
|
864
|
+
await this.core.emitError({
|
|
865
|
+
error: handlerError,
|
|
866
|
+
code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
|
|
867
|
+
context: {
|
|
868
|
+
agentId,
|
|
869
|
+
toolCallId: toolCall.id,
|
|
870
|
+
toolName: toolCall.function.name,
|
|
871
|
+
parsedArgs,
|
|
872
|
+
toolType: "specific",
|
|
873
|
+
messageId: message.id
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
if (errorMessage) {
|
|
879
|
+
toolCallResult = `Error: ${errorMessage}`;
|
|
880
|
+
}
|
|
881
|
+
await this.core.notifySubscribers(
|
|
882
|
+
(subscriber) => subscriber.onToolExecutionEnd?.({
|
|
883
|
+
copilotkit: this.core,
|
|
884
|
+
toolCallId: toolCall.id,
|
|
885
|
+
agentId,
|
|
886
|
+
toolName: toolCall.function.name,
|
|
887
|
+
result: errorMessage ? "" : toolCallResult,
|
|
888
|
+
error: errorMessage
|
|
889
|
+
}),
|
|
890
|
+
"Subscriber onToolExecutionEnd error:"
|
|
891
|
+
);
|
|
892
|
+
if (isArgumentError) {
|
|
893
|
+
throw new Error(errorMessage ?? "Tool execution failed");
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if (!errorMessage || !isArgumentError) {
|
|
897
|
+
const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
|
|
898
|
+
const toolMessage = {
|
|
899
|
+
id: randomUUID3(),
|
|
900
|
+
role: "tool",
|
|
901
|
+
toolCallId: toolCall.id,
|
|
902
|
+
content: toolCallResult
|
|
903
|
+
};
|
|
904
|
+
agent.messages.splice(messageIndex + 1, 0, toolMessage);
|
|
905
|
+
if (!errorMessage && tool?.followUp !== false) {
|
|
906
|
+
return true;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
return false;
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Execute a wildcard tool
|
|
913
|
+
*/
|
|
914
|
+
async executeWildcardTool(wildcardTool, toolCall, message, agent, agentId) {
|
|
915
|
+
if (wildcardTool?.agentId && wildcardTool.agentId !== agent.agentId) {
|
|
916
|
+
return false;
|
|
917
|
+
}
|
|
918
|
+
let toolCallResult = "";
|
|
919
|
+
let errorMessage;
|
|
920
|
+
let isArgumentError = false;
|
|
921
|
+
if (wildcardTool?.handler) {
|
|
922
|
+
let parsedArgs;
|
|
923
|
+
try {
|
|
924
|
+
parsedArgs = JSON.parse(toolCall.function.arguments);
|
|
925
|
+
} catch (error) {
|
|
926
|
+
const parseError = error instanceof Error ? error : new Error(String(error));
|
|
927
|
+
errorMessage = parseError.message;
|
|
928
|
+
isArgumentError = true;
|
|
929
|
+
await this.core.emitError({
|
|
930
|
+
error: parseError,
|
|
931
|
+
code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
|
|
932
|
+
context: {
|
|
933
|
+
agentId,
|
|
934
|
+
toolCallId: toolCall.id,
|
|
935
|
+
toolName: toolCall.function.name,
|
|
936
|
+
rawArguments: toolCall.function.arguments,
|
|
937
|
+
toolType: "wildcard",
|
|
938
|
+
messageId: message.id
|
|
939
|
+
}
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
const wildcardArgs = {
|
|
943
|
+
toolName: toolCall.function.name,
|
|
944
|
+
args: parsedArgs
|
|
945
|
+
};
|
|
946
|
+
await this.core.notifySubscribers(
|
|
947
|
+
(subscriber) => subscriber.onToolExecutionStart?.({
|
|
948
|
+
copilotkit: this.core,
|
|
949
|
+
toolCallId: toolCall.id,
|
|
950
|
+
agentId,
|
|
951
|
+
toolName: toolCall.function.name,
|
|
952
|
+
args: wildcardArgs
|
|
953
|
+
}),
|
|
954
|
+
"Subscriber onToolExecutionStart error:"
|
|
955
|
+
);
|
|
956
|
+
if (!errorMessage) {
|
|
957
|
+
try {
|
|
958
|
+
const result = await wildcardTool.handler(wildcardArgs, toolCall);
|
|
959
|
+
if (result === void 0 || result === null) {
|
|
960
|
+
toolCallResult = "";
|
|
961
|
+
} else if (typeof result === "string") {
|
|
962
|
+
toolCallResult = result;
|
|
963
|
+
} else {
|
|
964
|
+
toolCallResult = JSON.stringify(result);
|
|
965
|
+
}
|
|
966
|
+
} catch (error) {
|
|
967
|
+
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
968
|
+
errorMessage = handlerError.message;
|
|
969
|
+
await this.core.emitError({
|
|
970
|
+
error: handlerError,
|
|
971
|
+
code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
|
|
972
|
+
context: {
|
|
973
|
+
agentId,
|
|
974
|
+
toolCallId: toolCall.id,
|
|
975
|
+
toolName: toolCall.function.name,
|
|
976
|
+
parsedArgs: wildcardArgs,
|
|
977
|
+
toolType: "wildcard",
|
|
978
|
+
messageId: message.id
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
if (errorMessage) {
|
|
984
|
+
toolCallResult = `Error: ${errorMessage}`;
|
|
985
|
+
}
|
|
986
|
+
await this.core.notifySubscribers(
|
|
987
|
+
(subscriber) => subscriber.onToolExecutionEnd?.({
|
|
988
|
+
copilotkit: this.core,
|
|
989
|
+
toolCallId: toolCall.id,
|
|
990
|
+
agentId,
|
|
991
|
+
toolName: toolCall.function.name,
|
|
992
|
+
result: errorMessage ? "" : toolCallResult,
|
|
993
|
+
error: errorMessage
|
|
994
|
+
}),
|
|
995
|
+
"Subscriber onToolExecutionEnd error:"
|
|
996
|
+
);
|
|
997
|
+
if (isArgumentError) {
|
|
998
|
+
throw new Error(errorMessage ?? "Tool execution failed");
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
if (!errorMessage || !isArgumentError) {
|
|
1002
|
+
const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
|
|
1003
|
+
const toolMessage = {
|
|
1004
|
+
id: randomUUID3(),
|
|
1005
|
+
role: "tool",
|
|
1006
|
+
toolCallId: toolCall.id,
|
|
1007
|
+
content: toolCallResult
|
|
1008
|
+
};
|
|
1009
|
+
agent.messages.splice(messageIndex + 1, 0, toolMessage);
|
|
1010
|
+
if (!errorMessage && wildcardTool?.followUp !== false) {
|
|
1011
|
+
return true;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return false;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Build frontend tools for an agent
|
|
1018
|
+
*/
|
|
738
1019
|
buildFrontendTools(agentId) {
|
|
739
1020
|
return this._tools.filter((tool) => !tool.agentId || tool.agentId === agentId).map((tool) => ({
|
|
740
1021
|
name: tool.name,
|
|
@@ -742,13 +1023,16 @@ var CopilotKitCore = class {
|
|
|
742
1023
|
parameters: createToolSchema(tool)
|
|
743
1024
|
}));
|
|
744
1025
|
}
|
|
745
|
-
|
|
1026
|
+
/**
|
|
1027
|
+
* Create an agent error subscriber
|
|
1028
|
+
*/
|
|
1029
|
+
createAgentErrorSubscriber(agent) {
|
|
746
1030
|
const emitAgentError = async (error, code, extraContext = {}) => {
|
|
747
1031
|
const context = { ...extraContext };
|
|
748
|
-
if (
|
|
749
|
-
context.agentId =
|
|
1032
|
+
if (agent.agentId) {
|
|
1033
|
+
context.agentId = agent.agentId;
|
|
750
1034
|
}
|
|
751
|
-
await this.emitError({
|
|
1035
|
+
await this.core.emitError({
|
|
752
1036
|
error,
|
|
753
1037
|
code,
|
|
754
1038
|
context
|
|
@@ -756,13 +1040,9 @@ var CopilotKitCore = class {
|
|
|
756
1040
|
};
|
|
757
1041
|
return {
|
|
758
1042
|
onRunFailed: async ({ error }) => {
|
|
759
|
-
await emitAgentError(
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
{
|
|
763
|
-
source: "onRunFailed"
|
|
764
|
-
}
|
|
765
|
-
);
|
|
1043
|
+
await emitAgentError(error, "agent_run_failed_event" /* AGENT_RUN_FAILED_EVENT */, {
|
|
1044
|
+
source: "onRunFailed"
|
|
1045
|
+
});
|
|
766
1046
|
},
|
|
767
1047
|
onRunErrorEvent: async ({ event }) => {
|
|
768
1048
|
const eventError = event?.rawEvent instanceof Error ? event.rawEvent : event?.rawEvent?.error instanceof Error ? event.rawEvent.error : void 0;
|
|
@@ -771,15 +1051,11 @@ var CopilotKitCore = class {
|
|
|
771
1051
|
if (event?.code && !rawError.code) {
|
|
772
1052
|
rawError.code = event.code;
|
|
773
1053
|
}
|
|
774
|
-
await emitAgentError(
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
event,
|
|
780
|
-
runtimeErrorCode: event?.code
|
|
781
|
-
}
|
|
782
|
-
);
|
|
1054
|
+
await emitAgentError(rawError, "agent_run_error_event" /* AGENT_RUN_ERROR_EVENT */, {
|
|
1055
|
+
source: "onRunErrorEvent",
|
|
1056
|
+
event,
|
|
1057
|
+
runtimeErrorCode: event?.code
|
|
1058
|
+
});
|
|
783
1059
|
}
|
|
784
1060
|
};
|
|
785
1061
|
}
|
|
@@ -812,6 +1088,224 @@ function createToolSchema(tool) {
|
|
|
812
1088
|
return schema;
|
|
813
1089
|
}
|
|
814
1090
|
|
|
1091
|
+
// src/core/core.ts
|
|
1092
|
+
var CopilotKitCoreErrorCode = /* @__PURE__ */ ((CopilotKitCoreErrorCode2) => {
|
|
1093
|
+
CopilotKitCoreErrorCode2["RUNTIME_INFO_FETCH_FAILED"] = "runtime_info_fetch_failed";
|
|
1094
|
+
CopilotKitCoreErrorCode2["AGENT_CONNECT_FAILED"] = "agent_connect_failed";
|
|
1095
|
+
CopilotKitCoreErrorCode2["AGENT_RUN_FAILED"] = "agent_run_failed";
|
|
1096
|
+
CopilotKitCoreErrorCode2["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
|
|
1097
|
+
CopilotKitCoreErrorCode2["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
|
|
1098
|
+
CopilotKitCoreErrorCode2["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
|
|
1099
|
+
CopilotKitCoreErrorCode2["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
|
|
1100
|
+
return CopilotKitCoreErrorCode2;
|
|
1101
|
+
})(CopilotKitCoreErrorCode || {});
|
|
1102
|
+
var CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ ((CopilotKitCoreRuntimeConnectionStatus2) => {
|
|
1103
|
+
CopilotKitCoreRuntimeConnectionStatus2["Disconnected"] = "disconnected";
|
|
1104
|
+
CopilotKitCoreRuntimeConnectionStatus2["Connected"] = "connected";
|
|
1105
|
+
CopilotKitCoreRuntimeConnectionStatus2["Connecting"] = "connecting";
|
|
1106
|
+
CopilotKitCoreRuntimeConnectionStatus2["Error"] = "error";
|
|
1107
|
+
return CopilotKitCoreRuntimeConnectionStatus2;
|
|
1108
|
+
})(CopilotKitCoreRuntimeConnectionStatus || {});
|
|
1109
|
+
var CopilotKitCore = class {
|
|
1110
|
+
_headers;
|
|
1111
|
+
_properties;
|
|
1112
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
1113
|
+
// Delegate classes
|
|
1114
|
+
agentRegistry;
|
|
1115
|
+
contextStore;
|
|
1116
|
+
suggestionEngine;
|
|
1117
|
+
runHandler;
|
|
1118
|
+
constructor({
|
|
1119
|
+
runtimeUrl,
|
|
1120
|
+
headers = {},
|
|
1121
|
+
properties = {},
|
|
1122
|
+
agents__unsafe_dev_only = {},
|
|
1123
|
+
tools = [],
|
|
1124
|
+
suggestionsConfig = []
|
|
1125
|
+
}) {
|
|
1126
|
+
this._headers = headers;
|
|
1127
|
+
this._properties = properties;
|
|
1128
|
+
this.agentRegistry = new AgentRegistry(this);
|
|
1129
|
+
this.contextStore = new ContextStore(this);
|
|
1130
|
+
this.suggestionEngine = new SuggestionEngine(this);
|
|
1131
|
+
this.runHandler = new RunHandler(this);
|
|
1132
|
+
this.agentRegistry.initialize(agents__unsafe_dev_only);
|
|
1133
|
+
this.runHandler.initialize(tools);
|
|
1134
|
+
this.suggestionEngine.initialize(suggestionsConfig);
|
|
1135
|
+
this.agentRegistry.setRuntimeUrl(runtimeUrl);
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Internal method used by delegate classes to notify subscribers
|
|
1139
|
+
*/
|
|
1140
|
+
async notifySubscribers(handler, errorMessage) {
|
|
1141
|
+
await Promise.all(
|
|
1142
|
+
Array.from(this.subscribers).map(async (subscriber) => {
|
|
1143
|
+
try {
|
|
1144
|
+
await handler(subscriber);
|
|
1145
|
+
} catch (error) {
|
|
1146
|
+
console.error(errorMessage, error);
|
|
1147
|
+
}
|
|
1148
|
+
})
|
|
1149
|
+
);
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Internal method used by delegate classes to emit errors
|
|
1153
|
+
*/
|
|
1154
|
+
async emitError({
|
|
1155
|
+
error,
|
|
1156
|
+
code,
|
|
1157
|
+
context = {}
|
|
1158
|
+
}) {
|
|
1159
|
+
await this.notifySubscribers(
|
|
1160
|
+
(subscriber) => subscriber.onError?.({
|
|
1161
|
+
copilotkit: this,
|
|
1162
|
+
error,
|
|
1163
|
+
code,
|
|
1164
|
+
context
|
|
1165
|
+
}),
|
|
1166
|
+
"Subscriber onError error:"
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Snapshot accessors
|
|
1171
|
+
*/
|
|
1172
|
+
get context() {
|
|
1173
|
+
return this.contextStore.context;
|
|
1174
|
+
}
|
|
1175
|
+
get agents() {
|
|
1176
|
+
return this.agentRegistry.agents;
|
|
1177
|
+
}
|
|
1178
|
+
get tools() {
|
|
1179
|
+
return this.runHandler.tools;
|
|
1180
|
+
}
|
|
1181
|
+
get runtimeUrl() {
|
|
1182
|
+
return this.agentRegistry.runtimeUrl;
|
|
1183
|
+
}
|
|
1184
|
+
setRuntimeUrl(runtimeUrl) {
|
|
1185
|
+
this.agentRegistry.setRuntimeUrl(runtimeUrl);
|
|
1186
|
+
}
|
|
1187
|
+
get runtimeVersion() {
|
|
1188
|
+
return this.agentRegistry.runtimeVersion;
|
|
1189
|
+
}
|
|
1190
|
+
get headers() {
|
|
1191
|
+
return this._headers;
|
|
1192
|
+
}
|
|
1193
|
+
get properties() {
|
|
1194
|
+
return this._properties;
|
|
1195
|
+
}
|
|
1196
|
+
get runtimeConnectionStatus() {
|
|
1197
|
+
return this.agentRegistry.runtimeConnectionStatus;
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Configuration updates
|
|
1201
|
+
*/
|
|
1202
|
+
setHeaders(headers) {
|
|
1203
|
+
this._headers = headers;
|
|
1204
|
+
this.agentRegistry.applyHeadersToAgents(this.agentRegistry.agents);
|
|
1205
|
+
void this.notifySubscribers(
|
|
1206
|
+
(subscriber) => subscriber.onHeadersChanged?.({
|
|
1207
|
+
copilotkit: this,
|
|
1208
|
+
headers: this.headers
|
|
1209
|
+
}),
|
|
1210
|
+
"Subscriber onHeadersChanged error:"
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
setProperties(properties) {
|
|
1214
|
+
this._properties = properties;
|
|
1215
|
+
void this.notifySubscribers(
|
|
1216
|
+
(subscriber) => subscriber.onPropertiesChanged?.({
|
|
1217
|
+
copilotkit: this,
|
|
1218
|
+
properties: this.properties
|
|
1219
|
+
}),
|
|
1220
|
+
"Subscriber onPropertiesChanged error:"
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* Agent management (delegated to AgentRegistry)
|
|
1225
|
+
*/
|
|
1226
|
+
setAgents__unsafe_dev_only(agents) {
|
|
1227
|
+
this.agentRegistry.setAgents__unsafe_dev_only(agents);
|
|
1228
|
+
}
|
|
1229
|
+
addAgent__unsafe_dev_only(params) {
|
|
1230
|
+
this.agentRegistry.addAgent__unsafe_dev_only(params);
|
|
1231
|
+
}
|
|
1232
|
+
removeAgent__unsafe_dev_only(id) {
|
|
1233
|
+
this.agentRegistry.removeAgent__unsafe_dev_only(id);
|
|
1234
|
+
}
|
|
1235
|
+
getAgent(id) {
|
|
1236
|
+
return this.agentRegistry.getAgent(id);
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Context management (delegated to ContextStore)
|
|
1240
|
+
*/
|
|
1241
|
+
addContext(context) {
|
|
1242
|
+
return this.contextStore.addContext(context);
|
|
1243
|
+
}
|
|
1244
|
+
removeContext(id) {
|
|
1245
|
+
this.contextStore.removeContext(id);
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Suggestions management (delegated to SuggestionEngine)
|
|
1249
|
+
*/
|
|
1250
|
+
addSuggestionsConfig(config) {
|
|
1251
|
+
return this.suggestionEngine.addSuggestionsConfig(config);
|
|
1252
|
+
}
|
|
1253
|
+
removeSuggestionsConfig(id) {
|
|
1254
|
+
this.suggestionEngine.removeSuggestionsConfig(id);
|
|
1255
|
+
}
|
|
1256
|
+
reloadSuggestions(agentId) {
|
|
1257
|
+
this.suggestionEngine.reloadSuggestions(agentId);
|
|
1258
|
+
}
|
|
1259
|
+
clearSuggestions(agentId) {
|
|
1260
|
+
this.suggestionEngine.clearSuggestions(agentId);
|
|
1261
|
+
}
|
|
1262
|
+
getSuggestions(agentId) {
|
|
1263
|
+
return this.suggestionEngine.getSuggestions(agentId);
|
|
1264
|
+
}
|
|
1265
|
+
/**
|
|
1266
|
+
* Tool management (delegated to RunHandler)
|
|
1267
|
+
*/
|
|
1268
|
+
addTool(tool) {
|
|
1269
|
+
this.runHandler.addTool(tool);
|
|
1270
|
+
}
|
|
1271
|
+
removeTool(id, agentId) {
|
|
1272
|
+
this.runHandler.removeTool(id, agentId);
|
|
1273
|
+
}
|
|
1274
|
+
getTool(params) {
|
|
1275
|
+
return this.runHandler.getTool(params);
|
|
1276
|
+
}
|
|
1277
|
+
setTools(tools) {
|
|
1278
|
+
this.runHandler.setTools(tools);
|
|
1279
|
+
}
|
|
1280
|
+
/**
|
|
1281
|
+
* Subscription lifecycle
|
|
1282
|
+
*/
|
|
1283
|
+
subscribe(subscriber) {
|
|
1284
|
+
this.subscribers.add(subscriber);
|
|
1285
|
+
return () => {
|
|
1286
|
+
this.unsubscribe(subscriber);
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
unsubscribe(subscriber) {
|
|
1290
|
+
this.subscribers.delete(subscriber);
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* Agent connectivity (delegated to RunHandler)
|
|
1294
|
+
*/
|
|
1295
|
+
async connectAgent(params) {
|
|
1296
|
+
return this.runHandler.connectAgent(params);
|
|
1297
|
+
}
|
|
1298
|
+
async runAgent(params) {
|
|
1299
|
+
return this.runHandler.runAgent(params);
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Internal method used by RunHandler to build frontend tools
|
|
1303
|
+
*/
|
|
1304
|
+
buildFrontendTools(agentId) {
|
|
1305
|
+
return this.runHandler.buildFrontendTools(agentId);
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
|
|
815
1309
|
// src/types.ts
|
|
816
1310
|
var ToolCallStatus = /* @__PURE__ */ ((ToolCallStatus2) => {
|
|
817
1311
|
ToolCallStatus2["InProgress"] = "inProgress";
|
|
@@ -1036,10 +1530,14 @@ ${indent}${fence}`;
|
|
|
1036
1530
|
return result;
|
|
1037
1531
|
}
|
|
1038
1532
|
export {
|
|
1533
|
+
AgentRegistry,
|
|
1534
|
+
ContextStore,
|
|
1039
1535
|
CopilotKitCore,
|
|
1040
1536
|
CopilotKitCoreErrorCode,
|
|
1041
1537
|
CopilotKitCoreRuntimeConnectionStatus,
|
|
1042
1538
|
ProxiedCopilotRuntimeAgent,
|
|
1539
|
+
RunHandler,
|
|
1540
|
+
SuggestionEngine,
|
|
1043
1541
|
ToolCallStatus,
|
|
1044
1542
|
completePartialMarkdown
|
|
1045
1543
|
};
|