@copilotkitnext/core 0.0.12 → 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 +361 -51
- package/dist/index.d.ts +361 -51
- package/dist/index.js +1014 -477
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1009 -476
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// src/core.ts
|
|
2
|
-
import { DEFAULT_AGENT_ID, randomUUID, logger } from "@copilotkitnext/shared";
|
|
1
|
+
// src/core/agent-registry.ts
|
|
3
2
|
import { HttpAgent as HttpAgent2 } from "@ag-ui/client";
|
|
3
|
+
import { logger } from "@copilotkitnext/shared";
|
|
4
4
|
|
|
5
5
|
// src/agent.ts
|
|
6
6
|
import {
|
|
@@ -26,129 +26,43 @@ var ProxiedCopilotRuntimeAgent = class extends HttpAgent {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
// src/core.ts
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
CopilotKitCoreErrorCode2["AGENT_RUN_FAILED"] = "agent_run_failed";
|
|
35
|
-
CopilotKitCoreErrorCode2["AGENT_RUN_FAILED_EVENT"] = "agent_run_failed_event";
|
|
36
|
-
CopilotKitCoreErrorCode2["AGENT_RUN_ERROR_EVENT"] = "agent_run_error_event";
|
|
37
|
-
CopilotKitCoreErrorCode2["TOOL_ARGUMENT_PARSE_FAILED"] = "tool_argument_parse_failed";
|
|
38
|
-
CopilotKitCoreErrorCode2["TOOL_HANDLER_FAILED"] = "tool_handler_failed";
|
|
39
|
-
return CopilotKitCoreErrorCode2;
|
|
40
|
-
})(CopilotKitCoreErrorCode || {});
|
|
41
|
-
var CopilotKitCoreRuntimeConnectionStatus = /* @__PURE__ */ ((CopilotKitCoreRuntimeConnectionStatus2) => {
|
|
42
|
-
CopilotKitCoreRuntimeConnectionStatus2["Disconnected"] = "disconnected";
|
|
43
|
-
CopilotKitCoreRuntimeConnectionStatus2["Connected"] = "connected";
|
|
44
|
-
CopilotKitCoreRuntimeConnectionStatus2["Connecting"] = "connecting";
|
|
45
|
-
CopilotKitCoreRuntimeConnectionStatus2["Error"] = "error";
|
|
46
|
-
return CopilotKitCoreRuntimeConnectionStatus2;
|
|
47
|
-
})(CopilotKitCoreRuntimeConnectionStatus || {});
|
|
48
|
-
var CopilotKitCore = class {
|
|
49
|
-
_headers;
|
|
50
|
-
_properties;
|
|
51
|
-
_context = {};
|
|
29
|
+
// src/core/agent-registry.ts
|
|
30
|
+
var AgentRegistry = class {
|
|
31
|
+
constructor(core) {
|
|
32
|
+
this.core = core;
|
|
33
|
+
}
|
|
52
34
|
_agents = {};
|
|
53
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
-
_tools = [];
|
|
55
35
|
localAgents = {};
|
|
56
36
|
remoteAgents = {};
|
|
57
|
-
subscribers = /* @__PURE__ */ new Set();
|
|
58
37
|
_runtimeUrl;
|
|
59
38
|
_runtimeVersion;
|
|
60
39
|
_runtimeConnectionStatus = "disconnected" /* Disconnected */;
|
|
61
|
-
constructor({
|
|
62
|
-
runtimeUrl,
|
|
63
|
-
headers = {},
|
|
64
|
-
properties = {},
|
|
65
|
-
agents__unsafe_dev_only = {},
|
|
66
|
-
tools = []
|
|
67
|
-
}) {
|
|
68
|
-
this._headers = headers;
|
|
69
|
-
this._properties = properties;
|
|
70
|
-
this.localAgents = this.assignAgentIds(agents__unsafe_dev_only);
|
|
71
|
-
this.applyHeadersToAgents(this.localAgents);
|
|
72
|
-
this._agents = this.localAgents;
|
|
73
|
-
this._tools = tools;
|
|
74
|
-
this.setRuntimeUrl(runtimeUrl);
|
|
75
|
-
}
|
|
76
|
-
applyHeadersToAgent(agent) {
|
|
77
|
-
if (agent instanceof HttpAgent2) {
|
|
78
|
-
agent.headers = { ...this.headers };
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
applyHeadersToAgents(agents) {
|
|
82
|
-
Object.values(agents).forEach((agent) => {
|
|
83
|
-
this.applyHeadersToAgent(agent);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
assignAgentIds(agents) {
|
|
87
|
-
Object.entries(agents).forEach(([id, agent]) => {
|
|
88
|
-
if (agent && !agent.agentId) {
|
|
89
|
-
agent.agentId = id;
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
return agents;
|
|
93
|
-
}
|
|
94
|
-
async notifySubscribers(handler, errorMessage) {
|
|
95
|
-
await Promise.all(
|
|
96
|
-
Array.from(this.subscribers).map(async (subscriber) => {
|
|
97
|
-
try {
|
|
98
|
-
await handler(subscriber);
|
|
99
|
-
} catch (error) {
|
|
100
|
-
logger.error(errorMessage, error);
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
async emitError({
|
|
106
|
-
error,
|
|
107
|
-
code,
|
|
108
|
-
context = {}
|
|
109
|
-
}) {
|
|
110
|
-
await this.notifySubscribers(
|
|
111
|
-
(subscriber) => subscriber.onError?.({
|
|
112
|
-
copilotkit: this,
|
|
113
|
-
error,
|
|
114
|
-
code,
|
|
115
|
-
context
|
|
116
|
-
}),
|
|
117
|
-
"Subscriber onError error:"
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
resolveAgentId(agent, providedAgentId) {
|
|
121
|
-
if (providedAgentId) {
|
|
122
|
-
return providedAgentId;
|
|
123
|
-
}
|
|
124
|
-
if (agent.agentId) {
|
|
125
|
-
return agent.agentId;
|
|
126
|
-
}
|
|
127
|
-
const found = Object.entries(this._agents).find(([, storedAgent]) => {
|
|
128
|
-
return storedAgent === agent;
|
|
129
|
-
});
|
|
130
|
-
if (found) {
|
|
131
|
-
agent.agentId = found[0];
|
|
132
|
-
return found[0];
|
|
133
|
-
}
|
|
134
|
-
agent.agentId = DEFAULT_AGENT_ID;
|
|
135
|
-
return DEFAULT_AGENT_ID;
|
|
136
|
-
}
|
|
137
40
|
/**
|
|
138
|
-
*
|
|
41
|
+
* Get all agents as a readonly record
|
|
139
42
|
*/
|
|
140
|
-
get context() {
|
|
141
|
-
return this._context;
|
|
142
|
-
}
|
|
143
43
|
get agents() {
|
|
144
44
|
return this._agents;
|
|
145
45
|
}
|
|
146
|
-
get tools() {
|
|
147
|
-
return this._tools;
|
|
148
|
-
}
|
|
149
46
|
get runtimeUrl() {
|
|
150
47
|
return this._runtimeUrl;
|
|
151
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) {
|
|
59
|
+
this.localAgents = this.assignAgentIds(agents);
|
|
60
|
+
this.applyHeadersToAgents(this.localAgents);
|
|
61
|
+
this._agents = this.localAgents;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Set the runtime URL and update connection
|
|
65
|
+
*/
|
|
152
66
|
setRuntimeUrl(runtimeUrl) {
|
|
153
67
|
const normalizedRuntimeUrl = runtimeUrl ? runtimeUrl.replace(/\/$/, "") : void 0;
|
|
154
68
|
if (this._runtimeUrl === normalizedRuntimeUrl) {
|
|
@@ -157,54 +71,88 @@ var CopilotKitCore = class {
|
|
|
157
71
|
this._runtimeUrl = normalizedRuntimeUrl;
|
|
158
72
|
void this.updateRuntimeConnection();
|
|
159
73
|
}
|
|
160
|
-
|
|
161
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Set all agents at once (for development use)
|
|
76
|
+
*/
|
|
77
|
+
setAgents__unsafe_dev_only(agents) {
|
|
78
|
+
Object.entries(agents).forEach(([id, agent]) => {
|
|
79
|
+
if (agent) {
|
|
80
|
+
this.validateAndAssignAgentId(id, agent);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
this.localAgents = agents;
|
|
84
|
+
this._agents = { ...this.localAgents, ...this.remoteAgents };
|
|
85
|
+
this.applyHeadersToAgents(this._agents);
|
|
86
|
+
void this.notifyAgentsChanged();
|
|
162
87
|
}
|
|
163
|
-
|
|
164
|
-
|
|
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();
|
|
165
97
|
}
|
|
166
|
-
|
|
167
|
-
|
|
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();
|
|
168
105
|
}
|
|
169
|
-
|
|
170
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Get an agent by ID
|
|
108
|
+
*/
|
|
109
|
+
getAgent(id) {
|
|
110
|
+
if (id in this._agents) {
|
|
111
|
+
return this._agents[id];
|
|
112
|
+
}
|
|
113
|
+
if (this.runtimeUrl !== void 0 && (this.runtimeConnectionStatus === "disconnected" /* Disconnected */ || this.runtimeConnectionStatus === "connecting" /* Connecting */)) {
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
console.warn(`Agent ${id} not found`);
|
|
117
|
+
return void 0;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Apply current headers to an agent
|
|
121
|
+
*/
|
|
122
|
+
applyHeadersToAgent(agent) {
|
|
123
|
+
if (agent instanceof HttpAgent2) {
|
|
124
|
+
agent.headers = { ...this.core.headers };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
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,43 +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
187
|
logger.warn(`Failed to load runtime info (${this.runtimeUrl}/info): ${message}`);
|
|
263
188
|
const runtimeError = error instanceof Error ? error : new Error(String(error));
|
|
264
|
-
await this.emitError({
|
|
189
|
+
await this.core.emitError({
|
|
265
190
|
error: runtimeError,
|
|
266
191
|
code: "runtime_info_fetch_failed" /* RUNTIME_INFO_FETCH_FAILED */,
|
|
267
192
|
context: {
|
|
@@ -271,114 +196,479 @@ var CopilotKitCore = class {
|
|
|
271
196
|
}
|
|
272
197
|
}
|
|
273
198
|
/**
|
|
274
|
-
*
|
|
199
|
+
* Assign agent IDs to a record of agents
|
|
275
200
|
*/
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}),
|
|
284
|
-
"Subscriber onHeadersChanged error:"
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
setProperties(properties) {
|
|
288
|
-
this._properties = properties;
|
|
289
|
-
void this.notifySubscribers(
|
|
290
|
-
(subscriber) => subscriber.onPropertiesChanged?.({
|
|
291
|
-
copilotkit: this,
|
|
292
|
-
properties: this.properties
|
|
293
|
-
}),
|
|
294
|
-
"Subscriber onPropertiesChanged error:"
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
setAgents__unsafe_dev_only(agents) {
|
|
298
|
-
this.localAgents = this.assignAgentIds(agents);
|
|
299
|
-
this._agents = { ...this.localAgents, ...this.remoteAgents };
|
|
300
|
-
this.applyHeadersToAgents(this._agents);
|
|
301
|
-
void this.notifySubscribers(
|
|
302
|
-
(subscriber) => subscriber.onAgentsChanged?.({
|
|
303
|
-
copilotkit: this,
|
|
304
|
-
agents: this._agents
|
|
305
|
-
}),
|
|
306
|
-
"Subscriber onAgentsChanged error:"
|
|
307
|
-
);
|
|
201
|
+
assignAgentIds(agents) {
|
|
202
|
+
Object.entries(agents).forEach(([id, agent]) => {
|
|
203
|
+
if (agent) {
|
|
204
|
+
this.validateAndAssignAgentId(id, agent);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
return agents;
|
|
308
208
|
}
|
|
309
|
-
|
|
310
|
-
|
|
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
|
+
}
|
|
311
218
|
if (!agent.agentId) {
|
|
312
|
-
agent.agentId =
|
|
219
|
+
agent.agentId = registrationId;
|
|
313
220
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
|
320
230
|
}),
|
|
321
|
-
"
|
|
231
|
+
"Error in CopilotKitCore subscriber (onRuntimeConnectionStatusChanged):"
|
|
322
232
|
);
|
|
323
233
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
234
|
+
/**
|
|
235
|
+
* Notify subscribers of agent changes
|
|
236
|
+
*/
|
|
237
|
+
async notifyAgentsChanged() {
|
|
238
|
+
await this.core.notifySubscribers(
|
|
328
239
|
(subscriber) => subscriber.onAgentsChanged?.({
|
|
329
|
-
copilotkit: this,
|
|
240
|
+
copilotkit: this.core,
|
|
330
241
|
agents: this._agents
|
|
331
242
|
}),
|
|
332
243
|
"Subscriber onAgentsChanged error:"
|
|
333
244
|
);
|
|
334
245
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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;
|
|
345
260
|
}
|
|
346
261
|
/**
|
|
347
|
-
*
|
|
262
|
+
* Add a new context entry
|
|
263
|
+
* @returns The ID of the created context entry
|
|
348
264
|
*/
|
|
349
265
|
addContext({ description, value }) {
|
|
350
266
|
const id = randomUUID();
|
|
351
267
|
this._context[id] = { description, value };
|
|
352
|
-
void this.notifySubscribers(
|
|
353
|
-
(subscriber) => subscriber.onContextChanged?.({
|
|
354
|
-
copilotkit: this,
|
|
355
|
-
context: this._context
|
|
356
|
-
}),
|
|
357
|
-
"Subscriber onContextChanged error:"
|
|
358
|
-
);
|
|
268
|
+
void this.notifySubscribers();
|
|
359
269
|
return id;
|
|
360
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Remove a context entry by ID
|
|
273
|
+
*/
|
|
361
274
|
removeContext(id) {
|
|
362
275
|
delete this._context[id];
|
|
363
|
-
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(
|
|
364
283
|
(subscriber) => subscriber.onContextChanged?.({
|
|
365
|
-
copilotkit: this,
|
|
284
|
+
copilotkit: this.core,
|
|
366
285
|
context: this._context
|
|
367
286
|
}),
|
|
368
287
|
"Subscriber onContextChanged error:"
|
|
369
288
|
);
|
|
370
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
|
+
}
|
|
371
658
|
/**
|
|
372
|
-
*
|
|
659
|
+
* Add a tool to the registry
|
|
373
660
|
*/
|
|
374
661
|
addTool(tool) {
|
|
375
662
|
const existingToolIndex = this._tools.findIndex((t) => t.name === tool.name && t.agentId === tool.agentId);
|
|
376
663
|
if (existingToolIndex !== -1) {
|
|
377
|
-
|
|
664
|
+
logger2.warn(`Tool already exists: '${tool.name}' for agent '${tool.agentId || "global"}', skipping.`);
|
|
378
665
|
return;
|
|
379
666
|
}
|
|
380
667
|
this._tools.push(tool);
|
|
381
668
|
}
|
|
669
|
+
/**
|
|
670
|
+
* Remove a tool by name and optionally by agentId
|
|
671
|
+
*/
|
|
382
672
|
removeTool(id, agentId) {
|
|
383
673
|
this._tools = this._tools.filter((tool) => {
|
|
384
674
|
if (agentId !== void 0) {
|
|
@@ -409,40 +699,28 @@ var CopilotKitCore = class {
|
|
|
409
699
|
this._tools = [...tools];
|
|
410
700
|
}
|
|
411
701
|
/**
|
|
412
|
-
*
|
|
413
|
-
*/
|
|
414
|
-
subscribe(subscriber) {
|
|
415
|
-
this.subscribers.add(subscriber);
|
|
416
|
-
return () => {
|
|
417
|
-
this.unsubscribe(subscriber);
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
unsubscribe(subscriber) {
|
|
421
|
-
this.subscribers.delete(subscriber);
|
|
422
|
-
}
|
|
423
|
-
/**
|
|
424
|
-
* Agent connectivity
|
|
702
|
+
* Connect an agent (establish initial connection)
|
|
425
703
|
*/
|
|
426
|
-
async connectAgent({ agent
|
|
704
|
+
async connectAgent({ agent }) {
|
|
427
705
|
try {
|
|
428
|
-
if (agent instanceof
|
|
429
|
-
agent.headers = { ...this.headers };
|
|
706
|
+
if (agent instanceof HttpAgent3) {
|
|
707
|
+
agent.headers = { ...this.core.headers };
|
|
430
708
|
}
|
|
431
709
|
const runAgentResult = await agent.connectAgent(
|
|
432
710
|
{
|
|
433
|
-
forwardedProps: this.properties,
|
|
434
|
-
tools: this.buildFrontendTools(agentId)
|
|
711
|
+
forwardedProps: this.core.properties,
|
|
712
|
+
tools: this.buildFrontendTools(agent.agentId)
|
|
435
713
|
},
|
|
436
|
-
this.createAgentErrorSubscriber(agent
|
|
714
|
+
this.createAgentErrorSubscriber(agent)
|
|
437
715
|
);
|
|
438
|
-
return this.processAgentResult({ runAgentResult, agent
|
|
716
|
+
return this.processAgentResult({ runAgentResult, agent });
|
|
439
717
|
} catch (error) {
|
|
440
718
|
const connectError = error instanceof Error ? error : new Error(String(error));
|
|
441
719
|
const context = {};
|
|
442
|
-
if (
|
|
443
|
-
context.agentId =
|
|
720
|
+
if (agent.agentId) {
|
|
721
|
+
context.agentId = agent.agentId;
|
|
444
722
|
}
|
|
445
|
-
await this.emitError({
|
|
723
|
+
await this.core.emitError({
|
|
446
724
|
error: connectError,
|
|
447
725
|
code: "agent_connect_failed" /* AGENT_CONNECT_FAILED */,
|
|
448
726
|
context
|
|
@@ -450,9 +728,13 @@ var CopilotKitCore = class {
|
|
|
450
728
|
throw error;
|
|
451
729
|
}
|
|
452
730
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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 };
|
|
456
738
|
}
|
|
457
739
|
if (withMessages) {
|
|
458
740
|
agent.addMessages(withMessages);
|
|
@@ -460,22 +742,22 @@ var CopilotKitCore = class {
|
|
|
460
742
|
try {
|
|
461
743
|
const runAgentResult = await agent.runAgent(
|
|
462
744
|
{
|
|
463
|
-
forwardedProps: this.properties,
|
|
464
|
-
tools: this.buildFrontendTools(agentId)
|
|
745
|
+
forwardedProps: this.core.properties,
|
|
746
|
+
tools: this.buildFrontendTools(agent.agentId)
|
|
465
747
|
},
|
|
466
|
-
this.createAgentErrorSubscriber(agent
|
|
748
|
+
this.createAgentErrorSubscriber(agent)
|
|
467
749
|
);
|
|
468
|
-
return this.processAgentResult({ runAgentResult, agent
|
|
750
|
+
return this.processAgentResult({ runAgentResult, agent });
|
|
469
751
|
} catch (error) {
|
|
470
752
|
const runError = error instanceof Error ? error : new Error(String(error));
|
|
471
753
|
const context = {};
|
|
472
|
-
if (
|
|
473
|
-
context.agentId =
|
|
754
|
+
if (agent.agentId) {
|
|
755
|
+
context.agentId = agent.agentId;
|
|
474
756
|
}
|
|
475
757
|
if (withMessages) {
|
|
476
758
|
context.messageCount = withMessages.length;
|
|
477
759
|
}
|
|
478
|
-
await this.emitError({
|
|
760
|
+
await this.core.emitError({
|
|
479
761
|
error: runError,
|
|
480
762
|
code: "agent_run_failed" /* AGENT_RUN_FAILED */,
|
|
481
763
|
context
|
|
@@ -483,13 +765,15 @@ var CopilotKitCore = class {
|
|
|
483
765
|
throw error;
|
|
484
766
|
}
|
|
485
767
|
}
|
|
768
|
+
/**
|
|
769
|
+
* Process agent result and execute tools
|
|
770
|
+
*/
|
|
486
771
|
async processAgentResult({
|
|
487
772
|
runAgentResult,
|
|
488
|
-
agent
|
|
489
|
-
agentId
|
|
773
|
+
agent
|
|
490
774
|
}) {
|
|
491
775
|
const { newMessages } = runAgentResult;
|
|
492
|
-
const
|
|
776
|
+
const agentId = agent.agentId;
|
|
493
777
|
let needsFollowUp = false;
|
|
494
778
|
for (const message of newMessages) {
|
|
495
779
|
if (message.role === "assistant") {
|
|
@@ -497,205 +781,19 @@ var CopilotKitCore = class {
|
|
|
497
781
|
if (newMessages.findIndex((m) => m.role === "tool" && m.toolCallId === toolCall.id) === -1) {
|
|
498
782
|
const tool = this.getTool({
|
|
499
783
|
toolName: toolCall.function.name,
|
|
500
|
-
agentId
|
|
784
|
+
agentId: agent.agentId
|
|
501
785
|
});
|
|
502
786
|
if (tool) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
let toolCallResult = "";
|
|
507
|
-
let errorMessage;
|
|
508
|
-
let isArgumentError = false;
|
|
509
|
-
if (tool?.handler) {
|
|
510
|
-
let parsedArgs;
|
|
511
|
-
try {
|
|
512
|
-
parsedArgs = JSON.parse(toolCall.function.arguments);
|
|
513
|
-
} catch (error) {
|
|
514
|
-
const parseError = error instanceof Error ? error : new Error(String(error));
|
|
515
|
-
errorMessage = parseError.message;
|
|
516
|
-
isArgumentError = true;
|
|
517
|
-
await this.emitError({
|
|
518
|
-
error: parseError,
|
|
519
|
-
code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
|
|
520
|
-
context: {
|
|
521
|
-
agentId: effectiveAgentId,
|
|
522
|
-
toolCallId: toolCall.id,
|
|
523
|
-
toolName: toolCall.function.name,
|
|
524
|
-
rawArguments: toolCall.function.arguments,
|
|
525
|
-
toolType: "specific",
|
|
526
|
-
messageId: message.id
|
|
527
|
-
}
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
await this.notifySubscribers(
|
|
531
|
-
(subscriber) => subscriber.onToolExecutionStart?.({
|
|
532
|
-
copilotkit: this,
|
|
533
|
-
toolCallId: toolCall.id,
|
|
534
|
-
agentId: effectiveAgentId,
|
|
535
|
-
toolName: toolCall.function.name,
|
|
536
|
-
args: parsedArgs
|
|
537
|
-
}),
|
|
538
|
-
"Subscriber onToolExecutionStart error:"
|
|
539
|
-
);
|
|
540
|
-
if (!errorMessage) {
|
|
541
|
-
try {
|
|
542
|
-
const result = await tool.handler(parsedArgs, toolCall);
|
|
543
|
-
if (result === void 0 || result === null) {
|
|
544
|
-
toolCallResult = "";
|
|
545
|
-
} else if (typeof result === "string") {
|
|
546
|
-
toolCallResult = result;
|
|
547
|
-
} else {
|
|
548
|
-
toolCallResult = JSON.stringify(result);
|
|
549
|
-
}
|
|
550
|
-
} catch (error) {
|
|
551
|
-
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
552
|
-
errorMessage = handlerError.message;
|
|
553
|
-
await this.emitError({
|
|
554
|
-
error: handlerError,
|
|
555
|
-
code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
|
|
556
|
-
context: {
|
|
557
|
-
agentId: effectiveAgentId,
|
|
558
|
-
toolCallId: toolCall.id,
|
|
559
|
-
toolName: toolCall.function.name,
|
|
560
|
-
parsedArgs,
|
|
561
|
-
toolType: "specific",
|
|
562
|
-
messageId: message.id
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
if (errorMessage) {
|
|
568
|
-
toolCallResult = `Error: ${errorMessage}`;
|
|
569
|
-
}
|
|
570
|
-
await this.notifySubscribers(
|
|
571
|
-
(subscriber) => subscriber.onToolExecutionEnd?.({
|
|
572
|
-
copilotkit: this,
|
|
573
|
-
toolCallId: toolCall.id,
|
|
574
|
-
agentId: effectiveAgentId,
|
|
575
|
-
toolName: toolCall.function.name,
|
|
576
|
-
result: errorMessage ? "" : toolCallResult,
|
|
577
|
-
error: errorMessage
|
|
578
|
-
}),
|
|
579
|
-
"Subscriber onToolExecutionEnd error:"
|
|
580
|
-
);
|
|
581
|
-
if (isArgumentError) {
|
|
582
|
-
throw new Error(errorMessage ?? "Tool execution failed");
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
if (!errorMessage || !isArgumentError) {
|
|
586
|
-
const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
|
|
587
|
-
const toolMessage = {
|
|
588
|
-
id: randomUUID(),
|
|
589
|
-
role: "tool",
|
|
590
|
-
toolCallId: toolCall.id,
|
|
591
|
-
content: toolCallResult
|
|
592
|
-
};
|
|
593
|
-
agent.messages.splice(messageIndex + 1, 0, toolMessage);
|
|
594
|
-
if (!errorMessage && tool?.followUp !== false) {
|
|
595
|
-
needsFollowUp = true;
|
|
596
|
-
}
|
|
787
|
+
const followUp = await this.executeSpecificTool(tool, toolCall, message, agent, agentId);
|
|
788
|
+
if (followUp) {
|
|
789
|
+
needsFollowUp = true;
|
|
597
790
|
}
|
|
598
791
|
} else {
|
|
599
|
-
const wildcardTool = this.getTool({ toolName: "*", agentId });
|
|
792
|
+
const wildcardTool = this.getTool({ toolName: "*", agentId: agent.agentId });
|
|
600
793
|
if (wildcardTool) {
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
let toolCallResult = "";
|
|
605
|
-
let errorMessage;
|
|
606
|
-
let isArgumentError = false;
|
|
607
|
-
if (wildcardTool?.handler) {
|
|
608
|
-
let parsedArgs;
|
|
609
|
-
try {
|
|
610
|
-
parsedArgs = JSON.parse(toolCall.function.arguments);
|
|
611
|
-
} catch (error) {
|
|
612
|
-
const parseError = error instanceof Error ? error : new Error(String(error));
|
|
613
|
-
errorMessage = parseError.message;
|
|
614
|
-
isArgumentError = true;
|
|
615
|
-
await this.emitError({
|
|
616
|
-
error: parseError,
|
|
617
|
-
code: "tool_argument_parse_failed" /* TOOL_ARGUMENT_PARSE_FAILED */,
|
|
618
|
-
context: {
|
|
619
|
-
agentId: effectiveAgentId,
|
|
620
|
-
toolCallId: toolCall.id,
|
|
621
|
-
toolName: toolCall.function.name,
|
|
622
|
-
rawArguments: toolCall.function.arguments,
|
|
623
|
-
toolType: "wildcard",
|
|
624
|
-
messageId: message.id
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
const wildcardArgs = {
|
|
629
|
-
toolName: toolCall.function.name,
|
|
630
|
-
args: parsedArgs
|
|
631
|
-
};
|
|
632
|
-
await this.notifySubscribers(
|
|
633
|
-
(subscriber) => subscriber.onToolExecutionStart?.({
|
|
634
|
-
copilotkit: this,
|
|
635
|
-
toolCallId: toolCall.id,
|
|
636
|
-
agentId: effectiveAgentId,
|
|
637
|
-
toolName: toolCall.function.name,
|
|
638
|
-
args: wildcardArgs
|
|
639
|
-
}),
|
|
640
|
-
"Subscriber onToolExecutionStart error:"
|
|
641
|
-
);
|
|
642
|
-
if (!errorMessage) {
|
|
643
|
-
try {
|
|
644
|
-
const result = await wildcardTool.handler(wildcardArgs, toolCall);
|
|
645
|
-
if (result === void 0 || result === null) {
|
|
646
|
-
toolCallResult = "";
|
|
647
|
-
} else if (typeof result === "string") {
|
|
648
|
-
toolCallResult = result;
|
|
649
|
-
} else {
|
|
650
|
-
toolCallResult = JSON.stringify(result);
|
|
651
|
-
}
|
|
652
|
-
} catch (error) {
|
|
653
|
-
const handlerError = error instanceof Error ? error : new Error(String(error));
|
|
654
|
-
errorMessage = handlerError.message;
|
|
655
|
-
await this.emitError({
|
|
656
|
-
error: handlerError,
|
|
657
|
-
code: "tool_handler_failed" /* TOOL_HANDLER_FAILED */,
|
|
658
|
-
context: {
|
|
659
|
-
agentId: effectiveAgentId,
|
|
660
|
-
toolCallId: toolCall.id,
|
|
661
|
-
toolName: toolCall.function.name,
|
|
662
|
-
parsedArgs: wildcardArgs,
|
|
663
|
-
toolType: "wildcard",
|
|
664
|
-
messageId: message.id
|
|
665
|
-
}
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
if (errorMessage) {
|
|
670
|
-
toolCallResult = `Error: ${errorMessage}`;
|
|
671
|
-
}
|
|
672
|
-
await this.notifySubscribers(
|
|
673
|
-
(subscriber) => subscriber.onToolExecutionEnd?.({
|
|
674
|
-
copilotkit: this,
|
|
675
|
-
toolCallId: toolCall.id,
|
|
676
|
-
agentId: effectiveAgentId,
|
|
677
|
-
toolName: toolCall.function.name,
|
|
678
|
-
result: errorMessage ? "" : toolCallResult,
|
|
679
|
-
error: errorMessage
|
|
680
|
-
}),
|
|
681
|
-
"Subscriber onToolExecutionEnd error:"
|
|
682
|
-
);
|
|
683
|
-
if (isArgumentError) {
|
|
684
|
-
throw new Error(errorMessage ?? "Tool execution failed");
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
if (!errorMessage || !isArgumentError) {
|
|
688
|
-
const messageIndex = agent.messages.findIndex((m) => m.id === message.id);
|
|
689
|
-
const toolMessage = {
|
|
690
|
-
id: randomUUID(),
|
|
691
|
-
role: "tool",
|
|
692
|
-
toolCallId: toolCall.id,
|
|
693
|
-
content: toolCallResult
|
|
694
|
-
};
|
|
695
|
-
agent.messages.splice(messageIndex + 1, 0, toolMessage);
|
|
696
|
-
if (!errorMessage && wildcardTool?.followUp !== false) {
|
|
697
|
-
needsFollowUp = true;
|
|
698
|
-
}
|
|
794
|
+
const followUp = await this.executeWildcardTool(wildcardTool, toolCall, message, agent, agentId);
|
|
795
|
+
if (followUp) {
|
|
796
|
+
needsFollowUp = true;
|
|
699
797
|
}
|
|
700
798
|
}
|
|
701
799
|
}
|
|
@@ -704,10 +802,220 @@ var CopilotKitCore = class {
|
|
|
704
802
|
}
|
|
705
803
|
}
|
|
706
804
|
if (needsFollowUp) {
|
|
707
|
-
return await this.runAgent({ agent
|
|
805
|
+
return await this.runAgent({ agent });
|
|
708
806
|
}
|
|
807
|
+
void this.core.suggestionEngine.reloadSuggestions(agentId);
|
|
709
808
|
return runAgentResult;
|
|
710
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
|
+
*/
|
|
711
1019
|
buildFrontendTools(agentId) {
|
|
712
1020
|
return this._tools.filter((tool) => !tool.agentId || tool.agentId === agentId).map((tool) => ({
|
|
713
1021
|
name: tool.name,
|
|
@@ -715,13 +1023,16 @@ var CopilotKitCore = class {
|
|
|
715
1023
|
parameters: createToolSchema(tool)
|
|
716
1024
|
}));
|
|
717
1025
|
}
|
|
718
|
-
|
|
1026
|
+
/**
|
|
1027
|
+
* Create an agent error subscriber
|
|
1028
|
+
*/
|
|
1029
|
+
createAgentErrorSubscriber(agent) {
|
|
719
1030
|
const emitAgentError = async (error, code, extraContext = {}) => {
|
|
720
1031
|
const context = { ...extraContext };
|
|
721
|
-
if (
|
|
722
|
-
context.agentId =
|
|
1032
|
+
if (agent.agentId) {
|
|
1033
|
+
context.agentId = agent.agentId;
|
|
723
1034
|
}
|
|
724
|
-
await this.emitError({
|
|
1035
|
+
await this.core.emitError({
|
|
725
1036
|
error,
|
|
726
1037
|
code,
|
|
727
1038
|
context
|
|
@@ -777,6 +1088,224 @@ function createToolSchema(tool) {
|
|
|
777
1088
|
return schema;
|
|
778
1089
|
}
|
|
779
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
|
+
|
|
780
1309
|
// src/types.ts
|
|
781
1310
|
var ToolCallStatus = /* @__PURE__ */ ((ToolCallStatus2) => {
|
|
782
1311
|
ToolCallStatus2["InProgress"] = "inProgress";
|
|
@@ -1001,10 +1530,14 @@ ${indent}${fence}`;
|
|
|
1001
1530
|
return result;
|
|
1002
1531
|
}
|
|
1003
1532
|
export {
|
|
1533
|
+
AgentRegistry,
|
|
1534
|
+
ContextStore,
|
|
1004
1535
|
CopilotKitCore,
|
|
1005
1536
|
CopilotKitCoreErrorCode,
|
|
1006
1537
|
CopilotKitCoreRuntimeConnectionStatus,
|
|
1007
1538
|
ProxiedCopilotRuntimeAgent,
|
|
1539
|
+
RunHandler,
|
|
1540
|
+
SuggestionEngine,
|
|
1008
1541
|
ToolCallStatus,
|
|
1009
1542
|
completePartialMarkdown
|
|
1010
1543
|
};
|