@cogitator-ai/channels 0.16.0 → 0.17.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.
Files changed (69) hide show
  1. package/README.md +53 -12
  2. package/dist/assistant-config.d.ts +40 -0
  3. package/dist/assistant-config.d.ts.map +1 -1
  4. package/dist/assistant-config.js +66 -0
  5. package/dist/assistant-config.js.map +1 -1
  6. package/dist/channels/email/address.d.ts +44 -0
  7. package/dist/channels/email/address.d.ts.map +1 -0
  8. package/dist/channels/email/address.js +211 -0
  9. package/dist/channels/email/address.js.map +1 -0
  10. package/dist/channels/email/auth.d.ts +59 -0
  11. package/dist/channels/email/auth.d.ts.map +1 -0
  12. package/dist/channels/email/auth.js +212 -0
  13. package/dist/channels/email/auth.js.map +1 -0
  14. package/dist/channels/email/channel.d.ts +256 -0
  15. package/dist/channels/email/channel.d.ts.map +1 -0
  16. package/dist/channels/email/channel.js +701 -0
  17. package/dist/channels/email/channel.js.map +1 -0
  18. package/dist/channels/email/errors.d.ts +11 -0
  19. package/dist/channels/email/errors.d.ts.map +1 -0
  20. package/dist/channels/email/errors.js +13 -0
  21. package/dist/channels/email/errors.js.map +1 -0
  22. package/dist/channels/email/imap.d.ts +125 -0
  23. package/dist/channels/email/imap.d.ts.map +1 -0
  24. package/dist/channels/email/imap.js +309 -0
  25. package/dist/channels/email/imap.js.map +1 -0
  26. package/dist/channels/email/index.d.ts +7 -0
  27. package/dist/channels/email/index.d.ts.map +1 -0
  28. package/dist/channels/email/index.js +3 -0
  29. package/dist/channels/email/index.js.map +1 -0
  30. package/dist/channels/email/mime.d.ts +71 -0
  31. package/dist/channels/email/mime.d.ts.map +1 -0
  32. package/dist/channels/email/mime.js +83 -0
  33. package/dist/channels/email/mime.js.map +1 -0
  34. package/dist/channels/email/multipart.d.ts +28 -0
  35. package/dist/channels/email/multipart.d.ts.map +1 -0
  36. package/dist/channels/email/multipart.js +102 -0
  37. package/dist/channels/email/multipart.js.map +1 -0
  38. package/dist/channels/email/providers.d.ts +49 -0
  39. package/dist/channels/email/providers.d.ts.map +1 -0
  40. package/dist/channels/email/providers.js +292 -0
  41. package/dist/channels/email/providers.js.map +1 -0
  42. package/dist/channels/email/reply.d.ts +9 -0
  43. package/dist/channels/email/reply.d.ts.map +1 -0
  44. package/dist/channels/email/reply.js +122 -0
  45. package/dist/channels/email/reply.js.map +1 -0
  46. package/dist/formatters/html.d.ts +16 -0
  47. package/dist/formatters/html.d.ts.map +1 -0
  48. package/dist/formatters/html.js +535 -0
  49. package/dist/formatters/html.js.map +1 -0
  50. package/dist/formatters/markdown.d.ts.map +1 -1
  51. package/dist/formatters/markdown.js +1 -0
  52. package/dist/formatters/markdown.js.map +1 -1
  53. package/dist/gateway.d.ts +23 -1
  54. package/dist/gateway.d.ts.map +1 -1
  55. package/dist/gateway.js +104 -14
  56. package/dist/gateway.js.map +1 -1
  57. package/dist/inbound-debounce.d.ts +4 -1
  58. package/dist/inbound-debounce.d.ts.map +1 -1
  59. package/dist/inbound-debounce.js +4 -2
  60. package/dist/inbound-debounce.js.map +1 -1
  61. package/dist/index.d.ts +3 -1
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +3 -1
  64. package/dist/index.js.map +1 -1
  65. package/dist/runtime-builder.d.ts +9 -0
  66. package/dist/runtime-builder.d.ts.map +1 -1
  67. package/dist/runtime-builder.js +110 -0
  68. package/dist/runtime-builder.js.map +1 -1
  69. package/package.json +25 -8
package/README.md CHANGED
@@ -16,6 +16,7 @@ pnpm add @slack/bolt # Slack
16
16
  pnpm add @whiskeysockets/baileys # WhatsApp, 6.x or 7.x (+ qrcode-terminal to print the pairing QR)
17
17
  pnpm add ws # WebChat
18
18
  pnpm add @atproto/api # Bluesky (Threads and GitHub need no SDK)
19
+ pnpm add nodemailer imapflow postal-mime # Email: SMTP, IMAP and MIME parsing (webhooks need nodemailer, plus postal-mime for raw MIME)
19
20
 
20
21
  # RuntimeBuilder (`cogitator up`)
21
22
  pnpm add better-sqlite3 # SQLite memory, knowledge graph and core facts (always needed)
@@ -244,17 +245,41 @@ const github = githubChannel({
244
245
 
245
246
  The agent answers new issues and pull requests, comments on them, reviews with a body and comments on lines of a diff, from a repository or organization webhook. Each issue or pull request is a conversation, `channelId` `owner/repo#number`, and answers are comments on it. A comment on a line is answered in its review thread, which is the message's `topicId`, so each review thread is a conversation of its own. Deliveries are answered at once and handled after, each once by its `X-GitHub-Delivery` and the comment it carries (remembered in memory). It answers only the repository's owner, members and collaborators unless `associations` or `authors` say otherwise, since what people write steers an agent that holds the token, so give the bot an account and a token of its own scoped to its repositories. The bot skips its own comments and other bots (`allowBots` lets them in), and by default answers only mentions of `@login`, outside code and quotes, plus the next comment of someone it answered and comments in review threads it replied in. Answers go out finished (GitHub notifies people of a comment's first text, `stream: true` edits a comment as it grows, at most every 3 seconds), as several comments past 65536 characters. Reactions use GitHub's eight. GitHub has no upload API for comments, so `sendFile` links a file with a public `url` and refuses a buffer. A GitHub App installation token cannot read `GET /user`: set `login` to `<app-slug>[bot]`. Docs: [GitHub](https://cogitator.app/docs/channels/github).
246
247
 
248
+ ### Email
249
+
250
+ ```typescript
251
+ import { emailChannel } from '@cogitator-ai/channels';
252
+
253
+ const email = emailChannel({
254
+ address: 'assistant@example.com', // sends from it, never answers it
255
+ allowFrom: ['example.com', 'ann@partner.org'], // default: nobody, with a warning
256
+ imap: {
257
+ host: 'imap.gmail.com',
258
+ auth: { user: 'assistant@example.com', pass: process.env.EMAIL_IMAP_PASSWORD! },
259
+ },
260
+ smtp: {
261
+ host: 'smtp.gmail.com',
262
+ port: 587,
263
+ auth: { user: 'assistant@example.com', pass: process.env.EMAIL_SMTP_PASSWORD! },
264
+ }, // or { transport } for any nodemailer transport
265
+ // or instead of imap, a provider's inbound webhook:
266
+ // webhook: { provider: 'mailgun', signingKey: process.env.EMAIL_MAILGUN_SIGNING_KEY!, port: 8788 },
267
+ });
268
+ ```
269
+
270
+ The agent answers mail in its thread. Mail comes from a mailbox over IMAP (IDLE reports new mail at once, a poll every minute catches the rest, a message is marked read once the Gateway took it, so a restart reads only new mail, a refused or dropped one stays or becomes unread again, mail over 25 MB is skipped, a dropped connection is opened again with a wait that doubles up to a minute) or from the inbound webhook of Mailgun (HMAC of timestamp and token, refused after 5 minutes and handled once), Postmark or SendGrid (neither signs, so the URL carries basic auth or a `token`), answered `503` when the Gateway does not take the mail, so the provider retries. Answers go out over SMTP with `nodemailer`, as HTML rendered from the Markdown with a plain text alternative, a `Re:` subject and `In-Reply-To` and `References` set, so mail clients keep the thread. A sender is a conversation partner: `channelId` and `userId` are the address in lower case, and `topicId` is the thread's first `Message-ID`, so each email thread is a conversation of its own. The agent reads the plain text part (or the HTML as text) without the quoted history and the signature, with the subject on a thread's first mail, and attachments up to 10 MB. Mail from the bot itself, mail with the `X-Cogitator` header it puts on what it sends, auto-replies, bounces and bulk mail are skipped, and each `Message-ID` is handled once. Email is spoofable: the bot answers only `allowFrom` and `owners` (the address outside the quotes of `From`), drops mail whose DKIM, SPF or DMARC results fail for the `From` domain (`senderAuth: 'required'` also drops mail without results), and gives owner mail to the agent only with a passing result. It trusts only results the receiving side wrote: Mailgun's and SendGrid's, Postmark's spam tests, and over IMAP the `Authentication-Results` of `trustedAuthservIds` (such as `mx.google.com`), without which IMAP mail has no sender authentication. Answers cannot be edited. Docs: [Email](https://cogitator.app/docs/channels/email).
271
+
247
272
  ## Platform Comparison
248
273
 
249
- | Feature | Telegram | Discord | Slack | WhatsApp | WebChat | Bluesky | Threads | GitHub |
250
- | ------------------ | ------------ | ------- | --------- | -------- | --------- | ------------------ | ------------------ | ------------------- |
251
- | Streaming (edit) | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ (sent finished) | ❌ (sent finished) | with `stream: true` |
252
- | Reactions | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ (8 kinds) |
253
- | Typing indicator | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
254
- | Photos → vision | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
255
- | Voice → STT | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
256
- | Max message length | 4096 | 2000 | 40000 | 65536 | unlimited | 300 per post | 500 per post | 65536 per comment |
257
- | Public URL needed | webhook only | no | HTTP only | no | no | no | webhooks only | yes (webhook) |
274
+ | Feature | Telegram | Discord | Slack | WhatsApp | WebChat | Bluesky | Threads | GitHub | Email |
275
+ | ------------------ | ------------ | ------- | --------- | -------- | --------- | ------------------ | ------------------ | ------------------- | ------------------ |
276
+ | Streaming (edit) | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ (sent finished) | ❌ (sent finished) | with `stream: true` | ❌ (sent finished) |
277
+ | Reactions | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ (8 kinds) | ❌ |
278
+ | Typing indicator | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
279
+ | Photos → vision | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ (attachments) |
280
+ | Voice → STT | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ (attachments) |
281
+ | Max message length | 4096 | 2000 | 40000 | 65536 | unlimited | 300 per post | 500 per post | 65536 per comment | unlimited |
282
+ | Public URL needed | webhook only | no | HTTP only | no | no | no | webhooks only | yes (webhook) | webhooks only |
258
283
 
259
284
  Outbound calls (`sendText`, `editText`, `sendFile`, `deleteMessage`) throw when the channel is not started, the target chat is unavailable or the platform rejects the request — wrap direct calls in `try/catch`. WebChat is the exception: only `sendText` throws for a disconnected client, the other calls are dropped. `sendText` returns the platform message id (for Discord, the id of the first chunk; continuation chunks are edited and deleted with it).
260
285
 
@@ -307,7 +332,7 @@ Docs: [Social Feeds](https://cogitator.app/docs/channels/feeds).
307
332
 
308
333
  Routes incoming messages to your agent. Handles:
309
334
 
310
- - Conversation threads: one per user per conversation (chat, forum topic, Slack thread, Bluesky or Threads post thread, GitHub issue, pull request or review thread), answered one message at a time
335
+ - Conversation threads: one per user per conversation (chat, forum topic, Slack thread, Bluesky or Threads post thread, GitHub issue, pull request or review thread, email thread), answered one message at a time
311
336
  - Session management (per-user, per-channel) with an optional custom `sessionManager`
312
337
  - History compaction, hierarchical into a handoff of grounded atoms or with LLM-written summaries
313
338
  - Streaming with `StreamBuffer` when `stream` is set (message editing, splits at the platform limit without losing text); without `stream` the full answer is sent once the run finishes
@@ -362,10 +387,11 @@ A thread is the conversation memory and the queue of one user in one conversatio
362
387
  | Discord | channel, a thread is a channel of its own | `discord:98765:1234` |
363
388
  | Bluesky, Threads | the post thread's root (`conversationId`), not the reply post | `bluesky:thread:at://did:plc:a/app.bsky.feed.post/1:did:plc:b` |
364
389
  | GitHub | issue or pull request, plus the review thread (`topicId`) | `github:acme/app#12:583231`, `github:acme/app#12:1840022:583231` |
390
+ | Email | sender, plus the email thread (`topicId`, its first `Message-ID`) | `email:ann@example.com:<a1@example.com>:ann@example.com` |
365
391
  | WhatsApp | chat, a chat addressed by LID by the phone-number jid | `whatsapp:15550001111@s.whatsapp.net:15550001111` |
366
392
  | WebChat | client | `webchat:c7f2:c7f2` |
367
393
 
368
- So a user keeps a separate thread in their private chat, in each group and in each topic, and every reply in a Bluesky or Threads post thread lands in the same one. In a Slack channel each top-level message is answered in a new Slack thread, a conversation of its own without the history of earlier ones, and its follow-ups in that thread continue it, while a DM is one conversation. On GitHub each issue or pull request is a conversation, and each review thread another one. A WhatsApp chat that reaches a person by LID gets their phone-number jid as its `conversationId` when WhatsApp shares it, so it stays one thread with the chat addressed by phone number.
394
+ So a user keeps a separate thread in their private chat, in each group and in each topic, and every reply in a Bluesky or Threads post thread lands in the same one. In a Slack channel each top-level message is answered in a new Slack thread, a conversation of its own without the history of earlier ones, and its follow-ups in that thread continue it, while a DM is one conversation. On GitHub each issue or pull request is a conversation, and each review thread another one. By email each thread is a conversation, however its subject changes. A WhatsApp chat that reaches a person by LID gets their phone-number jid as its `conversationId` when WhatsApp shares it, so it stays one thread with the chat addressed by phone number.
369
395
 
370
396
  The gateway keeps the conversations of each user in their session's metadata (`conversations`, up to 50, most recent first), and `compactAll()` finds their threads there after a restart. A run gets the `topicId` and `conversationId` of its message, and its tools see them in their context, so `schedule_task` stores them with the task and `HeartbeatScheduler` fires it into the same topic and thread, even when the user has moved on to another one. A task without them is answered in the topic and thread of the user's most recent conversation in its chat. With a custom `threadKey` the gateway keeps no conversations and leaves stored sessions out of `compactAll()`, except with `legacyThreadKey`, whose thread of each stored session it still finds.
371
397
 
@@ -689,7 +715,7 @@ session:
689
715
 
690
716
  For a parsed YAML file, validate it first with `new RuntimeBuilder(AssistantConfigSchema.parse(yamlObject), process.env)` (the schema is exported, along with the `AssistantConfigInput` / `AssistantConfigOutput` types).
691
717
 
692
- - **Channels:** the terminal REPL plus `channels.telegram` (`TG_TOKEN` or `TELEGRAM_TOKEN`), `channels.discord` (`DISCORD_TOKEN`) and `channels.slack` (`SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET`, optional `SLACK_APP_TOKEN` / `SLACK_PORT`). A configured channel without its token is skipped with a warning. `channels.whatsapp` (`{ ownerIds?, sessionPath? }`, owner ids are phone numbers without `@s.whatsapp.net`, the session defaults to `~/.cogitator/whatsapp-session`) needs `@whiskeysockets/baileys`. `channels.webchat` (`{ port?, path? }`, default `8080` and `/ws`, no `ownerIds`) needs `ws` and starts only with `WEBCHAT_TOKEN` set, and clients connect with `?token=<WEBCHAT_TOKEN>`. `channels.bluesky` (`{ ownerIds?, posts?, directMessages?, pollInterval?, tokenPath? }`, owner ids are DIDs) needs `@atproto/api` and starts with `BLUESKY_HANDLE` and `BLUESKY_APP_PASSWORD`. `channels.threads` (`{ ownerIds?, webhook?: { port, path? }, pollInterval?, tokenPath? }`, owner ids are usernames) starts with `THREADS_ACCESS_TOKEN`, and with `THREADS_APP_SECRET` and `THREADS_VERIFY_TOKEN` for webhooks. Both keep their session or token in `tokenPath` (default `~/.cogitator/tokens.json`). `channels.github` (`{ ownerIds?, webhook?: { port?, path? }, trigger?, repositories?, associations?, authors?, login?, allowBots?, stream? }`, owner ids are numeric user ids, the webhook server defaults to port `8787` at `/github/webhook`) starts with `GITHUB_CHANNEL_TOKEN` (falling back to `GITHUB_TOKEN` with a warning) and `GITHUB_WEBHOOK_SECRET`, and calls `GITHUB_API_URL` when set (GitHub Enterprise Server).
718
+ - **Channels:** the terminal REPL plus `channels.telegram` (`TG_TOKEN` or `TELEGRAM_TOKEN`), `channels.discord` (`DISCORD_TOKEN`) and `channels.slack` (`SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET`, optional `SLACK_APP_TOKEN` / `SLACK_PORT`). A configured channel without its token is skipped with a warning. `channels.whatsapp` (`{ ownerIds?, sessionPath? }`, owner ids are phone numbers without `@s.whatsapp.net`, the session defaults to `~/.cogitator/whatsapp-session`) needs `@whiskeysockets/baileys`. `channels.webchat` (`{ port?, path? }`, default `8080` and `/ws`, no `ownerIds`) needs `ws` and starts only with `WEBCHAT_TOKEN` set, and clients connect with `?token=<WEBCHAT_TOKEN>`. `channels.bluesky` (`{ ownerIds?, posts?, directMessages?, pollInterval?, tokenPath? }`, owner ids are DIDs) needs `@atproto/api` and starts with `BLUESKY_HANDLE` and `BLUESKY_APP_PASSWORD`. `channels.threads` (`{ ownerIds?, webhook?: { port, path? }, pollInterval?, tokenPath? }`, owner ids are usernames) starts with `THREADS_ACCESS_TOKEN`, and with `THREADS_APP_SECRET` and `THREADS_VERIFY_TOKEN` for webhooks. Both keep their session or token in `tokenPath` (default `~/.cogitator/tokens.json`). `channels.github` (`{ ownerIds?, webhook?: { port?, path? }, trigger?, repositories?, associations?, authors?, login?, allowBots?, stream? }`, owner ids are numeric user ids, the webhook server defaults to port `8787` at `/github/webhook`) starts with `GITHUB_CHANNEL_TOKEN` (falling back to `GITHUB_TOKEN` with a warning) and `GITHUB_WEBHOOK_SECRET`, and calls `GITHUB_API_URL` when set (GitHub Enterprise Server). `channels.email` (`{ ownerIds?, address?, name?, aliases?, allowFrom?, senderAuth?, trustedAuthservIds?, subject?, imap?: { host?, port?, secure?, mailbox?, pollInterval?, lookbackDays? }, smtp?: { host?, port?, secure? }, webhook?: { provider, port?, path? } }`, owner ids are addresses, allowed and given owner rights with a passing sender authentication, the webhook server defaults to port `8788` at `/email/webhook`) needs `nodemailer`, plus `imapflow` and `postal-mime` for IMAP. It takes the address, hosts and ports from the file or `EMAIL_ADDRESS`, `EMAIL_IMAP_HOST`, `EMAIL_IMAP_PORT`, `EMAIL_SMTP_HOST` and `EMAIL_SMTP_PORT`, the passwords from `EMAIL_IMAP_PASSWORD` and `EMAIL_SMTP_PASSWORD` (users `EMAIL_IMAP_USER` and `EMAIL_SMTP_USER`, default the address), and reads over IMAP when `imap` is set or `EMAIL_IMAP_HOST` is. A Mailgun webhook needs `EMAIL_MAILGUN_SIGNING_KEY`, Postmark and SendGrid `EMAIL_WEBHOOK_TOKEN` (`?token=` in the URL) or `EMAIL_WEBHOOK_USER` and `EMAIL_WEBHOOK_PASSWORD` (basic auth).
693
719
 
694
720
  - **Memory:** `memory.adapter: sqlite` (default, `memory.path`, default `~/.cogitator/memory.db`) or `postgres` (`memory.connectionString`, `DATABASE_URL` or `POSTGRES_URL`, requires `pg`). Core facts always live in the SQLite file, as memory items with their history. The knowledge graph (`memory.knowledgeGraph`) and auto-extraction (`memory.autoExtract`) are on by default, and the memory tools keep memory items in the memory store too: `remember` keeps a fact as the user's (an `active` item, a core fact) only when its `quote` is in one of the run user's own messages on the thread's active branch, else as a suggestion, `recall` searches the items of the user and the thread, and `forget` lets go only the run's own that hold the query as whole words (a run without a user keeps its facts in the thread's memory). The assistant's agent id is its `name`, the same across restarts. `memory.compaction.threshold` enables history compaction, hierarchical, keeping about 4000 tokens of the newest turns verbatim.
695
721
  - **Fresh context:** the gateway builds an agent per message: instructions (with known user facts) and the `/model` override are resolved each time. The current date and time go to each run as its `brief`, with the input, so they do not change the instructions and their prompt cache. `runtime.agent` is the base agent.
@@ -739,6 +765,21 @@ GITHUB_TOKEN=ghp_... # capabilities.github, and the channel's fallba
739
765
  GITHUB_WEBHOOK_SECRET=... # the secret set on the webhook
740
766
  GITHUB_API_URL=... # GitHub Enterprise Server only, https://<host>/api/v3
741
767
 
768
+ # Email (channels.email, hosts and ports may be in cogitator.yml instead)
769
+ EMAIL_ADDRESS=assistant@example.com
770
+ EMAIL_IMAP_HOST=imap.gmail.com # reading over IMAP
771
+ EMAIL_IMAP_PORT=993
772
+ EMAIL_IMAP_USER=... # default EMAIL_ADDRESS
773
+ EMAIL_IMAP_PASSWORD=... # an app password for Gmail and Outlook
774
+ EMAIL_SMTP_HOST=smtp.gmail.com
775
+ EMAIL_SMTP_PORT=587 # 465 for TLS from the start
776
+ EMAIL_SMTP_USER=... # default EMAIL_ADDRESS
777
+ EMAIL_SMTP_PASSWORD=...
778
+ EMAIL_MAILGUN_SIGNING_KEY=... # webhook.provider: mailgun
779
+ EMAIL_WEBHOOK_TOKEN=... # webhook.provider: postmark or sendgrid, ?token= in the URL
780
+ EMAIL_WEBHOOK_USER=... # or basic auth in the URL, https://user:password@host/email/webhook
781
+ EMAIL_WEBHOOK_PASSWORD=...
782
+
742
783
  # STT (optional, for voice messages — pick one)
743
784
  DEEPGRAM_API_KEY=... # highest priority
744
785
  GROQ_API_KEY=... # free tier
@@ -1,4 +1,8 @@
1
1
  import { z } from 'zod';
2
+ /** An email address, as `channels.email` takes them */
3
+ export declare const EMAIL_ADDRESS_PATTERN: RegExp;
4
+ /** An entry of `channels.email.allowFrom`: an address, a domain, `*.domain`, `@domain` or `*` */
5
+ export declare const EMAIL_ALLOW_FROM_PATTERN: RegExp;
2
6
  export declare const AssistantConfigSchema: z.ZodObject<{
3
7
  name: z.ZodString;
4
8
  personality: z.ZodString;
@@ -71,6 +75,42 @@ export declare const AssistantConfigSchema: z.ZodObject<{
71
75
  allowBots: z.ZodOptional<z.ZodBoolean>;
72
76
  stream: z.ZodOptional<z.ZodBoolean>;
73
77
  }, z.core.$strip>>;
78
+ email: z.ZodOptional<z.ZodObject<{
79
+ ownerIds: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
80
+ address: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
81
+ name: z.ZodOptional<z.ZodString>;
82
+ aliases: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>>;
83
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodString>>;
84
+ senderAuth: z.ZodOptional<z.ZodEnum<{
85
+ required: "required";
86
+ "when-reported": "when-reported";
87
+ off: "off";
88
+ }>>;
89
+ trustedAuthservIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
90
+ subject: z.ZodOptional<z.ZodString>;
91
+ imap: z.ZodOptional<z.ZodObject<{
92
+ host: z.ZodOptional<z.ZodString>;
93
+ port: z.ZodOptional<z.ZodNumber>;
94
+ secure: z.ZodOptional<z.ZodBoolean>;
95
+ mailbox: z.ZodOptional<z.ZodString>;
96
+ pollInterval: z.ZodOptional<z.ZodNumber>;
97
+ lookbackDays: z.ZodOptional<z.ZodNumber>;
98
+ }, z.core.$strip>>;
99
+ smtp: z.ZodOptional<z.ZodObject<{
100
+ host: z.ZodOptional<z.ZodString>;
101
+ port: z.ZodOptional<z.ZodNumber>;
102
+ secure: z.ZodOptional<z.ZodBoolean>;
103
+ }, z.core.$strip>>;
104
+ webhook: z.ZodOptional<z.ZodObject<{
105
+ provider: z.ZodEnum<{
106
+ mailgun: "mailgun";
107
+ postmark: "postmark";
108
+ sendgrid: "sendgrid";
109
+ }>;
110
+ port: z.ZodDefault<z.ZodNumber>;
111
+ path: z.ZodOptional<z.ZodString>;
112
+ }, z.core.$strip>>;
113
+ }, z.core.$strip>>;
74
114
  }, z.core.$strip>>>;
75
115
  capabilities: z.ZodDefault<z.ZodOptional<z.ZodObject<{
76
116
  webSearch: z.ZodOptional<z.ZodBoolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-config.d.ts","sourceRoot":"","sources":["../src/assistant-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqLxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BhC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
1
+ {"version":3,"file":"assistant-config.d.ts","sourceRoot":"","sources":["../src/assistant-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB,uDAAuD;AACvD,eAAO,MAAM,qBAAqB,QAA4C,CAAC;AAE/E,iGAAiG;AACjG,eAAO,MAAM,wBAAwB,QACwC,CAAC;AA4O9E,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BhC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -10,6 +10,15 @@ const McpServerSchema = z.object({
10
10
  requiresApproval: z.boolean().optional(),
11
11
  });
12
12
  const OwnerIdsSchema = z.array(z.string()).optional();
13
+ /** An email address, as `channels.email` takes them */
14
+ export const EMAIL_ADDRESS_PATTERN = /^[^\s@<>]+@[^\s@<>.]+(?:\.[^\s@<>.]+)+$/;
15
+ /** An entry of `channels.email.allowFrom`: an address, a domain, `*.domain`, `@domain` or `*` */
16
+ export const EMAIL_ALLOW_FROM_PATTERN = /^(\*|(\*\.|@)?[^\s@*.]+(?:\.[^\s@*.]+)+|[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+)$/;
17
+ const EmailAddressSchema = z
18
+ .string()
19
+ .trim()
20
+ .regex(EMAIL_ADDRESS_PATTERN, 'Not an email address')
21
+ .transform((address) => address.toLowerCase());
13
22
  const AssistantChannelsSchema = z.object({
14
23
  telegram: z.object({ ownerIds: OwnerIdsSchema }).optional(),
15
24
  discord: z.object({ ownerIds: OwnerIdsSchema }).optional(),
@@ -98,6 +107,63 @@ const AssistantChannelsSchema = z.object({
98
107
  stream: z.boolean().optional(),
99
108
  })
100
109
  .optional(),
110
+ email: z
111
+ .object({
112
+ /**
113
+ * Owner addresses, also answered whatever `allowFrom` says, but only when their sender
114
+ * authentication passes (unless `senderAuth` is `off`), since a `From` can be forged
115
+ */
116
+ ownerIds: z.array(EmailAddressSchema).optional(),
117
+ /** The bot's address (default `EMAIL_ADDRESS` from the env) */
118
+ address: EmailAddressSchema.optional(),
119
+ /** The display name of the mail it sends */
120
+ name: z.string().optional(),
121
+ /** Other addresses of the bot, never answered */
122
+ aliases: z.array(EmailAddressSchema).optional(),
123
+ /** Who it answers: addresses, domains, `*.domain` or `*` (default nobody but the owners) */
124
+ allowFrom: z
125
+ .array(z
126
+ .string()
127
+ .regex(EMAIL_ALLOW_FROM_PATTERN, 'An allowFrom entry is an address, a domain, *.domain or *'))
128
+ .optional(),
129
+ /** `when-reported` (default), `required` or `off`: how DKIM, SPF and DMARC results are used */
130
+ senderAuth: z.enum(['required', 'when-reported', 'off']).optional(),
131
+ /** The authserv-ids whose Authentication-Results count (default the topmost header) */
132
+ trustedAuthservIds: z.array(z.string()).optional(),
133
+ /** The subject of mail that starts a conversation */
134
+ subject: z.string().optional(),
135
+ /** Read mail over IMAP, host, port, user and password may also come from EMAIL_IMAP_* */
136
+ imap: z
137
+ .object({
138
+ host: z.string().optional(),
139
+ port: z.number().int().positive().optional(),
140
+ secure: z.boolean().optional(),
141
+ mailbox: z.string().optional(),
142
+ pollInterval: z.number().int().positive().optional(),
143
+ lookbackDays: z.number().positive().optional(),
144
+ })
145
+ .optional(),
146
+ /** Send over SMTP, host, port, user and password may also come from EMAIL_SMTP_* */
147
+ smtp: z
148
+ .object({
149
+ host: z.string().optional(),
150
+ port: z.number().int().positive().optional(),
151
+ secure: z.boolean().optional(),
152
+ })
153
+ .optional(),
154
+ /** Take mail from a provider's inbound webhook, on its own server (default port 8788) */
155
+ webhook: z
156
+ .object({
157
+ provider: z.enum(['mailgun', 'postmark', 'sendgrid']),
158
+ port: z.number().int().positive().default(8788),
159
+ path: z
160
+ .string()
161
+ .regex(/^\//, 'The webhook path starts with /, such as /email/webhook')
162
+ .optional(),
163
+ })
164
+ .optional(),
165
+ })
166
+ .optional(),
101
167
  });
102
168
  const ApprovalsSchema = z
103
169
  .object({
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-config.js","sourceRoot":"","sources":["../src/assistant-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assistant-config.js","sourceRoot":"","sources":["../src/assistant-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /** A mailbox of an address header: the address and the display name, if any. */
2
+ export interface EmailMailbox {
3
+ address: string;
4
+ name?: string;
5
+ }
6
+ /** Headers of a message by lower-case name, in their order, duplicates kept. */
7
+ export type EmailHeaders = readonly (readonly [name: string, value: string])[];
8
+ /** An address in the form the channel keys senders by: trimmed and in lower case. */
9
+ export declare function normalizeAddress(address: string): string;
10
+ /** Whether `text` is a plain address, `local@domain.tld`. */
11
+ export declare function isAddress(text: string): boolean;
12
+ /** The domain of an address, in lower case. */
13
+ export declare function domainOf(address: string): string;
14
+ /** Header text with its RFC 2047 encoded words (`=?utf-8?B?...?=`, `=?utf-8?Q?...?=`) decoded. */
15
+ export declare function decodeMimeWords(text: string): string;
16
+ /**
17
+ * The first mailbox of an address header such as `From`: `"Ann Lee" <ann@example.com>`,
18
+ * `Ann <ann@example.com>` or `ann@example.com (Ann)`, with encoded words in the name decoded.
19
+ * The address is the angle address outside quoted strings and comments, so a display name that
20
+ * holds another address cannot pass for it.
21
+ */
22
+ export declare function parseMailbox(value: string | undefined): EmailMailbox | undefined;
23
+ /** The message ids (`<id@host>`) of a `Message-ID`, `In-Reply-To` or `References` header. */
24
+ export declare function messageIdsOf(value: string | undefined): string[];
25
+ /** The first message id of a header, if it has one. */
26
+ export declare function messageIdOf(value: string | undefined): string | undefined;
27
+ /** A header block (`Name: value` lines, folded lines continuing with whitespace) as headers. */
28
+ export declare function parseHeaderBlock(block: string): EmailHeaders;
29
+ /** The first value of a header, by its name in any letter case. */
30
+ export declare function headerOf(headers: EmailHeaders, name: string): string | undefined;
31
+ /** Every value of a header, top to bottom, by its name in any letter case. */
32
+ export declare function headersOf(headers: EmailHeaders, name: string): string[];
33
+ /**
34
+ * Whether `domain` is aligned with the author's domain `fromDomain` in the relaxed DMARC sense:
35
+ * the same domain, or one a subdomain of the other.
36
+ */
37
+ export declare function alignedDomains(domain: string, fromDomain: string): boolean;
38
+ /**
39
+ * Whether an allow list lets `address` in. Entries are addresses (`ann@example.com`), domains
40
+ * (`example.com` or `@example.com`, without subdomains), subdomain wildcards (`*.example.com`)
41
+ * or `*` for everyone, in any letter case.
42
+ */
43
+ export declare function allowsSender(list: readonly string[], address: string): boolean;
44
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../../src/channels/email/address.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,gFAAgF;AAChF,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;AAI/E,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,6DAA6D;AAC7D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGhD;AAUD,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoBpD;AAwED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAYhF;AAED,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAMhE;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEzE;AAED,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAc5D;AAED,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhF;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAGvE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAK1E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAU9E"}
@@ -0,0 +1,211 @@
1
+ const ADDRESS = /^[^\s@<>()",;:]+@[^\s@<>()",;:.]+(?:\.[^\s@<>()",;:.]+)+$/;
2
+ /** An address in the form the channel keys senders by: trimmed and in lower case. */
3
+ export function normalizeAddress(address) {
4
+ return address.trim().replace(/^<|>$/g, '').toLowerCase();
5
+ }
6
+ /** Whether `text` is a plain address, `local@domain.tld`. */
7
+ export function isAddress(text) {
8
+ return ADDRESS.test(text);
9
+ }
10
+ /** The domain of an address, in lower case. */
11
+ export function domainOf(address) {
12
+ const at = address.lastIndexOf('@');
13
+ return at === -1 ? '' : address.slice(at + 1).toLowerCase();
14
+ }
15
+ function decodeBytes(bytes, charset) {
16
+ try {
17
+ return new TextDecoder(charset.toLowerCase()).decode(bytes);
18
+ }
19
+ catch {
20
+ return new TextDecoder('utf-8').decode(bytes);
21
+ }
22
+ }
23
+ /** Header text with its RFC 2047 encoded words (`=?utf-8?B?...?=`, `=?utf-8?Q?...?=`) decoded. */
24
+ export function decodeMimeWords(text) {
25
+ return text
26
+ .replace(/(=\?[^?\s]+\?[bq]\?[^?\s]*\?=)\s+(?==\?[^?\s]+\?[bq]\?)/gi, '$1')
27
+ .replace(/=\?([^?\s*]+)(?:\*[^?\s]*)?\?([bq])\?([^?\s]*)\?=/gi, (word, charset, encoding, data) => {
28
+ if (encoding.toLowerCase() === 'b') {
29
+ return decodeBytes(Buffer.from(data, 'base64'), charset);
30
+ }
31
+ const bytes = [];
32
+ const text = data.replace(/_/g, ' ');
33
+ for (let i = 0; i < text.length; i++) {
34
+ if (text[i] === '=' && /^[0-9a-f]{2}$/i.test(text.slice(i + 1, i + 3))) {
35
+ bytes.push(parseInt(text.slice(i + 1, i + 3), 16));
36
+ i += 2;
37
+ }
38
+ else
39
+ bytes.push(text.charCodeAt(i) & 0xff);
40
+ }
41
+ return bytes.length ? decodeBytes(Uint8Array.from(bytes), charset) : word;
42
+ });
43
+ }
44
+ /**
45
+ * Splits the first mailbox of an address header (RFC 5322) in one pass: quoted strings and
46
+ * comments are taken as text, so an address written inside them (`"x <ceo@victim.com>"`) is
47
+ * part of the name and never the address. The mailbox ends at the first comma outside them.
48
+ */
49
+ function mailboxParts(text) {
50
+ let phrase = '';
51
+ let bare = '';
52
+ let comment;
53
+ let angle;
54
+ let quoted = false;
55
+ let depth = 0;
56
+ let currentComment = '';
57
+ let inAngle = false;
58
+ let angleText = '';
59
+ for (let i = 0; i < text.length; i++) {
60
+ const char = text[i];
61
+ if (quoted) {
62
+ if (char === '\\' && i + 1 < text.length)
63
+ phrase += text[++i];
64
+ else if (char === '"')
65
+ quoted = false;
66
+ else
67
+ phrase += char;
68
+ continue;
69
+ }
70
+ if (depth > 0) {
71
+ if (char === '\\' && i + 1 < text.length)
72
+ currentComment += text[++i];
73
+ else if (char === '(') {
74
+ depth++;
75
+ currentComment += char;
76
+ }
77
+ else if (char === ')') {
78
+ depth--;
79
+ if (depth === 0)
80
+ comment ??= currentComment.trim();
81
+ else
82
+ currentComment += char;
83
+ }
84
+ else
85
+ currentComment += char;
86
+ continue;
87
+ }
88
+ if (inAngle) {
89
+ if (char === '>') {
90
+ inAngle = false;
91
+ angle = angleText.trim();
92
+ }
93
+ else
94
+ angleText += char;
95
+ continue;
96
+ }
97
+ if (char === '"')
98
+ quoted = true;
99
+ else if (char === '(') {
100
+ depth = 1;
101
+ currentComment = '';
102
+ }
103
+ else if (char === '<') {
104
+ inAngle = true;
105
+ angleText = '';
106
+ }
107
+ else if (char === ',')
108
+ break;
109
+ else {
110
+ if (angle === undefined)
111
+ phrase += char;
112
+ bare += char;
113
+ }
114
+ }
115
+ return { ...(angle !== undefined && { angle }), phrase, bare, ...(comment && { comment }) };
116
+ }
117
+ /**
118
+ * The first mailbox of an address header such as `From`: `"Ann Lee" <ann@example.com>`,
119
+ * `Ann <ann@example.com>` or `ann@example.com (Ann)`, with encoded words in the name decoded.
120
+ * The address is the angle address outside quoted strings and comments, so a display name that
121
+ * holds another address cannot pass for it.
122
+ */
123
+ export function parseMailbox(value) {
124
+ if (!value)
125
+ return undefined;
126
+ const parts = mailboxParts(value.replace(/\r?\n[ \t]+/g, ' ').trim());
127
+ if (parts.angle !== undefined) {
128
+ const address = normalizeAddress(parts.angle);
129
+ if (!isAddress(address))
130
+ return undefined;
131
+ const name = decodeMimeWords(parts.phrase.replace(/\s+/g, ' ').trim()).trim();
132
+ return name ? { address, name } : { address };
133
+ }
134
+ const address = normalizeAddress(parts.bare.trim());
135
+ if (!isAddress(address))
136
+ return undefined;
137
+ return parts.comment ? { address, name: decodeMimeWords(parts.comment) } : { address };
138
+ }
139
+ /** The message ids (`<id@host>`) of a `Message-ID`, `In-Reply-To` or `References` header. */
140
+ export function messageIdsOf(value) {
141
+ if (!value)
142
+ return [];
143
+ const ids = value.match(/<[^<>\s]+>/g);
144
+ if (ids)
145
+ return ids;
146
+ const bare = value.trim();
147
+ return bare && !/\s/.test(bare) ? [`<${bare.replace(/^<|>$/g, '')}>`] : [];
148
+ }
149
+ /** The first message id of a header, if it has one. */
150
+ export function messageIdOf(value) {
151
+ return messageIdsOf(value)[0];
152
+ }
153
+ /** A header block (`Name: value` lines, folded lines continuing with whitespace) as headers. */
154
+ export function parseHeaderBlock(block) {
155
+ const headers = [];
156
+ for (const line of block.replace(/\r\n?/g, '\n').split('\n')) {
157
+ if (!line)
158
+ break;
159
+ if (/^[ \t]/.test(line) && headers.length > 0) {
160
+ const last = headers[headers.length - 1];
161
+ last[1] = `${last[1]} ${line.trim()}`;
162
+ continue;
163
+ }
164
+ const colon = line.indexOf(':');
165
+ if (colon <= 0)
166
+ continue;
167
+ headers.push([line.slice(0, colon).trim().toLowerCase(), line.slice(colon + 1).trim()]);
168
+ }
169
+ return headers;
170
+ }
171
+ /** The first value of a header, by its name in any letter case. */
172
+ export function headerOf(headers, name) {
173
+ const wanted = name.toLowerCase();
174
+ return headers.find(([key]) => key === wanted)?.[1];
175
+ }
176
+ /** Every value of a header, top to bottom, by its name in any letter case. */
177
+ export function headersOf(headers, name) {
178
+ const wanted = name.toLowerCase();
179
+ return headers.filter(([key]) => key === wanted).map(([, value]) => value);
180
+ }
181
+ /**
182
+ * Whether `domain` is aligned with the author's domain `fromDomain` in the relaxed DMARC sense:
183
+ * the same domain, or one a subdomain of the other.
184
+ */
185
+ export function alignedDomains(domain, fromDomain) {
186
+ const a = domain.toLowerCase().replace(/\.$/, '');
187
+ const b = fromDomain.toLowerCase().replace(/\.$/, '');
188
+ if (!a || !b)
189
+ return false;
190
+ return a === b || a.endsWith(`.${b}`) || b.endsWith(`.${a}`);
191
+ }
192
+ /**
193
+ * Whether an allow list lets `address` in. Entries are addresses (`ann@example.com`), domains
194
+ * (`example.com` or `@example.com`, without subdomains), subdomain wildcards (`*.example.com`)
195
+ * or `*` for everyone, in any letter case.
196
+ */
197
+ export function allowsSender(list, address) {
198
+ const sender = normalizeAddress(address);
199
+ const domain = domainOf(sender);
200
+ return list.some((raw) => {
201
+ const entry = raw.trim().toLowerCase();
202
+ if (entry === '*')
203
+ return true;
204
+ if (entry.startsWith('*.'))
205
+ return domain.endsWith(entry.slice(1));
206
+ if (entry.includes('@') && !entry.startsWith('@'))
207
+ return entry === sender;
208
+ return entry.replace(/^@/, '') === domain;
209
+ });
210
+ }
211
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../../../src/channels/email/address.ts"],"names":[],"mappings":"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"}