agents 0.0.0-b342dcf → 0.0.0-b4ebb44
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/ai-chat-agent.d.ts +31 -5
- package/dist/ai-chat-agent.js +119 -115
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-react.d.ts +17 -4
- package/dist/ai-react.js +28 -29
- package/dist/ai-react.js.map +1 -1
- package/dist/chunk-767EASBA.js +106 -0
- package/dist/chunk-767EASBA.js.map +1 -0
- package/dist/{chunk-WNICV3OI.js → chunk-E3LCYPCB.js} +70 -37
- package/dist/chunk-E3LCYPCB.js.map +1 -0
- package/dist/chunk-NKZZ66QY.js +116 -0
- package/dist/chunk-NKZZ66QY.js.map +1 -0
- package/dist/{chunk-UAKVEVG5.js → chunk-ZRRXJUAA.js} +344 -162
- package/dist/chunk-ZRRXJUAA.js.map +1 -0
- package/dist/client.d.ts +15 -1
- package/dist/client.js +6 -126
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +110 -13
- package/dist/index.js +4 -3
- package/dist/mcp/client.d.ts +31 -16
- package/dist/mcp/client.js +1 -2
- package/dist/mcp/do-oauth-client-provider.d.ts +3 -3
- package/dist/mcp/do-oauth-client-provider.js +3 -103
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +20 -10
- package/dist/mcp/index.js +148 -173
- package/dist/mcp/index.js.map +1 -1
- package/dist/react.d.ts +85 -5
- package/dist/react.js +20 -8
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +2 -2
- package/dist/schedule.js +4 -6
- package/dist/schedule.js.map +1 -1
- package/dist/serializable.d.ts +32 -0
- package/dist/serializable.js +1 -0
- package/package.json +71 -68
- package/src/index.ts +400 -85
- package/dist/chunk-HMLY7DHA.js +0 -16
- package/dist/chunk-UAKVEVG5.js.map +0 -1
- package/dist/chunk-WNICV3OI.js.map +0 -1
- /package/dist/{chunk-HMLY7DHA.js.map → serializable.js.map} +0 -0
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MCPClientManager
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-E3LCYPCB.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "./chunk-
|
|
5
|
+
DurableObjectOAuthClientProvider
|
|
6
|
+
} from "./chunk-767EASBA.js";
|
|
7
|
+
import {
|
|
8
|
+
camelCaseToKebabCase
|
|
9
|
+
} from "./chunk-NKZZ66QY.js";
|
|
10
10
|
|
|
11
11
|
// src/index.ts
|
|
12
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
13
|
+
import { parseCronExpression } from "cron-schedule";
|
|
14
|
+
import { nanoid } from "nanoid";
|
|
12
15
|
import {
|
|
13
|
-
|
|
16
|
+
getServerByName,
|
|
14
17
|
routePartykitRequest,
|
|
15
|
-
|
|
18
|
+
Server
|
|
16
19
|
} from "partyserver";
|
|
17
|
-
import { parseCronExpression } from "cron-schedule";
|
|
18
|
-
import { nanoid } from "nanoid";
|
|
19
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
20
20
|
function isRPCRequest(msg) {
|
|
21
21
|
return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "rpc" && "id" in msg && typeof msg.id === "string" && "method" in msg && typeof msg.method === "string" && "args" in msg && Array.isArray(msg.args);
|
|
22
22
|
}
|
|
@@ -43,25 +43,68 @@ var agentContext = new AsyncLocalStorage();
|
|
|
43
43
|
function getCurrentAgent() {
|
|
44
44
|
const store = agentContext.getStore();
|
|
45
45
|
if (!store) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
return {
|
|
47
|
+
agent: void 0,
|
|
48
|
+
connection: void 0,
|
|
49
|
+
request: void 0
|
|
50
|
+
};
|
|
49
51
|
}
|
|
50
52
|
return store;
|
|
51
53
|
}
|
|
52
|
-
var _state, _ParentClass, _Agent_instances, setStateInternal_fn, tryCatch_fn, scheduleNextAlarm_fn, isCallable_fn;
|
|
53
54
|
var Agent = class extends Server {
|
|
54
55
|
constructor(ctx, env) {
|
|
55
56
|
super(ctx, env);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.mcp = new MCPClientManager(__privateGet(this, _ParentClass).name, "0.0.1");
|
|
57
|
+
this._state = DEFAULT_STATE;
|
|
58
|
+
this._ParentClass = Object.getPrototypeOf(this).constructor;
|
|
59
|
+
this.mcp = new MCPClientManager(this._ParentClass.name, "0.0.1");
|
|
60
60
|
/**
|
|
61
61
|
* Initial state for the Agent
|
|
62
62
|
* Override to provide default state values
|
|
63
63
|
*/
|
|
64
64
|
this.initialState = DEFAULT_STATE;
|
|
65
|
+
/**
|
|
66
|
+
* Method called when an alarm fires.
|
|
67
|
+
* Executes any scheduled tasks that are due.
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* To schedule a task, please use the `this.schedule` method instead.
|
|
71
|
+
* See {@link https://developers.cloudflare.com/agents/api-reference/schedule-tasks/}
|
|
72
|
+
*/
|
|
73
|
+
this.alarm = async () => {
|
|
74
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
75
|
+
const result = this.sql`
|
|
76
|
+
SELECT * FROM cf_agents_schedules WHERE time <= ${now}
|
|
77
|
+
`;
|
|
78
|
+
for (const row of result || []) {
|
|
79
|
+
const callback = this[row.callback];
|
|
80
|
+
if (!callback) {
|
|
81
|
+
console.error(`callback ${row.callback} not found`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
await agentContext.run(
|
|
85
|
+
{ agent: this, connection: void 0, request: void 0 },
|
|
86
|
+
async () => {
|
|
87
|
+
try {
|
|
88
|
+
await callback.bind(this)(JSON.parse(row.payload), row);
|
|
89
|
+
} catch (e) {
|
|
90
|
+
console.error(`error executing callback "${row.callback}"`, e);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
if (row.type === "cron") {
|
|
95
|
+
const nextExecutionTime = getNextCronTime(row.cron);
|
|
96
|
+
const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
|
|
97
|
+
this.sql`
|
|
98
|
+
UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
|
|
99
|
+
`;
|
|
100
|
+
} else {
|
|
101
|
+
this.sql`
|
|
102
|
+
DELETE FROM cf_agents_schedules WHERE id = ${row.id}
|
|
103
|
+
`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
await this._scheduleNextAlarm();
|
|
107
|
+
};
|
|
65
108
|
this.sql`
|
|
66
109
|
CREATE TABLE IF NOT EXISTS cf_agents_state (
|
|
67
110
|
id TEXT PRIMARY KEY NOT NULL,
|
|
@@ -69,7 +112,7 @@ var Agent = class extends Server {
|
|
|
69
112
|
)
|
|
70
113
|
`;
|
|
71
114
|
void this.ctx.blockConcurrencyWhile(async () => {
|
|
72
|
-
return
|
|
115
|
+
return this._tryCatch(async () => {
|
|
73
116
|
this.sql`
|
|
74
117
|
CREATE TABLE IF NOT EXISTS cf_agents_schedules (
|
|
75
118
|
id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
|
|
@@ -85,22 +128,55 @@ var Agent = class extends Server {
|
|
|
85
128
|
await this.alarm();
|
|
86
129
|
});
|
|
87
130
|
});
|
|
131
|
+
this.sql`
|
|
132
|
+
CREATE TABLE IF NOT EXISTS cf_agents_mcp_servers (
|
|
133
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
134
|
+
name TEXT NOT NULL,
|
|
135
|
+
server_url TEXT NOT NULL,
|
|
136
|
+
callback_url TEXT NOT NULL,
|
|
137
|
+
client_id TEXT,
|
|
138
|
+
auth_url TEXT,
|
|
139
|
+
server_options TEXT
|
|
140
|
+
)
|
|
141
|
+
`;
|
|
142
|
+
const _onRequest = this.onRequest.bind(this);
|
|
143
|
+
this.onRequest = (request) => {
|
|
144
|
+
return agentContext.run(
|
|
145
|
+
{ agent: this, connection: void 0, request },
|
|
146
|
+
async () => {
|
|
147
|
+
if (this.mcp.isCallbackRequest(request)) {
|
|
148
|
+
await this.mcp.handleCallbackRequest(request);
|
|
149
|
+
this.broadcast(
|
|
150
|
+
JSON.stringify({
|
|
151
|
+
mcp: this.getMcpServers(),
|
|
152
|
+
type: "cf_agent_mcp_servers"
|
|
153
|
+
})
|
|
154
|
+
);
|
|
155
|
+
return new Response("<script>window.close();</script>", {
|
|
156
|
+
headers: { "content-type": "text/html" },
|
|
157
|
+
status: 200
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return this._tryCatch(() => _onRequest(request));
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
};
|
|
88
164
|
const _onMessage = this.onMessage.bind(this);
|
|
89
165
|
this.onMessage = async (connection, message) => {
|
|
90
166
|
return agentContext.run(
|
|
91
167
|
{ agent: this, connection, request: void 0 },
|
|
92
168
|
async () => {
|
|
93
169
|
if (typeof message !== "string") {
|
|
94
|
-
return
|
|
170
|
+
return this._tryCatch(() => _onMessage(connection, message));
|
|
95
171
|
}
|
|
96
172
|
let parsed;
|
|
97
173
|
try {
|
|
98
174
|
parsed = JSON.parse(message);
|
|
99
|
-
} catch (
|
|
100
|
-
return
|
|
175
|
+
} catch (_e) {
|
|
176
|
+
return this._tryCatch(() => _onMessage(connection, message));
|
|
101
177
|
}
|
|
102
178
|
if (isStateUpdateMessage(parsed)) {
|
|
103
|
-
|
|
179
|
+
this._setStateInternal(parsed.state, connection);
|
|
104
180
|
return;
|
|
105
181
|
}
|
|
106
182
|
if (isRPCRequest(parsed)) {
|
|
@@ -110,7 +186,7 @@ var Agent = class extends Server {
|
|
|
110
186
|
if (typeof methodFn !== "function") {
|
|
111
187
|
throw new Error(`Method ${method} does not exist`);
|
|
112
188
|
}
|
|
113
|
-
if (!
|
|
189
|
+
if (!this._isCallable(method)) {
|
|
114
190
|
throw new Error(`Method ${method} is not callable`);
|
|
115
191
|
}
|
|
116
192
|
const metadata = callableMetadata.get(methodFn);
|
|
@@ -121,26 +197,26 @@ var Agent = class extends Server {
|
|
|
121
197
|
}
|
|
122
198
|
const result = await methodFn.apply(this, args);
|
|
123
199
|
const response = {
|
|
124
|
-
|
|
200
|
+
done: true,
|
|
125
201
|
id,
|
|
126
|
-
success: true,
|
|
127
202
|
result,
|
|
128
|
-
|
|
203
|
+
success: true,
|
|
204
|
+
type: "rpc"
|
|
129
205
|
};
|
|
130
206
|
connection.send(JSON.stringify(response));
|
|
131
207
|
} catch (e) {
|
|
132
208
|
const response = {
|
|
133
|
-
|
|
209
|
+
error: e instanceof Error ? e.message : "Unknown error occurred",
|
|
134
210
|
id: parsed.id,
|
|
135
211
|
success: false,
|
|
136
|
-
|
|
212
|
+
type: "rpc"
|
|
137
213
|
};
|
|
138
214
|
connection.send(JSON.stringify(response));
|
|
139
215
|
console.error("RPC error:", e);
|
|
140
216
|
}
|
|
141
217
|
return;
|
|
142
218
|
}
|
|
143
|
-
return
|
|
219
|
+
return this._tryCatch(() => _onMessage(connection, message));
|
|
144
220
|
}
|
|
145
221
|
);
|
|
146
222
|
};
|
|
@@ -153,23 +229,61 @@ var Agent = class extends Server {
|
|
|
153
229
|
if (this.state) {
|
|
154
230
|
connection.send(
|
|
155
231
|
JSON.stringify({
|
|
156
|
-
|
|
157
|
-
|
|
232
|
+
state: this.state,
|
|
233
|
+
type: "cf_agent_state"
|
|
158
234
|
})
|
|
159
235
|
);
|
|
160
236
|
}
|
|
161
|
-
|
|
237
|
+
connection.send(
|
|
238
|
+
JSON.stringify({
|
|
239
|
+
mcp: this.getMcpServers(),
|
|
240
|
+
type: "cf_agent_mcp_servers"
|
|
241
|
+
})
|
|
242
|
+
);
|
|
243
|
+
return this._tryCatch(() => _onConnect(connection, ctx2));
|
|
162
244
|
}, 20);
|
|
163
245
|
}
|
|
164
246
|
);
|
|
165
247
|
};
|
|
248
|
+
const _onStart = this.onStart.bind(this);
|
|
249
|
+
this.onStart = async () => {
|
|
250
|
+
return agentContext.run(
|
|
251
|
+
{ agent: this, connection: void 0, request: void 0 },
|
|
252
|
+
async () => {
|
|
253
|
+
const servers = this.sql`
|
|
254
|
+
SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
|
|
255
|
+
`;
|
|
256
|
+
await Promise.allSettled(
|
|
257
|
+
servers.filter((server) => server.auth_url === null).map((server) => {
|
|
258
|
+
return this._connectToMcpServerInternal(
|
|
259
|
+
server.name,
|
|
260
|
+
server.server_url,
|
|
261
|
+
server.callback_url,
|
|
262
|
+
server.server_options ? JSON.parse(server.server_options) : void 0,
|
|
263
|
+
{
|
|
264
|
+
id: server.id,
|
|
265
|
+
oauthClientId: server.client_id ?? void 0
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
})
|
|
269
|
+
);
|
|
270
|
+
this.broadcast(
|
|
271
|
+
JSON.stringify({
|
|
272
|
+
mcp: this.getMcpServers(),
|
|
273
|
+
type: "cf_agent_mcp_servers"
|
|
274
|
+
})
|
|
275
|
+
);
|
|
276
|
+
await this._tryCatch(() => _onStart());
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
};
|
|
166
280
|
}
|
|
167
281
|
/**
|
|
168
282
|
* Current state of the Agent
|
|
169
283
|
*/
|
|
170
284
|
get state() {
|
|
171
|
-
if (
|
|
172
|
-
return
|
|
285
|
+
if (this._state !== DEFAULT_STATE) {
|
|
286
|
+
return this._state;
|
|
173
287
|
}
|
|
174
288
|
const wasChanged = this.sql`
|
|
175
289
|
SELECT state FROM cf_agents_state WHERE id = ${STATE_WAS_CHANGED}
|
|
@@ -180,8 +294,8 @@ var Agent = class extends Server {
|
|
|
180
294
|
if (wasChanged[0]?.state === "true" || // we do this check for people who updated their code before we shipped wasChanged
|
|
181
295
|
result[0]?.state) {
|
|
182
296
|
const state = result[0]?.state;
|
|
183
|
-
|
|
184
|
-
return
|
|
297
|
+
this._state = JSON.parse(state);
|
|
298
|
+
return this._state;
|
|
185
299
|
}
|
|
186
300
|
if (this.initialState === DEFAULT_STATE) {
|
|
187
301
|
return void 0;
|
|
@@ -209,24 +323,53 @@ var Agent = class extends Server {
|
|
|
209
323
|
throw this.onError(e);
|
|
210
324
|
}
|
|
211
325
|
}
|
|
326
|
+
_setStateInternal(state, source = "server") {
|
|
327
|
+
this._state = state;
|
|
328
|
+
this.sql`
|
|
329
|
+
INSERT OR REPLACE INTO cf_agents_state (id, state)
|
|
330
|
+
VALUES (${STATE_ROW_ID}, ${JSON.stringify(state)})
|
|
331
|
+
`;
|
|
332
|
+
this.sql`
|
|
333
|
+
INSERT OR REPLACE INTO cf_agents_state (id, state)
|
|
334
|
+
VALUES (${STATE_WAS_CHANGED}, ${JSON.stringify(true)})
|
|
335
|
+
`;
|
|
336
|
+
this.broadcast(
|
|
337
|
+
JSON.stringify({
|
|
338
|
+
state,
|
|
339
|
+
type: "cf_agent_state"
|
|
340
|
+
}),
|
|
341
|
+
source !== "server" ? [source.id] : []
|
|
342
|
+
);
|
|
343
|
+
return this._tryCatch(() => {
|
|
344
|
+
const { connection, request } = agentContext.getStore() || {};
|
|
345
|
+
return agentContext.run(
|
|
346
|
+
{ agent: this, connection, request },
|
|
347
|
+
async () => {
|
|
348
|
+
return this.onStateUpdate(state, source);
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
212
353
|
/**
|
|
213
354
|
* Update the Agent's state
|
|
214
355
|
* @param state New state to set
|
|
215
356
|
*/
|
|
216
357
|
setState(state) {
|
|
217
|
-
|
|
358
|
+
this._setStateInternal(state, "server");
|
|
218
359
|
}
|
|
219
360
|
/**
|
|
220
361
|
* Called when the Agent's state is updated
|
|
221
362
|
* @param state Updated state
|
|
222
363
|
* @param source Source of the state update ("server" or a client connection)
|
|
223
364
|
*/
|
|
365
|
+
// biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
|
|
224
366
|
onStateUpdate(state, source) {
|
|
225
367
|
}
|
|
226
368
|
/**
|
|
227
369
|
* Called when the Agent receives an email
|
|
228
370
|
* @param email Email message to process
|
|
229
371
|
*/
|
|
372
|
+
// biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
|
|
230
373
|
onEmail(email) {
|
|
231
374
|
return agentContext.run(
|
|
232
375
|
{ agent: this, connection: void 0, request: void 0 },
|
|
@@ -235,6 +378,13 @@ var Agent = class extends Server {
|
|
|
235
378
|
}
|
|
236
379
|
);
|
|
237
380
|
}
|
|
381
|
+
async _tryCatch(fn) {
|
|
382
|
+
try {
|
|
383
|
+
return await fn();
|
|
384
|
+
} catch (e) {
|
|
385
|
+
throw this.onError(e);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
238
388
|
onError(connectionOrError, error) {
|
|
239
389
|
let theError;
|
|
240
390
|
if (connectionOrError && error) {
|
|
@@ -284,10 +434,10 @@ var Agent = class extends Server {
|
|
|
284
434
|
payload
|
|
285
435
|
)}, 'scheduled', ${timestamp})
|
|
286
436
|
`;
|
|
287
|
-
await
|
|
437
|
+
await this._scheduleNextAlarm();
|
|
288
438
|
return {
|
|
289
|
-
id,
|
|
290
439
|
callback,
|
|
440
|
+
id,
|
|
291
441
|
payload,
|
|
292
442
|
time: timestamp,
|
|
293
443
|
type: "scheduled"
|
|
@@ -302,12 +452,12 @@ var Agent = class extends Server {
|
|
|
302
452
|
payload
|
|
303
453
|
)}, 'delayed', ${when}, ${timestamp})
|
|
304
454
|
`;
|
|
305
|
-
await
|
|
455
|
+
await this._scheduleNextAlarm();
|
|
306
456
|
return {
|
|
307
|
-
id,
|
|
308
457
|
callback,
|
|
309
|
-
payload,
|
|
310
458
|
delayInSeconds: when,
|
|
459
|
+
id,
|
|
460
|
+
payload,
|
|
311
461
|
time: timestamp,
|
|
312
462
|
type: "delayed"
|
|
313
463
|
};
|
|
@@ -321,12 +471,12 @@ var Agent = class extends Server {
|
|
|
321
471
|
payload
|
|
322
472
|
)}, 'cron', ${when}, ${timestamp})
|
|
323
473
|
`;
|
|
324
|
-
await
|
|
474
|
+
await this._scheduleNextAlarm();
|
|
325
475
|
return {
|
|
326
|
-
id,
|
|
327
476
|
callback,
|
|
328
|
-
payload,
|
|
329
477
|
cron: when,
|
|
478
|
+
id,
|
|
479
|
+
payload,
|
|
330
480
|
time: timestamp,
|
|
331
481
|
type: "cron"
|
|
332
482
|
};
|
|
@@ -388,47 +538,21 @@ var Agent = class extends Server {
|
|
|
388
538
|
*/
|
|
389
539
|
async cancelSchedule(id) {
|
|
390
540
|
this.sql`DELETE FROM cf_agents_schedules WHERE id = ${id}`;
|
|
391
|
-
await
|
|
541
|
+
await this._scheduleNextAlarm();
|
|
392
542
|
return true;
|
|
393
543
|
}
|
|
394
|
-
|
|
395
|
-
* Method called when an alarm fires
|
|
396
|
-
* Executes any scheduled tasks that are due
|
|
397
|
-
*/
|
|
398
|
-
async alarm() {
|
|
399
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
544
|
+
async _scheduleNextAlarm() {
|
|
400
545
|
const result = this.sql`
|
|
401
|
-
SELECT
|
|
546
|
+
SELECT time FROM cf_agents_schedules
|
|
547
|
+
WHERE time > ${Math.floor(Date.now() / 1e3)}
|
|
548
|
+
ORDER BY time ASC
|
|
549
|
+
LIMIT 1
|
|
402
550
|
`;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
continue;
|
|
408
|
-
}
|
|
409
|
-
await agentContext.run(
|
|
410
|
-
{ agent: this, connection: void 0, request: void 0 },
|
|
411
|
-
async () => {
|
|
412
|
-
try {
|
|
413
|
-
await callback.bind(this)(JSON.parse(row.payload), row);
|
|
414
|
-
} catch (e) {
|
|
415
|
-
console.error(`error executing callback "${row.callback}"`, e);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
);
|
|
419
|
-
if (row.type === "cron") {
|
|
420
|
-
const nextExecutionTime = getNextCronTime(row.cron);
|
|
421
|
-
const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
|
|
422
|
-
this.sql`
|
|
423
|
-
UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
|
|
424
|
-
`;
|
|
425
|
-
} else {
|
|
426
|
-
this.sql`
|
|
427
|
-
DELETE FROM cf_agents_schedules WHERE id = ${row.id}
|
|
428
|
-
`;
|
|
429
|
-
}
|
|
551
|
+
if (!result) return;
|
|
552
|
+
if (result.length > 0 && "time" in result[0]) {
|
|
553
|
+
const nextTime = result[0].time * 1e3;
|
|
554
|
+
await this.ctx.storage.setAlarm(nextTime);
|
|
430
555
|
}
|
|
431
|
-
await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
|
|
432
556
|
}
|
|
433
557
|
/**
|
|
434
558
|
* Destroy the Agent, removing all state and scheduled tasks
|
|
@@ -436,67 +560,131 @@ var Agent = class extends Server {
|
|
|
436
560
|
async destroy() {
|
|
437
561
|
this.sql`DROP TABLE IF EXISTS cf_agents_state`;
|
|
438
562
|
this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
|
|
563
|
+
this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
|
|
439
564
|
await this.ctx.storage.deleteAlarm();
|
|
440
565
|
await this.ctx.storage.deleteAll();
|
|
566
|
+
this.ctx.abort("destroyed");
|
|
441
567
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
568
|
+
/**
|
|
569
|
+
* Get all methods marked as callable on this Agent
|
|
570
|
+
* @returns A map of method names to their metadata
|
|
571
|
+
*/
|
|
572
|
+
_isCallable(method) {
|
|
573
|
+
return callableMetadata.has(this[method]);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Connect to a new MCP Server
|
|
577
|
+
*
|
|
578
|
+
* @param url MCP Server SSE URL
|
|
579
|
+
* @param callbackHost Base host for the agent, used for the redirect URI.
|
|
580
|
+
* @param agentsPrefix agents routing prefix if not using `agents`
|
|
581
|
+
* @param options MCP client and transport (header) options
|
|
582
|
+
* @returns authUrl
|
|
583
|
+
*/
|
|
584
|
+
async addMcpServer(serverName, url, callbackHost, agentsPrefix = "agents", options) {
|
|
585
|
+
const callbackUrl = `${callbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
|
|
586
|
+
const result = await this._connectToMcpServerInternal(
|
|
587
|
+
serverName,
|
|
588
|
+
url,
|
|
589
|
+
callbackUrl,
|
|
590
|
+
options
|
|
591
|
+
);
|
|
592
|
+
this.broadcast(
|
|
593
|
+
JSON.stringify({
|
|
594
|
+
mcp: this.getMcpServers(),
|
|
595
|
+
type: "cf_agent_mcp_servers"
|
|
596
|
+
})
|
|
597
|
+
);
|
|
598
|
+
return result;
|
|
599
|
+
}
|
|
600
|
+
async _connectToMcpServerInternal(serverName, url, callbackUrl, options, reconnect) {
|
|
601
|
+
const authProvider = new DurableObjectOAuthClientProvider(
|
|
602
|
+
this.ctx.storage,
|
|
603
|
+
this.name,
|
|
604
|
+
callbackUrl
|
|
605
|
+
);
|
|
606
|
+
if (reconnect) {
|
|
607
|
+
authProvider.serverId = reconnect.id;
|
|
608
|
+
if (reconnect.oauthClientId) {
|
|
609
|
+
authProvider.clientId = reconnect.oauthClientId;
|
|
469
610
|
}
|
|
611
|
+
}
|
|
612
|
+
let headerTransportOpts = {};
|
|
613
|
+
if (options?.transport?.headers) {
|
|
614
|
+
headerTransportOpts = {
|
|
615
|
+
eventSourceInit: {
|
|
616
|
+
fetch: (url2, init) => fetch(url2, {
|
|
617
|
+
...init,
|
|
618
|
+
headers: options?.transport?.headers
|
|
619
|
+
})
|
|
620
|
+
},
|
|
621
|
+
requestInit: {
|
|
622
|
+
headers: options?.transport?.headers
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
const { id, authUrl, clientId } = await this.mcp.connect(url, {
|
|
627
|
+
client: options?.client,
|
|
628
|
+
reconnect,
|
|
629
|
+
transport: {
|
|
630
|
+
...headerTransportOpts,
|
|
631
|
+
authProvider
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
this.sql`
|
|
635
|
+
INSERT OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
|
|
636
|
+
VALUES (
|
|
637
|
+
${id},
|
|
638
|
+
${serverName},
|
|
639
|
+
${url},
|
|
640
|
+
${clientId ?? null},
|
|
641
|
+
${authUrl ?? null},
|
|
642
|
+
${callbackUrl},
|
|
643
|
+
${options ? JSON.stringify(options) : null}
|
|
644
|
+
);
|
|
645
|
+
`;
|
|
646
|
+
return {
|
|
647
|
+
authUrl,
|
|
648
|
+
id
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
async removeMcpServer(id) {
|
|
652
|
+
this.mcp.closeConnection(id);
|
|
653
|
+
this.sql`
|
|
654
|
+
DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
|
|
655
|
+
`;
|
|
656
|
+
this.broadcast(
|
|
657
|
+
JSON.stringify({
|
|
658
|
+
mcp: this.getMcpServers(),
|
|
659
|
+
type: "cf_agent_mcp_servers"
|
|
660
|
+
})
|
|
470
661
|
);
|
|
471
|
-
});
|
|
472
|
-
};
|
|
473
|
-
tryCatch_fn = async function(fn) {
|
|
474
|
-
try {
|
|
475
|
-
return await fn();
|
|
476
|
-
} catch (e) {
|
|
477
|
-
throw this.onError(e);
|
|
478
662
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
663
|
+
getMcpServers() {
|
|
664
|
+
const mcpState = {
|
|
665
|
+
prompts: this.mcp.listPrompts(),
|
|
666
|
+
resources: this.mcp.listResources(),
|
|
667
|
+
servers: {},
|
|
668
|
+
tools: this.mcp.listTools()
|
|
669
|
+
};
|
|
670
|
+
const servers = this.sql`
|
|
671
|
+
SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
|
|
486
672
|
`;
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
673
|
+
for (const server of servers) {
|
|
674
|
+
const serverConn = this.mcp.mcpConnections[server.id];
|
|
675
|
+
mcpState.servers[server.id] = {
|
|
676
|
+
auth_url: server.auth_url,
|
|
677
|
+
capabilities: serverConn?.serverCapabilities ?? null,
|
|
678
|
+
instructions: serverConn?.instructions ?? null,
|
|
679
|
+
name: server.name,
|
|
680
|
+
server_url: server.server_url,
|
|
681
|
+
// mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
|
|
682
|
+
state: serverConn?.connectionState ?? "authenticating"
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
return mcpState;
|
|
491
686
|
}
|
|
492
687
|
};
|
|
493
|
-
/**
|
|
494
|
-
* Get all methods marked as callable on this Agent
|
|
495
|
-
* @returns A map of method names to their metadata
|
|
496
|
-
*/
|
|
497
|
-
isCallable_fn = function(method) {
|
|
498
|
-
return callableMetadata.has(this[method]);
|
|
499
|
-
};
|
|
500
688
|
/**
|
|
501
689
|
* Agent configuration options
|
|
502
690
|
*/
|
|
@@ -507,9 +695,9 @@ Agent.options = {
|
|
|
507
695
|
};
|
|
508
696
|
async function routeAgentRequest(request, env, options) {
|
|
509
697
|
const corsHeaders = options?.cors === true ? {
|
|
510
|
-
"Access-Control-Allow-Origin": "*",
|
|
511
|
-
"Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
|
|
512
698
|
"Access-Control-Allow-Credentials": "true",
|
|
699
|
+
"Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
|
|
700
|
+
"Access-Control-Allow-Origin": "*",
|
|
513
701
|
"Access-Control-Max-Age": "86400"
|
|
514
702
|
} : options?.cors;
|
|
515
703
|
if (request.method === "OPTIONS") {
|
|
@@ -540,59 +728,53 @@ async function routeAgentRequest(request, env, options) {
|
|
|
540
728
|
}
|
|
541
729
|
return response;
|
|
542
730
|
}
|
|
543
|
-
async function routeAgentEmail(
|
|
731
|
+
async function routeAgentEmail(_email, _env, _options) {
|
|
544
732
|
}
|
|
545
|
-
function getAgentByName(namespace, name, options) {
|
|
733
|
+
async function getAgentByName(namespace, name, options) {
|
|
546
734
|
return getServerByName(namespace, name, options);
|
|
547
735
|
}
|
|
548
|
-
var _connection, _id, _closed;
|
|
549
736
|
var StreamingResponse = class {
|
|
550
737
|
constructor(connection, id) {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
__privateSet(this, _connection, connection);
|
|
555
|
-
__privateSet(this, _id, id);
|
|
738
|
+
this._closed = false;
|
|
739
|
+
this._connection = connection;
|
|
740
|
+
this._id = id;
|
|
556
741
|
}
|
|
557
742
|
/**
|
|
558
743
|
* Send a chunk of data to the client
|
|
559
744
|
* @param chunk The data to send
|
|
560
745
|
*/
|
|
561
746
|
send(chunk) {
|
|
562
|
-
if (
|
|
747
|
+
if (this._closed) {
|
|
563
748
|
throw new Error("StreamingResponse is already closed");
|
|
564
749
|
}
|
|
565
750
|
const response = {
|
|
566
|
-
|
|
567
|
-
id:
|
|
568
|
-
success: true,
|
|
751
|
+
done: false,
|
|
752
|
+
id: this._id,
|
|
569
753
|
result: chunk,
|
|
570
|
-
|
|
754
|
+
success: true,
|
|
755
|
+
type: "rpc"
|
|
571
756
|
};
|
|
572
|
-
|
|
757
|
+
this._connection.send(JSON.stringify(response));
|
|
573
758
|
}
|
|
574
759
|
/**
|
|
575
760
|
* End the stream and send the final chunk (if any)
|
|
576
761
|
* @param finalChunk Optional final chunk of data to send
|
|
577
762
|
*/
|
|
578
763
|
end(finalChunk) {
|
|
579
|
-
if (
|
|
764
|
+
if (this._closed) {
|
|
580
765
|
throw new Error("StreamingResponse is already closed");
|
|
581
766
|
}
|
|
582
|
-
|
|
767
|
+
this._closed = true;
|
|
583
768
|
const response = {
|
|
584
|
-
|
|
585
|
-
id:
|
|
586
|
-
success: true,
|
|
769
|
+
done: true,
|
|
770
|
+
id: this._id,
|
|
587
771
|
result: finalChunk,
|
|
588
|
-
|
|
772
|
+
success: true,
|
|
773
|
+
type: "rpc"
|
|
589
774
|
};
|
|
590
|
-
|
|
775
|
+
this._connection.send(JSON.stringify(response));
|
|
591
776
|
}
|
|
592
777
|
};
|
|
593
|
-
_connection = new WeakMap();
|
|
594
|
-
_id = new WeakMap();
|
|
595
|
-
_closed = new WeakMap();
|
|
596
778
|
|
|
597
779
|
export {
|
|
598
780
|
unstable_callable,
|
|
@@ -603,4 +785,4 @@ export {
|
|
|
603
785
|
getAgentByName,
|
|
604
786
|
StreamingResponse
|
|
605
787
|
};
|
|
606
|
-
//# sourceMappingURL=chunk-
|
|
788
|
+
//# sourceMappingURL=chunk-ZRRXJUAA.js.map
|