@desplega.ai/agent-swarm 1.152.0 → 1.152.1

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 (66) hide show
  1. package/README.md +2 -0
  2. package/dist/{acp-adapter-d05sg0q4.js → acp-adapter-4s7q25ft.js} +1 -1
  3. package/dist/{actions-4sc0v342.js → actions-cs6rhmvc.js} +12 -12
  4. package/dist/{app-2d0v6kt6.js → app-j54aq0dj.js} +3 -3
  5. package/dist/{assistant-zs6wdnrf.js → assistant-w1pgn7vf.js} +13 -13
  6. package/dist/{boot-reembed-vhh33520.js → boot-reembed-42vgkrrj.js} +4 -4
  7. package/dist/{boot-reembed-3dwdnnsr.js → boot-reembed-smy30z32.js} +3 -3
  8. package/dist/{boot-scrub-logs-e1fnabcg.js → boot-scrub-logs-b6s72fsw.js} +2 -2
  9. package/dist/{claude-adapter-h58xqzzd.js → claude-adapter-fh7rmcj9.js} +3 -3
  10. package/dist/{claude-sdk-session-pbaczbgt.js → claude-sdk-session-xhynatn9.js} +3 -3
  11. package/dist/{cli-wp7cejrg.js → cli-3g61md6v.js} +1 -1
  12. package/dist/{cli-4fqn2vpg.js → cli-3pft2z6r.js} +4 -4
  13. package/dist/{cli-72vksk1n.js → cli-72tgtzr1.js} +18 -18
  14. package/dist/{cli-zdcdh02m.js → cli-7bwaerjt.js} +1 -1
  15. package/dist/{cli-awb59f08.js → cli-b4dyetqt.js} +2 -2
  16. package/dist/{cli-gacq5hg8.js → cli-bdt7w021.js} +1 -1
  17. package/dist/{cli-p2hx1pxm.js → cli-dsyg66vt.js} +3 -3
  18. package/dist/{cli-t1mykkng.js → cli-ftdjz1mk.js} +8 -8
  19. package/dist/{cli-jh9txj4n.js → cli-gfez0qmk.js} +1 -1
  20. package/dist/{cli-nd5s3m4y.js → cli-gxf2ebyz.js} +2 -2
  21. package/dist/{cli-evgy5w3y.js → cli-jtvs5m8q.js} +1 -1
  22. package/dist/{cli-t6axtdcg.js → cli-jytf5mw9.js} +1 -1
  23. package/dist/{cli-5bqt4gwa.js → cli-kf8qp2vf.js} +2 -2
  24. package/dist/{cli-6k2athpf.js → cli-ks8a1cgq.js} +2 -2
  25. package/dist/{cli-5p007m2q.js → cli-ng4q6a9t.js} +5 -5
  26. package/dist/{cli-8fy9dmpv.js → cli-sakxd2rg.js} +2 -2
  27. package/dist/{cli-f1f9n77e.js → cli-sqmh7jj1.js} +1 -1
  28. package/dist/{cli-87hdfyde.js → cli-v9sk4dzw.js} +1 -1
  29. package/dist/{cli-cs9z1hw3.js → cli-vbk025fm.js} +1 -1
  30. package/dist/{cli-cwvey7n1.js → cli-wfve107r.js} +8 -8
  31. package/dist/{cli-fhdssm2v.js → cli-y8tayczk.js} +2 -2
  32. package/dist/cli.js +11 -11
  33. package/dist/{codex-adapter-v3cz462q.js → codex-adapter-k6yq95sn.js} +2 -2
  34. package/dist/{codex-session-runner-de1a5g5z.js → codex-session-runner-3rp84pk8.js} +2 -2
  35. package/dist/{commands-wfqqpn95.js → commands-pbr5jzy5.js} +2 -2
  36. package/dist/{db-9zzv5y05.js → db-z0xaa59a.js} +2 -2
  37. package/dist/{dispatcher-hfm1jbgx.js → dispatcher-pwpgsj0x.js} +11 -11
  38. package/dist/{handlers-wrrhsack.js → handlers-5mzk4mbg.js} +14 -14
  39. package/dist/{hook-9skye8zd.js → hook-8bz33zee.js} +1 -1
  40. package/dist/{hook-fgjv62k5.js → hook-kbh84zb1.js} +2 -2
  41. package/dist/{http-7grttjfq.js → http-pppxg5vr.js} +90 -29
  42. package/dist/{index-30pz2h9w.js → index-68bd9b5f.js} +11 -11
  43. package/dist/{index-myfwqqyq.js → index-k1hq1qt6.js} +7 -7
  44. package/dist/{index-4ek1df87.js → index-mjpxsr6k.js} +12 -12
  45. package/dist/{index-pfhzrh1d.js → index-y0te09pn.js} +3 -3
  46. package/dist/{index-29gxx9ar.js → index-z0zwjtkn.js} +11 -11
  47. package/dist/{keepalive-j75m2m7k.js → keepalive-xvmwnh1d.js} +4 -4
  48. package/dist/{lead-a1hpjt0a.js → lead-pf8nvxt8.js} +15 -15
  49. package/dist/{maintenance-tngjzqdq.js → maintenance-jk4q0wgg.js} +4 -4
  50. package/dist/{oauth-refresh-sweep-em1fn044.js → oauth-refresh-sweep-6207x9sj.js} +3 -3
  51. package/dist/{onboard-fv7ezvwx.js → onboard-b0csgm0q.js} +2 -2
  52. package/dist/{otel-impl-6vbb568y.js → otel-impl-b6rfehth.js} +1 -1
  53. package/dist/{pricing-refresh-nmm949an.js → pricing-refresh-4e201wtd.js} +4 -4
  54. package/dist/{rbac-roles-0fz5qryx.js → rbac-roles-mkc5n5qa.js} +3 -3
  55. package/dist/{rbac-roles-xtp05syf.js → rbac-roles-zp6e4geh.js} +2 -2
  56. package/dist/{render-v2-fpb8whme.js → render-v2-4fazz9tf.js} +3 -3
  57. package/dist/{seed-pricing-zwa8bs3t.js → seed-pricing-thxpn9vn.js} +3 -3
  58. package/dist/{setup-3ybwbdpd.js → setup-wb0z8cat.js} +2 -2
  59. package/dist/{work-objects-rmayxcx7.js → work-objects-h3498kwe.js} +14 -14
  60. package/dist/{worker-rng4jhnh.js → worker-2m2tzxp3.js} +15 -15
  61. package/openapi.json +2 -2
  62. package/package.json +1 -1
  63. package/src/agentmail/inbound-archive.ts +71 -0
  64. package/src/agentmail/types.ts +2 -0
  65. package/src/http/webhooks.ts +13 -5
  66. package/src/tests/agentmail-inbound-archive.test.ts +418 -0
@@ -3,7 +3,7 @@ import {
3
3
  createDefaultMcpJson,
4
4
  createDefaultSettingsLocal,
5
5
  createHooksConfig
6
- } from "./cli-wp7cejrg.js";
6
+ } from "./cli-3g61md6v.js";
7
7
  import {
8
8
  require_jsx_dev_runtime
9
9
  } from "./cli-s2qjdd6z.js";
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  init_package,
15
15
  package_default
16
- } from "./cli-jh9txj4n.js";
16
+ } from "./cli-gfez0qmk.js";
17
17
  import {
18
18
  Box_default,
19
19
  Select,
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  init_package,
6
6
  package_default
7
- } from "./cli-jh9txj4n.js";
7
+ } from "./cli-gfez0qmk.js";
8
8
  import {
9
9
  init_secret_scrubber,
10
10
  scrubSecrets
@@ -2,9 +2,9 @@ import {
2
2
  PRICING_REFRESH_INTERVAL_MS,
3
3
  refreshPricingFromModelsDev,
4
4
  startPricingRefreshLoop
5
- } from "./cli-5bqt4gwa.js";
6
- import"./cli-zdcdh02m.js";
7
- import"./cli-gacq5hg8.js";
5
+ } from "./cli-kf8qp2vf.js";
6
+ import"./cli-7bwaerjt.js";
7
+ import"./cli-bdt7w021.js";
8
8
  import"./cli-ht5rs63n.js";
9
9
  import"./cli-z61ykvam.js";
10
10
  import"./cli-dv6cdjs2.js";
@@ -12,7 +12,7 @@ import"./cli-c2mk1kgf.js";
12
12
  import"./cli-ej6gbxfb.js";
13
13
  import"./cli-sd0mxa3c.js";
14
14
  import"./cli-w5e1d1vv.js";
15
- import"./cli-jh9txj4n.js";
15
+ import"./cli-gfez0qmk.js";
16
16
  import"./cli-r2ap2czm.js";
17
17
  import"./cli-zf8jjwex.js";
18
18
  import"./cli-bc05qbss.js";
@@ -7,9 +7,9 @@ import {
7
7
  getUserGrant,
8
8
  listUserRoles,
9
9
  runRbacCliCommand
10
- } from "./cli-t6axtdcg.js";
10
+ } from "./cli-jytf5mw9.js";
11
11
  import"./cli-zfzznn7c.js";
12
- import"./cli-gacq5hg8.js";
12
+ import"./cli-bdt7w021.js";
13
13
  import"./cli-ht5rs63n.js";
14
14
  import"./cli-z61ykvam.js";
15
15
  import"./cli-dv6cdjs2.js";
@@ -17,7 +17,7 @@ import"./cli-c2mk1kgf.js";
17
17
  import"./cli-ej6gbxfb.js";
18
18
  import"./cli-sd0mxa3c.js";
19
19
  import"./cli-w5e1d1vv.js";
20
- import"./cli-jh9txj4n.js";
20
+ import"./cli-gfez0qmk.js";
21
21
  import"./cli-r2ap2czm.js";
22
22
  import"./cli-zf8jjwex.js";
23
23
  import"./cli-bc05qbss.js";
@@ -5,7 +5,7 @@ import {
5
5
  getDb,
6
6
  getDbClient,
7
7
  init_db
8
- } from "./cli-gacq5hg8.js";
8
+ } from "./cli-bdt7w021.js";
9
9
  import"./cli-ht5rs63n.js";
10
10
  import"./cli-z61ykvam.js";
11
11
  import"./cli-dv6cdjs2.js";
@@ -16,7 +16,7 @@ import {
16
16
  } from "./cli-ej6gbxfb.js";
17
17
  import"./cli-sd0mxa3c.js";
18
18
  import"./cli-w5e1d1vv.js";
19
- import"./cli-jh9txj4n.js";
19
+ import"./cli-gfez0qmk.js";
20
20
  import"./cli-r2ap2czm.js";
21
21
  import"./cli-zf8jjwex.js";
22
22
  import"./cli-bc05qbss.js";
@@ -9,11 +9,11 @@ import {
9
9
  processSlackRenderV2,
10
10
  renderThreadTree,
11
11
  streamOutcomeCard
12
- } from "./cli-cwvey7n1.js";
12
+ } from "./cli-wfve107r.js";
13
13
  import"./cli-q51yprfq.js";
14
14
  import"./cli-yatxqynm.js";
15
15
  import"./cli-2658f6at.js";
16
- import"./cli-gacq5hg8.js";
16
+ import"./cli-bdt7w021.js";
17
17
  import"./cli-ht5rs63n.js";
18
18
  import"./cli-z61ykvam.js";
19
19
  import"./cli-dv6cdjs2.js";
@@ -21,7 +21,7 @@ import"./cli-c2mk1kgf.js";
21
21
  import"./cli-ej6gbxfb.js";
22
22
  import"./cli-sd0mxa3c.js";
23
23
  import"./cli-w5e1d1vv.js";
24
- import"./cli-jh9txj4n.js";
24
+ import"./cli-gfez0qmk.js";
25
25
  import"./cli-r2ap2czm.js";
26
26
  import"./cli-pzxba7gw.js";
27
27
  import"./cli-zf8jjwex.js";
@@ -2,8 +2,8 @@ import {
2
2
  buildModelsDevSeedRows,
3
3
  buildPricingSeedRows,
4
4
  seedPricingFromModelsDev
5
- } from "./cli-zdcdh02m.js";
6
- import"./cli-gacq5hg8.js";
5
+ } from "./cli-7bwaerjt.js";
6
+ import"./cli-bdt7w021.js";
7
7
  import"./cli-ht5rs63n.js";
8
8
  import"./cli-z61ykvam.js";
9
9
  import"./cli-dv6cdjs2.js";
@@ -11,7 +11,7 @@ import"./cli-c2mk1kgf.js";
11
11
  import"./cli-ej6gbxfb.js";
12
12
  import"./cli-sd0mxa3c.js";
13
13
  import"./cli-w5e1d1vv.js";
14
- import"./cli-jh9txj4n.js";
14
+ import"./cli-gfez0qmk.js";
15
15
  import"./cli-r2ap2czm.js";
16
16
  import"./cli-zf8jjwex.js";
17
17
  import"./cli-bc05qbss.js";
@@ -4,14 +4,14 @@ import {
4
4
  createDefaultMcpJson,
5
5
  createDefaultSettingsLocal,
6
6
  createHooksConfig
7
- } from "./cli-wp7cejrg.js";
7
+ } from "./cli-3g61md6v.js";
8
8
  import {
9
9
  require_jsx_dev_runtime
10
10
  } from "./cli-s2qjdd6z.js";
11
11
  import {
12
12
  getApiKey
13
13
  } from "./cli-f14fvzag.js";
14
- import"./cli-jh9txj4n.js";
14
+ import"./cli-gfez0qmk.js";
15
15
  import {
16
16
  Box_default,
17
17
  Spinner,
@@ -1,34 +1,34 @@
1
1
  import {
2
2
  isUserAllowed
3
- } from "./cli-5p007m2q.js";
4
- import"./cli-4fqn2vpg.js";
5
- import"./cli-awb59f08.js";
6
- import"./cli-72vksk1n.js";
3
+ } from "./cli-ng4q6a9t.js";
4
+ import"./cli-3pft2z6r.js";
5
+ import"./cli-b4dyetqt.js";
6
+ import"./cli-72tgtzr1.js";
7
7
  import"./cli-0z2v4nhw.js";
8
8
  import"./cli-4wppfkcm.js";
9
9
  import"./cli-e7d20cty.js";
10
10
  import"./cli-re8z5p8p.js";
11
11
  import"./cli-3dpj7atn.js";
12
- import"./cli-5bqt4gwa.js";
13
- import"./cli-t6axtdcg.js";
12
+ import"./cli-kf8qp2vf.js";
13
+ import"./cli-jytf5mw9.js";
14
14
  import"./cli-zfzznn7c.js";
15
- import"./cli-p2hx1pxm.js";
15
+ import"./cli-dsyg66vt.js";
16
16
  import"./cli-epan13p1.js";
17
17
  import"./cli-y89t4nca.js";
18
18
  import"./cli-f14fvzag.js";
19
19
  import"./cli-fad8m16k.js";
20
- import"./cli-cs9z1hw3.js";
21
- import"./cli-zdcdh02m.js";
20
+ import"./cli-vbk025fm.js";
21
+ import"./cli-7bwaerjt.js";
22
22
  import"./cli-bsakbbkm.js";
23
- import"./cli-nd5s3m4y.js";
23
+ import"./cli-gxf2ebyz.js";
24
24
  import"./cli-51tf7ac3.js";
25
25
  import {
26
26
  getTaskUrl,
27
27
  slackTaskOutput
28
- } from "./cli-cwvey7n1.js";
28
+ } from "./cli-wfve107r.js";
29
29
  import"./cli-q51yprfq.js";
30
30
  import"./cli-yatxqynm.js";
31
- import"./cli-evgy5w3y.js";
31
+ import"./cli-jtvs5m8q.js";
32
32
  import"./cli-fm4ytsdk.js";
33
33
  import"./cli-aehm1rbq.js";
34
34
  import"./cli-2658f6at.js";
@@ -37,7 +37,7 @@ import {
37
37
  getAgentById,
38
38
  getTaskById,
39
39
  init_db
40
- } from "./cli-gacq5hg8.js";
40
+ } from "./cli-bdt7w021.js";
41
41
  import"./cli-ht5rs63n.js";
42
42
  import"./cli-z61ykvam.js";
43
43
  import"./cli-dv6cdjs2.js";
@@ -48,7 +48,7 @@ import {
48
48
  } from "./cli-ej6gbxfb.js";
49
49
  import"./cli-sd0mxa3c.js";
50
50
  import"./cli-w5e1d1vv.js";
51
- import"./cli-jh9txj4n.js";
51
+ import"./cli-gfez0qmk.js";
52
52
  import"./cli-r2ap2czm.js";
53
53
  import"./cli-pzxba7gw.js";
54
54
  import"./cli-f7kvq46p.js";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  runAgent
3
- } from "./cli-t1mykkng.js";
3
+ } from "./cli-ftdjz1mk.js";
4
4
  import"./cli-pgj4a5fb.js";
5
5
  import"./cli-kj76p1ez.js";
6
6
  import"./cli-9b13ggd1.js";
7
7
  import"./cli-d3p82erb.js";
8
- import"./cli-8fy9dmpv.js";
9
- import"./cli-f1f9n77e.js";
8
+ import"./cli-sakxd2rg.js";
9
+ import"./cli-sqmh7jj1.js";
10
10
  import"./cli-wbyk465z.js";
11
11
  import"./cli-tng3131n.js";
12
12
  import"./cli-5bfdm1ah.js";
13
- import"./cli-87hdfyde.js";
13
+ import"./cli-v9sk4dzw.js";
14
14
  import"./cli-hsxj0yar.js";
15
15
  import"./cli-r94z9p1z.js";
16
16
  import"./cli-b5b30yzk.js";
@@ -25,34 +25,34 @@ import"./cli-eree7rnv.js";
25
25
  import"./cli-4yc5d8fk.js";
26
26
  import {
27
27
  getEnabledCapabilities
28
- } from "./cli-72vksk1n.js";
28
+ } from "./cli-72tgtzr1.js";
29
29
  import"./cli-0z2v4nhw.js";
30
30
  import"./cli-4wppfkcm.js";
31
31
  import"./cli-e7d20cty.js";
32
32
  import"./cli-re8z5p8p.js";
33
33
  import"./cli-3dpj7atn.js";
34
- import"./cli-5bqt4gwa.js";
35
- import"./cli-t6axtdcg.js";
34
+ import"./cli-kf8qp2vf.js";
35
+ import"./cli-jytf5mw9.js";
36
36
  import"./cli-zfzznn7c.js";
37
- import"./cli-p2hx1pxm.js";
37
+ import"./cli-dsyg66vt.js";
38
38
  import"./cli-epan13p1.js";
39
39
  import"./cli-y89t4nca.js";
40
40
  import"./cli-f14fvzag.js";
41
41
  import"./cli-fad8m16k.js";
42
- import"./cli-cs9z1hw3.js";
43
- import"./cli-zdcdh02m.js";
42
+ import"./cli-vbk025fm.js";
43
+ import"./cli-7bwaerjt.js";
44
44
  import"./cli-bsakbbkm.js";
45
- import"./cli-nd5s3m4y.js";
45
+ import"./cli-gxf2ebyz.js";
46
46
  import"./cli-51tf7ac3.js";
47
- import"./cli-cwvey7n1.js";
47
+ import"./cli-wfve107r.js";
48
48
  import"./cli-q51yprfq.js";
49
49
  import"./cli-yatxqynm.js";
50
- import"./cli-evgy5w3y.js";
50
+ import"./cli-jtvs5m8q.js";
51
51
  import"./cli-fm4ytsdk.js";
52
52
  import"./cli-aehm1rbq.js";
53
53
  import"./cli-2658f6at.js";
54
54
  import"./cli-jsp14b6c.js";
55
- import"./cli-gacq5hg8.js";
55
+ import"./cli-bdt7w021.js";
56
56
  import"./cli-ht5rs63n.js";
57
57
  import"./cli-z61ykvam.js";
58
58
  import"./cli-dv6cdjs2.js";
@@ -60,7 +60,7 @@ import"./cli-c2mk1kgf.js";
60
60
  import"./cli-ej6gbxfb.js";
61
61
  import"./cli-sd0mxa3c.js";
62
62
  import"./cli-w5e1d1vv.js";
63
- import"./cli-jh9txj4n.js";
63
+ import"./cli-gfez0qmk.js";
64
64
  import"./cli-r2ap2czm.js";
65
65
  import"./cli-pzxba7gw.js";
66
66
  import"./cli-f7kvq46p.js";
package/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Agent Swarm API",
5
- "version": "1.152.0",
5
+ "version": "1.152.1",
6
6
  "description": "Multi-agent orchestration API for Claude Code, Codex, and Gemini CLI. Enables task distribution, agent communication, and service discovery.\n\nMCP tools are documented separately in [MCP.md](./MCP.md)."
7
7
  },
8
8
  "servers": [
@@ -46581,7 +46581,7 @@
46581
46581
  }
46582
46582
  },
46583
46583
  "503": {
46584
- "description": "AgentMail integration not configured",
46584
+ "description": "AgentMail integration not configured or inbound archive unavailable",
46585
46585
  "content": {
46586
46586
  "application/json": {
46587
46587
  "schema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@desplega.ai/agent-swarm",
3
- "version": "1.152.0",
3
+ "version": "1.152.1",
4
4
  "description": "agent-swarm.dev — an open-source operating system for AI work: a lead agent breaks goals into tasks, routes them to specialized workers such as Claude Code or Codex, runs each worker in an isolated container, and preserves shared memory, tools, schedules, and review gates so delegated work compounds across sessions.",
5
5
  "keywords": [
6
6
  "agent-swarm.dev",
@@ -0,0 +1,71 @@
1
+ import { createHash } from "node:crypto";
2
+ import { claimKv, sweepExpiredKv } from "../be/db";
3
+ import { scrubSecrets } from "../utils/secret-scrubber";
4
+ import type { AgentMailWebhookPayload } from "./types";
5
+
6
+ export const INBOUND_ARCHIVE_NAMESPACE = "agentmail-inbound";
7
+ export const INBOUND_ARCHIVE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
8
+ const text = (value: unknown, limit: number) =>
9
+ typeof value === "string" ? scrubSecrets(value).slice(0, limit) : "";
10
+
11
+ export const inboundArchiveKey = (inboxId: string, messageId: string) =>
12
+ createHash("sha256")
13
+ .update(JSON.stringify([inboxId, messageId]))
14
+ .digest("hex");
15
+
16
+ /** Persist verified deliveries before ACK, independent of task-routing filters.
17
+ * One minimized entry per message for 30 days from capture. Live retries preserve
18
+ * the first delivery and its expiry; a replay after expiry starts a new window.
19
+ * This is a delivery archive, not proof of historical completeness.
20
+ */
21
+ export async function archiveInboundMessage(payload: AgentMailWebhookPayload): Promise<void> {
22
+ if (
23
+ ![
24
+ "message.received",
25
+ "message.received.unauthenticated",
26
+ "message.received.blocked",
27
+ "message.received.spam",
28
+ ].includes(payload.event_type)
29
+ )
30
+ return;
31
+ const message = payload.message;
32
+ if (!message?.inbox_id || !message.message_id || !message.thread_id) {
33
+ throw new Error("Inbound webhook missing inbox, message or thread ID");
34
+ }
35
+ const now = Date.now();
36
+ // Remove expired payloads on traffic as well as the KV point-read lazy sweep.
37
+ await sweepExpiredKv(INBOUND_ARCHIVE_NAMESPACE, now);
38
+ const minimized = {
39
+ event_type: payload.event_type,
40
+ message: {
41
+ inbox_id: message.inbox_id,
42
+ message_id: message.message_id,
43
+ thread_id: message.thread_id,
44
+ from_: text(Array.isArray(message.from_) ? message.from_.join(", ") : message.from_, 1500),
45
+ reply_to: Array.isArray(message.reply_to)
46
+ ? message.reply_to.slice(0, 20).map((value) => text(value, 1500))
47
+ : undefined,
48
+ subject: text(message.subject, 300),
49
+ text: text(message.text, 16000),
50
+ html: text(message.html, 16000),
51
+ timestamp: text(message.timestamp || message.created_at, 100),
52
+ labels: Array.isArray(message.labels)
53
+ ? message.labels.filter((label) => label === "unauthenticated")
54
+ : [],
55
+ attachments: Array.isArray(message.attachments)
56
+ ? message.attachments.map((attachment) => ({
57
+ filename: text(attachment.filename, 1500),
58
+ content_type: text(attachment.content_type, 200),
59
+ size: typeof attachment.size === "number" ? attachment.size : null,
60
+ }))
61
+ : undefined,
62
+ },
63
+ };
64
+ await claimKv({
65
+ namespace: INBOUND_ARCHIVE_NAMESPACE,
66
+ key: inboundArchiveKey(message.inbox_id, message.message_id),
67
+ value: { version: 1, capturedAt: new Date(now).toISOString(), payload: minimized },
68
+ expiresAt: now + INBOUND_ARCHIVE_TTL_MS,
69
+ valueType: "json",
70
+ });
71
+ }
@@ -44,6 +44,8 @@ export interface AgentMailWebhookPayload {
44
44
  export type AgentMailEventType =
45
45
  | "message.received"
46
46
  | "message.received.unauthenticated"
47
+ | "message.received.blocked"
48
+ | "message.received.spam"
47
49
  | "message.sent"
48
50
  | "message.delivered"
49
51
  | "message.bounced"
@@ -8,6 +8,7 @@ import {
8
8
  isSenderAllowed,
9
9
  verifyAgentMailWebhook,
10
10
  } from "../agentmail";
11
+ import { archiveInboundMessage } from "../agentmail/inbound-archive";
11
12
  import type {
12
13
  CheckRunEvent,
13
14
  CheckSuiteEvent,
@@ -109,7 +110,7 @@ const agentmailWebhook = route({
109
110
  responses: {
110
111
  200: { description: "Event received", schema: z.object({ received: z.literal(true) }) },
111
112
  401: { description: "Invalid signature" },
112
- 503: { description: "AgentMail integration not configured" },
113
+ 503: { description: "AgentMail integration not configured or inbound archive unavailable" },
113
114
  },
114
115
  });
115
116
 
@@ -486,11 +487,18 @@ export async function handleWebhooks(
486
487
  return true;
487
488
  }
488
489
 
489
- // Return 200 immediately — Svix best practice to avoid retries.
490
- // Processing happens asynchronously below; dedup is handled in handlers.ts.
491
- agentmailWebhook.respond(res, 200, { received: true });
492
-
493
490
  const payload = verified as AgentMailWebhookPayload;
491
+ try {
492
+ await archiveInboundMessage(payload);
493
+ } catch (err) {
494
+ console.error("[AgentMail] Inbound archive failed; requesting webhook retry", err);
495
+ res.writeHead(503, { "Content-Type": "application/json" });
496
+ res.end(JSON.stringify({ error: "Inbound archive unavailable" }));
497
+ return true;
498
+ }
499
+ // Only acknowledge received events after durable capture. Task routing below
500
+ // remains independent: rejected senders and routing failures stay discoverable.
501
+ agentmailWebhook.respond(res, 200, { received: true });
494
502
 
495
503
  if (
496
504
  payload.message &&