@framers/agentos-ext-channel-email 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # @framers/agentos-ext-channel-email
2
+
3
+ Email for AgentOS. `EmailService` sends mail through SMTP or Resend's HTTPS API, and reads, searches, extracts codes from and replies to mail through IMAP. The pack's factory wraps the service in a messaging-channel adapter and five tools for an agent.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @framers/agentos-ext-channel-email
9
+ ```
10
+
11
+ It needs Node.js 20 or later, the floor of nodemailer 10. Its runtime dependencies are [nodemailer](https://github.com/nodemailer/nodemailer) for SMTP and [imapflow](https://github.com/postalsys/imapflow) for IMAP. `@framers/agentos` is an optional peer, needed only when an agent loads the pack: nothing in the pack imports it, so `EmailService` works without it.
12
+
13
+ ## Sending through SMTP
14
+
15
+ ```ts
16
+ import { EmailService } from '@framers/agentos-ext-channel-email';
17
+
18
+ const email = new EmailService({
19
+ smtp: { host: 'smtp.example.com', user: 'hello@example.com', password: process.env.SMTP_PASSWORD ?? '' },
20
+ from: 'Example <hello@example.com>',
21
+ });
22
+ await email.initialize();
23
+ await email.sendEmail({ to: 'reader@example.com', subject: 'Hello', body: 'Plain words.', html: '<p>Plain words.</p>' });
24
+ ```
25
+
26
+ `smtp` takes `host`, `user` and `password`, with `port` and `secure`: by default the connection uses TLS on port 465, and `secure: false` moves the default port to 587. `initialize()` checks the connection, and a failed check is not an error. The pack's factory reads the account from the secrets `email.smtpHost`, `email.smtpUser` and `email.smtpPassword`, or from `SMTP_HOST`, `SMTP_USER` and `SMTP_PASSWORD`.
27
+
28
+ ## Sending through Resend
29
+
30
+ ```ts
31
+ import { EmailService } from '@framers/agentos-ext-channel-email';
32
+
33
+ const email = new EmailService({
34
+ resend: { apiKey: process.env.RESEND_API_KEY ?? '' },
35
+ from: 'Example <hello@example.com>',
36
+ });
37
+ await email.initialize();
38
+ const { messageId } = await email.sendEmail({
39
+ to: 'reader@example.com',
40
+ subject: 'Hello',
41
+ body: 'Plain words.',
42
+ html: '<p>Plain words.</p>',
43
+ replyTo: 'team@example.com',
44
+ idempotencyKey: 'welcome-reader-1',
45
+ });
46
+ ```
47
+
48
+ Each message goes out as `POST /emails` with the key as the bearer and the text and HTML parts in the same call, and `messageId` is the id Resend gives the email, or the empty string when an accepted answer names none or its body cannot be read: a 2xx means the email was sent, so the send never fails after one. A refusal that is tried again repeats the same request, with the same key and any `Idempotency-Key`, so one send makes at most `maxRetries + 1` requests. `idempotencyKey` is sent as Resend's `Idempotency-Key` header: another request under the same key within 24 hours delivers nothing more ([idempotency keys](https://resend.com/docs/dashboard/emails/idempotency-keys)). Keep it to 256 characters at most and free of personal data. SMTP ignores it.
49
+
50
+ Attachments take a `filename` with `content` (a string or a Buffer, sent as Base64) or a `path`. Through Resend, an `http` or `https` path is the address Resend fetches the file from, and a `data:` address or a file on this host is read by the transport and sent as content, as nodemailer reads both over SMTP; when `content` is given too, such a path is left out. A file that cannot be read throws its own error before any request. Through either transport `sendEmail` reads a file on this host, and through SMTP it fetches an `http` or `https` address, from this process: such a path must come from the developer's code and never from a model's output. The `emailSend` tool and the channel adapter take only `content`, a `data:` address and, through Resend, an `http` or `https` address.
51
+
52
+ | `resend` option | Default | What it sets |
53
+ |---|---|---|
54
+ | `apiKey` | required | The API key, or a function that returns it at each send, so a rotated key applies without a restart |
55
+ | `baseUrl` | `https://api.resend.com` | The API's origin, such as a proxy's or a test server's |
56
+ | `userAgent` | `agentos-ext-channel-email` | The `User-Agent` of every request; Resend refuses a request without one |
57
+ | `timeoutMs` | 15,000 | The longest one send may take, its retries and their waits included |
58
+ | `maxRetries` | 2 | The most retries one send makes |
59
+
60
+ The pack's factory sends through Resend when it has a Resend key and no SMTP host: the option `resendApiKey`, the secret `email.resendApiKey` or `RESEND_API_KEY`, with `resendBaseUrl` for the origin. Given an SMTP host, it keeps SMTP.
61
+
62
+ ## The From
63
+
64
+ `from` sets the From header of both transports, and a display name is allowed (`Example <hello@example.com>`). With SMTP it falls back to the SMTP user; with Resend it is required, and `initialize()` throws without it. Replies are sent from it too. The pack's factory reads it from the option `from`, then from `EMAIL_FROM`.
65
+
66
+ ## Errors and retries
67
+
68
+ A refusal from Resend throws `EmailApiError`, with `status` (the HTTP status), `type` (Resend's error name, such as `validation_error`, or `unknown` when the answer's body is not JSON, names no error, or names one that is not 1 to 64 letters, digits, `_`, `.`, `:` or `-`) and `retryAfterSeconds` (the answer's `retry-after`, or `null`). Its message names the status and the type and never carries Resend's message, which can quote an address.
69
+
70
+ `fetch`'s own errors pass through as it throws them: a `TypeError` when the connection fails, and a `TimeoutError` when `timeoutMs` passes before an answer comes. A deadline that passes while an answer's body is being read throws no `TimeoutError`: a refusal then throws `EmailApiError` with `type` `unknown`, and an accepted send resolves with an empty `messageId`. The key is trimmed at each send. A key, an `idempotencyKey` or a `userAgent` that holds a character an HTTP header cannot carry (a line break or another control character other than a tab, or a character above U+00FF) throws an `Error` before any request, and its message names which one and none of its value.
71
+
72
+ A send is tried again only on the terms of Resend's [errors](https://resend.com/docs/api-reference/errors) and [rate limit](https://resend.com/docs/api-reference/rate-limit) pages, as `retryWaitSeconds` decides:
73
+
74
+ - `rate_limit_exceeded` (429): always, since nothing was sent;
75
+ - `concurrent_idempotent_requests` (409) and any 5xx, such as `application_error` (500) and `service_unavailable` (503): only when the send has an `idempotencyKey`, so a retry cannot deliver twice;
76
+ - never `daily_quota_exceeded` or `monthly_quota_exceeded` (both 429), `validation_error`, `invalid_idempotent_request` or any other 4xx.
77
+
78
+ The wait is the answer's `retry-after` when it has one, else as many seconds as the retry's number: one, then two. A send makes at most `maxRetries` retries, and a wait that would pass the deadline is not taken: the refusal is thrown instead.
79
+
80
+ ## Reading mail
81
+
82
+ `readInbox`, `searchEmails`, `extractCodes` and `replyToEmail` read through IMAP: the `imap` account (`host`, `user` and `password`, with `port` and `secure`, by default TLS on port 993), or the SMTP account when `imap` is not given. With Resend, reading needs `imap`. A reply goes out through the transport that sends, threaded with `In-Reply-To` and `References`. The pack's factory reads the account from the secrets `email.imap.host`, `email.imap.user` and `email.imap.password`, or from `IMAP_HOST`, `IMAP_USER` and `IMAP_PASSWORD`.
83
+
84
+ ## In an agent
85
+
86
+ `createExtensionPack(context)` returns five tools, `emailSend`, `emailRead`, `emailSearch`, `emailExtractCodes` and `emailReply`, and the messaging channel `emailChannel`. Its options (`smtpHost`, `smtpUser`, `smtpPassword`, `smtpPort`, `smtpSecure`, `imapHost`, `imapUser`, `imapPassword`, `imapPort`, `imapSecure`, `resendApiKey`, `resendBaseUrl`, `from`) take precedence over the secrets and the environment variables named above. `manifest.json` lists the SMTP secrets as required, and the IMAP secrets and `email.resendApiKey` as optional.
87
+
88
+ A model names the tools' arguments and the channel's blocks, so `emailSend` and `emailChannel` pass on an attachment only as `content`, a `data:` address or, through Resend, an `http` or `https` address. They refuse any other before anything is sent, reading no file and fetching no address: the tool answers `{ success: false, error }`, the adapter throws an `Error`, and the message names the attachment's filename, never its path.
89
+
90
+ ## API
91
+
92
+ | Export | What it is |
93
+ |---|---|
94
+ | `createExtensionPack(context)` | The pack's factory: the five tools and the channel adapter |
95
+ | `EmailService` | Sends through SMTP or Resend's HTTPS API; reads, searches, extracts codes and replies through IMAP |
96
+ | `ResendTransport` | Resend's send call, which `EmailService` uses when its configuration names `resend` |
97
+ | `EmailApiError`, `retryWaitSeconds` | A refusal from Resend, and the wait before its retry (`null` for none) |
98
+ | `EmailChannelAdapter` | The messaging-channel adapter |
99
+ | `EmailSendTool`, `EmailReadTool`, `EmailSearchTool`, `EmailExtractCodesTool`, `EmailReplyTool` | The five tools |
100
+ | `EmailConfig`, `SendEmailOptions`, `EmailMessage`, `SearchEmailOptions`, `ResendOptions`, `OutgoingEmail`, `OutgoingAttachment`, `EmailChannelOptions`, `ExtensionContext`, `ExtensionPack` | The types of the configuration, the messages, the options and the pack |
101
+
102
+ ## License
103
+
104
+ Apache-2.0
@@ -42,6 +42,12 @@ export declare class EmailChannelAdapter {
42
42
  initialize(_auth: ChannelAuthConfig): Promise<void>;
43
43
  shutdown(): Promise<void>;
44
44
  getConnectionInfo(): ChannelConnectionInfo;
45
+ /**
46
+ * Sends `content` to `conversationId`, or replies when it names `replyToMessageId` (a reply carries no attachments).
47
+ * Its `document` and `image` blocks become attachments, each with the block's `content` or its `url` as the path, and
48
+ * one that is not `content`, a `data:` address or, through Resend, an `http(s)` address throws an `Error` naming its
49
+ * filename before anything is sent, a reply included.
50
+ */
45
51
  sendMessage(conversationId: string, content: MessageContent): Promise<ChannelSendResult>;
46
52
  sendTypingIndicator(_conversationId: string, _isTyping: boolean): Promise<void>;
47
53
  on(handler: ChannelEventHandler, _eventTypes?: ChannelEventType[]): () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"EmailChannelAdapter.d.ts","sourceRoot":"","sources":["../src/EmailChannelAdapter.ts"],"names":[],"mappings":"AACA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AACrC,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACvC,MAAM,MAAM,uBAAuB,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,OAAO,CAAC;AAC7G,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,uBAAuB,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC,CAAC;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvE,qBAAa,mBAAmB;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAW;IAC7C,QAAQ,CAAC,WAAW,WAAW;IAC/B,QAAQ,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAEjD;IAEF,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,YAAY,CAAuB;gBAE/B,OAAO,EAAE,YAAY;IAI3B,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,iBAAiB,IAAI,qBAAqB;IAcpC,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAqCxF,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrF,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,WAAW,CAAC,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAI;CAI/E"}
1
+ {"version":3,"file":"EmailChannelAdapter.d.ts","sourceRoot":"","sources":["../src/EmailChannelAdapter.ts"],"names":[],"mappings":"AACA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AACrC,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACvC,MAAM,MAAM,uBAAuB,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,OAAO,CAAC;AAC7G,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,uBAAuB,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC,CAAC;IACpD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvE,qBAAa,mBAAmB;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAW;IAC7C,QAAQ,CAAC,WAAW,WAAW;IAC/B,QAAQ,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAEjD;IAEF,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,YAAY,CAAuB;gBAE/B,OAAO,EAAE,YAAY;IAI3B,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,iBAAiB,IAAI,qBAAqB;IAc1C;;;;;OAKG;IACG,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwCxF,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrF,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,WAAW,CAAC,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAI;CAI/E"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.EmailChannelAdapter = void 0;
8
+ const agentAttachments_js_1 = require("./agentAttachments.js");
8
9
  class EmailChannelAdapter {
9
10
  constructor(service) {
10
11
  this.platform = 'email';
@@ -45,6 +46,12 @@ class EmailChannelAdapter {
45
46
  platformInfo: { platform: 'email' },
46
47
  };
47
48
  }
49
+ /**
50
+ * Sends `content` to `conversationId`, or replies when it names `replyToMessageId` (a reply carries no attachments).
51
+ * Its `document` and `image` blocks become attachments, each with the block's `content` or its `url` as the path, and
52
+ * one that is not `content`, a `data:` address or, through Resend, an `http(s)` address throws an `Error` naming its
53
+ * filename before anything is sent, a reply included.
54
+ */
48
55
  async sendMessage(conversationId, content) {
49
56
  const textBlock = content.blocks.find((b) => b.type === 'text');
50
57
  const htmlBlock = content.blocks.find((b) => b.type === 'rich_text' || b.type === 'html');
@@ -63,6 +70,8 @@ class EmailChannelAdapter {
63
70
  });
64
71
  }
65
72
  }
73
+ // A model writes these blocks: an attachment this process would read or fetch stops the message here.
74
+ (0, agentAttachments_js_1.requireAgentAttachments)(attachments, this.service.transport === 'resend');
66
75
  if (content.replyToMessageId) {
67
76
  const result = await this.service.replyToEmail(content.replyToMessageId, text, html);
68
77
  return { messageId: result.messageId, timestamp: new Date().toISOString() };
@@ -1 +1 @@
1
- {"version":3,"file":"EmailChannelAdapter.js","sourceRoot":"","sources":["../src/EmailChannelAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EmailChannelAdapter.js","sourceRoot":"","sources":["../src/EmailChannelAdapter.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,24 @@
1
1
  /**
2
2
  * @fileoverview Email service layer.
3
3
  *
4
- * Wraps nodemailer (SMTP) and imapflow (IMAP) for sending,
5
- * reading, searching, and replying to emails.
4
+ * Sends through nodemailer (SMTP) or Resend's HTTPS API, and reads,
5
+ * searches, and fetches the messages it replies to through imapflow (IMAP).
6
6
  */
7
+ import type { ResendOptions } from './ResendTransport.js';
8
+ /** The accounts the service uses: an SMTP account or Resend's HTTPS API to send, and IMAP to read. */
7
9
  export interface EmailConfig {
8
- smtp: {
10
+ /** The SMTP account that sends, and reads when `imap` is not given. Required unless `resend` is given. */
11
+ smtp?: {
9
12
  host: string;
10
13
  user: string;
11
14
  password: string;
12
15
  port?: number;
13
16
  secure?: boolean;
14
17
  };
18
+ /** Resend's HTTPS API in place of SMTP for sending; reading mail still needs `imap`. */
19
+ resend?: ResendOptions;
20
+ /** The From header, a display name allowed ("Example <hello@example.com>"); the SMTP user when unset. Required with `resend`. */
21
+ from?: string;
15
22
  imap?: {
16
23
  host: string;
17
24
  user: string;
@@ -34,6 +41,8 @@ export interface SendEmailOptions {
34
41
  replyTo?: string;
35
42
  cc?: string;
36
43
  bcc?: string;
44
+ /** Resend's Idempotency-Key for this message; SMTP ignores it. */
45
+ idempotencyKey?: string;
37
46
  }
38
47
  export interface EmailMessage {
39
48
  messageId: string;
@@ -55,11 +64,29 @@ export interface SearchEmailOptions {
55
64
  export declare class EmailService {
56
65
  private config;
57
66
  private transporter;
67
+ private resend;
58
68
  private running;
59
69
  constructor(config: EmailConfig);
70
+ /**
71
+ * Opens the transport that sends: Resend's API when `resend` is given (`from` is then required), else the SMTP
72
+ * account. Throws an `Error` before opening anything when the configuration gives neither `resend` nor `smtp`.
73
+ */
60
74
  initialize(): Promise<void>;
61
75
  shutdown(): Promise<void>;
62
76
  get isRunning(): boolean;
77
+ /**
78
+ * The transport that sends: `'resend'` or `'smtp'` once `initialize()` has opened it, `null` before that and after
79
+ * `shutdown()`. The `emailSend` tool and the channel adapter read it to tell which attachments they may pass on.
80
+ */
81
+ get transport(): 'resend' | 'smtp' | null;
82
+ /**
83
+ * Sends one message through the transport `initialize()` opened and resolves with the id it gives. An attachment's
84
+ * `path` may be a file on this host, which this process reads through either transport, or an `http:` or `https:`
85
+ * address, which this process fetches through SMTP (through Resend, Resend's servers fetch it): such a path must come
86
+ * from the developer's code and never from a model's output. The `emailSend` tool and the channel adapter accept only
87
+ * `content`, `data:` addresses and, through Resend, `http(s)` addresses, and refuse any other attachment before
88
+ * sending.
89
+ */
63
90
  sendEmail(options: SendEmailOptions): Promise<{
64
91
  messageId: string;
65
92
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"EmailService.d.ts","sourceRoot":"","sources":["../src/EmailService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EmailService.d.ts","sourceRoot":"","sources":["../src/EmailService.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,8 @@
3
3
  /**
4
4
  * @fileoverview Email service layer.
5
5
  *
6
- * Wraps nodemailer (SMTP) and imapflow (IMAP) for sending,
7
- * reading, searching, and replying to emails.
6
+ * Sends through nodemailer (SMTP) or Resend's HTTPS API, and reads,
7
+ * searches, and fetches the messages it replies to through imapflow (IMAP).
8
8
  */
9
9
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
10
  if (k2 === undefined) k2 = k;
@@ -43,16 +43,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
43
43
  exports.EmailService = void 0;
44
44
  const nodemailer = __importStar(require("nodemailer"));
45
45
  const imapflow_1 = require("imapflow");
46
+ const ResendTransport_js_1 = require("./ResendTransport.js");
46
47
  // ---------------------------------------------------------------------------
47
48
  // Service
48
49
  // ---------------------------------------------------------------------------
49
50
  class EmailService {
50
51
  constructor(config) {
51
52
  this.transporter = null;
53
+ this.resend = null;
52
54
  this.running = false;
53
55
  this.config = config;
54
56
  }
57
+ /**
58
+ * Opens the transport that sends: Resend's API when `resend` is given (`from` is then required), else the SMTP
59
+ * account. Throws an `Error` before opening anything when the configuration gives neither `resend` nor `smtp`.
60
+ */
55
61
  async initialize() {
62
+ if (this.config.resend) {
63
+ if (!this.config.from)
64
+ throw new Error('A From address is required to send through Resend');
65
+ this.resend = new ResendTransport_js_1.ResendTransport(this.config.resend);
66
+ this.running = true;
67
+ return;
68
+ }
69
+ if (!this.config.smtp)
70
+ throw new Error('Sending mail needs an SMTP account or a Resend key');
56
71
  // Set up SMTP transporter
57
72
  this.transporter = nodemailer.createTransport({
58
73
  host: this.config.smtp.host,
@@ -77,18 +92,50 @@ class EmailService {
77
92
  this.transporter.close();
78
93
  this.transporter = null;
79
94
  }
95
+ this.resend = null;
80
96
  this.running = false;
81
97
  }
82
98
  get isRunning() {
83
99
  return this.running;
84
100
  }
101
+ /**
102
+ * The transport that sends: `'resend'` or `'smtp'` once `initialize()` has opened it, `null` before that and after
103
+ * `shutdown()`. The `emailSend` tool and the channel adapter read it to tell which attachments they may pass on.
104
+ */
105
+ get transport() {
106
+ if (this.resend)
107
+ return 'resend';
108
+ return this.transporter ? 'smtp' : null;
109
+ }
85
110
  // ── Send Email ──
111
+ /**
112
+ * Sends one message through the transport `initialize()` opened and resolves with the id it gives. An attachment's
113
+ * `path` may be a file on this host, which this process reads through either transport, or an `http:` or `https:`
114
+ * address, which this process fetches through SMTP (through Resend, Resend's servers fetch it): such a path must come
115
+ * from the developer's code and never from a model's output. The `emailSend` tool and the channel adapter accept only
116
+ * `content`, `data:` addresses and, through Resend, `http(s)` addresses, and refuse any other attachment before
117
+ * sending.
118
+ */
86
119
  async sendEmail(options) {
87
120
  this.requireRunning();
121
+ if (this.resend) {
122
+ return this.resend.send({
123
+ from: this.config.from,
124
+ to: options.to,
125
+ subject: options.subject,
126
+ text: options.body,
127
+ html: options.html,
128
+ replyTo: options.replyTo,
129
+ cc: options.cc,
130
+ bcc: options.bcc,
131
+ idempotencyKey: options.idempotencyKey,
132
+ attachments: options.attachments,
133
+ });
134
+ }
88
135
  if (!this.transporter)
89
136
  throw new Error('SMTP transporter not initialized');
90
137
  const info = await this.transporter.sendMail({
91
- from: this.config.smtp.user,
138
+ from: this.config.from ?? this.config.smtp.user,
92
139
  to: options.to,
93
140
  subject: options.subject,
94
141
  text: options.body,
@@ -260,13 +307,13 @@ class EmailService {
260
307
  // ── Reply to Email ──
261
308
  async replyToEmail(messageId, body, html) {
262
309
  this.requireRunning();
263
- if (!this.transporter)
264
- throw new Error('SMTP transporter not initialized');
310
+ if (!this.transporter && !this.resend)
311
+ throw new Error('No transport initialized');
265
312
  // Fetch the original message to get reply headers
266
313
  const client = await this.getImapClient();
267
314
  let originalFrom = '';
268
315
  let originalSubject = '';
269
- let references = '';
316
+ let previous = '';
270
317
  try {
271
318
  const lock = await client.getMailboxLock('INBOX');
272
319
  try {
@@ -278,7 +325,7 @@ class EmailService {
278
325
  originalSubject = msg.envelope?.subject ?? '';
279
326
  const headersStr = msg.headers?.toString() ?? '';
280
327
  const refsMatch = headersStr.match(/References:\s*(.+)/i);
281
- references = refsMatch ? refsMatch[1].trim() : '';
328
+ previous = refsMatch ? refsMatch[1].trim() : '';
282
329
  }
283
330
  }
284
331
  }
@@ -290,24 +337,34 @@ class EmailService {
290
337
  await client.logout();
291
338
  }
292
339
  const replySubject = originalSubject.startsWith('Re:') ? originalSubject : `Re: ${originalSubject}`;
340
+ const references = previous ? `${previous} ${messageId}` : messageId;
341
+ if (this.resend) {
342
+ return this.resend.send({
343
+ from: this.config.from,
344
+ to: originalFrom,
345
+ subject: replySubject,
346
+ text: body,
347
+ html,
348
+ headers: { 'In-Reply-To': messageId, References: references },
349
+ });
350
+ }
293
351
  const info = await this.transporter.sendMail({
294
- from: this.config.smtp.user,
352
+ from: this.config.from ?? this.config.smtp.user,
295
353
  to: originalFrom,
296
354
  subject: replySubject,
297
355
  text: body,
298
356
  html,
299
357
  inReplyTo: messageId,
300
- references: references ? `${references} ${messageId}` : messageId,
358
+ references,
301
359
  });
302
360
  return { messageId: info.messageId };
303
361
  }
304
362
  // ── Private: IMAP Client ──
305
363
  async getImapClient() {
306
- const imapConfig = this.config.imap ?? {
307
- host: this.config.smtp.host,
308
- user: this.config.smtp.user,
309
- password: this.config.smtp.password,
310
- };
364
+ const imapConfig = this.config.imap ??
365
+ (this.config.smtp ? { host: this.config.smtp.host, user: this.config.smtp.user, password: this.config.smtp.password } : undefined);
366
+ if (!imapConfig)
367
+ throw new Error('Reading mail needs an IMAP account');
311
368
  const client = new imapflow_1.ImapFlow({
312
369
  host: imapConfig.host,
313
370
  port: imapConfig.port ?? 993,
@@ -1 +1 @@
1
- {"version":3,"file":"EmailService.js","sourceRoot":"","sources":["../src/EmailService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EmailService.js","sourceRoot":"","sources":["../src/EmailService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @fileoverview A transport for Resend's HTTPS API: one `POST /emails` a message, the API key as the bearer, an
3
+ * `Idempotency-Key` when the caller gives one, the text and the HTML part in one call, and Resend's own retry terms
4
+ * inside one deadline. A refusal keeps the status and Resend's error name, never its message, which can quote an
5
+ * address.
6
+ */
7
+ /**
8
+ * An attachment path Resend fetches the file from itself: an `http:` or `https:` address. The agent surfaces'
9
+ * attachment check passes an address by this same test, so an address it passes is never read here.
10
+ */
11
+ export declare const REMOTE_ADDRESS: RegExp;
12
+ /** What the transport needs: the key, and where and as what it calls. */
13
+ export interface ResendOptions {
14
+ /**
15
+ * The API key, or a function that answers it at each send (a key file read when a message goes out). Whitespace around
16
+ * it, such as a key file's final line break, is trimmed.
17
+ */
18
+ apiKey: string | (() => string);
19
+ /** The API's origin with no trailing slash; Resend's own when unset. */
20
+ baseUrl?: string;
21
+ /** The `User-Agent` every request carries, which Resend requires; the pack's name when unset. */
22
+ userAgent?: string;
23
+ /** The longest one send may take, its retries and their waits included; fifteen seconds when unset. */
24
+ timeoutMs?: number;
25
+ /** The most retries one send makes; two when unset. */
26
+ maxRetries?: number;
27
+ }
28
+ /**
29
+ * One file sent with a message: its `content` (Base64 on the wire), or a `path`. An `http:` or `https:` path is the
30
+ * address Resend fetches the file from; a `data:` address or a file on this host is read here and sent as content, as
31
+ * nodemailer reads both over SMTP. With `content` given, a path Resend cannot fetch is left out. This process reads a
32
+ * file path, so it must come from the developer's code and never from a model's output: the pack's `emailSend` tool
33
+ * and channel adapter accept only `content`, `data:` addresses and, through Resend, `http(s)` addresses.
34
+ */
35
+ export interface OutgoingAttachment {
36
+ filename: string;
37
+ content?: string | Buffer;
38
+ path?: string;
39
+ contentType?: string;
40
+ }
41
+ /** One message as the transport sends it. */
42
+ export interface OutgoingEmail {
43
+ /** The From header; a display name is allowed, as in "Example <hello@example.com>". */
44
+ from: string;
45
+ /** The one recipient. */
46
+ to: string;
47
+ subject: string;
48
+ /** The plain-text part. */
49
+ text: string;
50
+ /** The HTML part, sent in the same call. */
51
+ html?: string;
52
+ replyTo?: string;
53
+ cc?: string;
54
+ bcc?: string;
55
+ /** Headers added to the message, such as `In-Reply-To` and `References` for a reply. */
56
+ headers?: Record<string, string>;
57
+ /**
58
+ * Resend's `Idempotency-Key`: a second request under the same key within 24 hours delivers nothing more. At most 256
59
+ * characters, and never personal data.
60
+ */
61
+ idempotencyKey?: string;
62
+ attachments?: OutgoingAttachment[];
63
+ }
64
+ /** A send Resend answered outside 2xx: its status, Resend's error name (`unknown` when it named none) and the wait it asked for. */
65
+ export declare class EmailApiError extends Error {
66
+ /** The type's own name. */
67
+ name: string;
68
+ /** The HTTP status Resend answered with. */
69
+ readonly status: number;
70
+ /** Resend's error name, such as `rate_limit_exceeded`, or `unknown`. */
71
+ readonly type: string;
72
+ /** The seconds the answer's `retry-after` header asked for, or null. */
73
+ readonly retryAfterSeconds: number | null;
74
+ constructor(status: number, type: string, retryAfterSeconds: number | null);
75
+ }
76
+ /**
77
+ * The wait before the next try, in seconds, or null when the refusal is not tried again: a rate limit always (it was
78
+ * refused before anything was sent), and under an idempotency key a 409 `concurrent_idempotent_requests` and any 5xx,
79
+ * which Resend's errors page answers with "Try the request again later"; never a quota, a validation error or
80
+ * `invalid_idempotent_request`. The wait is the answer's `retry-after`, else one second, then two.
81
+ */
82
+ export declare function retryWaitSeconds(error: EmailApiError, keyed: boolean, retry: number): number | null;
83
+ /** Resend's send call. */
84
+ export declare class ResendTransport {
85
+ private readonly options;
86
+ constructor(options: ResendOptions);
87
+ /**
88
+ * Sends one message: the key read once and trimmed, then `POST /emails`, tried again on Resend's terms while the
89
+ * deadline allows. Throws an `Error` before any request when the key, the idempotency key or the User-Agent holds a
90
+ * character an HTTP header cannot carry, with a message that names the field and none of its value; `EmailApiError`
91
+ * for a refusal; and what `fetch` throws for a connection that fails (`TypeError`) or the deadline (`TimeoutError`),
92
+ * so a caller can tell them apart. A 2xx answer always resolves, since Resend has taken the email: its `messageId` is
93
+ * the empty string when the answer names no id or its body cannot be read before the deadline. An attachment from a
94
+ * `data:` address or a file on this host is read first, before the deadline starts; a file that cannot be read throws
95
+ * its own error before any request.
96
+ */
97
+ send(message: OutgoingEmail): Promise<{
98
+ messageId: string;
99
+ }>;
100
+ }
101
+ //# sourceMappingURL=ResendTransport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResendTransport.d.ts","sourceRoot":"","sources":["../src/ResendTransport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAkB,CAAC;AAK9C,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAChC,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uGAAuG;IACvG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACpC;AAED,oIAAoI;AACpI,qBAAa,aAAc,SAAQ,KAAK;IACtC,2BAA2B;IAClB,IAAI,SAAmB;IAEhC,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,wEAAwE;IACxE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;gBAE9B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,IAAI;CAM3E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGnG;AAsFD,0BAA0B;AAC1B,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;gBAE5B,OAAO,EAAE,aAAa;IAIlC;;;;;;;;;OASG;IACG,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAwBnE"}
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview A transport for Resend's HTTPS API: one `POST /emails` a message, the API key as the bearer, an
4
+ * `Idempotency-Key` when the caller gives one, the text and the HTML part in one call, and Resend's own retry terms
5
+ * inside one deadline. A refusal keeps the status and Resend's error name, never its message, which can quote an
6
+ * address.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.ResendTransport = exports.EmailApiError = exports.REMOTE_ADDRESS = void 0;
10
+ exports.retryWaitSeconds = retryWaitSeconds;
11
+ const promises_1 = require("node:fs/promises");
12
+ /** Resend's API origin. */
13
+ const RESEND_API = 'https://api.resend.com';
14
+ /** The `User-Agent` sent when the caller names none: Resend refuses a request without one. */
15
+ const DEFAULT_USER_AGENT = 'agentos-ext-channel-email';
16
+ /** The longest one send may take when the caller names no deadline, retries and their waits included. */
17
+ const DEFAULT_TIMEOUT_MS = 15000;
18
+ /** The retries one send makes at most when the caller names no number. */
19
+ const DEFAULT_MAX_RETRIES = 2;
20
+ /** The shape of an error name Resend gives, such as `validation_error`; any other value is read as `unknown`. */
21
+ const ERROR_NAME = /^[A-Za-z0-9_.:-]{1,64}$/;
22
+ /**
23
+ * A character an HTTP header value cannot carry through Node's `fetch` (undici), whose own header check this is: only a
24
+ * tab, a space, the visible ASCII characters and U+0080 to U+00FF pass. `Headers` throws a `TypeError` for a character
25
+ * above U+00FF and for a NUL, CR or LF inside the value (that one quoting the whole value, key and all), and the
26
+ * request fails for any other control character.
27
+ */
28
+ const NOT_A_HEADER_CHARACTER = /[^\t\x20-\x7e\x80-\xff]/;
29
+ /**
30
+ * An attachment path Resend fetches the file from itself: an `http:` or `https:` address. The agent surfaces'
31
+ * attachment check passes an address by this same test, so an address it passes is never read here.
32
+ */
33
+ exports.REMOTE_ADDRESS = /^https?:\/\//i;
34
+ /** A `data:` address, which holds its attachment's bytes in itself. */
35
+ const DATA_ADDRESS = /^data:/i;
36
+ /** A send Resend answered outside 2xx: its status, Resend's error name (`unknown` when it named none) and the wait it asked for. */
37
+ class EmailApiError extends Error {
38
+ constructor(status, type, retryAfterSeconds) {
39
+ super(`Resend refused the email with ${status} ${type}`);
40
+ /** The type's own name. */
41
+ this.name = 'EmailApiError';
42
+ this.status = status;
43
+ this.type = type;
44
+ this.retryAfterSeconds = retryAfterSeconds;
45
+ }
46
+ }
47
+ exports.EmailApiError = EmailApiError;
48
+ /**
49
+ * The wait before the next try, in seconds, or null when the refusal is not tried again: a rate limit always (it was
50
+ * refused before anything was sent), and under an idempotency key a 409 `concurrent_idempotent_requests` and any 5xx,
51
+ * which Resend's errors page answers with "Try the request again later"; never a quota, a validation error or
52
+ * `invalid_idempotent_request`. The wait is the answer's `retry-after`, else one second, then two.
53
+ */
54
+ function retryWaitSeconds(error, keyed, retry) {
55
+ const tryAgain = error.type === 'rate_limit_exceeded' || (keyed && (error.type === 'concurrent_idempotent_requests' || error.status >= 500));
56
+ return tryAgain ? (error.retryAfterSeconds ?? retry) : null;
57
+ }
58
+ /** The answer's `retry-after` in seconds, or null when it is absent or not a number of seconds. */
59
+ function retryAfterOf(headers) {
60
+ const raw = headers.get('retry-after');
61
+ if (raw === null || raw.trim() === '')
62
+ return null;
63
+ const seconds = Number(raw);
64
+ return Number.isFinite(seconds) && seconds >= 0 ? seconds : null;
65
+ }
66
+ /** A refusal read from Resend's answer: the status, the error's name when it is a word, the wait; the rest dropped. */
67
+ async function refusalOf(answer) {
68
+ let type = 'unknown';
69
+ try {
70
+ const body = await answer.json();
71
+ const name = typeof body === 'object' && body !== null && 'name' in body ? body.name : undefined;
72
+ if (typeof name === 'string' && ERROR_NAME.test(name))
73
+ type = name;
74
+ }
75
+ catch {
76
+ // not JSON: the name stays unknown
77
+ }
78
+ return new EmailApiError(answer.status, type, retryAfterOf(answer.headers));
79
+ }
80
+ /**
81
+ * The message's id from a 2xx answer, or the empty string when the answer's body names none or cannot be read (not
82
+ * JSON, no `id`, or cut off by the deadline). A 2xx means Resend took the email, so the send still succeeds: a failure
83
+ * reported here would lead a caller to send the email a second time.
84
+ */
85
+ async function messageIdOf(answer) {
86
+ try {
87
+ const body = await answer.json();
88
+ const id = typeof body === 'object' && body !== null && 'id' in body ? body.id : undefined;
89
+ return typeof id === 'string' ? id : '';
90
+ }
91
+ catch {
92
+ return '';
93
+ }
94
+ }
95
+ /** What a path Resend cannot fetch holds: a `data:` address decoded, with its media type, or a file on this host read. */
96
+ async function readAttachment(path) {
97
+ if (DATA_ADDRESS.test(path)) {
98
+ // fetch decodes a data: address itself, Base64 or percent-encoded, by the Fetch standard's data: URL processor.
99
+ const decoded = await fetch(path);
100
+ return { bytes: Buffer.from(await decoded.arrayBuffer()), type: decoded.headers.get('content-type') };
101
+ }
102
+ return { bytes: await (0, promises_1.readFile)(path), type: null };
103
+ }
104
+ /** One attachment in Resend's shape: an `http:` or `https:` path as Resend's own, any other path read into content. */
105
+ async function attachmentOf(attachment) {
106
+ const shaped = { filename: attachment.filename };
107
+ if (attachment.content !== undefined) {
108
+ shaped.content = (typeof attachment.content === 'string' ? Buffer.from(attachment.content) : attachment.content).toString('base64');
109
+ }
110
+ if (attachment.path !== undefined && exports.REMOTE_ADDRESS.test(attachment.path)) {
111
+ shaped.path = attachment.path;
112
+ }
113
+ else if (attachment.path !== undefined && attachment.content === undefined) {
114
+ const { bytes, type } = await readAttachment(attachment.path);
115
+ shaped.content = bytes.toString('base64');
116
+ if (type !== null)
117
+ shaped.content_type = type;
118
+ }
119
+ if (attachment.contentType !== undefined)
120
+ shaped.content_type = attachment.contentType;
121
+ return shaped;
122
+ }
123
+ /** The request's JSON body: the fields Resend's send call names, and only those the message carries. */
124
+ async function bodyOf(message) {
125
+ const body = { from: message.from, to: [message.to], subject: message.subject, text: message.text };
126
+ if (message.html !== undefined)
127
+ body.html = message.html;
128
+ if (message.replyTo !== undefined)
129
+ body.reply_to = message.replyTo;
130
+ if (message.cc !== undefined)
131
+ body.cc = message.cc;
132
+ if (message.bcc !== undefined)
133
+ body.bcc = message.bcc;
134
+ if (message.headers !== undefined)
135
+ body.headers = message.headers;
136
+ if (message.attachments !== undefined && message.attachments.length > 0)
137
+ body.attachments = await Promise.all(message.attachments.map(attachmentOf));
138
+ return body;
139
+ }
140
+ /**
141
+ * Throws an `Error` that names the field and none of its value when a header's value holds a character a header cannot
142
+ * carry, so the send stops before any request rather than inside `fetch` with a `TypeError` that reads as a failed
143
+ * connection.
144
+ */
145
+ function requireHeaderValue(value, field) {
146
+ if (NOT_A_HEADER_CHARACTER.test(value))
147
+ throw new Error(`${field} holds a character an HTTP header cannot carry`);
148
+ }
149
+ /** Resend's send call. */
150
+ class ResendTransport {
151
+ constructor(options) {
152
+ this.options = options;
153
+ }
154
+ /**
155
+ * Sends one message: the key read once and trimmed, then `POST /emails`, tried again on Resend's terms while the
156
+ * deadline allows. Throws an `Error` before any request when the key, the idempotency key or the User-Agent holds a
157
+ * character an HTTP header cannot carry, with a message that names the field and none of its value; `EmailApiError`
158
+ * for a refusal; and what `fetch` throws for a connection that fails (`TypeError`) or the deadline (`TimeoutError`),
159
+ * so a caller can tell them apart. A 2xx answer always resolves, since Resend has taken the email: its `messageId` is
160
+ * the empty string when the answer names no id or its body cannot be read before the deadline. An attachment from a
161
+ * `data:` address or a file on this host is read first, before the deadline starts; a file that cannot be read throws
162
+ * its own error before any request.
163
+ */
164
+ async send(message) {
165
+ // String() keeps the coercion a template literal gave a key answered outside TypeScript, such as a Buffer.
166
+ const key = String(typeof this.options.apiKey === 'function' ? this.options.apiKey() : this.options.apiKey).trim();
167
+ requireHeaderValue(key, 'The Resend API key');
168
+ const userAgent = this.options.userAgent ?? DEFAULT_USER_AGENT;
169
+ requireHeaderValue(userAgent, 'The User-Agent');
170
+ if (message.idempotencyKey !== undefined)
171
+ requireHeaderValue(message.idempotencyKey, 'The idempotency key');
172
+ const body = JSON.stringify(await bodyOf(message));
173
+ const timeoutMs = this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
174
+ const maxRetries = this.options.maxRetries ?? DEFAULT_MAX_RETRIES;
175
+ const deadline = Date.now() + timeoutMs;
176
+ const signal = AbortSignal.timeout(timeoutMs);
177
+ const headers = new Headers({ Authorization: `Bearer ${key}`, 'Content-Type': 'application/json', 'User-Agent': userAgent });
178
+ if (message.idempotencyKey !== undefined)
179
+ headers.set('Idempotency-Key', message.idempotencyKey);
180
+ const url = `${(this.options.baseUrl ?? RESEND_API).replace(/\/+$/, '')}/emails`;
181
+ for (let retry = 0;; retry += 1) {
182
+ const answer = await fetch(url, { method: 'POST', headers, body, redirect: 'error', signal });
183
+ if (answer.ok)
184
+ return { messageId: await messageIdOf(answer) };
185
+ const error = await refusalOf(answer);
186
+ const wait = retry < maxRetries ? retryWaitSeconds(error, message.idempotencyKey !== undefined, retry + 1) : null;
187
+ if (wait === null || Date.now() + wait * 1000 >= deadline)
188
+ throw error;
189
+ await new Promise((resolve) => setTimeout(resolve, wait * 1000));
190
+ }
191
+ }
192
+ }
193
+ exports.ResendTransport = ResendTransport;
194
+ //# sourceMappingURL=ResendTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResendTransport.js","sourceRoot":"","sources":["../src/ResendTransport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview The attachment check of the pack's two agent surfaces, the `emailSend` tool and the channel adapter,
3
+ * whose arguments a model writes. `EmailService.sendEmail` reads a file path on this host, and through SMTP fetches an
4
+ * `http:` or `https:` address from this host, so text that steers an agent could have it mail any file the process can
5
+ * read, or the answer of an address only this host reaches. The two surfaces pass on only what neither transport reads
6
+ * or fetches here.
7
+ */
8
+ /**
9
+ * Throws an `Error` when an attachment an agent named would make this process read a file or fetch an address, before
10
+ * anything is sent and without reading the file or fetching the address. An attachment passes when its `content`, if
11
+ * given, is a string or a Buffer, and its `path`, if given, is a `data:` address, or an `http:` or `https:` address
12
+ * while the service sends through Resend, whose servers fetch it. A path is checked even next to `content`, since
13
+ * nodemailer reads `path` first, and `content` of any other kind is refused, since nodemailer reads the `path` or
14
+ * fetches the `href` of a content object. The message names the attachment's `filename`, or its place in the list when
15
+ * it has none, and the rule, never its path.
16
+ *
17
+ * @param attachments The attachments as the surface took them. `undefined` or `null` passes, since there is nothing to
18
+ * send. Any other value that is not a list is refused, since nodemailer takes a single attachment object as a list of
19
+ * one and reads its `path`.
20
+ * @param throughResend Whether the service sends through Resend, as `EmailService.transport` tells.
21
+ */
22
+ export declare function requireAgentAttachments(attachments: unknown, throughResend: boolean): void;
23
+ //# sourceMappingURL=agentAttachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentAttachments.d.ts","sourceRoot":"","sources":["../src/agentAttachments.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiBH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,GAAG,IAAI,CAgB1F"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview The attachment check of the pack's two agent surfaces, the `emailSend` tool and the channel adapter,
4
+ * whose arguments a model writes. `EmailService.sendEmail` reads a file path on this host, and through SMTP fetches an
5
+ * `http:` or `https:` address from this host, so text that steers an agent could have it mail any file the process can
6
+ * read, or the answer of an address only this host reaches. The two surfaces pass on only what neither transport reads
7
+ * or fetches here.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.requireAgentAttachments = requireAgentAttachments;
11
+ const ResendTransport_js_1 = require("./ResendTransport.js");
12
+ /**
13
+ * A `data:` address up to the comma that ends its header. nodemailer decodes a path only in this form, with `data:` in
14
+ * lowercase and a comma, and reads any other path that is not an `http(s)` address as a file.
15
+ */
16
+ const DATA_ADDRESS = /^data:[^,]*,/;
17
+ /** The rule a refusal names when the service sends through Resend. */
18
+ const THROUGH_RESEND = 'an attachment takes its content as a string, a data: address or an http(s) address; files on this machine are not read';
19
+ /** The rule a refusal names when the service sends through SMTP. */
20
+ const THROUGH_SMTP = 'through SMTP an attachment takes its content as a string or a data: address; files on this machine are not read and addresses are not fetched';
21
+ /**
22
+ * Throws an `Error` when an attachment an agent named would make this process read a file or fetch an address, before
23
+ * anything is sent and without reading the file or fetching the address. An attachment passes when its `content`, if
24
+ * given, is a string or a Buffer, and its `path`, if given, is a `data:` address, or an `http:` or `https:` address
25
+ * while the service sends through Resend, whose servers fetch it. A path is checked even next to `content`, since
26
+ * nodemailer reads `path` first, and `content` of any other kind is refused, since nodemailer reads the `path` or
27
+ * fetches the `href` of a content object. The message names the attachment's `filename`, or its place in the list when
28
+ * it has none, and the rule, never its path.
29
+ *
30
+ * @param attachments The attachments as the surface took them. `undefined` or `null` passes, since there is nothing to
31
+ * send. Any other value that is not a list is refused, since nodemailer takes a single attachment object as a list of
32
+ * one and reads its `path`.
33
+ * @param throughResend Whether the service sends through Resend, as `EmailService.transport` tells.
34
+ */
35
+ function requireAgentAttachments(attachments, throughResend) {
36
+ if (attachments === undefined || attachments === null)
37
+ return;
38
+ if (!Array.isArray(attachments))
39
+ throw new Error('The attachments were refused: give them as a list');
40
+ for (const [index, attachment] of attachments.entries()) {
41
+ const { filename, content, path } = (typeof attachment === 'object' && attachment !== null ? attachment : {});
42
+ const contentPasses = content === undefined || typeof content === 'string' || Buffer.isBuffer(content);
43
+ const pathPasses = path === undefined || (typeof path === 'string' && (DATA_ADDRESS.test(path) || (throughResend && ResendTransport_js_1.REMOTE_ADDRESS.test(path))));
44
+ if (contentPasses && pathPasses)
45
+ continue;
46
+ const named = typeof filename === 'string' && filename !== '' ? JSON.stringify(filename) : `number ${index + 1}`;
47
+ throw new Error(`The attachment ${named} was refused: ${throughResend ? THROUGH_RESEND : THROUGH_SMTP}`);
48
+ }
49
+ }
50
+ //# sourceMappingURL=agentAttachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentAttachments.js","sourceRoot":"","sources":["../src/agentAttachments.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AA+BH,0DAgBC;AA7CD,6DAAsD;AAEtD;;;GAGG;AACH,MAAM,YAAY,GAAG,cAAc,CAAC;AAEpC,sEAAsE;AACtE,MAAM,cAAc,GAAG,wHAAwH,CAAC;AAEhJ,oEAAoE;AACpE,MAAM,YAAY,GAChB,+IAA+I,CAAC;AAElJ;;;;;;;;;;;;;GAaG;AACH,SAAgB,uBAAuB,CAAC,WAAoB,EAAE,aAAsB;IAClF,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO;IAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACtG,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAI3G,CAAC;QACF,MAAM,aAAa,GAAG,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvG,MAAM,UAAU,GACd,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,mCAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAChI,IAAI,aAAa,IAAI,UAAU;YAAE,SAAS;QAC1C,MAAM,KAAK,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,GAAG,CAAC,EAAE,CAAC;QACjH,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,iBAAiB,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;IAC3G,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,7 +2,8 @@
2
2
  * @fileoverview Email Channel Extension for AgentOS.
3
3
  *
4
4
  * Provides an IChannelAdapter + 5 tools for sending, reading, searching,
5
- * extracting codes from, and replying to emails via SMTP/IMAP.
5
+ * extracting codes from, and replying to emails: it sends through SMTP or
6
+ * Resend's HTTPS API and reads through IMAP.
6
7
  *
7
8
  * @module @framers/agentos-ext-channel-email
8
9
  */
@@ -17,6 +18,18 @@ export interface EmailChannelOptions {
17
18
  imapPassword?: string;
18
19
  imapPort?: number;
19
20
  imapSecure?: boolean;
21
+ /**
22
+ * Resend's API key. With no SMTP host, mail is sent through Resend's HTTPS API. Falls back to the secret
23
+ * `email.resendApiKey`, then to `RESEND_API_KEY`.
24
+ */
25
+ resendApiKey?: string;
26
+ /** Resend's API origin, such as a proxy's; Resend's own when unset. */
27
+ resendBaseUrl?: string;
28
+ /**
29
+ * The From header, a display name allowed (`Example <hello@example.com>`). Falls back to `EMAIL_FROM`, then to the
30
+ * SMTP user; required when sending through Resend.
31
+ */
32
+ from?: string;
20
33
  secrets?: Record<string, string>;
21
34
  }
22
35
  export interface ExtensionContext {
@@ -38,6 +51,8 @@ export interface ExtensionPack {
38
51
  export declare function createExtensionPack(context: ExtensionContext): ExtensionPack;
39
52
  export { EmailService } from './EmailService.js';
40
53
  export type { EmailConfig, SendEmailOptions, EmailMessage, SearchEmailOptions } from './EmailService.js';
54
+ export { ResendTransport, EmailApiError, retryWaitSeconds } from './ResendTransport.js';
55
+ export type { ResendOptions, OutgoingEmail, OutgoingAttachment } from './ResendTransport.js';
41
56
  export { EmailChannelAdapter } from './EmailChannelAdapter.js';
42
57
  export { EmailSendTool } from './tools/send.js';
43
58
  export { EmailReadTool } from './tools/read.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAeH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AA2ED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACtF,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAMD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAgC5E;AAMD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAeH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAkFD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACtF,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAMD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAgC5E;AAMD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxF,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -4,12 +4,13 @@
4
4
  * @fileoverview Email Channel Extension for AgentOS.
5
5
  *
6
6
  * Provides an IChannelAdapter + 5 tools for sending, reading, searching,
7
- * extracting codes from, and replying to emails via SMTP/IMAP.
7
+ * extracting codes from, and replying to emails: it sends through SMTP or
8
+ * Resend's HTTPS API and reads through IMAP.
8
9
  *
9
10
  * @module @framers/agentos-ext-channel-email
10
11
  */
11
12
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.EmailReplyTool = exports.EmailExtractCodesTool = exports.EmailSearchTool = exports.EmailReadTool = exports.EmailSendTool = exports.EmailChannelAdapter = exports.EmailService = void 0;
13
+ exports.EmailReplyTool = exports.EmailExtractCodesTool = exports.EmailSearchTool = exports.EmailReadTool = exports.EmailSendTool = exports.EmailChannelAdapter = exports.retryWaitSeconds = exports.EmailApiError = exports.ResendTransport = exports.EmailService = void 0;
13
14
  exports.createExtensionPack = createExtensionPack;
14
15
  const EmailService_js_1 = require("./EmailService.js");
15
16
  const EmailChannelAdapter_js_1 = require("./EmailChannelAdapter.js");
@@ -40,6 +41,8 @@ function resolveConfig(opts, secrets) {
40
41
  process.env.SMTP_PASSWORD ??
41
42
  process.env.EMAIL_SMTP_PASSWORD ??
42
43
  '';
44
+ const resendApiKey = opts.resendApiKey ?? secrets['email.resendApiKey'] ?? process.env.RESEND_API_KEY;
45
+ const from = opts.from ?? process.env.EMAIL_FROM;
43
46
  const imapHost = opts.imapHost ??
44
47
  secrets['email.imapHost'] ??
45
48
  secrets['email.imap.host'] ??
@@ -55,15 +58,19 @@ function resolveConfig(opts, secrets) {
55
58
  secrets['email.imap.password'] ??
56
59
  process.env.IMAP_PASSWORD ??
57
60
  process.env.EMAIL_IMAP_PASSWORD;
58
- const config = {
59
- smtp: {
60
- host: smtpHost,
61
- user: smtpUser,
62
- password: smtpPassword,
63
- port: opts.smtpPort,
64
- secure: opts.smtpSecure,
65
- },
66
- };
61
+ // SMTP stays the transport whenever a host is given; Resend sends only when a key is given and no SMTP host.
62
+ const config = smtpHost === '' && resendApiKey
63
+ ? { resend: { apiKey: resendApiKey, baseUrl: opts.resendBaseUrl }, from }
64
+ : {
65
+ smtp: {
66
+ host: smtpHost,
67
+ user: smtpUser,
68
+ password: smtpPassword,
69
+ port: opts.smtpPort,
70
+ secure: opts.smtpSecure,
71
+ },
72
+ from,
73
+ };
67
74
  if (imapHost && imapUser && imapPassword) {
68
75
  config.imap = {
69
76
  host: imapHost,
@@ -101,7 +108,7 @@ function createExtensionPack(context) {
101
108
  { id: 'emailChannel', kind: 'messaging-channel', priority: 50, payload: adapter },
102
109
  ],
103
110
  onActivate: async () => {
104
- await adapter.initialize({ platform: 'email', credential: config.smtp.user });
111
+ await adapter.initialize({ platform: 'email', credential: config.smtp?.user ?? config.from ?? '' });
105
112
  },
106
113
  onDeactivate: async () => {
107
114
  await adapter.shutdown();
@@ -113,6 +120,10 @@ function createExtensionPack(context) {
113
120
  // ---------------------------------------------------------------------------
114
121
  var EmailService_js_2 = require("./EmailService.js");
115
122
  Object.defineProperty(exports, "EmailService", { enumerable: true, get: function () { return EmailService_js_2.EmailService; } });
123
+ var ResendTransport_js_1 = require("./ResendTransport.js");
124
+ Object.defineProperty(exports, "ResendTransport", { enumerable: true, get: function () { return ResendTransport_js_1.ResendTransport; } });
125
+ Object.defineProperty(exports, "EmailApiError", { enumerable: true, get: function () { return ResendTransport_js_1.EmailApiError; } });
126
+ Object.defineProperty(exports, "retryWaitSeconds", { enumerable: true, get: function () { return ResendTransport_js_1.retryWaitSeconds; } });
116
127
  var EmailChannelAdapter_js_2 = require("./EmailChannelAdapter.js");
117
128
  Object.defineProperty(exports, "EmailChannelAdapter", { enumerable: true, get: function () { return EmailChannelAdapter_js_2.EmailChannelAdapter; } });
118
129
  var send_js_2 = require("./tools/send.js");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ export declare class EmailSendTool {
4
4
  readonly id = "emailSend";
5
5
  readonly name = "emailSend";
6
6
  readonly displayName = "Send Email";
7
- readonly description = "Send an email with text or HTML body and optional attachments via SMTP.";
7
+ readonly description = "Send an email with text or HTML body and optional attachments via SMTP or Resend's HTTPS API.";
8
8
  readonly category = "communication";
9
9
  readonly version = "0.1.0";
10
10
  readonly hasSideEffects = true;
@@ -39,6 +39,10 @@ export declare class EmailSendTool {
39
39
  type: string;
40
40
  description: string;
41
41
  };
42
+ content: {
43
+ type: string;
44
+ description: string;
45
+ };
42
46
  };
43
47
  };
44
48
  description: string;
@@ -47,6 +51,10 @@ export declare class EmailSendTool {
47
51
  required: string[];
48
52
  };
49
53
  constructor(service: EmailService);
54
+ /**
55
+ * Sends the email. An attachment passes only as `content`, a `data:` address or, through Resend, an `http(s)`
56
+ * address: any other is refused before anything is sent, with `{ success: false, error }` naming its filename.
57
+ */
50
58
  execute(args: {
51
59
  to: string;
52
60
  subject: string;
@@ -1 +1 @@
1
- {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,qBAAa,aAAa;IA+BZ,OAAO,CAAC,OAAO;IA9B3B,QAAQ,CAAC,EAAE,eAAe;IAC1B,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,gBAAgB;IACpC,QAAQ,CAAC,WAAW,6EAA6E;IACjG,QAAQ,CAAC,QAAQ,mBAAmB;IACpC,QAAQ,CAAC,OAAO,WAAW;IAC3B,QAAQ,CAAC,cAAc,QAAQ;IAE/B,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAoBlB;gBAEkB,OAAO,EAAE,YAAY;IAEnC,OAAO,CAAC,IAAI,EAAE;QAClB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC5E,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAc9D"}
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,qBAAa,aAAa;IAgCZ,OAAO,CAAC,OAAO;IA/B3B,QAAQ,CAAC,EAAE,eAAe;IAC1B,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,gBAAgB;IACpC,QAAQ,CAAC,WAAW,mGAAmG;IACvH,QAAQ,CAAC,QAAQ,mBAAmB;IACpC,QAAQ,CAAC,OAAO,WAAW;IAC3B,QAAQ,CAAC,cAAc,QAAQ;IAE/B,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAqBlB;gBAEkB,OAAO,EAAE,YAAY;IAEzC;;;OAGG;IACG,OAAO,CAAC,IAAI,EAAE;QAClB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC5E,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAe9D"}
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EmailSendTool = void 0;
4
+ const agentAttachments_js_1 = require("../agentAttachments.js");
4
5
  class EmailSendTool {
5
6
  constructor(service) {
6
7
  this.service = service;
7
8
  this.id = 'emailSend';
8
9
  this.name = 'emailSend';
9
10
  this.displayName = 'Send Email';
10
- this.description = 'Send an email with text or HTML body and optional attachments via SMTP.';
11
+ this.description = "Send an email with text or HTML body and optional attachments via SMTP or Resend's HTTPS API.";
11
12
  this.category = 'communication';
12
13
  this.version = '0.1.0';
13
14
  this.hasSideEffects = true;
@@ -24,7 +25,8 @@ class EmailSendTool {
24
25
  type: 'object',
25
26
  properties: {
26
27
  filename: { type: 'string' },
27
- path: { type: 'string', description: 'File path or URL' },
28
+ path: { type: 'string', description: 'A data: address, or an http(s) address when sending through Resend; files on this machine are not read' },
29
+ content: { type: 'string', description: "The file's content as text; give a binary file in path as a Base64 data: address" },
28
30
  },
29
31
  },
30
32
  description: 'Optional file attachments',
@@ -33,8 +35,13 @@ class EmailSendTool {
33
35
  required: ['to', 'subject', 'body'],
34
36
  };
35
37
  }
38
+ /**
39
+ * Sends the email. An attachment passes only as `content`, a `data:` address or, through Resend, an `http(s)`
40
+ * address: any other is refused before anything is sent, with `{ success: false, error }` naming its filename.
41
+ */
36
42
  async execute(args) {
37
43
  try {
44
+ (0, agentAttachments_js_1.requireAgentAttachments)(args.attachments, this.service.transport === 'resend');
38
45
  const result = await this.service.sendEmail({
39
46
  to: args.to,
40
47
  subject: args.subject,
@@ -1 +1 @@
1
- {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":";;;AAGA,MAAa,aAAa;IA+BxB,YAAoB,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;QA9BhC,OAAE,GAAG,WAAW,CAAC;QACjB,SAAI,GAAG,WAAW,CAAC;QACnB,gBAAW,GAAG,YAAY,CAAC;QAC3B,gBAAW,GAAG,yEAAyE,CAAC;QACxF,aAAQ,GAAG,eAAe,CAAC;QAC3B,YAAO,GAAG,OAAO,CAAC;QAClB,mBAAc,GAAG,IAAI,CAAC;QAEtB,gBAAW,GAAG;YACrB,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBAC9D,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;gBAC9D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;gBAC9D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;gBACjE,WAAW,EAAE;oBACX,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE;yBAC1D;qBACF;oBACD,WAAW,EAAE,2BAA2B;iBACzC;aACF;YACD,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC;SACpC,CAAC;IAE0C,CAAC;IAE7C,KAAK,CAAC,OAAO,CAAC,IAMb;QACC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;gBAC1C,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACzC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;CACF;AArDD,sCAqDC"}
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/tools/send.ts"],"names":[],"mappings":";;;AAEA,gEAAiE;AAEjE,MAAa,aAAa;IAgCxB,YAAoB,OAAqB;QAArB,YAAO,GAAP,OAAO,CAAc;QA/BhC,OAAE,GAAG,WAAW,CAAC;QACjB,SAAI,GAAG,WAAW,CAAC;QACnB,gBAAW,GAAG,YAAY,CAAC;QAC3B,gBAAW,GAAG,+FAA+F,CAAC;QAC9G,aAAQ,GAAG,eAAe,CAAC;QAC3B,YAAO,GAAG,OAAO,CAAC;QAClB,mBAAc,GAAG,IAAI,CAAC;QAEtB,gBAAW,GAAG;YACrB,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBAC9D,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;gBAC9D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;gBAC9D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;gBACjE,WAAW,EAAE;oBACX,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE;4BACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wGAAwG,EAAE;4BAC/I,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kFAAkF,EAAE;yBAC7H;qBACF;oBACD,WAAW,EAAE,2BAA2B;iBACzC;aACF;YACD,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC;SACpC,CAAC;IAE0C,CAAC;IAE7C;;;OAGG;IACH,KAAK,CAAC,OAAO,CAAC,IAMb;QACC,IAAI,CAAC;YACH,IAAA,6CAAuB,EAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC;YAC/E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;gBAC1C,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACzC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;CACF;AA3DD,sCA2DC"}
package/manifest.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
3
3
  "id": "com.framers.channels.email",
4
4
  "name": "Email Channel Extension",
5
- "version": "0.1.1",
6
- "description": "Bidirectional email integration — send, read, search, extract verification codes, and reply to email threads via SMTP and IMAP.",
5
+ "version": "0.2.0",
6
+ "description": "Bidirectional email integration: send through SMTP or Resend's HTTPS API, and read, search, extract verification codes and reply through IMAP.",
7
7
  "categories": ["channel", "communication"],
8
8
  "platforms": ["email"],
9
9
  "sdk": "nodemailer",
@@ -16,9 +16,9 @@
16
16
  { "kind": "messaging-channel", "id": "emailChannel", "displayName": "Email Channel Adapter" }
17
17
  ],
18
18
  "requiredSecrets": ["email.smtpHost", "email.smtpUser", "email.smtpPassword"],
19
- "optionalSecrets": ["email.imap.host", "email.imap.user", "email.imap.password"],
19
+ "optionalSecrets": ["email.imap.host", "email.imap.user", "email.imap.password", "email.resendApiKey"],
20
20
  "features": [
21
- "Send emails with text, HTML, and attachments via SMTP",
21
+ "Send emails with text, HTML, and attachments via SMTP or Resend's HTTPS API",
22
22
  "Read inbox and other IMAP folders",
23
23
  "Search emails by query, folder, and date range",
24
24
  "Extract verification codes and OTPs from email bodies",
package/package.json CHANGED
@@ -1,26 +1,31 @@
1
1
  {
2
2
  "name": "@framers/agentos-ext-channel-email",
3
- "version": "0.1.1",
4
- "description": "Email channel adapter for AgentOS — send, read, search, extract codes, and reply to emails via SMTP/IMAP.",
3
+ "version": "0.2.0",
4
+ "description": "Email channel adapter for AgentOS: send through SMTP or Resend's HTTPS API, and read, search, extract codes and reply through IMAP.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "license": "Apache-2.0",
7
8
  "files": [
8
9
  "dist",
9
10
  "manifest.json"
10
11
  ],
11
12
  "peerDependencies": {
12
- "@framers/agentos": "^0.10.28"
13
+ "@framers/agentos": ">=0.10.40"
14
+ },
15
+ "peerDependenciesMeta": {
16
+ "@framers/agentos": {
17
+ "optional": true
18
+ }
13
19
  },
14
20
  "dependencies": {
15
21
  "imapflow": "^1.0.0",
16
- "nodemailer": "^6.9.0"
22
+ "nodemailer": "^10.0.16"
17
23
  },
18
24
  "devDependencies": {
19
25
  "@types/node": "^20.0.0",
20
- "@types/nodemailer": "^6.4.0",
21
26
  "typescript": "^5.0.0",
22
- "vitest": "^1.0.0",
23
- "@framers/agentos": "^0.10.28"
27
+ "vitest": "^3.2.7",
28
+ "@framers/agentos": "^0.13.19"
24
29
  },
25
30
  "repository": {
26
31
  "type": "git",