agents 0.0.0-74a8c74 → 0.0.0-75614c2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/ai-chat-agent.d.ts +50 -5
  2. package/dist/ai-chat-agent.js +118 -51
  3. package/dist/ai-chat-agent.js.map +1 -1
  4. package/dist/ai-react.d.ts +17 -4
  5. package/dist/ai-react.js +62 -46
  6. package/dist/ai-react.js.map +1 -1
  7. package/dist/ai-types.d.ts +5 -0
  8. package/dist/chunk-767EASBA.js +106 -0
  9. package/dist/chunk-767EASBA.js.map +1 -0
  10. package/dist/{chunk-SZEXGW6W.js → chunk-CGWTDCBQ.js} +381 -170
  11. package/dist/chunk-CGWTDCBQ.js.map +1 -0
  12. package/dist/chunk-E3LCYPCB.js +469 -0
  13. package/dist/chunk-E3LCYPCB.js.map +1 -0
  14. package/dist/chunk-NKZZ66QY.js +116 -0
  15. package/dist/chunk-NKZZ66QY.js.map +1 -0
  16. package/dist/client.d.ts +15 -1
  17. package/dist/client.js +6 -126
  18. package/dist/client.js.map +1 -1
  19. package/dist/index.d.ts +124 -20
  20. package/dist/index.js +8 -7
  21. package/dist/mcp/client.d.ts +142 -34
  22. package/dist/mcp/client.js +3 -780
  23. package/dist/mcp/client.js.map +1 -1
  24. package/dist/mcp/do-oauth-client-provider.d.ts +41 -0
  25. package/dist/mcp/do-oauth-client-provider.js +7 -0
  26. package/dist/mcp/do-oauth-client-provider.js.map +1 -0
  27. package/dist/mcp/index.d.ts +50 -7
  28. package/dist/mcp/index.js +719 -71
  29. package/dist/mcp/index.js.map +1 -1
  30. package/dist/react.d.ts +85 -5
  31. package/dist/react.js +50 -29
  32. package/dist/react.js.map +1 -1
  33. package/dist/schedule.d.ts +2 -2
  34. package/dist/schedule.js +4 -4
  35. package/dist/schedule.js.map +1 -1
  36. package/dist/serializable.d.ts +32 -0
  37. package/dist/serializable.js +1 -0
  38. package/dist/serializable.js.map +1 -0
  39. package/package.json +76 -53
  40. package/src/index.ts +431 -93
  41. package/dist/chunk-EZ76ZGDB.js +0 -1721
  42. package/dist/chunk-EZ76ZGDB.js.map +0 -1
  43. package/dist/chunk-SZEXGW6W.js.map +0 -1
@@ -1,13 +1,22 @@
1
+ import {
2
+ MCPClientManager
3
+ } from "./chunk-E3LCYPCB.js";
4
+ import {
5
+ DurableObjectOAuthClientProvider
6
+ } from "./chunk-767EASBA.js";
7
+ import {
8
+ camelCaseToKebabCase
9
+ } from "./chunk-NKZZ66QY.js";
10
+
1
11
  // src/index.ts
12
+ import { AsyncLocalStorage } from "async_hooks";
13
+ import { parseCronExpression } from "cron-schedule";
14
+ import { nanoid } from "nanoid";
2
15
  import {
3
- Server,
16
+ getServerByName,
4
17
  routePartykitRequest,
5
- getServerByName
18
+ Server
6
19
  } from "partyserver";
7
- import { parseCronExpression } from "cron-schedule";
8
- import { nanoid } from "nanoid";
9
- import { AsyncLocalStorage } from "node:async_hooks";
10
- import { WorkflowEntrypoint as CFWorkflowEntrypoint } from "cloudflare:workers";
11
20
  function isRPCRequest(msg) {
12
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);
13
22
  }
@@ -23,8 +32,6 @@ function unstable_callable(metadata = {}) {
23
32
  return target;
24
33
  };
25
34
  }
26
- var WorkflowEntrypoint = class extends CFWorkflowEntrypoint {
27
- };
28
35
  function getNextCronTime(cron) {
29
36
  const interval = parseCronExpression(cron);
30
37
  return interval.getNextDate();
@@ -32,69 +39,72 @@ function getNextCronTime(cron) {
32
39
  var STATE_ROW_ID = "cf_state_row_id";
33
40
  var STATE_WAS_CHANGED = "cf_state_was_changed";
34
41
  var DEFAULT_STATE = {};
35
- var unstable_context = new AsyncLocalStorage();
36
- var Agent = class extends Server {
37
- #state = DEFAULT_STATE;
38
- /**
39
- * Initial state for the Agent
40
- * Override to provide default state values
41
- */
42
- initialState = DEFAULT_STATE;
43
- /**
44
- * Current state of the Agent
45
- */
46
- get state() {
47
- if (this.#state !== DEFAULT_STATE) {
48
- return this.#state;
49
- }
50
- const wasChanged = this.sql`
51
- SELECT state FROM cf_agents_state WHERE id = ${STATE_WAS_CHANGED}
52
- `;
53
- const result = this.sql`
54
- SELECT state FROM cf_agents_state WHERE id = ${STATE_ROW_ID}
55
- `;
56
- if (wasChanged[0]?.state === "true" || // we do this check for people who updated their code before we shipped wasChanged
57
- result[0]?.state) {
58
- const state = result[0]?.state;
59
- this.#state = JSON.parse(state);
60
- return this.#state;
61
- }
62
- if (this.initialState === DEFAULT_STATE) {
63
- return void 0;
64
- }
65
- this.setState(this.initialState);
66
- return this.initialState;
67
- }
68
- /**
69
- * Agent configuration options
70
- */
71
- static options = {
72
- /** Whether the Agent should hibernate when inactive */
73
- hibernate: true
74
- // default to hibernate
75
- };
76
- /**
77
- * Execute SQL queries against the Agent's database
78
- * @template T Type of the returned rows
79
- * @param strings SQL query template strings
80
- * @param values Values to be inserted into the query
81
- * @returns Array of query results
82
- */
83
- sql(strings, ...values) {
84
- let query = "";
85
- try {
86
- query = strings.reduce(
87
- (acc, str, i) => acc + str + (i < values.length ? "?" : ""),
88
- ""
89
- );
90
- return [...this.ctx.storage.sql.exec(query, ...values)];
91
- } catch (e) {
92
- console.error(`failed to execute sql query: ${query}`, e);
93
- throw this.onError(e);
94
- }
42
+ var agentContext = new AsyncLocalStorage();
43
+ function getCurrentAgent() {
44
+ const store = agentContext.getStore();
45
+ if (!store) {
46
+ return {
47
+ agent: void 0,
48
+ connection: void 0,
49
+ request: void 0
50
+ };
95
51
  }
52
+ return store;
53
+ }
54
+ var Agent = class extends Server {
96
55
  constructor(ctx, env) {
97
56
  super(ctx, env);
57
+ this._state = DEFAULT_STATE;
58
+ this._ParentClass = Object.getPrototypeOf(this).constructor;
59
+ this.mcp = new MCPClientManager(this._ParentClass.name, "0.0.1");
60
+ /**
61
+ * Initial state for the Agent
62
+ * Override to provide default state values
63
+ */
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
+ };
98
108
  this.sql`
99
109
  CREATE TABLE IF NOT EXISTS cf_agents_state (
100
110
  id TEXT PRIMARY KEY NOT NULL,
@@ -102,7 +112,7 @@ var Agent = class extends Server {
102
112
  )
103
113
  `;
104
114
  void this.ctx.blockConcurrencyWhile(async () => {
105
- return this.#tryCatch(async () => {
115
+ return this._tryCatch(async () => {
106
116
  this.sql`
107
117
  CREATE TABLE IF NOT EXISTS cf_agents_schedules (
108
118
  id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
@@ -118,22 +128,55 @@ var Agent = class extends Server {
118
128
  await this.alarm();
119
129
  });
120
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
+ };
121
164
  const _onMessage = this.onMessage.bind(this);
122
165
  this.onMessage = async (connection, message) => {
123
- return unstable_context.run(
166
+ return agentContext.run(
124
167
  { agent: this, connection, request: void 0 },
125
168
  async () => {
126
169
  if (typeof message !== "string") {
127
- return this.#tryCatch(() => _onMessage(connection, message));
170
+ return this._tryCatch(() => _onMessage(connection, message));
128
171
  }
129
172
  let parsed;
130
173
  try {
131
174
  parsed = JSON.parse(message);
132
- } catch (e) {
133
- return this.#tryCatch(() => _onMessage(connection, message));
175
+ } catch (_e) {
176
+ return this._tryCatch(() => _onMessage(connection, message));
134
177
  }
135
178
  if (isStateUpdateMessage(parsed)) {
136
- this.#setStateInternal(parsed.state, connection);
179
+ this._setStateInternal(parsed.state, connection);
137
180
  return;
138
181
  }
139
182
  if (isRPCRequest(parsed)) {
@@ -143,7 +186,7 @@ var Agent = class extends Server {
143
186
  if (typeof methodFn !== "function") {
144
187
  throw new Error(`Method ${method} does not exist`);
145
188
  }
146
- if (!this.#isCallable(method)) {
189
+ if (!this._isCallable(method)) {
147
190
  throw new Error(`Method ${method} is not callable`);
148
191
  }
149
192
  const metadata = callableMetadata.get(methodFn);
@@ -154,51 +197,135 @@ var Agent = class extends Server {
154
197
  }
155
198
  const result = await methodFn.apply(this, args);
156
199
  const response = {
157
- type: "rpc",
200
+ done: true,
158
201
  id,
159
- success: true,
160
202
  result,
161
- done: true
203
+ success: true,
204
+ type: "rpc"
162
205
  };
163
206
  connection.send(JSON.stringify(response));
164
207
  } catch (e) {
165
208
  const response = {
166
- type: "rpc",
209
+ error: e instanceof Error ? e.message : "Unknown error occurred",
167
210
  id: parsed.id,
168
211
  success: false,
169
- error: e instanceof Error ? e.message : "Unknown error occurred"
212
+ type: "rpc"
170
213
  };
171
214
  connection.send(JSON.stringify(response));
172
215
  console.error("RPC error:", e);
173
216
  }
174
217
  return;
175
218
  }
176
- return this.#tryCatch(() => _onMessage(connection, message));
219
+ return this._tryCatch(() => _onMessage(connection, message));
177
220
  }
178
221
  );
179
222
  };
180
223
  const _onConnect = this.onConnect.bind(this);
181
224
  this.onConnect = (connection, ctx2) => {
182
- return unstable_context.run(
225
+ return agentContext.run(
183
226
  { agent: this, connection, request: ctx2.request },
184
227
  async () => {
185
228
  setTimeout(() => {
186
229
  if (this.state) {
187
230
  connection.send(
188
231
  JSON.stringify({
189
- type: "cf_agent_state",
190
- state: this.state
232
+ state: this.state,
233
+ type: "cf_agent_state"
191
234
  })
192
235
  );
193
236
  }
194
- return this.#tryCatch(() => _onConnect(connection, ctx2));
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));
195
244
  }, 20);
196
245
  }
197
246
  );
198
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
+ Promise.allSettled(
257
+ servers.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
+ ).then((_results) => {
270
+ this.broadcast(
271
+ JSON.stringify({
272
+ type: "cf_agent_mcp_servers",
273
+ mcp: this.getMcpServers()
274
+ })
275
+ );
276
+ });
277
+ await this._tryCatch(() => _onStart());
278
+ }
279
+ );
280
+ };
199
281
  }
200
- #setStateInternal(state, source = "server") {
201
- this.#state = state;
282
+ /**
283
+ * Current state of the Agent
284
+ */
285
+ get state() {
286
+ if (this._state !== DEFAULT_STATE) {
287
+ return this._state;
288
+ }
289
+ const wasChanged = this.sql`
290
+ SELECT state FROM cf_agents_state WHERE id = ${STATE_WAS_CHANGED}
291
+ `;
292
+ const result = this.sql`
293
+ SELECT state FROM cf_agents_state WHERE id = ${STATE_ROW_ID}
294
+ `;
295
+ if (wasChanged[0]?.state === "true" || // we do this check for people who updated their code before we shipped wasChanged
296
+ result[0]?.state) {
297
+ const state = result[0]?.state;
298
+ this._state = JSON.parse(state);
299
+ return this._state;
300
+ }
301
+ if (this.initialState === DEFAULT_STATE) {
302
+ return void 0;
303
+ }
304
+ this.setState(this.initialState);
305
+ return this.initialState;
306
+ }
307
+ /**
308
+ * Execute SQL queries against the Agent's database
309
+ * @template T Type of the returned rows
310
+ * @param strings SQL query template strings
311
+ * @param values Values to be inserted into the query
312
+ * @returns Array of query results
313
+ */
314
+ sql(strings, ...values) {
315
+ let query = "";
316
+ try {
317
+ query = strings.reduce(
318
+ (acc, str, i) => acc + str + (i < values.length ? "?" : ""),
319
+ ""
320
+ );
321
+ return [...this.ctx.storage.sql.exec(query, ...values)];
322
+ } catch (e) {
323
+ console.error(`failed to execute sql query: ${query}`, e);
324
+ throw this.onError(e);
325
+ }
326
+ }
327
+ _setStateInternal(state, source = "server") {
328
+ this._state = state;
202
329
  this.sql`
203
330
  INSERT OR REPLACE INTO cf_agents_state (id, state)
204
331
  VALUES (${STATE_ROW_ID}, ${JSON.stringify(state)})
@@ -209,14 +336,14 @@ var Agent = class extends Server {
209
336
  `;
210
337
  this.broadcast(
211
338
  JSON.stringify({
212
- type: "cf_agent_state",
213
- state
339
+ state,
340
+ type: "cf_agent_state"
214
341
  }),
215
342
  source !== "server" ? [source.id] : []
216
343
  );
217
- return this.#tryCatch(() => {
218
- const { connection, request } = unstable_context.getStore() || {};
219
- return unstable_context.run(
344
+ return this._tryCatch(() => {
345
+ const { connection, request } = agentContext.getStore() || {};
346
+ return agentContext.run(
220
347
  { agent: this, connection, request },
221
348
  async () => {
222
349
  return this.onStateUpdate(state, source);
@@ -229,28 +356,30 @@ var Agent = class extends Server {
229
356
  * @param state New state to set
230
357
  */
231
358
  setState(state) {
232
- this.#setStateInternal(state, "server");
359
+ this._setStateInternal(state, "server");
233
360
  }
234
361
  /**
235
362
  * Called when the Agent's state is updated
236
363
  * @param state Updated state
237
364
  * @param source Source of the state update ("server" or a client connection)
238
365
  */
366
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
239
367
  onStateUpdate(state, source) {
240
368
  }
241
369
  /**
242
370
  * Called when the Agent receives an email
243
371
  * @param email Email message to process
244
372
  */
373
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
245
374
  onEmail(email) {
246
- return unstable_context.run(
375
+ return agentContext.run(
247
376
  { agent: this, connection: void 0, request: void 0 },
248
377
  async () => {
249
378
  console.error("onEmail not implemented");
250
379
  }
251
380
  );
252
381
  }
253
- async #tryCatch(fn) {
382
+ async _tryCatch(fn) {
254
383
  try {
255
384
  return await fn();
256
385
  } catch (e) {
@@ -306,10 +435,10 @@ var Agent = class extends Server {
306
435
  payload
307
436
  )}, 'scheduled', ${timestamp})
308
437
  `;
309
- await this.#scheduleNextAlarm();
438
+ await this._scheduleNextAlarm();
310
439
  return {
311
- id,
312
440
  callback,
441
+ id,
313
442
  payload,
314
443
  time: timestamp,
315
444
  type: "scheduled"
@@ -324,12 +453,12 @@ var Agent = class extends Server {
324
453
  payload
325
454
  )}, 'delayed', ${when}, ${timestamp})
326
455
  `;
327
- await this.#scheduleNextAlarm();
456
+ await this._scheduleNextAlarm();
328
457
  return {
329
- id,
330
458
  callback,
331
- payload,
332
459
  delayInSeconds: when,
460
+ id,
461
+ payload,
333
462
  time: timestamp,
334
463
  type: "delayed"
335
464
  };
@@ -343,12 +472,12 @@ var Agent = class extends Server {
343
472
  payload
344
473
  )}, 'cron', ${when}, ${timestamp})
345
474
  `;
346
- await this.#scheduleNextAlarm();
475
+ await this._scheduleNextAlarm();
347
476
  return {
348
- id,
349
477
  callback,
350
- payload,
351
478
  cron: when,
479
+ id,
480
+ payload,
352
481
  time: timestamp,
353
482
  type: "cron"
354
483
  };
@@ -410,10 +539,10 @@ var Agent = class extends Server {
410
539
  */
411
540
  async cancelSchedule(id) {
412
541
  this.sql`DELETE FROM cf_agents_schedules WHERE id = ${id}`;
413
- await this.#scheduleNextAlarm();
542
+ await this._scheduleNextAlarm();
414
543
  return true;
415
544
  }
416
- async #scheduleNextAlarm() {
545
+ async _scheduleNextAlarm() {
417
546
  const result = this.sql`
418
547
  SELECT time FROM cf_agents_schedules
419
548
  WHERE time > ${Math.floor(Date.now() / 1e3)}
@@ -426,67 +555,152 @@ var Agent = class extends Server {
426
555
  await this.ctx.storage.setAlarm(nextTime);
427
556
  }
428
557
  }
429
- /**
430
- * Method called when an alarm fires
431
- * Executes any scheduled tasks that are due
432
- */
433
- async alarm() {
434
- const now = Math.floor(Date.now() / 1e3);
435
- const result = this.sql`
436
- SELECT * FROM cf_agents_schedules WHERE time <= ${now}
437
- `;
438
- for (const row of result || []) {
439
- const callback = this[row.callback];
440
- if (!callback) {
441
- console.error(`callback ${row.callback} not found`);
442
- continue;
443
- }
444
- await unstable_context.run(
445
- { agent: this, connection: void 0, request: void 0 },
446
- async () => {
447
- try {
448
- await callback.bind(this)(JSON.parse(row.payload), row);
449
- } catch (e) {
450
- console.error(`error executing callback "${row.callback}"`, e);
451
- }
452
- }
453
- );
454
- if (row.type === "cron") {
455
- const nextExecutionTime = getNextCronTime(row.cron);
456
- const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
457
- this.sql`
458
- UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
459
- `;
460
- } else {
461
- this.sql`
462
- DELETE FROM cf_agents_schedules WHERE id = ${row.id}
463
- `;
464
- }
465
- }
466
- await this.#scheduleNextAlarm();
467
- }
468
558
  /**
469
559
  * Destroy the Agent, removing all state and scheduled tasks
470
560
  */
471
561
  async destroy() {
472
562
  this.sql`DROP TABLE IF EXISTS cf_agents_state`;
473
563
  this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
564
+ this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
474
565
  await this.ctx.storage.deleteAlarm();
475
566
  await this.ctx.storage.deleteAll();
567
+ this.ctx.abort("destroyed");
476
568
  }
477
569
  /**
478
570
  * Get all methods marked as callable on this Agent
479
571
  * @returns A map of method names to their metadata
480
572
  */
481
- #isCallable(method) {
573
+ _isCallable(method) {
482
574
  return callableMetadata.has(this[method]);
483
575
  }
576
+ /**
577
+ * Connect to a new MCP Server
578
+ *
579
+ * @param url MCP Server SSE URL
580
+ * @param callbackHost Base host for the agent, used for the redirect URI.
581
+ * @param agentsPrefix agents routing prefix if not using `agents`
582
+ * @param options MCP client and transport (header) options
583
+ * @returns authUrl
584
+ */
585
+ async addMcpServer(serverName, url, callbackHost, agentsPrefix = "agents", options) {
586
+ const callbackUrl = `${callbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
587
+ const result = await this._connectToMcpServerInternal(
588
+ serverName,
589
+ url,
590
+ callbackUrl,
591
+ options
592
+ );
593
+ this.sql`
594
+ INSERT
595
+ OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
596
+ VALUES (
597
+ ${result.id},
598
+ ${serverName},
599
+ ${url},
600
+ ${result.clientId ?? null},
601
+ ${result.authUrl ?? null},
602
+ ${callbackUrl},
603
+ ${options ? JSON.stringify(options) : null}
604
+ );
605
+ `;
606
+ this.broadcast(
607
+ JSON.stringify({
608
+ mcp: this.getMcpServers(),
609
+ type: "cf_agent_mcp_servers"
610
+ })
611
+ );
612
+ return result;
613
+ }
614
+ async _connectToMcpServerInternal(_serverName, url, callbackUrl, options, reconnect) {
615
+ const authProvider = new DurableObjectOAuthClientProvider(
616
+ this.ctx.storage,
617
+ this.name,
618
+ callbackUrl
619
+ );
620
+ if (reconnect) {
621
+ authProvider.serverId = reconnect.id;
622
+ if (reconnect.oauthClientId) {
623
+ authProvider.clientId = reconnect.oauthClientId;
624
+ }
625
+ }
626
+ let headerTransportOpts = {};
627
+ if (options?.transport?.headers) {
628
+ headerTransportOpts = {
629
+ eventSourceInit: {
630
+ fetch: (url2, init) => fetch(url2, {
631
+ ...init,
632
+ headers: options?.transport?.headers
633
+ })
634
+ },
635
+ requestInit: {
636
+ headers: options?.transport?.headers
637
+ }
638
+ };
639
+ }
640
+ const { id, authUrl, clientId } = await this.mcp.connect(url, {
641
+ client: options?.client,
642
+ reconnect,
643
+ transport: {
644
+ ...headerTransportOpts,
645
+ authProvider
646
+ }
647
+ });
648
+ return {
649
+ authUrl,
650
+ clientId,
651
+ id
652
+ };
653
+ }
654
+ async removeMcpServer(id) {
655
+ this.mcp.closeConnection(id);
656
+ this.sql`
657
+ DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
658
+ `;
659
+ this.broadcast(
660
+ JSON.stringify({
661
+ mcp: this.getMcpServers(),
662
+ type: "cf_agent_mcp_servers"
663
+ })
664
+ );
665
+ }
666
+ getMcpServers() {
667
+ const mcpState = {
668
+ prompts: this.mcp.listPrompts(),
669
+ resources: this.mcp.listResources(),
670
+ servers: {},
671
+ tools: this.mcp.listTools()
672
+ };
673
+ const servers = this.sql`
674
+ SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
675
+ `;
676
+ for (const server of servers) {
677
+ const serverConn = this.mcp.mcpConnections[server.id];
678
+ mcpState.servers[server.id] = {
679
+ auth_url: server.auth_url,
680
+ capabilities: serverConn?.serverCapabilities ?? null,
681
+ instructions: serverConn?.instructions ?? null,
682
+ name: server.name,
683
+ server_url: server.server_url,
684
+ // mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
685
+ state: serverConn?.connectionState ?? "authenticating"
686
+ };
687
+ }
688
+ return mcpState;
689
+ }
690
+ };
691
+ /**
692
+ * Agent configuration options
693
+ */
694
+ Agent.options = {
695
+ /** Whether the Agent should hibernate when inactive */
696
+ hibernate: true
697
+ // default to hibernate
484
698
  };
485
699
  async function routeAgentRequest(request, env, options) {
486
700
  const corsHeaders = options?.cors === true ? {
487
- "Access-Control-Allow-Origin": "*",
488
- "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
489
701
  "Access-Control-Allow-Credentials": "true",
702
+ "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
703
+ "Access-Control-Allow-Origin": "*",
490
704
  "Access-Control-Max-Age": "86400"
491
705
  } : options?.cors;
492
706
  if (request.method === "OPTIONS") {
@@ -517,64 +731,61 @@ async function routeAgentRequest(request, env, options) {
517
731
  }
518
732
  return response;
519
733
  }
520
- async function routeAgentEmail(email, env, options) {
734
+ async function routeAgentEmail(_email, _env, _options) {
521
735
  }
522
- function getAgentByName(namespace, name, options) {
736
+ async function getAgentByName(namespace, name, options) {
523
737
  return getServerByName(namespace, name, options);
524
738
  }
525
739
  var StreamingResponse = class {
526
- #connection;
527
- #id;
528
- #closed = false;
529
740
  constructor(connection, id) {
530
- this.#connection = connection;
531
- this.#id = id;
741
+ this._closed = false;
742
+ this._connection = connection;
743
+ this._id = id;
532
744
  }
533
745
  /**
534
746
  * Send a chunk of data to the client
535
747
  * @param chunk The data to send
536
748
  */
537
749
  send(chunk) {
538
- if (this.#closed) {
750
+ if (this._closed) {
539
751
  throw new Error("StreamingResponse is already closed");
540
752
  }
541
753
  const response = {
542
- type: "rpc",
543
- id: this.#id,
544
- success: true,
754
+ done: false,
755
+ id: this._id,
545
756
  result: chunk,
546
- done: false
757
+ success: true,
758
+ type: "rpc"
547
759
  };
548
- this.#connection.send(JSON.stringify(response));
760
+ this._connection.send(JSON.stringify(response));
549
761
  }
550
762
  /**
551
763
  * End the stream and send the final chunk (if any)
552
764
  * @param finalChunk Optional final chunk of data to send
553
765
  */
554
766
  end(finalChunk) {
555
- if (this.#closed) {
767
+ if (this._closed) {
556
768
  throw new Error("StreamingResponse is already closed");
557
769
  }
558
- this.#closed = true;
770
+ this._closed = true;
559
771
  const response = {
560
- type: "rpc",
561
- id: this.#id,
562
- success: true,
772
+ done: true,
773
+ id: this._id,
563
774
  result: finalChunk,
564
- done: true
775
+ success: true,
776
+ type: "rpc"
565
777
  };
566
- this.#connection.send(JSON.stringify(response));
778
+ this._connection.send(JSON.stringify(response));
567
779
  }
568
780
  };
569
781
 
570
782
  export {
571
783
  unstable_callable,
572
- WorkflowEntrypoint,
573
- unstable_context,
784
+ getCurrentAgent,
574
785
  Agent,
575
786
  routeAgentRequest,
576
787
  routeAgentEmail,
577
788
  getAgentByName,
578
789
  StreamingResponse
579
790
  };
580
- //# sourceMappingURL=chunk-SZEXGW6W.js.map
791
+ //# sourceMappingURL=chunk-CGWTDCBQ.js.map