@desplega.ai/agent-swarm 1.152.0 → 1.152.2
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 +3 -0
- package/dist/{acp-adapter-d05sg0q4.js → acp-adapter-pfeje2v5.js} +1 -1
- package/dist/{actions-4sc0v342.js → actions-0sttc7f5.js} +12 -12
- package/dist/{app-2d0v6kt6.js → app-p8teva95.js} +3 -3
- package/dist/{assistant-zs6wdnrf.js → assistant-r45jnsrt.js} +15 -15
- package/dist/{boot-reembed-vhh33520.js → boot-reembed-1qmybsd4.js} +4 -4
- package/dist/{boot-reembed-3dwdnnsr.js → boot-reembed-je26h5y7.js} +3 -3
- package/dist/{boot-scrub-logs-e1fnabcg.js → boot-scrub-logs-gte3h1mm.js} +2 -2
- package/dist/{claude-adapter-h58xqzzd.js → claude-adapter-csc1mzka.js} +3 -3
- package/dist/{claude-sdk-session-pbaczbgt.js → claude-sdk-session-fcd6f078.js} +3 -3
- package/dist/{cli-zdcdh02m.js → cli-2nnd56zt.js} +1 -1
- package/dist/{cli-awb59f08.js → cli-3bpzj8me.js} +2 -2
- package/dist/{cli-f1f9n77e.js → cli-4ahpr4sw.js} +1 -1
- package/dist/{cli-cs9z1hw3.js → cli-56h18ng2.js} +1 -1
- package/dist/{cli-5bqt4gwa.js → cli-b9dd0h3k.js} +2 -2
- package/dist/{cli-5p007m2q.js → cli-ckz5t2hb.js} +7 -7
- package/dist/{cli-p2hx1pxm.js → cli-fmy65jdn.js} +3 -3
- package/dist/{cli-fhdssm2v.js → cli-gphgnvpf.js} +2 -2
- package/dist/{cli-nd5s3m4y.js → cli-gpqcs935.js} +2 -2
- package/dist/{cli-wp7cejrg.js → cli-jbmc0r7r.js} +1 -1
- package/dist/{cli-evgy5w3y.js → cli-jew3jda5.js} +1 -1
- package/dist/{cli-4fqn2vpg.js → cli-jvy9qgjs.js} +12 -10
- package/dist/{cli-t1mykkng.js → cli-qd65dvr6.js} +8 -8
- package/dist/{cli-cwvey7n1.js → cli-qn042eh7.js} +8 -8
- package/dist/{cli-t6axtdcg.js → cli-r84ctdxn.js} +1 -1
- package/dist/{cli-6k2athpf.js → cli-wpv5rgg2.js} +2 -2
- package/dist/{cli-8fy9dmpv.js → cli-xw7vak96.js} +2 -2
- package/dist/{cli-87hdfyde.js → cli-xy1cchaf.js} +1 -1
- package/dist/{cli-72vksk1n.js → cli-z3wkng35.js} +18 -18
- package/dist/{cli-gacq5hg8.js → cli-zvgj5zg8.js} +1 -1
- package/dist/{cli-jh9txj4n.js → cli-zvkq5csn.js} +1 -1
- package/dist/cli.js +11 -11
- package/dist/{codex-adapter-v3cz462q.js → codex-adapter-fxmpsabw.js} +2 -2
- package/dist/{codex-session-runner-de1a5g5z.js → codex-session-runner-rr1e47ea.js} +2 -2
- package/dist/{commands-wfqqpn95.js → commands-0f5rxz51.js} +2 -2
- package/dist/{db-9zzv5y05.js → db-r3jxf3wy.js} +2 -2
- package/dist/{dispatcher-hfm1jbgx.js → dispatcher-06vph6q4.js} +11 -11
- package/dist/{handlers-wrrhsack.js → handlers-0hgtc910.js} +14 -14
- package/dist/{hook-9skye8zd.js → hook-9kvrv1er.js} +1 -1
- package/dist/{hook-fgjv62k5.js → hook-fbfhkat3.js} +2 -2
- package/dist/{http-7grttjfq.js → http-xbyx8k5j.js} +90 -29
- package/dist/{index-pfhzrh1d.js → index-gpfn1741.js} +3 -3
- package/dist/{index-29gxx9ar.js → index-jsw3aynb.js} +11 -11
- package/dist/{index-30pz2h9w.js → index-rnyahfn5.js} +11 -11
- package/dist/{index-4ek1df87.js → index-sgk50mbg.js} +12 -12
- package/dist/{index-myfwqqyq.js → index-tfsdxyv6.js} +7 -7
- package/dist/{keepalive-j75m2m7k.js → keepalive-s3xpr7sw.js} +4 -4
- package/dist/{lead-a1hpjt0a.js → lead-rq4n5r16.js} +15 -15
- package/dist/{maintenance-tngjzqdq.js → maintenance-f0atj1ab.js} +4 -4
- package/dist/{oauth-refresh-sweep-em1fn044.js → oauth-refresh-sweep-q0t3bxre.js} +3 -3
- package/dist/{onboard-fv7ezvwx.js → onboard-br5j1kch.js} +2 -2
- package/dist/{otel-impl-6vbb568y.js → otel-impl-vdqge2nt.js} +1 -1
- package/dist/{pricing-refresh-nmm949an.js → pricing-refresh-hb3691fd.js} +4 -4
- package/dist/{rbac-roles-0fz5qryx.js → rbac-roles-jh280k9g.js} +3 -3
- package/dist/{rbac-roles-xtp05syf.js → rbac-roles-t78xt39b.js} +2 -2
- package/dist/{render-v2-fpb8whme.js → render-v2-7p8r2ymg.js} +3 -3
- package/dist/{seed-pricing-zwa8bs3t.js → seed-pricing-hf889enh.js} +3 -3
- package/dist/{setup-3ybwbdpd.js → setup-w6mb03jv.js} +2 -2
- package/dist/{work-objects-rmayxcx7.js → work-objects-nt8gy1kj.js} +14 -14
- package/dist/{worker-rng4jhnh.js → worker-dwy617t0.js} +15 -15
- package/openapi.json +2 -2
- package/package.json +1 -1
- package/src/agentmail/inbound-archive.ts +71 -0
- package/src/agentmail/types.ts +2 -0
- package/src/http/webhooks.ts +13 -5
- package/src/slack/assistant.ts +10 -1
- package/src/slack/handlers.ts +10 -1
- package/src/slack/thread-buffer.ts +14 -3
- package/src/tests/agentmail-inbound-archive.test.ts +418 -0
- package/src/tests/slack-assistant.test.ts +134 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
createDefaultMcpJson,
|
|
4
4
|
createDefaultSettingsLocal,
|
|
5
5
|
createHooksConfig
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-jbmc0r7r.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-
|
|
16
|
+
} from "./cli-zvkq5csn.js";
|
|
17
17
|
import {
|
|
18
18
|
Box_default,
|
|
19
19
|
Select,
|
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
PRICING_REFRESH_INTERVAL_MS,
|
|
3
3
|
refreshPricingFromModelsDev,
|
|
4
4
|
startPricingRefreshLoop
|
|
5
|
-
} from "./cli-
|
|
6
|
-
import"./cli-
|
|
7
|
-
import"./cli-
|
|
5
|
+
} from "./cli-b9dd0h3k.js";
|
|
6
|
+
import"./cli-2nnd56zt.js";
|
|
7
|
+
import"./cli-zvgj5zg8.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-
|
|
15
|
+
import"./cli-zvkq5csn.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-
|
|
10
|
+
} from "./cli-r84ctdxn.js";
|
|
11
11
|
import"./cli-zfzznn7c.js";
|
|
12
|
-
import"./cli-
|
|
12
|
+
import"./cli-zvgj5zg8.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-
|
|
20
|
+
import"./cli-zvkq5csn.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-
|
|
8
|
+
} from "./cli-zvgj5zg8.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-
|
|
19
|
+
import"./cli-zvkq5csn.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-
|
|
12
|
+
} from "./cli-qn042eh7.js";
|
|
13
13
|
import"./cli-q51yprfq.js";
|
|
14
14
|
import"./cli-yatxqynm.js";
|
|
15
15
|
import"./cli-2658f6at.js";
|
|
16
|
-
import"./cli-
|
|
16
|
+
import"./cli-zvgj5zg8.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-
|
|
24
|
+
import"./cli-zvkq5csn.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-
|
|
6
|
-
import"./cli-
|
|
5
|
+
} from "./cli-2nnd56zt.js";
|
|
6
|
+
import"./cli-zvgj5zg8.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-
|
|
14
|
+
import"./cli-zvkq5csn.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-
|
|
7
|
+
} from "./cli-jbmc0r7r.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-
|
|
14
|
+
import"./cli-zvkq5csn.js";
|
|
15
15
|
import {
|
|
16
16
|
Box_default,
|
|
17
17
|
Spinner,
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isUserAllowed
|
|
3
|
-
} from "./cli-
|
|
4
|
-
import"./cli-
|
|
5
|
-
import"./cli-
|
|
6
|
-
import"./cli-
|
|
3
|
+
} from "./cli-ckz5t2hb.js";
|
|
4
|
+
import"./cli-jvy9qgjs.js";
|
|
5
|
+
import"./cli-3bpzj8me.js";
|
|
6
|
+
import"./cli-z3wkng35.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-
|
|
13
|
-
import"./cli-
|
|
12
|
+
import"./cli-b9dd0h3k.js";
|
|
13
|
+
import"./cli-r84ctdxn.js";
|
|
14
14
|
import"./cli-zfzznn7c.js";
|
|
15
|
-
import"./cli-
|
|
15
|
+
import"./cli-fmy65jdn.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-
|
|
21
|
-
import"./cli-
|
|
20
|
+
import"./cli-56h18ng2.js";
|
|
21
|
+
import"./cli-2nnd56zt.js";
|
|
22
22
|
import"./cli-bsakbbkm.js";
|
|
23
|
-
import"./cli-
|
|
23
|
+
import"./cli-gpqcs935.js";
|
|
24
24
|
import"./cli-51tf7ac3.js";
|
|
25
25
|
import {
|
|
26
26
|
getTaskUrl,
|
|
27
27
|
slackTaskOutput
|
|
28
|
-
} from "./cli-
|
|
28
|
+
} from "./cli-qn042eh7.js";
|
|
29
29
|
import"./cli-q51yprfq.js";
|
|
30
30
|
import"./cli-yatxqynm.js";
|
|
31
|
-
import"./cli-
|
|
31
|
+
import"./cli-jew3jda5.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-
|
|
40
|
+
} from "./cli-zvgj5zg8.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-
|
|
51
|
+
import"./cli-zvkq5csn.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-
|
|
3
|
+
} from "./cli-qd65dvr6.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-
|
|
9
|
-
import"./cli-
|
|
8
|
+
import"./cli-xw7vak96.js";
|
|
9
|
+
import"./cli-4ahpr4sw.js";
|
|
10
10
|
import"./cli-wbyk465z.js";
|
|
11
11
|
import"./cli-tng3131n.js";
|
|
12
12
|
import"./cli-5bfdm1ah.js";
|
|
13
|
-
import"./cli-
|
|
13
|
+
import"./cli-xy1cchaf.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-
|
|
28
|
+
} from "./cli-z3wkng35.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-
|
|
35
|
-
import"./cli-
|
|
34
|
+
import"./cli-b9dd0h3k.js";
|
|
35
|
+
import"./cli-r84ctdxn.js";
|
|
36
36
|
import"./cli-zfzznn7c.js";
|
|
37
|
-
import"./cli-
|
|
37
|
+
import"./cli-fmy65jdn.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-
|
|
43
|
-
import"./cli-
|
|
42
|
+
import"./cli-56h18ng2.js";
|
|
43
|
+
import"./cli-2nnd56zt.js";
|
|
44
44
|
import"./cli-bsakbbkm.js";
|
|
45
|
-
import"./cli-
|
|
45
|
+
import"./cli-gpqcs935.js";
|
|
46
46
|
import"./cli-51tf7ac3.js";
|
|
47
|
-
import"./cli-
|
|
47
|
+
import"./cli-qn042eh7.js";
|
|
48
48
|
import"./cli-q51yprfq.js";
|
|
49
49
|
import"./cli-yatxqynm.js";
|
|
50
|
-
import"./cli-
|
|
50
|
+
import"./cli-jew3jda5.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-
|
|
55
|
+
import"./cli-zvgj5zg8.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-
|
|
63
|
+
import"./cli-zvkq5csn.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.
|
|
5
|
+
"version": "1.152.2",
|
|
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.
|
|
3
|
+
"version": "1.152.2",
|
|
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
|
+
}
|
package/src/agentmail/types.ts
CHANGED
|
@@ -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"
|
package/src/http/webhooks.ts
CHANGED
|
@@ -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 &&
|
package/src/slack/assistant.ts
CHANGED
|
@@ -129,7 +129,15 @@ export function createAssistant(): Assistant {
|
|
|
129
129
|
|
|
130
130
|
// Follow-up message → buffer text and file metadata until the flush.
|
|
131
131
|
if (workingAgent && workingAgent.status !== "offline" && isAdditiveSlack()) {
|
|
132
|
-
bufferThreadMessage(
|
|
132
|
+
bufferThreadMessage(
|
|
133
|
+
channelId,
|
|
134
|
+
threadTs,
|
|
135
|
+
messageText,
|
|
136
|
+
userId,
|
|
137
|
+
message.ts,
|
|
138
|
+
files,
|
|
139
|
+
cachedBotUserId ?? undefined,
|
|
140
|
+
);
|
|
133
141
|
const count = getBufferMessageCount(`${channelId}:${threadTs}`);
|
|
134
142
|
const event = count === 1 ? "accepted" : "buffered";
|
|
135
143
|
await ackSlackMessage(client, channelId, message.ts, reactionName(event), event);
|
|
@@ -147,6 +155,7 @@ export function createAssistant(): Assistant {
|
|
|
147
155
|
// raw `messageText`, not this rendered copy.
|
|
148
156
|
const renderedMessageText = await rewriteSlackMentions(
|
|
149
157
|
buildEffectiveText(messageText, inbound.files, inbound.failed),
|
|
158
|
+
cachedBotUserId ?? undefined,
|
|
150
159
|
);
|
|
151
160
|
|
|
152
161
|
if (workingAgent && workingAgent.status !== "offline") {
|
package/src/slack/handlers.ts
CHANGED
|
@@ -523,7 +523,15 @@ export function registerMessageHandler(app: App): void {
|
|
|
523
523
|
);
|
|
524
524
|
|
|
525
525
|
if (nowMessage || msg.files?.length) {
|
|
526
|
-
bufferThreadMessage(
|
|
526
|
+
bufferThreadMessage(
|
|
527
|
+
msg.channel,
|
|
528
|
+
msg.thread_ts,
|
|
529
|
+
nowMessage,
|
|
530
|
+
msg.user,
|
|
531
|
+
msg.ts,
|
|
532
|
+
msg.files,
|
|
533
|
+
botUserId,
|
|
534
|
+
);
|
|
527
535
|
}
|
|
528
536
|
|
|
529
537
|
// Instant flush — no dependency
|
|
@@ -563,6 +571,7 @@ export function registerMessageHandler(app: App): void {
|
|
|
563
571
|
msg.user,
|
|
564
572
|
msg.ts,
|
|
565
573
|
msg.files,
|
|
574
|
+
botUserId,
|
|
566
575
|
);
|
|
567
576
|
|
|
568
577
|
// Slack feedback: react with the accepted reaction on first buffer, buffered on appends
|
|
@@ -30,6 +30,7 @@ interface BufferedMessage {
|
|
|
30
30
|
channelId: string;
|
|
31
31
|
threadTs: string;
|
|
32
32
|
files?: SlackFile[];
|
|
33
|
+
botUserId?: string;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
const BUFFER_TIMEOUT_MS = Number(process.env.ADDITIVE_SLACK_BUFFER_MS) || 10_000;
|
|
@@ -62,6 +63,7 @@ export function bufferThreadMessage(
|
|
|
62
63
|
userId: string,
|
|
63
64
|
ts: string,
|
|
64
65
|
files?: SlackFile[],
|
|
66
|
+
botUserId?: string,
|
|
65
67
|
): void {
|
|
66
68
|
slackBuffer.enqueue(makeKey(channelId, threadTs), {
|
|
67
69
|
text,
|
|
@@ -70,6 +72,7 @@ export function bufferThreadMessage(
|
|
|
70
72
|
channelId,
|
|
71
73
|
threadTs,
|
|
72
74
|
files,
|
|
75
|
+
botUserId,
|
|
73
76
|
});
|
|
74
77
|
}
|
|
75
78
|
|
|
@@ -98,7 +101,11 @@ export async function instantFlush(key: string): Promise<void> {
|
|
|
98
101
|
/**
|
|
99
102
|
* Fetch thread context from Slack for the buffer flush task description.
|
|
100
103
|
*/
|
|
101
|
-
async function getThreadContextForBuffer(
|
|
104
|
+
async function getThreadContextForBuffer(
|
|
105
|
+
channelId: string,
|
|
106
|
+
threadTs: string,
|
|
107
|
+
botUserId?: string,
|
|
108
|
+
): Promise<string> {
|
|
102
109
|
const app = getSlackApp();
|
|
103
110
|
if (!app) return "";
|
|
104
111
|
|
|
@@ -126,7 +133,7 @@ async function getThreadContextForBuffer(channelId: string, threadTs: string): P
|
|
|
126
133
|
})
|
|
127
134
|
.join("\n");
|
|
128
135
|
|
|
129
|
-
return await rewriteSlackMentions(formatted);
|
|
136
|
+
return await rewriteSlackMentions(formatted, botUserId);
|
|
130
137
|
} catch (error) {
|
|
131
138
|
console.error("[Slack] Failed to fetch thread context for buffer:", error);
|
|
132
139
|
return "";
|
|
@@ -153,6 +160,9 @@ async function slackFlush(
|
|
|
153
160
|
// Buffer is guaranteed to have at least one item — the first carries the
|
|
154
161
|
// original requester's userId (same semantics as the pre-refactor version).
|
|
155
162
|
const originalRequesterId = items[0]!.userId;
|
|
163
|
+
// Every buffered item is resolved from the same bot's auth.test() cache —
|
|
164
|
+
// any item carrying it is representative of the whole flush.
|
|
165
|
+
const botUserId = items.find((item) => item.botUserId)?.botUserId;
|
|
156
166
|
|
|
157
167
|
console.log(`[Slack] Flushing buffer: ${key} (${items.length} messages, immediate=${immediate})`);
|
|
158
168
|
|
|
@@ -182,6 +192,7 @@ async function slackFlush(
|
|
|
182
192
|
),
|
|
183
193
|
)
|
|
184
194
|
.join("\n---\n"),
|
|
195
|
+
botUserId,
|
|
185
196
|
);
|
|
186
197
|
const description = `[Thread follow-up — ${items.length} message(s) buffered]\n\n${combinedText}`;
|
|
187
198
|
|
|
@@ -234,7 +245,7 @@ async function slackFlush(
|
|
|
234
245
|
const lead = await getLeadAgent();
|
|
235
246
|
|
|
236
247
|
// Thread context for the task
|
|
237
|
-
const threadContext = await getThreadContextForBuffer(channelId, threadTs);
|
|
248
|
+
const threadContext = await getThreadContextForBuffer(channelId, threadTs, botUserId);
|
|
238
249
|
const fullDescription = threadContext
|
|
239
250
|
? `<thread_context>\n${threadContext}\n</thread_context>\n\n${description}`
|
|
240
251
|
: description;
|