agents 0.0.0-569680f → 0.0.0-57c0db2

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 (68) hide show
  1. package/README.md +255 -27
  2. package/dist/_esm-LV5FJ3HK.js +3922 -0
  3. package/dist/_esm-LV5FJ3HK.js.map +1 -0
  4. package/dist/ai-chat-agent.d.ts +12 -9
  5. package/dist/ai-chat-agent.js +151 -59
  6. package/dist/ai-chat-agent.js.map +1 -1
  7. package/dist/ai-chat-v5-migration.d.ts +152 -0
  8. package/dist/ai-chat-v5-migration.js +20 -0
  9. package/dist/ai-chat-v5-migration.js.map +1 -0
  10. package/dist/ai-react.d.ts +68 -71
  11. package/dist/ai-react.js +178 -37
  12. package/dist/ai-react.js.map +1 -1
  13. package/dist/ai-types.d.ts +37 -19
  14. package/dist/ai-types.js +7 -0
  15. package/dist/ccip-CMBYN64O.js +15 -0
  16. package/dist/ccip-CMBYN64O.js.map +1 -0
  17. package/dist/chunk-5Y6BEZDY.js +276 -0
  18. package/dist/chunk-5Y6BEZDY.js.map +1 -0
  19. package/dist/chunk-BER7KXUJ.js +18 -0
  20. package/dist/chunk-BER7KXUJ.js.map +1 -0
  21. package/dist/{chunk-RX76B6DL.js → chunk-HS7VEROK.js} +454 -179
  22. package/dist/chunk-HS7VEROK.js.map +1 -0
  23. package/dist/chunk-JJBFIGUC.js +5202 -0
  24. package/dist/chunk-JJBFIGUC.js.map +1 -0
  25. package/dist/{chunk-767EASBA.js → chunk-LL2AFX7V.js} +5 -2
  26. package/dist/chunk-LL2AFX7V.js.map +1 -0
  27. package/dist/chunk-PR4QN5HX.js +43 -0
  28. package/dist/chunk-PR4QN5HX.js.map +1 -0
  29. package/dist/{chunk-NKZZ66QY.js → chunk-QEVM4BVL.js} +5 -5
  30. package/dist/chunk-QEVM4BVL.js.map +1 -0
  31. package/dist/{chunk-TN7QOY4S.js → chunk-SKACXF37.js} +164 -21
  32. package/dist/chunk-SKACXF37.js.map +1 -0
  33. package/dist/chunk-TYAY6AU6.js +159 -0
  34. package/dist/chunk-TYAY6AU6.js.map +1 -0
  35. package/dist/chunk-UJVEAURM.js +150 -0
  36. package/dist/chunk-UJVEAURM.js.map +1 -0
  37. package/dist/client-CvaJdLQA.d.ts +5015 -0
  38. package/dist/client.d.ts +2 -2
  39. package/dist/client.js +3 -1
  40. package/dist/index.d.ts +557 -31
  41. package/dist/index.js +14 -12
  42. package/dist/mcp/client.d.ts +9 -1053
  43. package/dist/mcp/client.js +2 -1
  44. package/dist/mcp/do-oauth-client-provider.d.ts +1 -0
  45. package/dist/mcp/do-oauth-client-provider.js +2 -1
  46. package/dist/mcp/index.d.ts +64 -56
  47. package/dist/mcp/index.js +954 -638
  48. package/dist/mcp/index.js.map +1 -1
  49. package/dist/mcp/x402.d.ts +31 -0
  50. package/dist/mcp/x402.js +3195 -0
  51. package/dist/mcp/x402.js.map +1 -0
  52. package/dist/observability/index.d.ts +46 -12
  53. package/dist/observability/index.js +6 -4
  54. package/dist/react.d.ts +10 -6
  55. package/dist/react.js +8 -5
  56. package/dist/react.js.map +1 -1
  57. package/dist/schedule.d.ts +83 -9
  58. package/dist/schedule.js +17 -2
  59. package/dist/schedule.js.map +1 -1
  60. package/dist/secp256k1-M22GZP2U.js +2193 -0
  61. package/dist/secp256k1-M22GZP2U.js.map +1 -0
  62. package/package.json +26 -10
  63. package/src/index.ts +651 -236
  64. package/dist/chunk-767EASBA.js.map +0 -1
  65. package/dist/chunk-NKZZ66QY.js.map +0 -1
  66. package/dist/chunk-RX76B6DL.js.map +0 -1
  67. package/dist/chunk-TN7QOY4S.js.map +0 -1
  68. package/dist/index-aBwVVXj7.d.ts +0 -529
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  MCPClientManager
3
- } from "./chunk-TN7QOY4S.js";
3
+ } from "./chunk-SKACXF37.js";
4
4
  import {
5
5
  DurableObjectOAuthClientProvider
6
- } from "./chunk-767EASBA.js";
6
+ } from "./chunk-LL2AFX7V.js";
7
7
  import {
8
8
  camelCaseToKebabCase
9
- } from "./chunk-NKZZ66QY.js";
9
+ } from "./chunk-QEVM4BVL.js";
10
10
 
11
11
  // src/index.ts
12
12
  import { AsyncLocalStorage } from "async_hooks";
@@ -19,13 +19,13 @@ import {
19
19
  routePartykitRequest
20
20
  } from "partyserver";
21
21
  function isRPCRequest(msg) {
22
- 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
+ return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "rpc" /* RPC */ && "id" in msg && typeof msg.id === "string" && "method" in msg && typeof msg.method === "string" && "args" in msg && Array.isArray(msg.args);
23
23
  }
24
24
  function isStateUpdateMessage(msg) {
25
- return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "cf_agent_state" && "state" in msg;
25
+ return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "cf_agent_state" /* CF_AGENT_STATE */ && "state" in msg;
26
26
  }
27
27
  var callableMetadata = /* @__PURE__ */ new Map();
28
- function unstable_callable(metadata = {}) {
28
+ function callable(metadata = {}) {
29
29
  return function callableDecorator(target, context) {
30
30
  if (!callableMetadata.has(target)) {
31
31
  callableMetadata.set(target, metadata);
@@ -33,6 +33,16 @@ function unstable_callable(metadata = {}) {
33
33
  return target;
34
34
  };
35
35
  }
36
+ var didWarnAboutUnstableCallable = false;
37
+ var unstable_callable = (metadata = {}) => {
38
+ if (!didWarnAboutUnstableCallable) {
39
+ didWarnAboutUnstableCallable = true;
40
+ console.warn(
41
+ "unstable_callable is deprecated, use callable instead. unstable_callable will be removed in the next major version."
42
+ );
43
+ }
44
+ callable(metadata);
45
+ };
36
46
  function getNextCronTime(cron) {
37
47
  const interval = parseCronExpression(cron);
38
48
  return interval.getNextDate();
@@ -47,12 +57,24 @@ function getCurrentAgent() {
47
57
  return {
48
58
  agent: void 0,
49
59
  connection: void 0,
50
- request: void 0
60
+ request: void 0,
61
+ email: void 0
51
62
  };
52
63
  }
53
64
  return store;
54
65
  }
55
- var Agent = class extends Server {
66
+ function withAgentContext(method) {
67
+ return function(...args) {
68
+ const { connection, request, email, agent } = getCurrentAgent();
69
+ if (agent === this) {
70
+ return method.apply(this, args);
71
+ }
72
+ return agentContext.run({ agent: this, connection, request, email }, () => {
73
+ return method.apply(this, args);
74
+ });
75
+ };
76
+ }
77
+ var _Agent = class _Agent extends Server {
56
78
  constructor(ctx, env) {
57
79
  super(ctx, env);
58
80
  this._state = DEFAULT_STATE;
@@ -67,6 +89,7 @@ var Agent = class extends Server {
67
89
  * The observability implementation to use for the Agent
68
90
  */
69
91
  this.observability = genericObservability;
92
+ this._flushingQueue = false;
70
93
  /**
71
94
  * Method called when an alarm fires.
72
95
  * Executes any scheduled tasks that are due.
@@ -80,52 +103,74 @@ var Agent = class extends Server {
80
103
  const result = this.sql`
81
104
  SELECT * FROM cf_agents_schedules WHERE time <= ${now}
82
105
  `;
83
- for (const row of result || []) {
84
- const callback = this[row.callback];
85
- if (!callback) {
86
- console.error(`callback ${row.callback} not found`);
87
- continue;
88
- }
89
- await agentContext.run(
90
- { agent: this, connection: void 0, request: void 0 },
91
- async () => {
92
- try {
93
- this.observability?.emit(
94
- {
95
- displayMessage: `Schedule ${row.id} executed`,
96
- id: nanoid(),
97
- payload: row,
98
- timestamp: Date.now(),
99
- type: "schedule:execute"
100
- },
101
- this.ctx
102
- );
103
- await callback.bind(this)(JSON.parse(row.payload), row);
104
- } catch (e) {
105
- console.error(`error executing callback "${row.callback}"`, e);
106
- }
106
+ if (result && Array.isArray(result)) {
107
+ for (const row of result) {
108
+ const callback = this[row.callback];
109
+ if (!callback) {
110
+ console.error(`callback ${row.callback} not found`);
111
+ continue;
107
112
  }
108
- );
109
- if (row.type === "cron") {
110
- const nextExecutionTime = getNextCronTime(row.cron);
111
- const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
112
- this.sql`
113
+ await agentContext.run(
114
+ {
115
+ agent: this,
116
+ connection: void 0,
117
+ request: void 0,
118
+ email: void 0
119
+ },
120
+ async () => {
121
+ try {
122
+ this.observability?.emit(
123
+ {
124
+ displayMessage: `Schedule ${row.id} executed`,
125
+ id: nanoid(),
126
+ payload: {
127
+ callback: row.callback,
128
+ id: row.id
129
+ },
130
+ timestamp: Date.now(),
131
+ type: "schedule:execute"
132
+ },
133
+ this.ctx
134
+ );
135
+ await callback.bind(this)(JSON.parse(row.payload), row);
136
+ } catch (e) {
137
+ console.error(`error executing callback "${row.callback}"`, e);
138
+ }
139
+ }
140
+ );
141
+ if (row.type === "cron") {
142
+ const nextExecutionTime = getNextCronTime(row.cron);
143
+ const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
144
+ this.sql`
113
145
  UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
114
146
  `;
115
- } else {
116
- this.sql`
147
+ } else {
148
+ this.sql`
117
149
  DELETE FROM cf_agents_schedules WHERE id = ${row.id}
118
150
  `;
151
+ }
119
152
  }
120
153
  }
121
154
  await this._scheduleNextAlarm();
122
155
  };
156
+ if (!wrappedClasses.has(this.constructor)) {
157
+ this._autoWrapCustomMethods();
158
+ wrappedClasses.add(this.constructor);
159
+ }
123
160
  this.sql`
124
161
  CREATE TABLE IF NOT EXISTS cf_agents_state (
125
162
  id TEXT PRIMARY KEY NOT NULL,
126
163
  state TEXT
127
164
  )
128
165
  `;
166
+ this.sql`
167
+ CREATE TABLE IF NOT EXISTS cf_agents_queues (
168
+ id TEXT PRIMARY KEY NOT NULL,
169
+ payload TEXT,
170
+ callback TEXT,
171
+ created_at INTEGER DEFAULT (unixepoch())
172
+ )
173
+ `;
129
174
  void this.ctx.blockConcurrencyWhile(async () => {
130
175
  return this._tryCatch(async () => {
131
176
  this.sql`
@@ -157,14 +202,14 @@ var Agent = class extends Server {
157
202
  const _onRequest = this.onRequest.bind(this);
158
203
  this.onRequest = (request) => {
159
204
  return agentContext.run(
160
- { agent: this, connection: void 0, request },
205
+ { agent: this, connection: void 0, request, email: void 0 },
161
206
  async () => {
162
207
  if (this.mcp.isCallbackRequest(request)) {
163
208
  await this.mcp.handleCallbackRequest(request);
164
209
  this.broadcast(
165
210
  JSON.stringify({
166
211
  mcp: this.getMcpServers(),
167
- type: "cf_agent_mcp_servers"
212
+ type: "cf_agent_mcp_servers" /* CF_AGENT_MCP_SERVERS */
168
213
  })
169
214
  );
170
215
  return new Response("<script>window.close();</script>", {
@@ -179,7 +224,7 @@ var Agent = class extends Server {
179
224
  const _onMessage = this.onMessage.bind(this);
180
225
  this.onMessage = async (connection, message) => {
181
226
  return agentContext.run(
182
- { agent: this, connection, request: void 0 },
227
+ { agent: this, connection, request: void 0, email: void 0 },
183
228
  async () => {
184
229
  if (typeof message !== "string") {
185
230
  return this._tryCatch(() => _onMessage(connection, message));
@@ -216,10 +261,8 @@ var Agent = class extends Server {
216
261
  displayMessage: `RPC call to ${method}`,
217
262
  id: nanoid(),
218
263
  payload: {
219
- args,
220
264
  method,
221
- streaming: metadata?.streaming,
222
- success: true
265
+ streaming: metadata?.streaming
223
266
  },
224
267
  timestamp: Date.now(),
225
268
  type: "rpc"
@@ -231,7 +274,7 @@ var Agent = class extends Server {
231
274
  id,
232
275
  result,
233
276
  success: true,
234
- type: "rpc"
277
+ type: "rpc" /* RPC */
235
278
  };
236
279
  connection.send(JSON.stringify(response));
237
280
  } catch (e) {
@@ -239,7 +282,7 @@ var Agent = class extends Server {
239
282
  error: e instanceof Error ? e.message : "Unknown error occurred",
240
283
  id: parsed.id,
241
284
  success: false,
242
- type: "rpc"
285
+ type: "rpc" /* RPC */
243
286
  };
244
287
  connection.send(JSON.stringify(response));
245
288
  console.error("RPC error:", e);
@@ -253,70 +296,92 @@ var Agent = class extends Server {
253
296
  const _onConnect = this.onConnect.bind(this);
254
297
  this.onConnect = (connection, ctx2) => {
255
298
  return agentContext.run(
256
- { agent: this, connection, request: ctx2.request },
257
- async () => {
258
- setTimeout(() => {
259
- if (this.state) {
260
- connection.send(
261
- JSON.stringify({
262
- state: this.state,
263
- type: "cf_agent_state"
264
- })
265
- );
266
- }
299
+ { agent: this, connection, request: ctx2.request, email: void 0 },
300
+ () => {
301
+ if (this.state) {
267
302
  connection.send(
268
303
  JSON.stringify({
269
- mcp: this.getMcpServers(),
270
- type: "cf_agent_mcp_servers"
304
+ state: this.state,
305
+ type: "cf_agent_state" /* CF_AGENT_STATE */
271
306
  })
272
307
  );
273
- this.observability?.emit(
274
- {
275
- displayMessage: "Connection established",
276
- id: nanoid(),
277
- payload: {
278
- connectionId: connection.id
279
- },
280
- timestamp: Date.now(),
281
- type: "connect"
308
+ }
309
+ connection.send(
310
+ JSON.stringify({
311
+ mcp: this.getMcpServers(),
312
+ type: "cf_agent_mcp_servers" /* CF_AGENT_MCP_SERVERS */
313
+ })
314
+ );
315
+ this.observability?.emit(
316
+ {
317
+ displayMessage: "Connection established",
318
+ id: nanoid(),
319
+ payload: {
320
+ connectionId: connection.id
282
321
  },
283
- this.ctx
284
- );
285
- return this._tryCatch(() => _onConnect(connection, ctx2));
286
- }, 20);
322
+ timestamp: Date.now(),
323
+ type: "connect"
324
+ },
325
+ this.ctx
326
+ );
327
+ return this._tryCatch(() => _onConnect(connection, ctx2));
287
328
  }
288
329
  );
289
330
  };
290
331
  const _onStart = this.onStart.bind(this);
291
- this.onStart = async () => {
332
+ this.onStart = async (props) => {
292
333
  return agentContext.run(
293
- { agent: this, connection: void 0, request: void 0 },
334
+ {
335
+ agent: this,
336
+ connection: void 0,
337
+ request: void 0,
338
+ email: void 0
339
+ },
294
340
  async () => {
295
- const servers = this.sql`
341
+ await this._tryCatch(() => {
342
+ const servers = this.sql`
296
343
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
297
344
  `;
298
- Promise.allSettled(
299
- servers.map((server) => {
300
- return this._connectToMcpServerInternal(
301
- server.name,
302
- server.server_url,
303
- server.callback_url,
304
- server.server_options ? JSON.parse(server.server_options) : void 0,
305
- {
306
- id: server.id,
307
- oauthClientId: server.client_id ?? void 0
308
- }
309
- );
310
- })
311
- ).then((_results) => {
312
345
  this.broadcast(
313
346
  JSON.stringify({
314
347
  mcp: this.getMcpServers(),
315
- type: "cf_agent_mcp_servers"
348
+ type: "cf_agent_mcp_servers" /* CF_AGENT_MCP_SERVERS */
316
349
  })
317
350
  );
351
+ if (servers && Array.isArray(servers) && servers.length > 0) {
352
+ servers.forEach((server) => {
353
+ this._connectToMcpServerInternal(
354
+ server.name,
355
+ server.server_url,
356
+ server.callback_url,
357
+ server.server_options ? JSON.parse(server.server_options) : void 0,
358
+ {
359
+ id: server.id,
360
+ oauthClientId: server.client_id ?? void 0
361
+ }
362
+ ).then(() => {
363
+ this.broadcast(
364
+ JSON.stringify({
365
+ mcp: this.getMcpServers(),
366
+ type: "cf_agent_mcp_servers" /* CF_AGENT_MCP_SERVERS */
367
+ })
368
+ );
369
+ }).catch((error) => {
370
+ console.error(
371
+ `Error connecting to MCP server: ${server.name} (${server.server_url})`,
372
+ error
373
+ );
374
+ this.broadcast(
375
+ JSON.stringify({
376
+ mcp: this.getMcpServers(),
377
+ type: "cf_agent_mcp_servers" /* CF_AGENT_MCP_SERVERS */
378
+ })
379
+ );
380
+ });
381
+ });
382
+ }
383
+ return _onStart(props);
318
384
  });
319
- await this._tryCatch(() => _onStart());
320
385
  }
321
386
  );
322
387
  };
@@ -367,7 +432,6 @@ var Agent = class extends Server {
367
432
  }
368
433
  }
369
434
  _setStateInternal(state, source = "server") {
370
- const previousState = this._state;
371
435
  this._state = state;
372
436
  this.sql`
373
437
  INSERT OR REPLACE INTO cf_agents_state (id, state)
@@ -380,23 +444,20 @@ var Agent = class extends Server {
380
444
  this.broadcast(
381
445
  JSON.stringify({
382
446
  state,
383
- type: "cf_agent_state"
447
+ type: "cf_agent_state" /* CF_AGENT_STATE */
384
448
  }),
385
449
  source !== "server" ? [source.id] : []
386
450
  );
387
451
  return this._tryCatch(() => {
388
- const { connection, request } = agentContext.getStore() || {};
452
+ const { connection, request, email } = agentContext.getStore() || {};
389
453
  return agentContext.run(
390
- { agent: this, connection, request },
454
+ { agent: this, connection, request, email },
391
455
  async () => {
392
456
  this.observability?.emit(
393
457
  {
394
458
  displayMessage: "State updated",
395
459
  id: nanoid(),
396
- payload: {
397
- previousState,
398
- state
399
- },
460
+ payload: {},
400
461
  timestamp: Date.now(),
401
462
  type: "state:update"
402
463
  },
@@ -423,28 +484,65 @@ var Agent = class extends Server {
423
484
  onStateUpdate(state, source) {
424
485
  }
425
486
  /**
426
- * Called when the Agent receives an email
487
+ * Called when the Agent receives an email via routeAgentEmail()
427
488
  * Override this method to handle incoming emails
428
489
  * @param email Email message to process
429
490
  */
430
- async onEmail(email) {
491
+ async _onEmail(email) {
431
492
  return agentContext.run(
432
- { agent: this, connection: void 0, request: void 0 },
493
+ { agent: this, connection: void 0, request: void 0, email },
433
494
  async () => {
434
- console.log("Received email from:", email.from, "to:", email.to);
435
- console.log("Subject:", email.headers.get("subject"));
436
- console.log("Override onEmail() in your agent to process emails");
495
+ if ("onEmail" in this && typeof this.onEmail === "function") {
496
+ return this._tryCatch(
497
+ () => this.onEmail(email)
498
+ );
499
+ } else {
500
+ console.log("Received email from:", email.from, "to:", email.to);
501
+ console.log("Subject:", email.headers.get("subject"));
502
+ console.log(
503
+ "Implement onEmail(email: AgentEmail): Promise<void> in your agent to process emails"
504
+ );
505
+ }
437
506
  }
438
507
  );
439
508
  }
440
- async sendEmail(emailBinding, from, fromName, options) {
441
- const agentName = camelCaseToKebabCase(this._ParentClass.name);
442
- const agentId = this.name;
443
- return sendEmailWithRouting(emailBinding, from, fromName, {
444
- ...options,
445
- agentName,
446
- agentId,
447
- includeRoutingHeaders: true
509
+ /**
510
+ * Reply to an email
511
+ * @param email The email to reply to
512
+ * @param options Options for the reply
513
+ * @returns void
514
+ */
515
+ async replyToEmail(email, options) {
516
+ return this._tryCatch(async () => {
517
+ const agentName = camelCaseToKebabCase(this._ParentClass.name);
518
+ const agentId = this.name;
519
+ const { createMimeMessage } = await import("mimetext");
520
+ const msg = createMimeMessage();
521
+ msg.setSender({ addr: email.to, name: options.fromName });
522
+ msg.setRecipient(email.from);
523
+ msg.setSubject(
524
+ options.subject || `Re: ${email.headers.get("subject")}` || "No subject"
525
+ );
526
+ msg.addMessage({
527
+ contentType: options.contentType || "text/plain",
528
+ data: options.body
529
+ });
530
+ const domain = email.from.split("@")[1];
531
+ const messageId = `<${agentId}@${domain}>`;
532
+ msg.setHeader("In-Reply-To", email.headers.get("Message-ID"));
533
+ msg.setHeader("Message-ID", messageId);
534
+ msg.setHeader("X-Agent-Name", agentName);
535
+ msg.setHeader("X-Agent-ID", agentId);
536
+ if (options.headers) {
537
+ for (const [key, value] of Object.entries(options.headers)) {
538
+ msg.setHeader(key, value);
539
+ }
540
+ }
541
+ await email.reply({
542
+ from: email.to,
543
+ raw: msg.asRaw(),
544
+ to: email.from
545
+ });
448
546
  });
449
547
  }
450
548
  async _tryCatch(fn) {
@@ -454,6 +552,49 @@ var Agent = class extends Server {
454
552
  throw this.onError(e);
455
553
  }
456
554
  }
555
+ /**
556
+ * Automatically wrap custom methods with agent context
557
+ * This ensures getCurrentAgent() works in all custom methods without decorators
558
+ */
559
+ _autoWrapCustomMethods() {
560
+ const basePrototypes = [_Agent.prototype, Server.prototype];
561
+ const baseMethods = /* @__PURE__ */ new Set();
562
+ for (const baseProto of basePrototypes) {
563
+ let proto2 = baseProto;
564
+ while (proto2 && proto2 !== Object.prototype) {
565
+ const methodNames = Object.getOwnPropertyNames(proto2);
566
+ for (const methodName of methodNames) {
567
+ baseMethods.add(methodName);
568
+ }
569
+ proto2 = Object.getPrototypeOf(proto2);
570
+ }
571
+ }
572
+ let proto = Object.getPrototypeOf(this);
573
+ let depth = 0;
574
+ while (proto && proto !== Object.prototype && depth < 10) {
575
+ const methodNames = Object.getOwnPropertyNames(proto);
576
+ for (const methodName of methodNames) {
577
+ const descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
578
+ if (baseMethods.has(methodName) || methodName.startsWith("_") || !descriptor || !!descriptor.get || typeof descriptor.value !== "function") {
579
+ continue;
580
+ }
581
+ const wrappedFunction = withAgentContext(
582
+ // biome-ignore lint/suspicious/noExplicitAny: I can't typescript
583
+ this[methodName]
584
+ // biome-ignore lint/suspicious/noExplicitAny: I can't typescript
585
+ );
586
+ if (this._isCallable(methodName)) {
587
+ callableMetadata.set(
588
+ wrappedFunction,
589
+ callableMetadata.get(this[methodName])
590
+ );
591
+ }
592
+ this.constructor.prototype[methodName] = wrappedFunction;
593
+ }
594
+ proto = Object.getPrototypeOf(proto);
595
+ depth++;
596
+ }
597
+ }
457
598
  onError(connectionOrError, error) {
458
599
  let theError;
459
600
  if (connectionOrError && error) {
@@ -479,6 +620,108 @@ var Agent = class extends Server {
479
620
  render() {
480
621
  throw new Error("Not implemented");
481
622
  }
623
+ /**
624
+ * Queue a task to be executed in the future
625
+ * @param payload Payload to pass to the callback
626
+ * @param callback Name of the method to call
627
+ * @returns The ID of the queued task
628
+ */
629
+ async queue(callback, payload) {
630
+ const id = nanoid(9);
631
+ if (typeof callback !== "string") {
632
+ throw new Error("Callback must be a string");
633
+ }
634
+ if (typeof this[callback] !== "function") {
635
+ throw new Error(`this.${callback} is not a function`);
636
+ }
637
+ this.sql`
638
+ INSERT OR REPLACE INTO cf_agents_queues (id, payload, callback)
639
+ VALUES (${id}, ${JSON.stringify(payload)}, ${callback})
640
+ `;
641
+ void this._flushQueue().catch((e) => {
642
+ console.error("Error flushing queue:", e);
643
+ });
644
+ return id;
645
+ }
646
+ async _flushQueue() {
647
+ if (this._flushingQueue) {
648
+ return;
649
+ }
650
+ this._flushingQueue = true;
651
+ while (true) {
652
+ const result = this.sql`
653
+ SELECT * FROM cf_agents_queues
654
+ ORDER BY created_at ASC
655
+ `;
656
+ if (!result || result.length === 0) {
657
+ break;
658
+ }
659
+ for (const row of result || []) {
660
+ const callback = this[row.callback];
661
+ if (!callback) {
662
+ console.error(`callback ${row.callback} not found`);
663
+ continue;
664
+ }
665
+ const { connection, request, email } = agentContext.getStore() || {};
666
+ await agentContext.run(
667
+ {
668
+ agent: this,
669
+ connection,
670
+ request,
671
+ email
672
+ },
673
+ async () => {
674
+ await callback.bind(this)(JSON.parse(row.payload), row);
675
+ await this.dequeue(row.id);
676
+ }
677
+ );
678
+ }
679
+ }
680
+ this._flushingQueue = false;
681
+ }
682
+ /**
683
+ * Dequeue a task by ID
684
+ * @param id ID of the task to dequeue
685
+ */
686
+ async dequeue(id) {
687
+ this.sql`DELETE FROM cf_agents_queues WHERE id = ${id}`;
688
+ }
689
+ /**
690
+ * Dequeue all tasks
691
+ */
692
+ async dequeueAll() {
693
+ this.sql`DELETE FROM cf_agents_queues`;
694
+ }
695
+ /**
696
+ * Dequeue all tasks by callback
697
+ * @param callback Name of the callback to dequeue
698
+ */
699
+ async dequeueAllByCallback(callback) {
700
+ this.sql`DELETE FROM cf_agents_queues WHERE callback = ${callback}`;
701
+ }
702
+ /**
703
+ * Get a queued task by ID
704
+ * @param id ID of the task to get
705
+ * @returns The task or undefined if not found
706
+ */
707
+ async getQueue(id) {
708
+ const result = this.sql`
709
+ SELECT * FROM cf_agents_queues WHERE id = ${id}
710
+ `;
711
+ return result ? { ...result[0], payload: JSON.parse(result[0].payload) } : void 0;
712
+ }
713
+ /**
714
+ * Get all queues by key and value
715
+ * @param key Key to filter by
716
+ * @param value Value to filter by
717
+ * @returns Array of matching QueueItem objects
718
+ */
719
+ async getQueues(key, value) {
720
+ const result = this.sql`
721
+ SELECT * FROM cf_agents_queues
722
+ `;
723
+ return result.filter((row) => JSON.parse(row.payload)[key] === value);
724
+ }
482
725
  /**
483
726
  * Schedule a task to be executed in the future
484
727
  * @template T Type of the payload data
@@ -493,7 +736,10 @@ var Agent = class extends Server {
493
736
  {
494
737
  displayMessage: `Schedule ${schedule.id} created`,
495
738
  id: nanoid(),
496
- payload: schedule,
739
+ payload: {
740
+ callback,
741
+ id
742
+ },
497
743
  timestamp: Date.now(),
498
744
  type: "schedule:create"
499
745
  },
@@ -628,7 +874,10 @@ var Agent = class extends Server {
628
874
  {
629
875
  displayMessage: `Schedule ${id} cancelled`,
630
876
  id: nanoid(),
631
- payload: schedule,
877
+ payload: {
878
+ callback: schedule.callback,
879
+ id: schedule.id
880
+ },
632
881
  timestamp: Date.now(),
633
882
  type: "schedule:cancel"
634
883
  },
@@ -641,9 +890,9 @@ var Agent = class extends Server {
641
890
  }
642
891
  async _scheduleNextAlarm() {
643
892
  const result = this.sql`
644
- SELECT time FROM cf_agents_schedules
893
+ SELECT time FROM cf_agents_schedules
645
894
  WHERE time > ${Math.floor(Date.now() / 1e3)}
646
- ORDER BY time ASC
895
+ ORDER BY time ASC
647
896
  LIMIT 1
648
897
  `;
649
898
  if (!result) return;
@@ -659,6 +908,7 @@ var Agent = class extends Server {
659
908
  this.sql`DROP TABLE IF EXISTS cf_agents_state`;
660
909
  this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
661
910
  this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
911
+ this.sql`DROP TABLE IF EXISTS cf_agents_queues`;
662
912
  await this.ctx.storage.deleteAlarm();
663
913
  await this.ctx.storage.deleteAll();
664
914
  this.ctx.abort("destroyed");
@@ -713,7 +963,7 @@ var Agent = class extends Server {
713
963
  this.broadcast(
714
964
  JSON.stringify({
715
965
  mcp: this.getMcpServers(),
716
- type: "cf_agent_mcp_servers"
966
+ type: "cf_agent_mcp_servers" /* CF_AGENT_MCP_SERVERS */
717
967
  })
718
968
  );
719
969
  return result;
@@ -766,7 +1016,7 @@ var Agent = class extends Server {
766
1016
  this.broadcast(
767
1017
  JSON.stringify({
768
1018
  mcp: this.getMcpServers(),
769
- type: "cf_agent_mcp_servers"
1019
+ type: "cf_agent_mcp_servers" /* CF_AGENT_MCP_SERVERS */
770
1020
  })
771
1021
  );
772
1022
  }
@@ -780,17 +1030,19 @@ var Agent = class extends Server {
780
1030
  const servers = this.sql`
781
1031
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
782
1032
  `;
783
- for (const server of servers) {
784
- const serverConn = this.mcp.mcpConnections[server.id];
785
- mcpState.servers[server.id] = {
786
- auth_url: server.auth_url,
787
- capabilities: serverConn?.serverCapabilities ?? null,
788
- instructions: serverConn?.instructions ?? null,
789
- name: server.name,
790
- server_url: server.server_url,
791
- // mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
792
- state: serverConn?.connectionState ?? "authenticating"
793
- };
1033
+ if (servers && Array.isArray(servers) && servers.length > 0) {
1034
+ for (const server of servers) {
1035
+ const serverConn = this.mcp.mcpConnections[server.id];
1036
+ mcpState.servers[server.id] = {
1037
+ auth_url: server.auth_url,
1038
+ capabilities: serverConn?.serverCapabilities ?? null,
1039
+ instructions: serverConn?.instructions ?? null,
1040
+ name: server.name,
1041
+ server_url: server.server_url,
1042
+ // mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
1043
+ state: serverConn?.connectionState ?? "authenticating"
1044
+ };
1045
+ }
794
1046
  }
795
1047
  return mcpState;
796
1048
  }
@@ -798,11 +1050,13 @@ var Agent = class extends Server {
798
1050
  /**
799
1051
  * Agent configuration options
800
1052
  */
801
- Agent.options = {
1053
+ _Agent.options = {
802
1054
  /** Whether the Agent should hibernate when inactive */
803
1055
  hibernate: true
804
1056
  // default to hibernate
805
1057
  };
1058
+ var Agent = _Agent;
1059
+ var wrappedClasses = /* @__PURE__ */ new Set();
806
1060
  async function routeAgentRequest(request, env, options) {
807
1061
  const corsHeaders = options?.cors === true ? {
808
1062
  "Access-Control-Allow-Credentials": "true",
@@ -838,7 +1092,7 @@ async function routeAgentRequest(request, env, options) {
838
1092
  }
839
1093
  return response;
840
1094
  }
841
- function createHeaderBasedResolver() {
1095
+ function createHeaderBasedEmailResolver() {
842
1096
  return async (email, _env) => {
843
1097
  const messageId = email.headers.get("message-id");
844
1098
  if (messageId) {
@@ -869,7 +1123,7 @@ function createHeaderBasedResolver() {
869
1123
  return null;
870
1124
  };
871
1125
  }
872
- function createAddressBasedResolver(defaultAgentName) {
1126
+ function createAddressBasedEmailResolver(defaultAgentName) {
873
1127
  return async (email, _env) => {
874
1128
  const emailMatch = email.to.match(/^([^+@]+)(?:\+([^@]+))?@(.+)$/);
875
1129
  if (!emailMatch) {
@@ -888,55 +1142,76 @@ function createAddressBasedResolver(defaultAgentName) {
888
1142
  };
889
1143
  };
890
1144
  }
891
- function createCatchAllResolver(agentName, agentId) {
1145
+ function createCatchAllEmailResolver(agentName, agentId) {
892
1146
  return async () => ({ agentName, agentId });
893
1147
  }
1148
+ var agentMapCache = /* @__PURE__ */ new WeakMap();
894
1149
  async function routeAgentEmail(email, env, options) {
895
1150
  const routingInfo = await options.resolver(email, env);
896
1151
  if (!routingInfo) {
897
1152
  console.warn("No routing information found for email, dropping message");
898
1153
  return;
899
1154
  }
900
- const namespaceBinding = env[routingInfo.agentName];
901
- if (!namespaceBinding) {
902
- console.error(
903
- `Agent namespace '${routingInfo.agentName}' not found in environment`
904
- );
905
- return;
1155
+ if (!agentMapCache.has(env)) {
1156
+ const map = {};
1157
+ for (const [key, value] of Object.entries(env)) {
1158
+ if (value && typeof value === "object" && "idFromName" in value && typeof value.idFromName === "function") {
1159
+ map[key] = value;
1160
+ map[camelCaseToKebabCase(key)] = value;
1161
+ }
1162
+ }
1163
+ agentMapCache.set(env, map);
906
1164
  }
907
- if (typeof namespaceBinding !== "object" || !("idFromName" in namespaceBinding) || typeof namespaceBinding.idFromName !== "function") {
908
- console.error(
909
- `Environment binding '${routingInfo.agentName}' is not an AgentNamespace (found: ${typeof namespaceBinding})`
1165
+ const agentMap = agentMapCache.get(env);
1166
+ const namespace = agentMap[routingInfo.agentName];
1167
+ if (!namespace) {
1168
+ const availableAgents = Object.keys(agentMap).filter((key) => !key.includes("-")).join(", ");
1169
+ throw new Error(
1170
+ `Agent namespace '${routingInfo.agentName}' not found in environment. Available agents: ${availableAgents}`
910
1171
  );
911
- return;
912
1172
  }
913
- const namespace = namespaceBinding;
914
- const agent = await getAgentByName(namespace, routingInfo.agentId);
915
- await agent.onEmail(email);
916
- }
917
- async function sendEmailWithRouting(emailBinding, from, fromName, options) {
918
- const { createMimeMessage } = await import("mimetext");
919
- const msg = createMimeMessage();
920
- msg.setSender({ addr: from, name: fromName });
921
- msg.setRecipient(options.to);
922
- msg.setSubject(options.subject);
923
- msg.addMessage({
924
- contentType: options.contentType || "text/plain",
925
- data: options.body
926
- });
927
- if (options.includeRoutingHeaders && options.agentName && options.agentId) {
928
- const domain = options.domain || from.split("@")[1];
929
- const messageId = `<${options.agentId}@${domain}>`;
930
- msg.setHeader("Message-ID", messageId);
931
- msg.setHeader("X-Agent-Name", options.agentName);
932
- msg.setHeader("X-Agent-ID", options.agentId);
933
- }
934
- if (options.headers) {
935
- for (const [key, value] of Object.entries(options.headers)) {
936
- msg.setHeader(key, value);
937
- }
938
- }
939
- await emailBinding.send(new EmailMessage(from, options.to, msg.asRaw()));
1173
+ const agent = await getAgentByName(
1174
+ namespace,
1175
+ routingInfo.agentId
1176
+ );
1177
+ const serialisableEmail = {
1178
+ getRaw: async () => {
1179
+ const reader = email.raw.getReader();
1180
+ const chunks = [];
1181
+ let done = false;
1182
+ while (!done) {
1183
+ const { value, done: readerDone } = await reader.read();
1184
+ done = readerDone;
1185
+ if (value) {
1186
+ chunks.push(value);
1187
+ }
1188
+ }
1189
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
1190
+ const combined = new Uint8Array(totalLength);
1191
+ let offset = 0;
1192
+ for (const chunk of chunks) {
1193
+ combined.set(chunk, offset);
1194
+ offset += chunk.length;
1195
+ }
1196
+ return combined;
1197
+ },
1198
+ headers: email.headers,
1199
+ rawSize: email.rawSize,
1200
+ setReject: (reason) => {
1201
+ email.setReject(reason);
1202
+ },
1203
+ forward: (rcptTo, headers) => {
1204
+ return email.forward(rcptTo, headers);
1205
+ },
1206
+ reply: (options2) => {
1207
+ return email.reply(
1208
+ new EmailMessage(options2.from, options2.to, options2.raw)
1209
+ );
1210
+ },
1211
+ from: email.from,
1212
+ to: email.to
1213
+ };
1214
+ await agent._onEmail(serialisableEmail);
940
1215
  }
941
1216
  async function getAgentByName(namespace, name, options) {
942
1217
  return getServerByName(namespace, name, options);
@@ -960,7 +1235,7 @@ var StreamingResponse = class {
960
1235
  id: this._id,
961
1236
  result: chunk,
962
1237
  success: true,
963
- type: "rpc"
1238
+ type: "rpc" /* RPC */
964
1239
  };
965
1240
  this._connection.send(JSON.stringify(response));
966
1241
  }
@@ -978,7 +1253,7 @@ var StreamingResponse = class {
978
1253
  id: this._id,
979
1254
  result: finalChunk,
980
1255
  success: true,
981
- type: "rpc"
1256
+ type: "rpc" /* RPC */
982
1257
  };
983
1258
  this._connection.send(JSON.stringify(response));
984
1259
  }
@@ -1010,16 +1285,16 @@ function isLocalMode() {
1010
1285
 
1011
1286
  export {
1012
1287
  genericObservability,
1288
+ callable,
1013
1289
  unstable_callable,
1014
1290
  getCurrentAgent,
1015
1291
  Agent,
1016
1292
  routeAgentRequest,
1017
- createHeaderBasedResolver,
1018
- createAddressBasedResolver,
1019
- createCatchAllResolver,
1293
+ createHeaderBasedEmailResolver,
1294
+ createAddressBasedEmailResolver,
1295
+ createCatchAllEmailResolver,
1020
1296
  routeAgentEmail,
1021
- sendEmailWithRouting,
1022
1297
  getAgentByName,
1023
1298
  StreamingResponse
1024
1299
  };
1025
- //# sourceMappingURL=chunk-RX76B6DL.js.map
1300
+ //# sourceMappingURL=chunk-HS7VEROK.js.map