@desplega.ai/agent-swarm 2.7.2 → 2.7.3
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 +6 -0
- package/dist/{acp-adapter-624yge7a.js → acp-adapter-pdzw76ja.js} +1 -1
- package/dist/{actions-rd9xn281.js → actions-a90cfpca.js} +21 -21
- package/dist/{amp-adapter-k27hc00p.js → amp-adapter-4vtywcjk.js} +2 -2
- package/dist/{app-sjm3xc7g.js → app-8k68gygk.js} +3 -3
- package/dist/{assistant-6jbzs8wa.js → assistant-ck01q2yg.js} +32 -21
- package/dist/{boot-reembed-e2348eqc.js → boot-reembed-33spavpd.js} +1 -1
- package/dist/{boot-reembed-w53pd5xt.js → boot-reembed-xzge83a2.js} +1 -1
- package/dist/{boot-scrub-sweep-cpy4yg97.js → boot-scrub-sweep-mxvb8dr3.js} +3 -3
- package/dist/{boot-seeds-f6j4t6k6.js → boot-seeds-rpm8bb5r.js} +4 -4
- package/dist/{claude-adapter-v3ac8esd.js → claude-adapter-q12bcfj9.js} +3 -3
- package/dist/{claude-managed-setup-yyrkqvtm.js → claude-managed-setup-11vb6q89.js} +1 -1
- package/dist/{claude-sdk-session-85j69v6d.js → claude-sdk-session-gkv1107j.js} +10325 -10243
- package/dist/{cli-rs59z1qx.js → cli-07pcqwaj.js} +1 -1
- package/dist/{cli-6vq3ymqm.js → cli-0tkm519n.js} +1 -1
- package/dist/{cli-s7cm1927.js → cli-0xzbk52h.js} +4 -4
- package/dist/{cli-g0zc1b40.js → cli-0zae6bs6.js} +2 -2
- package/dist/{cli-p8yrsmfn.js → cli-10kjx0dm.js} +1 -1
- package/dist/{cli-7xsq63pe.js → cli-157ykn37.js} +10 -9
- package/dist/{cli-vjcj9k2p.js → cli-2h0rfmqk.js} +1 -1
- package/dist/{cli-9wasax9f.js → cli-35nzvqaf.js} +1 -1
- package/dist/{cli-e1p7dqe1.js → cli-4aydmmdy.js} +24 -3
- package/dist/{cli-942pp3bc.js → cli-54ax65rn.js} +3 -3
- package/dist/{cli-10cp92df.js → cli-5ke7gxwr.js} +6 -6
- package/dist/{cli-femw4q81.js → cli-6151a7dr.js} +2 -2
- package/dist/{cli-3cywb44q.js → cli-77eq8txs.js} +85 -3
- package/dist/{cli-atpfk4yd.js → cli-7cwrwb5x.js} +5 -5
- package/dist/{cli-bfbpvccx.js → cli-8a1k6mat.js} +61 -49
- package/dist/{cli-c18941tx.js → cli-8ch3b2r7.js} +3 -3
- package/dist/{cli-rs2s1t05.js → cli-9fk56y8c.js} +4 -4
- package/dist/{cli-0wx63vvw.js → cli-9km88w11.js} +1 -1
- package/dist/{cli-qy0z3mfj.js → cli-9vttw9nz.js} +56 -46
- package/dist/{cli-mzgppb7q.js → cli-a0w50zw9.js} +4 -4
- package/dist/{cli-z8a4mfz1.js → cli-aqp59jmv.js} +4 -4
- package/dist/{cli-5d8wd50e.js → cli-bs0fwb23.js} +1 -1
- package/dist/{cli-fa4kxxx3.js → cli-ct5920jb.js} +2 -2
- package/dist/{cli-0awbtmv2.js → cli-dek8hqjc.js} +10 -10
- package/dist/{cli-qp6adcmw.js → cli-e24w2mvk.js} +1 -1
- package/dist/{cli-t3npd8hm.js → cli-ghfhn1qc.js} +1 -1
- package/dist/{cli-jmcf8cnz.js → cli-ja369zab.js} +1 -1
- package/dist/{cli-wtjg6je3.js → cli-jhh7tbx6.js} +1 -1
- package/dist/{cli-e19bgatr.js → cli-jmk31131.js} +2 -2
- package/dist/{cli-2cj8fqv1.js → cli-kjcdzea8.js} +1 -1
- package/dist/{cli-1xpr5992.js → cli-kjha1q9k.js} +3 -3
- package/dist/{cli-9jfty8px.js → cli-ktcdczth.js} +538 -30
- package/dist/{cli-exd52qn4.js → cli-mcmpbpcc.js} +2 -2
- package/dist/{cli-2m2p3snc.js → cli-mmf43vcp.js} +6 -6
- package/dist/{cli-b2rhbaty.js → cli-pnm99spe.js} +10 -10
- package/dist/{cli-9jn9cj0q.js → cli-v9jk2k63.js} +1 -1
- package/dist/{cli-mt7bxjfd.js → cli-vhgcwppn.js} +1 -1
- package/dist/{cli-qa4hgda3.js → cli-vvz64zc5.js} +14 -13
- package/dist/{cli-txr0z97c.js → cli-wmhajw68.js} +171 -32
- package/dist/{cli-hzrmv8pg.js → cli-x38rmhap.js} +3 -3
- package/dist/{cli-hq9hd4hp.js → cli-xz6qjdqj.js} +1 -1
- package/dist/{cli-g9ypd5en.js → cli-z52gq55b.js} +4 -0
- package/dist/{cli-2qbmjfta.js → cli-z6219sd3.js} +4 -4
- package/dist/cli.js +19 -19
- package/dist/{codex-adapter-zm1bkdde.js → codex-adapter-46kbvvkx.js} +1 -1
- package/dist/{codex-hook-tkag7fxq.js → codex-hook-tm9ecrd5.js} +1 -1
- package/dist/{codex-session-runner-8k02mqw2.js → codex-session-runner-qy93hdrv.js} +1 -1
- package/dist/{commands-nw1dn4av.js → commands-hwdhacfx.js} +2 -2
- package/dist/{controller-3kkkmps0.js → controller-hjza5p1f.js} +3 -3
- package/dist/{controllers-connect-n2c4167r.js → controllers-connect-7m25cay2.js} +20 -20
- package/dist/{cursor-adapter-h5028emw.js → cursor-adapter-1qh7ps8w.js} +1 -1
- package/dist/{db-76y2msnf.js → db-w23k9301.js} +2 -2
- package/dist/{db-8rk0p8j1.js → db-wm8by383.js} +3 -3
- package/dist/{dispatcher-xp4wsx30.js → dispatcher-en25ebgc.js} +18 -18
- package/dist/{dsh-adapter-vyrr31bn.js → dsh-adapter-zkme32vd.js} +1 -1
- package/dist/{e2b-eesfj689.js → e2b-9z9mvt2p.js} +1 -1
- package/dist/{e2b-03nha1wz.js → e2b-yhvn70es.js} +1 -1
- package/dist/{embedding-space-ejefyep1.js → embedding-space-rgf4aypt.js} +6 -6
- package/dist/{embeddings-w297xaw0.js → embeddings-z9cmxhx1.js} +1 -1
- package/dist/{external-channel-mf9vp1fe.js → external-channel-g6vv85zv.js} +2 -2
- package/dist/{grok-adapter-mpzyyprz.js → grok-adapter-f6n1tpq3.js} +2 -2
- package/dist/handlers-ss5948rq.js +42 -0
- package/dist/{heartbeat-qnaycjzs.js → heartbeat-5xcdzz45.js} +21 -21
- package/dist/{hook-h6sqfzxr.js → hook-6423rme3.js} +2 -2
- package/dist/{hook-4zqdgea4.js → hook-8dk1csdd.js} +4 -4
- package/dist/{http-65ts210h.js → http-6mfh2ww9.js} +255 -60
- package/dist/{index-sqe7f6mj.js → index-0js6bgff.js} +1 -1
- package/dist/{index-farm1zsn.js → index-0ng1dd1t.js} +10937 -9527
- package/dist/{index-k3ewf1jg.js → index-5eyn1wc5.js} +18 -18
- package/dist/{index-vp4wa3qn.js → index-71gnebsn.js} +18 -18
- package/dist/{index-hdfad00b.js → index-q5gzpjdd.js} +12 -10
- package/dist/index-z3b1vfjx.js +44 -0
- package/dist/{keepalive-52k6skha.js → keepalive-cymckeg6.js} +3 -3
- package/dist/{lead-y9rj0gr1.js → lead-baknj2dh.js} +29 -29
- package/dist/{maintenance-f86wqfq6.js → maintenance-dfrnsx3n.js} +1 -1
- package/dist/{oauth-refresh-sweep-vddv9ky7.js → oauth-refresh-sweep-5dztk8x6.js} +2 -2
- package/dist/{onboard-8z2qk6gq.js → onboard-h36vja6y.js} +11 -6
- package/dist/{otel-impl-epet9j18.js → otel-impl-jerq8vz8.js} +1 -1
- package/dist/{pricing-refresh-6wm42a51.js → pricing-refresh-t3nx5krn.js} +3 -3
- package/dist/{rbac-roles-2kfcs1sc.js → rbac-roles-dw1awawd.js} +2 -2
- package/dist/{rbac-roles-13a0vj6d.js → rbac-roles-km0fc3e8.js} +1 -1
- package/dist/{registry-ajhexe44.js → registry-hzfh268v.js} +1 -1
- package/dist/{render-v2-cy8zsfsf.js → render-v2-65x4ayj8.js} +3 -3
- package/dist/{resume-c783qe6b.js → resume-61znk3hj.js} +6 -6
- package/dist/{session-access-s4tv0az8.js → session-access-4yc9htrg.js} +4 -4
- package/dist/{session-source-backfill-qzapz0ne.js → session-source-backfill-kr5bdjtp.js} +2 -2
- package/dist/{setup-st7htx1k.js → setup-9h61yr2p.js} +1 -1
- package/dist/{work-objects-ftj4zw70.js → work-objects-x7rb53qn.js} +27 -22
- package/dist/{worker-859fk25k.js → worker-7f3khgn0.js} +29 -29
- package/openapi.json +134 -3
- package/package.json +5 -5
- package/src/be/db/agents.ts +16 -1
- package/src/be/db/runtime.ts +25 -15
- package/src/be/db/session-summaries.ts +120 -0
- package/src/be/db/tasks/read.ts +7 -4
- package/src/be/db/tasks/search-index.ts +159 -0
- package/src/be/db/tasks/write.ts +3 -0
- package/src/be/db-queries/slack-inbound.ts +77 -0
- package/src/be/db.ts +27 -8
- package/src/be/mcp-overflow-sweep.ts +39 -0
- package/src/be/migrations/253_session_summaries.sql +300 -0
- package/src/be/migrations/254_query_audit_indexes.sql +25 -0
- package/src/be/migrations/256_agent_slack_icon.sql +2 -0
- package/src/be/migrations/257_agent_tasks_fts.sql +55 -0
- package/src/comb/config.ts +6 -2
- package/src/comb/requester.ts +69 -0
- package/src/comb/review-batch.ts +24 -2
- package/src/commands/onboard/agent-fs-version.ts +1 -1
- package/src/commands/onboard/compose-generator.ts +7 -2
- package/src/commands/onboard/env-generator.ts +8 -3
- package/src/commands/runner.ts +41 -24
- package/src/fs/agent-fs-provider.ts +9 -0
- package/src/heartbeat/heartbeat.ts +13 -6
- package/src/http/agents.ts +10 -2
- package/src/http/index.ts +15 -0
- package/src/http/integrations.ts +20 -0
- package/src/http/list-total-cache.ts +62 -0
- package/src/http/sessions.ts +9 -2
- package/src/http/slack-inbound.ts +1 -0
- package/src/http/status.ts +4 -1
- package/src/http/tasks.ts +12 -2
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/cursor-adapter.ts +1 -1
- package/src/providers/dsh-adapter.ts +1 -1
- package/src/queue-stall-alarm.ts +4 -1
- package/src/slack/actions.ts +2 -2
- package/src/slack/app-icon.ts +50 -0
- package/src/slack/app.ts +13 -1
- package/src/slack/assistant.ts +22 -1
- package/src/slack/event-dedup.test.ts +11 -0
- package/src/slack/event-dedup.ts +8 -4
- package/src/slack/inbound-dispatch.ts +58 -0
- package/src/slack/render-v2.ts +7 -8
- package/src/slack/responses.ts +21 -8
- package/src/slack/socket-ack.ts +237 -0
- package/src/slack/thread-buffer.ts +3 -5
- package/src/slack/watcher.ts +2 -2
- package/src/slack/work-objects.ts +5 -1
- package/src/tests/agent-fs-release-notes.test.ts +40 -0
- package/src/tests/agent-slack-icon.test.ts +85 -0
- package/src/tests/approval-cancellation-migration.test.ts +2 -0
- package/src/tests/asset-key-migration.test.ts +26 -0
- package/src/tests/comb-default.test.ts +159 -0
- package/src/tests/comb-review-batch.test.ts +192 -4
- package/src/tests/comb-status.test.ts +65 -2
- package/src/tests/db-agents.test.ts +13 -0
- package/src/tests/db-tasks-read.test.ts +10 -15
- package/src/tests/deploy-one-box.test.ts +161 -0
- package/src/tests/deploy-stubs.ts +68 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/e2e-codex-auth-chain.test.ts +18 -1
- package/src/tests/fixtures/deploy-stubs/bun +3 -0
- package/src/tests/fixtures/deploy-stubs/bunx +27 -0
- package/src/tests/fixtures/deploy-stubs/curl +26 -0
- package/src/tests/fixtures/deploy-stubs/docker +122 -0
- package/src/tests/fixtures/onboard/content.compose.yml.txt +5 -5
- package/src/tests/fixtures/onboard/dev.compose.yml.txt +4 -4
- package/src/tests/fixtures/onboard/full-all.compose.yml.txt +12 -12
- package/src/tests/fixtures/onboard/full.compose.yml.txt +12 -12
- package/src/tests/fixtures/onboard/research.compose.yml.txt +4 -4
- package/src/tests/fixtures/onboard/solo.compose.yml.txt +2 -2
- package/src/tests/heartbeat-expiry.test.ts +151 -25
- package/src/tests/http-api-integration.test.ts +31 -0
- package/src/tests/human-free-reclassify.test.ts +6 -0
- package/src/tests/install-sh-bind.test.ts +242 -0
- package/src/tests/install-sh-tunnel.test.ts +89 -0
- package/src/tests/kv-storage.test.ts +28 -0
- package/src/tests/list-endpoint-slimming.test.ts +3 -0
- package/src/tests/list-total-cache.test.ts +63 -0
- package/src/tests/mcp-overflow-sweep.test.ts +84 -0
- package/src/tests/onboard-compose.test.ts +17 -3
- package/src/tests/onboard-env.test.ts +13 -0
- package/src/tests/onboarding.test.ts +1 -1
- package/src/tests/preload.ts +1 -0
- package/src/tests/query-audit-plans.test.ts +314 -0
- package/src/tests/script-connections.test.ts +6 -0
- package/src/tests/session-summaries.test.ts +384 -0
- package/src/tests/sessions-tree.test.ts +5 -1
- package/src/tests/slack-app-icon.test.ts +90 -0
- package/src/tests/slack-external-channel-egress.test.ts +1 -1
- package/src/tests/slack-inbound-receipts.test.ts +34 -0
- package/src/tests/slack-inline-output.test.ts +29 -2
- package/src/tests/slack-render-v2-query-plans.test.ts +3 -2
- package/src/tests/slack-render-v2.test.ts +35 -0
- package/src/tests/slack-socket-ack.test.ts +553 -0
- package/src/tests/task-lineage.test.ts +3 -0
- package/src/tests/task-search-filter.test.ts +4 -4
- package/src/tests/task-search-fts.test.ts +320 -0
- package/src/tests/update-profile-auth.test.ts +28 -0
- package/src/tools/get-swarm.ts +1 -0
- package/src/tools/get-tasks.ts +6 -1
- package/src/tools/join-swarm.ts +1 -0
- package/src/tools/my-agent-info.ts +1 -0
- package/src/tools/slack-post.ts +2 -2
- package/src/tools/slack-reply.ts +2 -2
- package/src/tools/slack-start-thread.ts +2 -2
- package/src/tools/slack-update.ts +1 -1
- package/src/tools/update-profile.ts +20 -4
- package/src/tools/utils.ts +3 -4
- package/src/types.ts +47 -0
- package/src/utils/constants.ts +127 -5
- package/templates/official/lead/HEARTBEAT.md +4 -2
- package/templates/official/lead/config.json +2 -2
- package/templates/skills/swarm-docs/content.md +2 -0
- package/dist/handlers-7x8sywgr.js +0 -42
- package/dist/index-mc30r1hs.js +0 -44
|
@@ -2,18 +2,22 @@ import {
|
|
|
2
2
|
getAgentById2,
|
|
3
3
|
getTaskById2,
|
|
4
4
|
init_db3
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-wmhajw68.js";
|
|
6
6
|
import {
|
|
7
|
+
isAdmittedSlackDelivery,
|
|
7
8
|
slackTaskOutput,
|
|
8
9
|
getTaskUrl
|
|
9
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-ktcdczth.js";
|
|
11
|
+
import {
|
|
12
|
+
wasEventSeen
|
|
13
|
+
} from "./cli-157ykn37.js";
|
|
10
14
|
import {
|
|
11
15
|
shouldBlockChannel2
|
|
12
|
-
} from "./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
15
|
-
import"./cli-
|
|
16
|
-
import"./cli-
|
|
16
|
+
} from "./cli-0tkm519n.js";
|
|
17
|
+
import"./cli-9vttw9nz.js";
|
|
18
|
+
import"./cli-pnm99spe.js";
|
|
19
|
+
import"./cli-5ke7gxwr.js";
|
|
20
|
+
import"./cli-ghfhn1qc.js";
|
|
17
21
|
import"./cli-3ggwdtb0.js";
|
|
18
22
|
import"./cli-e8xyjvfc.js";
|
|
19
23
|
import"./cli-n0ysjjtv.js";
|
|
@@ -22,28 +26,27 @@ import"./cli-kvzgak7c.js";
|
|
|
22
26
|
import"./cli-445c1vp7.js";
|
|
23
27
|
import"./cli-jbgrwv4y.js";
|
|
24
28
|
import"./cli-eny54typ.js";
|
|
25
|
-
import"./cli-
|
|
26
|
-
import"./cli-
|
|
27
|
-
import"./cli-
|
|
28
|
-
import"./cli-
|
|
29
|
+
import"./cli-kjha1q9k.js";
|
|
30
|
+
import"./cli-e24w2mvk.js";
|
|
31
|
+
import"./cli-10kjx0dm.js";
|
|
32
|
+
import"./cli-jmk31131.js";
|
|
29
33
|
import"./cli-qz93y3x5.js";
|
|
30
|
-
import"./cli-
|
|
31
|
-
import"./cli-
|
|
32
|
-
import"./cli-
|
|
33
|
-
import"./cli-
|
|
34
|
-
import"./cli-
|
|
34
|
+
import"./cli-ja369zab.js";
|
|
35
|
+
import"./cli-a0w50zw9.js";
|
|
36
|
+
import"./cli-z52gq55b.js";
|
|
37
|
+
import"./cli-z6219sd3.js";
|
|
38
|
+
import"./cli-0xzbk52h.js";
|
|
35
39
|
import"./cli-3h26v7yj.js";
|
|
36
40
|
import"./cli-vpq0n13a.js";
|
|
37
|
-
import"./cli-
|
|
38
|
-
import"./cli-7xsq63pe.js";
|
|
41
|
+
import"./cli-54ax65rn.js";
|
|
39
42
|
import {
|
|
40
43
|
isUserAllowed2
|
|
41
|
-
} from "./cli-
|
|
44
|
+
} from "./cli-mmf43vcp.js";
|
|
42
45
|
import"./cli-13p25grh.js";
|
|
43
46
|
import"./cli-0adyhvq2.js";
|
|
44
|
-
import"./cli-
|
|
47
|
+
import"./cli-v9jk2k63.js";
|
|
45
48
|
import"./cli-rycdaj0a.js";
|
|
46
|
-
import"./cli-
|
|
49
|
+
import"./cli-kjcdzea8.js";
|
|
47
50
|
import {
|
|
48
51
|
isEnvFlagEnabled,
|
|
49
52
|
init_env_flag
|
|
@@ -125,9 +128,11 @@ async function getDetails(event, client) {
|
|
|
125
128
|
};
|
|
126
129
|
}
|
|
127
130
|
function registerWorkObjectHandlers(app) {
|
|
128
|
-
app.event("entity_details_requested", async ({ event, client, logger }) => {
|
|
131
|
+
app.event("entity_details_requested", async ({ event, body, client, logger }) => {
|
|
129
132
|
if (!isEnvFlagEnabled("SLACK_WORK_OBJECTS_ENABLED", false))
|
|
130
133
|
return;
|
|
134
|
+
if (!isAdmittedSlackDelivery() && wasEventSeen(body?.event_id))
|
|
135
|
+
return;
|
|
131
136
|
let details;
|
|
132
137
|
try {
|
|
133
138
|
details = await getDetails(event, client);
|
|
@@ -1,69 +1,69 @@
|
|
|
1
1
|
import"./cli-qz93y3x5.js";
|
|
2
2
|
import {
|
|
3
3
|
getEnabledCapabilities
|
|
4
|
-
} from "./cli-
|
|
5
|
-
import"./cli-
|
|
6
|
-
import"./cli-
|
|
7
|
-
import"./cli-
|
|
8
|
-
import"./cli-
|
|
9
|
-
import"./cli-
|
|
10
|
-
import"./cli-
|
|
4
|
+
} from "./cli-9vttw9nz.js";
|
|
5
|
+
import"./cli-wmhajw68.js";
|
|
6
|
+
import"./cli-ja369zab.js";
|
|
7
|
+
import"./cli-a0w50zw9.js";
|
|
8
|
+
import"./cli-10kjx0dm.js";
|
|
9
|
+
import"./cli-jmk31131.js";
|
|
10
|
+
import"./cli-e24w2mvk.js";
|
|
11
11
|
import"./cli-eny54typ.js";
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
12
|
+
import"./cli-pnm99spe.js";
|
|
13
|
+
import"./cli-5ke7gxwr.js";
|
|
14
|
+
import"./cli-ghfhn1qc.js";
|
|
15
15
|
import"./cli-3ggwdtb0.js";
|
|
16
16
|
import"./cli-e8xyjvfc.js";
|
|
17
|
-
import"./cli-
|
|
18
|
-
import"./cli-
|
|
17
|
+
import"./cli-ktcdczth.js";
|
|
18
|
+
import"./cli-0tkm519n.js";
|
|
19
19
|
import"./cli-n0ysjjtv.js";
|
|
20
20
|
import"./cli-2nf3b08t.js";
|
|
21
21
|
import"./cli-kvzgak7c.js";
|
|
22
22
|
import"./cli-445c1vp7.js";
|
|
23
23
|
import"./cli-jbgrwv4y.js";
|
|
24
|
-
import"./cli-
|
|
25
|
-
import"./cli-
|
|
26
|
-
import"./cli-
|
|
27
|
-
import"./cli-
|
|
24
|
+
import"./cli-kjha1q9k.js";
|
|
25
|
+
import"./cli-0xzbk52h.js";
|
|
26
|
+
import"./cli-z52gq55b.js";
|
|
27
|
+
import"./cli-z6219sd3.js";
|
|
28
28
|
import"./cli-3h26v7yj.js";
|
|
29
29
|
import"./cli-vpq0n13a.js";
|
|
30
30
|
import"./cli-8wd3mbyj.js";
|
|
31
31
|
import"./cli-vqgnyh76.js";
|
|
32
32
|
import"./cli-77cd6gy8.js";
|
|
33
|
-
import"./cli-
|
|
33
|
+
import"./cli-6151a7dr.js";
|
|
34
34
|
import {
|
|
35
35
|
runAgent
|
|
36
|
-
} from "./cli-
|
|
36
|
+
} from "./cli-8a1k6mat.js";
|
|
37
37
|
import"./cli-4887xyd1.js";
|
|
38
38
|
import"./cli-9cctx1tn.js";
|
|
39
39
|
import"./cli-cr3k93hd.js";
|
|
40
40
|
import"./cli-jc1g9ndz.js";
|
|
41
|
-
import"./cli-
|
|
42
|
-
import"./cli-
|
|
41
|
+
import"./cli-ct5920jb.js";
|
|
42
|
+
import"./cli-2h0rfmqk.js";
|
|
43
43
|
import"./cli-5xbma5yx.js";
|
|
44
44
|
import"./cli-d82btycs.js";
|
|
45
45
|
import"./cli-0726awxw.js";
|
|
46
|
-
import"./cli-
|
|
47
|
-
import"./cli-
|
|
46
|
+
import"./cli-aqp59jmv.js";
|
|
47
|
+
import"./cli-8ch3b2r7.js";
|
|
48
48
|
import"./cli-4bd1rck6.js";
|
|
49
49
|
import"./cli-h3e7bhvn.js";
|
|
50
50
|
import"./cli-prcyzecg.js";
|
|
51
51
|
import"./cli-dehgvj25.js";
|
|
52
52
|
import"./cli-kr5tjjtz.js";
|
|
53
|
-
import"./cli-
|
|
54
|
-
import"./cli-
|
|
53
|
+
import"./cli-mcmpbpcc.js";
|
|
54
|
+
import"./cli-9fk56y8c.js";
|
|
55
55
|
import"./cli-9y354g3j.js";
|
|
56
|
-
import"./cli-
|
|
57
|
-
import"./cli-
|
|
56
|
+
import"./cli-0zae6bs6.js";
|
|
57
|
+
import"./cli-xz6qjdqj.js";
|
|
58
58
|
import"./cli-0n39ee9n.js";
|
|
59
59
|
import"./cli-5z6xz9xs.js";
|
|
60
|
-
import"./cli-
|
|
60
|
+
import"./cli-07pcqwaj.js";
|
|
61
61
|
import"./cli-4zsenjhy.js";
|
|
62
62
|
import"./cli-13p25grh.js";
|
|
63
63
|
import"./cli-0adyhvq2.js";
|
|
64
|
-
import"./cli-
|
|
64
|
+
import"./cli-v9jk2k63.js";
|
|
65
65
|
import"./cli-rycdaj0a.js";
|
|
66
|
-
import"./cli-
|
|
66
|
+
import"./cli-kjcdzea8.js";
|
|
67
67
|
|
|
68
68
|
// src/commands/worker.ts
|
|
69
69
|
var workerConfig = {
|
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": "2.7.
|
|
5
|
+
"version": "2.7.3",
|
|
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": [
|
|
@@ -1016,6 +1016,64 @@
|
|
|
1016
1016
|
"reportedAt"
|
|
1017
1017
|
]
|
|
1018
1018
|
},
|
|
1019
|
+
"AgentSlackIcon": {
|
|
1020
|
+
"oneOf": [
|
|
1021
|
+
{
|
|
1022
|
+
"type": "object",
|
|
1023
|
+
"properties": {
|
|
1024
|
+
"type": {
|
|
1025
|
+
"type": "string",
|
|
1026
|
+
"enum": [
|
|
1027
|
+
"emoji"
|
|
1028
|
+
]
|
|
1029
|
+
},
|
|
1030
|
+
"emoji": {
|
|
1031
|
+
"type": "string",
|
|
1032
|
+
"maxLength": 102,
|
|
1033
|
+
"pattern": "^:[a-z0-9_+'-]+:$"
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
"required": [
|
|
1037
|
+
"type",
|
|
1038
|
+
"emoji"
|
|
1039
|
+
]
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
"type": "object",
|
|
1043
|
+
"properties": {
|
|
1044
|
+
"type": {
|
|
1045
|
+
"type": "string",
|
|
1046
|
+
"enum": [
|
|
1047
|
+
"url"
|
|
1048
|
+
]
|
|
1049
|
+
},
|
|
1050
|
+
"url": {
|
|
1051
|
+
"type": "string",
|
|
1052
|
+
"maxLength": 2048,
|
|
1053
|
+
"format": "uri"
|
|
1054
|
+
}
|
|
1055
|
+
},
|
|
1056
|
+
"required": [
|
|
1057
|
+
"type",
|
|
1058
|
+
"url"
|
|
1059
|
+
]
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
"type": "object",
|
|
1063
|
+
"properties": {
|
|
1064
|
+
"type": {
|
|
1065
|
+
"type": "string",
|
|
1066
|
+
"enum": [
|
|
1067
|
+
"app"
|
|
1068
|
+
]
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1071
|
+
"required": [
|
|
1072
|
+
"type"
|
|
1073
|
+
]
|
|
1074
|
+
}
|
|
1075
|
+
]
|
|
1076
|
+
},
|
|
1019
1077
|
"Agent": {
|
|
1020
1078
|
"type": "object",
|
|
1021
1079
|
"properties": {
|
|
@@ -1189,6 +1247,16 @@
|
|
|
1189
1247
|
}
|
|
1190
1248
|
]
|
|
1191
1249
|
},
|
|
1250
|
+
"slackIcon": {
|
|
1251
|
+
"oneOf": [
|
|
1252
|
+
{
|
|
1253
|
+
"$ref": "#/components/schemas/AgentSlackIcon"
|
|
1254
|
+
},
|
|
1255
|
+
{
|
|
1256
|
+
"type": "null"
|
|
1257
|
+
}
|
|
1258
|
+
]
|
|
1259
|
+
},
|
|
1192
1260
|
"createdAt": {
|
|
1193
1261
|
"type": "string",
|
|
1194
1262
|
"format": "date-time"
|
|
@@ -11804,6 +11872,16 @@
|
|
|
11804
11872
|
}
|
|
11805
11873
|
]
|
|
11806
11874
|
},
|
|
11875
|
+
"slackIcon": {
|
|
11876
|
+
"oneOf": [
|
|
11877
|
+
{
|
|
11878
|
+
"$ref": "#/components/schemas/AgentSlackIcon"
|
|
11879
|
+
},
|
|
11880
|
+
{
|
|
11881
|
+
"type": "null"
|
|
11882
|
+
}
|
|
11883
|
+
]
|
|
11884
|
+
},
|
|
11807
11885
|
"changeSource": {
|
|
11808
11886
|
"type": "string"
|
|
11809
11887
|
},
|
|
@@ -23619,6 +23697,42 @@
|
|
|
23619
23697
|
}
|
|
23620
23698
|
}
|
|
23621
23699
|
},
|
|
23700
|
+
"/api/integrations/slack/app-icon": {
|
|
23701
|
+
"get": {
|
|
23702
|
+
"summary": "The Slack app's own avatar, shown on posts with no icon override",
|
|
23703
|
+
"tags": [
|
|
23704
|
+
"Integrations"
|
|
23705
|
+
],
|
|
23706
|
+
"security": [
|
|
23707
|
+
{
|
|
23708
|
+
"bearerAuth": []
|
|
23709
|
+
}
|
|
23710
|
+
],
|
|
23711
|
+
"responses": {
|
|
23712
|
+
"200": {
|
|
23713
|
+
"description": "`imageUrl` is null when Slack is off or the lookup fails.",
|
|
23714
|
+
"content": {
|
|
23715
|
+
"application/json": {
|
|
23716
|
+
"schema": {
|
|
23717
|
+
"type": "object",
|
|
23718
|
+
"properties": {
|
|
23719
|
+
"imageUrl": {
|
|
23720
|
+
"type": [
|
|
23721
|
+
"string",
|
|
23722
|
+
"null"
|
|
23723
|
+
]
|
|
23724
|
+
}
|
|
23725
|
+
},
|
|
23726
|
+
"required": [
|
|
23727
|
+
"imageUrl"
|
|
23728
|
+
]
|
|
23729
|
+
}
|
|
23730
|
+
}
|
|
23731
|
+
}
|
|
23732
|
+
}
|
|
23733
|
+
}
|
|
23734
|
+
}
|
|
23735
|
+
},
|
|
23622
23736
|
"/api/integrations/chat/status": {
|
|
23623
23737
|
"get": {
|
|
23624
23738
|
"summary": "Chat SDK channel status: enabled flag, Slack clash, per-adapter health and webhook URL.",
|
|
@@ -30586,7 +30700,7 @@
|
|
|
30586
30700
|
"/status": {
|
|
30587
30701
|
"get": {
|
|
30588
30702
|
"summary": "Identity + setup readiness + live activity for the swarm dashboard",
|
|
30589
|
-
"description": "Single source of truth consumed by the UI home page. Identity comes from SWARM_* envs; setup milestones each emit `unverified | configured | verified`; automations report `running | needs_setup` from the same runtime preflight used at dispatch; activity counts agents alive in the last 5 min, leads that can take work (status idle or busy), and tasks created in the last 24h; agent_fs reports whether AGENT_FS_API_URL is set, plus the Comb settings (
|
|
30703
|
+
"description": "Single source of truth consumed by the UI home page. Identity comes from SWARM_* envs; setup milestones each emit `unverified | configured | verified`; automations report `running | needs_setup` from the same runtime preflight used at dispatch; activity counts agents alive in the last 5 min, leads that can take work (status idle or busy), and tasks created in the last 24h; agent_fs reports whether AGENT_FS_API_URL is set, plus the Comb settings (whether Files is on and, when off, what is missing; the browser-facing agent-fs URL, the shared org and drive ids, and the agent-fs user id of the swarm service account); telemetry reports the effective ANONYMIZED_TELEMETRY opt-out state.",
|
|
30590
30704
|
"tags": [
|
|
30591
30705
|
"Status"
|
|
30592
30706
|
],
|
|
@@ -30820,6 +30934,12 @@
|
|
|
30820
30934
|
"enabled": {
|
|
30821
30935
|
"type": "boolean"
|
|
30822
30936
|
},
|
|
30937
|
+
"reason": {
|
|
30938
|
+
"type": [
|
|
30939
|
+
"string",
|
|
30940
|
+
"null"
|
|
30941
|
+
]
|
|
30942
|
+
},
|
|
30823
30943
|
"api_url": {
|
|
30824
30944
|
"type": [
|
|
30825
30945
|
"string",
|
|
@@ -30850,6 +30970,7 @@
|
|
|
30850
30970
|
},
|
|
30851
30971
|
"required": [
|
|
30852
30972
|
"enabled",
|
|
30973
|
+
"reason",
|
|
30853
30974
|
"api_url",
|
|
30854
30975
|
"live_url",
|
|
30855
30976
|
"org_id",
|
|
@@ -33807,9 +33928,11 @@
|
|
|
33807
33928
|
},
|
|
33808
33929
|
{
|
|
33809
33930
|
"schema": {
|
|
33810
|
-
"type": "string"
|
|
33931
|
+
"type": "string",
|
|
33932
|
+
"description": "Search task text and title by word or phrase, with a prefix match on the last word, or a task id by prefix. Not a substring match: '2443' does not find '12443', and '%' and '_' are not wildcards."
|
|
33811
33933
|
},
|
|
33812
33934
|
"required": false,
|
|
33935
|
+
"description": "Search task text and title by word or phrase, with a prefix match on the last word, or a task id by prefix. Not a substring match: '2443' does not find '12443', and '%' and '_' are not wildcards.",
|
|
33813
33936
|
"name": "search",
|
|
33814
33937
|
"in": "query"
|
|
33815
33938
|
},
|
|
@@ -54576,6 +54699,9 @@
|
|
|
54576
54699
|
"uncertain": {
|
|
54577
54700
|
"type": "number"
|
|
54578
54701
|
},
|
|
54702
|
+
"ackNotReady": {
|
|
54703
|
+
"type": "number"
|
|
54704
|
+
},
|
|
54579
54705
|
"lastOutcomeAt": {
|
|
54580
54706
|
"type": [
|
|
54581
54707
|
"string",
|
|
@@ -54606,6 +54732,7 @@
|
|
|
54606
54732
|
"ignored",
|
|
54607
54733
|
"failed",
|
|
54608
54734
|
"uncertain",
|
|
54735
|
+
"ackNotReady",
|
|
54609
54736
|
"lastOutcomeAt",
|
|
54610
54737
|
"lastFailure"
|
|
54611
54738
|
]
|
|
@@ -54625,6 +54752,9 @@
|
|
|
54625
54752
|
"uncertain": {
|
|
54626
54753
|
"type": "number"
|
|
54627
54754
|
},
|
|
54755
|
+
"ackNotReady": {
|
|
54756
|
+
"type": "number"
|
|
54757
|
+
},
|
|
54628
54758
|
"lastOutcomeAt": {
|
|
54629
54759
|
"type": [
|
|
54630
54760
|
"string",
|
|
@@ -54655,6 +54785,7 @@
|
|
|
54655
54785
|
"ignored",
|
|
54656
54786
|
"failed",
|
|
54657
54787
|
"uncertain",
|
|
54788
|
+
"ackNotReady",
|
|
54658
54789
|
"lastOutcomeAt",
|
|
54659
54790
|
"lastFailure"
|
|
54660
54791
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@desplega.ai/agent-swarm",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.3",
|
|
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",
|
|
@@ -203,7 +203,7 @@
|
|
|
203
203
|
"dependencies": {
|
|
204
204
|
"@agentclientprotocol/sdk": "2.0.2",
|
|
205
205
|
"@ai-sdk/openai": "^3.0.41",
|
|
206
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
206
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.312",
|
|
207
207
|
"@anthropic-ai/sdk": "^1.3.0",
|
|
208
208
|
"@asteasolutions/zod-to-openapi": "^8.0.0",
|
|
209
209
|
"@aws-sdk/client-bedrock": "3.1048.0",
|
|
@@ -211,8 +211,8 @@
|
|
|
211
211
|
"@chat-adapter/slack": "4.41.1",
|
|
212
212
|
"@chat-adapter/teams": "4.41.1",
|
|
213
213
|
"@chat-adapter/telegram": "4.41.1",
|
|
214
|
-
"@cursor/sdk": "1.
|
|
215
|
-
"@desplega.ai/agent-fs-just-bash": "0.18.
|
|
214
|
+
"@cursor/sdk": "1.2.0",
|
|
215
|
+
"@desplega.ai/agent-fs-just-bash": "0.18.12",
|
|
216
216
|
"@desplega.ai/business-use": "^0.4.2",
|
|
217
217
|
"@earendil-works/pi-agent-core": "^1.4.0",
|
|
218
218
|
"@earendil-works/pi-ai": "^1.4.0",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
"@jitl/quickjs-singlefile-mjs-release-sync": "0.32.0",
|
|
222
222
|
"@linear/sdk": "^77.0.0",
|
|
223
223
|
"@modelcontextprotocol/sdk": "1.32.1",
|
|
224
|
-
"@openai/codex": "0.
|
|
224
|
+
"@openai/codex": "0.165.0",
|
|
225
225
|
"@openfort/openfort-node": "^0.9.1",
|
|
226
226
|
"@opentelemetry/api": "^1.9.1",
|
|
227
227
|
"@opentelemetry/api-logs": "^0.218.0",
|
package/src/be/db/agents.ts
CHANGED
|
@@ -5,12 +5,13 @@ import type {
|
|
|
5
5
|
AgentLog,
|
|
6
6
|
AgentLogEventType,
|
|
7
7
|
AgentSkill,
|
|
8
|
+
AgentSlackIcon,
|
|
8
9
|
AgentStatus,
|
|
9
10
|
AgentTask,
|
|
10
11
|
ProviderName,
|
|
11
12
|
RoutingAffinity,
|
|
12
13
|
} from "../../types";
|
|
13
|
-
import { AgentAvatarSchema } from "../../types";
|
|
14
|
+
import { AgentAvatarSchema, AgentSlackIconSchema } from "../../types";
|
|
14
15
|
import { isEnvFlagEnabled } from "../../utils/env-flag";
|
|
15
16
|
import { getDbClient } from "./runtime";
|
|
16
17
|
|
|
@@ -63,6 +64,8 @@ export type AgentRow = {
|
|
|
63
64
|
cred_status: string | null;
|
|
64
65
|
/** Migration 119: custom avatar (JSON of AgentAvatar). NULL = deterministic hash-derived fallback. */
|
|
65
66
|
avatar: string | null;
|
|
67
|
+
/** Migration 256: JSON of AgentSlackIcon. */
|
|
68
|
+
slack_icon: string | null;
|
|
66
69
|
runtime_pool_id: string | null;
|
|
67
70
|
runtime_provision_attempts: number;
|
|
68
71
|
runtime_provision_retry_at: string | null;
|
|
@@ -81,6 +84,17 @@ function parseAgentAvatar(raw: string | null): AgentAvatar | null {
|
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
86
|
|
|
87
|
+
/** Malformed content falls back to `null`, like `parseAgentAvatar`. */
|
|
88
|
+
function parseAgentSlackIcon(raw: string | null): AgentSlackIcon | null {
|
|
89
|
+
if (!raw) return null;
|
|
90
|
+
try {
|
|
91
|
+
const parsed = AgentSlackIconSchema.safeParse(JSON.parse(raw));
|
|
92
|
+
return parsed.success ? parsed.data : null;
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
84
98
|
/**
|
|
85
99
|
* Map an agent row to the `Agent` shape. When `slim` is true the six identity
|
|
86
100
|
* markdown blobs (`claudeMd`/`soulMd`/`identityMd`/`toolsMd`/`heartbeatMd`/
|
|
@@ -112,6 +126,7 @@ export function rowToAgent(row: AgentRow, slim = false): Agent {
|
|
|
112
126
|
: null,
|
|
113
127
|
credStatus: row.cred_status ? (JSON.parse(row.cred_status) as AgentCredStatus) : null,
|
|
114
128
|
avatar: parseAgentAvatar(row.avatar),
|
|
129
|
+
slackIcon: parseAgentSlackIcon(row.slack_icon),
|
|
115
130
|
};
|
|
116
131
|
if (slim) return base;
|
|
117
132
|
return {
|
package/src/be/db/runtime.ts
CHANGED
|
@@ -201,25 +201,35 @@ function bootOpenedDb(
|
|
|
201
201
|
.all()
|
|
202
202
|
.map((column) => `"${column.name.replaceAll('"', '""')}"`)
|
|
203
203
|
.join(", ");
|
|
204
|
+
// Triggers on other tables that read agent_tasks (the session summary
|
|
205
|
+
// recompute, migration 253) would fail the rename's schema check while
|
|
206
|
+
// agent_tasks is dropped, so they are dropped and re-created too.
|
|
204
207
|
const schemaObjects = database
|
|
205
|
-
.prepare<{ sql: string }, []>(
|
|
206
|
-
`SELECT sql FROM sqlite_master
|
|
207
|
-
WHERE
|
|
208
|
-
AND type IN ('index', 'trigger')
|
|
208
|
+
.prepare<{ name: string; tbl_name: string; sql: string }, []>(
|
|
209
|
+
`SELECT name, tbl_name, sql FROM sqlite_master
|
|
210
|
+
WHERE type IN ('index', 'trigger')
|
|
209
211
|
AND sql IS NOT NULL
|
|
212
|
+
AND (tbl_name = 'agent_tasks' OR (type = 'trigger' AND sql LIKE '%agent_tasks%'))
|
|
210
213
|
ORDER BY type, name`,
|
|
211
214
|
)
|
|
212
|
-
.all()
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
215
|
+
.all();
|
|
216
|
+
|
|
217
|
+
database
|
|
218
|
+
.transaction(() => {
|
|
219
|
+
database.run("DROP TABLE IF EXISTS agent_tasks_new");
|
|
220
|
+
database.run(rebuiltSchemaSql);
|
|
221
|
+
// Copy rowids too: agent_tasks_fts (migration 256) is keyed by them.
|
|
222
|
+
database.run(
|
|
223
|
+
`INSERT INTO agent_tasks_new (rowid, ${columns}) SELECT rowid, ${columns} FROM agent_tasks`,
|
|
224
|
+
);
|
|
225
|
+
for (const object of schemaObjects) {
|
|
226
|
+
if (object.tbl_name !== "agent_tasks") database.run(`DROP TRIGGER "${object.name}"`);
|
|
227
|
+
}
|
|
228
|
+
database.run("DROP TABLE agent_tasks");
|
|
229
|
+
database.run("ALTER TABLE agent_tasks_new RENAME TO agent_tasks");
|
|
230
|
+
for (const object of schemaObjects) database.run(object.sql);
|
|
231
|
+
})
|
|
232
|
+
.immediate();
|
|
223
233
|
|
|
224
234
|
database.run("PRAGMA foreign_keys=on");
|
|
225
235
|
console.log("[Migration] Successfully removed CHECK constraint on agent_tasks.status");
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { getDbClient } from "./runtime";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `session_summaries` and `session_members` (migration 253) store the session
|
|
5
|
+
* chain walk: one row per root with its chain aggregates, and the root of
|
|
6
|
+
* every chain task. Triggers keep them exact on every task, steering and
|
|
7
|
+
* approval write. The one exception is a deleted task's descendants: a
|
|
8
|
+
* trigger body cannot walk the chain, so `deleteTask` calls
|
|
9
|
+
* {@link dropSessionDescendants} before the DELETE.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Drop the members rows of a task's descendants. Once the task is gone, the
|
|
14
|
+
* chain walk no longer reaches them, so they belong to no session. Call it in
|
|
15
|
+
* the delete's transaction, before the DELETE; the delete trigger then
|
|
16
|
+
* recomputes the chain's summary.
|
|
17
|
+
*/
|
|
18
|
+
export async function dropSessionDescendants(taskId: string): Promise<void> {
|
|
19
|
+
// UNION, not UNION ALL: a parentTaskId cycle written before migration 253
|
|
20
|
+
// must not loop.
|
|
21
|
+
await getDbClient().run(
|
|
22
|
+
`WITH RECURSIVE descendant(id) AS (
|
|
23
|
+
SELECT id FROM agent_tasks WHERE parentTaskId = ?
|
|
24
|
+
UNION SELECT t.id FROM descendant d JOIN agent_tasks t ON t.parentTaskId = d.id
|
|
25
|
+
) DELETE FROM session_members WHERE taskId IN (SELECT id FROM descendant)`,
|
|
26
|
+
[taskId],
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface SessionSummaryDrift {
|
|
31
|
+
rootId: string;
|
|
32
|
+
/** The field that differs, or `member` for a chain task whose members row is wrong. */
|
|
33
|
+
field:
|
|
34
|
+
| "summary-missing"
|
|
35
|
+
| "summary-extra"
|
|
36
|
+
| "chainCount"
|
|
37
|
+
| "lastActivityAt"
|
|
38
|
+
| "latestStatus"
|
|
39
|
+
| "pendingApproval"
|
|
40
|
+
| "lastHumanAt"
|
|
41
|
+
| "member";
|
|
42
|
+
expected: string | number | null;
|
|
43
|
+
stored: string | number | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const HUMAN_TASK_SQL = `t.requestedByUserId IS NOT NULL AND t.requestedByUserIdInherited = 0
|
|
47
|
+
AND COALESCE(t.source, '') NOT IN ('mcp', 'system', 'schedule', 'workflow')`;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Read-only drift check: compares the stored summaries and members with a
|
|
51
|
+
* fresh chain walk (the rule `sessionSummaryQuery` applies today). Returns one
|
|
52
|
+
* row per mismatch, so an empty result means the tables are exact. With
|
|
53
|
+
* `since`, only roots whose chain activity is at or after it are compared.
|
|
54
|
+
* `latestStatus` is skipped when two chain tasks tie on the newest
|
|
55
|
+
* `lastUpdatedAt`: the walk then picks an arbitrary one.
|
|
56
|
+
*/
|
|
57
|
+
export function sessionSummaryDriftQuery(since: string | null = null): {
|
|
58
|
+
sql: string;
|
|
59
|
+
params: (string | null)[];
|
|
60
|
+
} {
|
|
61
|
+
return {
|
|
62
|
+
sql: `WITH RECURSIVE chain(root_id, id) AS (
|
|
63
|
+
SELECT id, id FROM agent_tasks WHERE parentTaskId IS NULL
|
|
64
|
+
UNION ALL SELECT c.root_id, t.id FROM chain c JOIN agent_tasks t ON t.parentTaskId = c.id
|
|
65
|
+
), walked AS (
|
|
66
|
+
SELECT c.root_id, COUNT(*) AS chainCount, t.status AS latestStatus,
|
|
67
|
+
MAX(t.lastUpdatedAt) AS lastActivityAt
|
|
68
|
+
FROM chain c JOIN agent_tasks t ON t.id = c.id GROUP BY c.root_id
|
|
69
|
+
), expected AS (
|
|
70
|
+
SELECT w.*,
|
|
71
|
+
(SELECT COUNT(*) FROM chain c JOIN agent_tasks t ON t.id = c.id
|
|
72
|
+
WHERE c.root_id = w.root_id AND t.lastUpdatedAt = w.lastActivityAt) AS newest,
|
|
73
|
+
EXISTS (SELECT 1 FROM chain c JOIN approval_requests ar ON ar.sourceTaskId = c.id
|
|
74
|
+
WHERE c.root_id = w.root_id AND ar.status = 'pending') AS pendingApproval,
|
|
75
|
+
(SELECT MAX(at) FROM (
|
|
76
|
+
SELECT t.createdAt AS at FROM chain c JOIN agent_tasks t ON t.id = c.id
|
|
77
|
+
WHERE c.root_id = w.root_id AND ${HUMAN_TASK_SQL}
|
|
78
|
+
UNION ALL SELECT sm.created_at FROM chain c JOIN task_steering_messages sm ON sm.task_id = c.id
|
|
79
|
+
WHERE c.root_id = w.root_id AND sm.created_by_kind = 'user' AND sm.status != 'cancelled'
|
|
80
|
+
UNION ALL SELECT ar.createdAt FROM chain c JOIN approval_requests ar ON ar.sourceTaskId = c.id
|
|
81
|
+
WHERE c.root_id = w.root_id AND ar.status = 'pending')) AS lastHumanAt
|
|
82
|
+
FROM walked w WHERE (? IS NULL OR w.lastActivityAt >= ?)
|
|
83
|
+
), stored AS (
|
|
84
|
+
SELECT * FROM session_summaries s WHERE (? IS NULL OR s.lastActivityAt >= ?)
|
|
85
|
+
)
|
|
86
|
+
SELECT e.root_id AS rootId, 'summary-missing' AS field, e.chainCount AS expected, NULL AS stored
|
|
87
|
+
FROM expected e LEFT JOIN session_summaries s ON s.rootId = e.root_id WHERE s.rootId IS NULL
|
|
88
|
+
UNION ALL SELECT s.rootId, 'summary-extra', NULL, s.chainCount
|
|
89
|
+
FROM stored s LEFT JOIN walked w ON w.root_id = s.rootId WHERE w.root_id IS NULL
|
|
90
|
+
UNION ALL SELECT e.root_id, 'chainCount', e.chainCount, s.chainCount
|
|
91
|
+
FROM expected e JOIN session_summaries s ON s.rootId = e.root_id WHERE s.chainCount IS NOT e.chainCount
|
|
92
|
+
UNION ALL SELECT e.root_id, 'lastActivityAt', e.lastActivityAt, s.lastActivityAt
|
|
93
|
+
FROM expected e JOIN session_summaries s ON s.rootId = e.root_id
|
|
94
|
+
WHERE s.lastActivityAt IS NOT e.lastActivityAt
|
|
95
|
+
UNION ALL SELECT e.root_id, 'latestStatus', e.latestStatus, s.latestStatus
|
|
96
|
+
FROM expected e JOIN session_summaries s ON s.rootId = e.root_id
|
|
97
|
+
WHERE e.newest = 1 AND s.latestStatus IS NOT e.latestStatus
|
|
98
|
+
UNION ALL SELECT e.root_id, 'pendingApproval', e.pendingApproval, s.pendingApprovalCount > 0
|
|
99
|
+
FROM expected e JOIN session_summaries s ON s.rootId = e.root_id
|
|
100
|
+
WHERE (s.pendingApprovalCount > 0) IS NOT e.pendingApproval
|
|
101
|
+
UNION ALL SELECT e.root_id, 'lastHumanAt', e.lastHumanAt, s.lastHumanAt
|
|
102
|
+
FROM expected e JOIN session_summaries s ON s.rootId = e.root_id
|
|
103
|
+
WHERE s.lastHumanAt IS NOT e.lastHumanAt
|
|
104
|
+
UNION ALL SELECT c.root_id, 'member', c.id, m.rootId
|
|
105
|
+
FROM chain c JOIN expected e ON e.root_id = c.root_id
|
|
106
|
+
LEFT JOIN session_members m ON m.taskId = c.id WHERE m.rootId IS NOT c.root_id
|
|
107
|
+
UNION ALL SELECT m.rootId, 'member', NULL, m.taskId
|
|
108
|
+
FROM session_members m LEFT JOIN chain c ON c.id = m.taskId AND c.root_id = m.rootId
|
|
109
|
+
WHERE c.id IS NULL AND (? IS NULL OR m.rootId IN (SELECT rootId FROM stored))`,
|
|
110
|
+
params: [since, since, since, since, since],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Run {@link sessionSummaryDriftQuery}. */
|
|
115
|
+
export async function findSessionSummaryDrift(
|
|
116
|
+
since: string | null = null,
|
|
117
|
+
): Promise<SessionSummaryDrift[]> {
|
|
118
|
+
const query = sessionSummaryDriftQuery(since);
|
|
119
|
+
return await getDbClient().query<SessionSummaryDrift>(query.sql, query.params);
|
|
120
|
+
}
|