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