agents 0.0.0-569680f → 0.0.0-579b228

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.
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  MCPClientManager
3
- } from "./chunk-TN7QOY4S.js";
3
+ } from "./chunk-MW5BQ2FW.js";
4
4
  import {
5
5
  DurableObjectOAuthClientProvider
6
- } from "./chunk-767EASBA.js";
6
+ } from "./chunk-PVQZBKN7.js";
7
7
  import {
8
8
  camelCaseToKebabCase
9
- } from "./chunk-NKZZ66QY.js";
9
+ } from "./chunk-KUH345EY.js";
10
10
 
11
11
  // src/index.ts
12
12
  import { AsyncLocalStorage } from "async_hooks";
@@ -47,12 +47,21 @@ function getCurrentAgent() {
47
47
  return {
48
48
  agent: void 0,
49
49
  connection: void 0,
50
- request: void 0
50
+ request: void 0,
51
+ email: void 0
51
52
  };
52
53
  }
53
54
  return store;
54
55
  }
55
- var Agent = class extends Server {
56
+ function withAgentContext(method) {
57
+ return function(...args) {
58
+ const { connection, request, email } = getCurrentAgent();
59
+ return agentContext.run({ agent: this, connection, request, email }, () => {
60
+ return method.apply(this, args);
61
+ });
62
+ };
63
+ }
64
+ var _Agent = class _Agent extends Server {
56
65
  constructor(ctx, env) {
57
66
  super(ctx, env);
58
67
  this._state = DEFAULT_STATE;
@@ -67,6 +76,7 @@ var Agent = class extends Server {
67
76
  * The observability implementation to use for the Agent
68
77
  */
69
78
  this.observability = genericObservability;
79
+ this._flushingQueue = false;
70
80
  /**
71
81
  * Method called when an alarm fires.
72
82
  * Executes any scheduled tasks that are due.
@@ -80,52 +90,68 @@ var Agent = class extends Server {
80
90
  const result = this.sql`
81
91
  SELECT * FROM cf_agents_schedules WHERE time <= ${now}
82
92
  `;
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
- }
93
+ if (result && Array.isArray(result)) {
94
+ for (const row of result) {
95
+ const callback = this[row.callback];
96
+ if (!callback) {
97
+ console.error(`callback ${row.callback} not found`);
98
+ continue;
107
99
  }
108
- );
109
- if (row.type === "cron") {
110
- const nextExecutionTime = getNextCronTime(row.cron);
111
- const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
112
- this.sql`
100
+ await agentContext.run(
101
+ {
102
+ agent: this,
103
+ connection: void 0,
104
+ request: void 0,
105
+ email: void 0
106
+ },
107
+ async () => {
108
+ try {
109
+ this.observability?.emit(
110
+ {
111
+ displayMessage: `Schedule ${row.id} executed`,
112
+ id: nanoid(),
113
+ payload: row,
114
+ timestamp: Date.now(),
115
+ type: "schedule:execute"
116
+ },
117
+ this.ctx
118
+ );
119
+ await callback.bind(this)(JSON.parse(row.payload), row);
120
+ } catch (e) {
121
+ console.error(`error executing callback "${row.callback}"`, e);
122
+ }
123
+ }
124
+ );
125
+ if (row.type === "cron") {
126
+ const nextExecutionTime = getNextCronTime(row.cron);
127
+ const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
128
+ this.sql`
113
129
  UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
114
130
  `;
115
- } else {
116
- this.sql`
131
+ } else {
132
+ this.sql`
117
133
  DELETE FROM cf_agents_schedules WHERE id = ${row.id}
118
134
  `;
135
+ }
119
136
  }
120
137
  }
121
138
  await this._scheduleNextAlarm();
122
139
  };
140
+ this._autoWrapCustomMethods();
123
141
  this.sql`
124
142
  CREATE TABLE IF NOT EXISTS cf_agents_state (
125
143
  id TEXT PRIMARY KEY NOT NULL,
126
144
  state TEXT
127
145
  )
128
146
  `;
147
+ this.sql`
148
+ CREATE TABLE IF NOT EXISTS cf_agents_queues (
149
+ id TEXT PRIMARY KEY NOT NULL,
150
+ payload TEXT,
151
+ callback TEXT,
152
+ created_at INTEGER DEFAULT (unixepoch())
153
+ )
154
+ `;
129
155
  void this.ctx.blockConcurrencyWhile(async () => {
130
156
  return this._tryCatch(async () => {
131
157
  this.sql`
@@ -157,7 +183,7 @@ var Agent = class extends Server {
157
183
  const _onRequest = this.onRequest.bind(this);
158
184
  this.onRequest = (request) => {
159
185
  return agentContext.run(
160
- { agent: this, connection: void 0, request },
186
+ { agent: this, connection: void 0, request, email: void 0 },
161
187
  async () => {
162
188
  if (this.mcp.isCallbackRequest(request)) {
163
189
  await this.mcp.handleCallbackRequest(request);
@@ -179,7 +205,7 @@ var Agent = class extends Server {
179
205
  const _onMessage = this.onMessage.bind(this);
180
206
  this.onMessage = async (connection, message) => {
181
207
  return agentContext.run(
182
- { agent: this, connection, request: void 0 },
208
+ { agent: this, connection, request: void 0, email: void 0 },
183
209
  async () => {
184
210
  if (typeof message !== "string") {
185
211
  return this._tryCatch(() => _onMessage(connection, message));
@@ -253,7 +279,7 @@ var Agent = class extends Server {
253
279
  const _onConnect = this.onConnect.bind(this);
254
280
  this.onConnect = (connection, ctx2) => {
255
281
  return agentContext.run(
256
- { agent: this, connection, request: ctx2.request },
282
+ { agent: this, connection, request: ctx2.request, email: void 0 },
257
283
  async () => {
258
284
  setTimeout(() => {
259
285
  if (this.state) {
@@ -290,32 +316,39 @@ var Agent = class extends Server {
290
316
  const _onStart = this.onStart.bind(this);
291
317
  this.onStart = async () => {
292
318
  return agentContext.run(
293
- { agent: this, connection: void 0, request: void 0 },
319
+ {
320
+ agent: this,
321
+ connection: void 0,
322
+ request: void 0,
323
+ email: void 0
324
+ },
294
325
  async () => {
295
326
  const servers = this.sql`
296
327
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
297
328
  `;
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
- this.broadcast(
313
- JSON.stringify({
314
- mcp: this.getMcpServers(),
315
- type: "cf_agent_mcp_servers"
329
+ if (servers && Array.isArray(servers) && servers.length > 0) {
330
+ Promise.allSettled(
331
+ servers.map((server) => {
332
+ return this._connectToMcpServerInternal(
333
+ server.name,
334
+ server.server_url,
335
+ server.callback_url,
336
+ server.server_options ? JSON.parse(server.server_options) : void 0,
337
+ {
338
+ id: server.id,
339
+ oauthClientId: server.client_id ?? void 0
340
+ }
341
+ );
316
342
  })
317
- );
318
- });
343
+ ).then((_results) => {
344
+ this.broadcast(
345
+ JSON.stringify({
346
+ mcp: this.getMcpServers(),
347
+ type: "cf_agent_mcp_servers"
348
+ })
349
+ );
350
+ });
351
+ }
319
352
  await this._tryCatch(() => _onStart());
320
353
  }
321
354
  );
@@ -385,9 +418,9 @@ var Agent = class extends Server {
385
418
  source !== "server" ? [source.id] : []
386
419
  );
387
420
  return this._tryCatch(() => {
388
- const { connection, request } = agentContext.getStore() || {};
421
+ const { connection, request, email } = agentContext.getStore() || {};
389
422
  return agentContext.run(
390
- { agent: this, connection, request },
423
+ { agent: this, connection, request, email },
391
424
  async () => {
392
425
  this.observability?.emit(
393
426
  {
@@ -423,28 +456,65 @@ var Agent = class extends Server {
423
456
  onStateUpdate(state, source) {
424
457
  }
425
458
  /**
426
- * Called when the Agent receives an email
459
+ * Called when the Agent receives an email via routeAgentEmail()
427
460
  * Override this method to handle incoming emails
428
461
  * @param email Email message to process
429
462
  */
430
- async onEmail(email) {
463
+ async _onEmail(email) {
431
464
  return agentContext.run(
432
- { agent: this, connection: void 0, request: void 0 },
465
+ { agent: this, connection: void 0, request: void 0, email },
433
466
  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");
467
+ if ("onEmail" in this && typeof this.onEmail === "function") {
468
+ return this._tryCatch(
469
+ () => this.onEmail(email)
470
+ );
471
+ } else {
472
+ console.log("Received email from:", email.from, "to:", email.to);
473
+ console.log("Subject:", email.headers.get("subject"));
474
+ console.log(
475
+ "Implement onEmail(email: AgentEmail): Promise<void> in your agent to process emails"
476
+ );
477
+ }
437
478
  }
438
479
  );
439
480
  }
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
481
+ /**
482
+ * Reply to an email
483
+ * @param email The email to reply to
484
+ * @param options Options for the reply
485
+ * @returns void
486
+ */
487
+ async replyToEmail(email, options) {
488
+ return this._tryCatch(async () => {
489
+ const agentName = camelCaseToKebabCase(this._ParentClass.name);
490
+ const agentId = this.name;
491
+ const { createMimeMessage } = await import("mimetext");
492
+ const msg = createMimeMessage();
493
+ msg.setSender({ addr: email.to, name: options.fromName });
494
+ msg.setRecipient(email.from);
495
+ msg.setSubject(
496
+ options.subject || `Re: ${email.headers.get("subject")}` || "No subject"
497
+ );
498
+ msg.addMessage({
499
+ contentType: options.contentType || "text/plain",
500
+ data: options.body
501
+ });
502
+ const domain = email.from.split("@")[1];
503
+ const messageId = `<${agentId}@${domain}>`;
504
+ msg.setHeader("In-Reply-To", email.headers.get("Message-ID"));
505
+ msg.setHeader("Message-ID", messageId);
506
+ msg.setHeader("X-Agent-Name", agentName);
507
+ msg.setHeader("X-Agent-ID", agentId);
508
+ if (options.headers) {
509
+ for (const [key, value] of Object.entries(options.headers)) {
510
+ msg.setHeader(key, value);
511
+ }
512
+ }
513
+ await email.reply({
514
+ from: email.to,
515
+ raw: msg.asRaw(),
516
+ to: email.from
517
+ });
448
518
  });
449
519
  }
450
520
  async _tryCatch(fn) {
@@ -454,6 +524,55 @@ var Agent = class extends Server {
454
524
  throw this.onError(e);
455
525
  }
456
526
  }
527
+ /**
528
+ * Automatically wrap custom methods with agent context
529
+ * This ensures getCurrentAgent() works in all custom methods without decorators
530
+ */
531
+ _autoWrapCustomMethods() {
532
+ const basePrototypes = [_Agent.prototype, Server.prototype];
533
+ const baseMethods = /* @__PURE__ */ new Set();
534
+ for (const baseProto of basePrototypes) {
535
+ let proto2 = baseProto;
536
+ while (proto2 && proto2 !== Object.prototype) {
537
+ const methodNames = Object.getOwnPropertyNames(proto2);
538
+ for (const methodName of methodNames) {
539
+ baseMethods.add(methodName);
540
+ }
541
+ proto2 = Object.getPrototypeOf(proto2);
542
+ }
543
+ }
544
+ let proto = Object.getPrototypeOf(this);
545
+ let depth = 0;
546
+ while (proto && proto !== Object.prototype && depth < 10) {
547
+ const methodNames = Object.getOwnPropertyNames(proto);
548
+ for (const methodName of methodNames) {
549
+ if (baseMethods.has(methodName) || methodName.startsWith("_") || typeof this[methodName] !== "function") {
550
+ continue;
551
+ }
552
+ if (!baseMethods.has(methodName)) {
553
+ const descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
554
+ if (descriptor && typeof descriptor.value === "function") {
555
+ const wrappedFunction = withAgentContext(
556
+ // biome-ignore lint/suspicious/noExplicitAny: I can't typescript
557
+ this[methodName]
558
+ // biome-ignore lint/suspicious/noExplicitAny: I can't typescript
559
+ );
560
+ if (this._isCallable(methodName)) {
561
+ callableMetadata.set(
562
+ wrappedFunction,
563
+ callableMetadata.get(
564
+ this[methodName]
565
+ )
566
+ );
567
+ }
568
+ this.constructor.prototype[methodName] = wrappedFunction;
569
+ }
570
+ }
571
+ }
572
+ proto = Object.getPrototypeOf(proto);
573
+ depth++;
574
+ }
575
+ }
457
576
  onError(connectionOrError, error) {
458
577
  let theError;
459
578
  if (connectionOrError && error) {
@@ -479,6 +598,108 @@ var Agent = class extends Server {
479
598
  render() {
480
599
  throw new Error("Not implemented");
481
600
  }
601
+ /**
602
+ * Queue a task to be executed in the future
603
+ * @param payload Payload to pass to the callback
604
+ * @param callback Name of the method to call
605
+ * @returns The ID of the queued task
606
+ */
607
+ async queue(callback, payload) {
608
+ const id = nanoid(9);
609
+ if (typeof callback !== "string") {
610
+ throw new Error("Callback must be a string");
611
+ }
612
+ if (typeof this[callback] !== "function") {
613
+ throw new Error(`this.${callback} is not a function`);
614
+ }
615
+ this.sql`
616
+ INSERT OR REPLACE INTO cf_agents_queues (id, payload, callback)
617
+ VALUES (${id}, ${JSON.stringify(payload)}, ${callback})
618
+ `;
619
+ void this._flushQueue().catch((e) => {
620
+ console.error("Error flushing queue:", e);
621
+ });
622
+ return id;
623
+ }
624
+ async _flushQueue() {
625
+ if (this._flushingQueue) {
626
+ return;
627
+ }
628
+ this._flushingQueue = true;
629
+ while (true) {
630
+ const result = this.sql`
631
+ SELECT * FROM cf_agents_queues
632
+ ORDER BY created_at ASC
633
+ `;
634
+ if (!result || result.length === 0) {
635
+ break;
636
+ }
637
+ for (const row of result || []) {
638
+ const callback = this[row.callback];
639
+ if (!callback) {
640
+ console.error(`callback ${row.callback} not found`);
641
+ continue;
642
+ }
643
+ const { connection, request, email } = agentContext.getStore() || {};
644
+ await agentContext.run(
645
+ {
646
+ agent: this,
647
+ connection,
648
+ request,
649
+ email
650
+ },
651
+ async () => {
652
+ await callback.bind(this)(JSON.parse(row.payload), row);
653
+ await this.dequeue(row.id);
654
+ }
655
+ );
656
+ }
657
+ }
658
+ this._flushingQueue = false;
659
+ }
660
+ /**
661
+ * Dequeue a task by ID
662
+ * @param id ID of the task to dequeue
663
+ */
664
+ async dequeue(id) {
665
+ this.sql`DELETE FROM cf_agents_queues WHERE id = ${id}`;
666
+ }
667
+ /**
668
+ * Dequeue all tasks
669
+ */
670
+ async dequeueAll() {
671
+ this.sql`DELETE FROM cf_agents_queues`;
672
+ }
673
+ /**
674
+ * Dequeue all tasks by callback
675
+ * @param callback Name of the callback to dequeue
676
+ */
677
+ async dequeueAllByCallback(callback) {
678
+ this.sql`DELETE FROM cf_agents_queues WHERE callback = ${callback}`;
679
+ }
680
+ /**
681
+ * Get a queued task by ID
682
+ * @param id ID of the task to get
683
+ * @returns The task or undefined if not found
684
+ */
685
+ async getQueue(id) {
686
+ const result = this.sql`
687
+ SELECT * FROM cf_agents_queues WHERE id = ${id}
688
+ `;
689
+ return result ? { ...result[0], payload: JSON.parse(result[0].payload) } : void 0;
690
+ }
691
+ /**
692
+ * Get all queues by key and value
693
+ * @param key Key to filter by
694
+ * @param value Value to filter by
695
+ * @returns Array of matching QueueItem objects
696
+ */
697
+ async getQueues(key, value) {
698
+ const result = this.sql`
699
+ SELECT * FROM cf_agents_queues
700
+ `;
701
+ return result.filter((row) => JSON.parse(row.payload)[key] === value);
702
+ }
482
703
  /**
483
704
  * Schedule a task to be executed in the future
484
705
  * @template T Type of the payload data
@@ -641,9 +862,9 @@ var Agent = class extends Server {
641
862
  }
642
863
  async _scheduleNextAlarm() {
643
864
  const result = this.sql`
644
- SELECT time FROM cf_agents_schedules
865
+ SELECT time FROM cf_agents_schedules
645
866
  WHERE time > ${Math.floor(Date.now() / 1e3)}
646
- ORDER BY time ASC
867
+ ORDER BY time ASC
647
868
  LIMIT 1
648
869
  `;
649
870
  if (!result) return;
@@ -659,6 +880,7 @@ var Agent = class extends Server {
659
880
  this.sql`DROP TABLE IF EXISTS cf_agents_state`;
660
881
  this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
661
882
  this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
883
+ this.sql`DROP TABLE IF EXISTS cf_agents_queues`;
662
884
  await this.ctx.storage.deleteAlarm();
663
885
  await this.ctx.storage.deleteAll();
664
886
  this.ctx.abort("destroyed");
@@ -780,17 +1002,19 @@ var Agent = class extends Server {
780
1002
  const servers = this.sql`
781
1003
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
782
1004
  `;
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
- };
1005
+ if (servers && Array.isArray(servers) && servers.length > 0) {
1006
+ for (const server of servers) {
1007
+ const serverConn = this.mcp.mcpConnections[server.id];
1008
+ mcpState.servers[server.id] = {
1009
+ auth_url: server.auth_url,
1010
+ capabilities: serverConn?.serverCapabilities ?? null,
1011
+ instructions: serverConn?.instructions ?? null,
1012
+ name: server.name,
1013
+ server_url: server.server_url,
1014
+ // mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
1015
+ state: serverConn?.connectionState ?? "authenticating"
1016
+ };
1017
+ }
794
1018
  }
795
1019
  return mcpState;
796
1020
  }
@@ -798,11 +1022,12 @@ var Agent = class extends Server {
798
1022
  /**
799
1023
  * Agent configuration options
800
1024
  */
801
- Agent.options = {
1025
+ _Agent.options = {
802
1026
  /** Whether the Agent should hibernate when inactive */
803
1027
  hibernate: true
804
1028
  // default to hibernate
805
1029
  };
1030
+ var Agent = _Agent;
806
1031
  async function routeAgentRequest(request, env, options) {
807
1032
  const corsHeaders = options?.cors === true ? {
808
1033
  "Access-Control-Allow-Credentials": "true",
@@ -838,7 +1063,7 @@ async function routeAgentRequest(request, env, options) {
838
1063
  }
839
1064
  return response;
840
1065
  }
841
- function createHeaderBasedResolver() {
1066
+ function createHeaderBasedEmailResolver() {
842
1067
  return async (email, _env) => {
843
1068
  const messageId = email.headers.get("message-id");
844
1069
  if (messageId) {
@@ -869,7 +1094,7 @@ function createHeaderBasedResolver() {
869
1094
  return null;
870
1095
  };
871
1096
  }
872
- function createAddressBasedResolver(defaultAgentName) {
1097
+ function createAddressBasedEmailResolver(defaultAgentName) {
873
1098
  return async (email, _env) => {
874
1099
  const emailMatch = email.to.match(/^([^+@]+)(?:\+([^@]+))?@(.+)$/);
875
1100
  if (!emailMatch) {
@@ -888,55 +1113,76 @@ function createAddressBasedResolver(defaultAgentName) {
888
1113
  };
889
1114
  };
890
1115
  }
891
- function createCatchAllResolver(agentName, agentId) {
1116
+ function createCatchAllEmailResolver(agentName, agentId) {
892
1117
  return async () => ({ agentName, agentId });
893
1118
  }
1119
+ var agentMapCache = /* @__PURE__ */ new WeakMap();
894
1120
  async function routeAgentEmail(email, env, options) {
895
1121
  const routingInfo = await options.resolver(email, env);
896
1122
  if (!routingInfo) {
897
1123
  console.warn("No routing information found for email, dropping message");
898
1124
  return;
899
1125
  }
900
- const namespaceBinding = env[routingInfo.agentName];
901
- if (!namespaceBinding) {
902
- console.error(
903
- `Agent namespace '${routingInfo.agentName}' not found in environment`
904
- );
905
- return;
1126
+ if (!agentMapCache.has(env)) {
1127
+ const map = {};
1128
+ for (const [key, value] of Object.entries(env)) {
1129
+ if (value && typeof value === "object" && "idFromName" in value && typeof value.idFromName === "function") {
1130
+ map[key] = value;
1131
+ map[camelCaseToKebabCase(key)] = value;
1132
+ }
1133
+ }
1134
+ agentMapCache.set(env, map);
906
1135
  }
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})`
1136
+ const agentMap = agentMapCache.get(env);
1137
+ const namespace = agentMap[routingInfo.agentName];
1138
+ if (!namespace) {
1139
+ const availableAgents = Object.keys(agentMap).filter((key) => !key.includes("-")).join(", ");
1140
+ throw new Error(
1141
+ `Agent namespace '${routingInfo.agentName}' not found in environment. Available agents: ${availableAgents}`
910
1142
  );
911
- return;
912
- }
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
1143
  }
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()));
1144
+ const agent = await getAgentByName(
1145
+ namespace,
1146
+ routingInfo.agentId
1147
+ );
1148
+ const serialisableEmail = {
1149
+ getRaw: async () => {
1150
+ const reader = email.raw.getReader();
1151
+ const chunks = [];
1152
+ let done = false;
1153
+ while (!done) {
1154
+ const { value, done: readerDone } = await reader.read();
1155
+ done = readerDone;
1156
+ if (value) {
1157
+ chunks.push(value);
1158
+ }
1159
+ }
1160
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
1161
+ const combined = new Uint8Array(totalLength);
1162
+ let offset = 0;
1163
+ for (const chunk of chunks) {
1164
+ combined.set(chunk, offset);
1165
+ offset += chunk.length;
1166
+ }
1167
+ return combined;
1168
+ },
1169
+ headers: email.headers,
1170
+ rawSize: email.rawSize,
1171
+ setReject: (reason) => {
1172
+ email.setReject(reason);
1173
+ },
1174
+ forward: (rcptTo, headers) => {
1175
+ return email.forward(rcptTo, headers);
1176
+ },
1177
+ reply: (options2) => {
1178
+ return email.reply(
1179
+ new EmailMessage(options2.from, options2.to, options2.raw)
1180
+ );
1181
+ },
1182
+ from: email.from,
1183
+ to: email.to
1184
+ };
1185
+ await agent._onEmail(serialisableEmail);
940
1186
  }
941
1187
  async function getAgentByName(namespace, name, options) {
942
1188
  return getServerByName(namespace, name, options);
@@ -1014,12 +1260,11 @@ export {
1014
1260
  getCurrentAgent,
1015
1261
  Agent,
1016
1262
  routeAgentRequest,
1017
- createHeaderBasedResolver,
1018
- createAddressBasedResolver,
1019
- createCatchAllResolver,
1263
+ createHeaderBasedEmailResolver,
1264
+ createAddressBasedEmailResolver,
1265
+ createCatchAllEmailResolver,
1020
1266
  routeAgentEmail,
1021
- sendEmailWithRouting,
1022
1267
  getAgentByName,
1023
1268
  StreamingResponse
1024
1269
  };
1025
- //# sourceMappingURL=chunk-RX76B6DL.js.map
1270
+ //# sourceMappingURL=chunk-CKHRUXM5.js.map