@desplega.ai/agent-swarm 2.4.5 → 2.5.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.
- package/README.md +4 -2
- package/dist/{acp-adapter-2wdkktv6.js → acp-adapter-7g6bpwbk.js} +8 -6
- package/dist/{actions-c40ebcm4.js → actions-w8xd014k.js} +23 -21
- package/dist/{amp-adapter-wb67m95z.js → amp-adapter-z4qvhacj.js} +2 -2
- package/dist/{anthropic-messages-g6pqmqk4.js → anthropic-messages-txs190dd.js} +17 -20
- package/dist/{app-353vre8g.js → app-nndcvftq.js} +3 -3
- package/dist/{assistant-sj1njh23.js → assistant-hjmqyscx.js} +24 -22
- package/dist/{azure-openai-responses-9dbmj346.js → azure-openai-responses-9kfwhmn7.js} +18 -13
- package/dist/{boot-reembed-b9c3az3c.js → boot-reembed-r8rhf9h8.js} +1 -1
- package/dist/{boot-reembed-qdkvxeem.js → boot-reembed-vwcj2y5d.js} +1 -1
- package/dist/{boot-scrub-sweep-m3wh8eks.js → boot-scrub-sweep-fr9q36ne.js} +4 -4
- package/dist/{boot-seeds-j2273s54.js → boot-seeds-9jqwnegq.js} +4 -4
- package/dist/{claude-adapter-m7q0a085.js → claude-adapter-2f8b85df.js} +8 -6
- package/dist/{claude-managed-adapter-5ptb6tzs.js → claude-managed-adapter-gt6pa35d.js} +2 -2
- package/dist/{claude-managed-setup-smrqk5j5.js → claude-managed-setup-c3hp36ph.js} +4 -4
- package/dist/{claude-sdk-session-38xnz21e.js → claude-sdk-session-05kat8rv.js} +9012 -8928
- package/dist/{cli-b9fcxxev.js → cli-007cnhm1.js} +50 -4
- package/dist/{cli-j4rqdf2n.js → cli-03vpq45j.js} +2 -2
- package/dist/{cli-1sp861s4.js → cli-0jy85zz4.js} +11 -11
- package/dist/{cli-j99azg3g.js → cli-1dp1zj04.js} +5 -5
- package/dist/{cli-3r8samv3.js → cli-1f0gp9vz.js} +3 -2
- package/dist/{cli-94gwyg7m.js → cli-22rmcjkg.js} +9 -9
- package/dist/{cli-ms85309d.js → cli-2jg61wab.js} +11 -11
- package/dist/{cli-0bqteszy.js → cli-2nf3b08t.js} +328 -25
- package/dist/{cli-9yqgm9nd.js → cli-2wba1ac9.js} +161 -63
- package/dist/{cli-cxxe61f6.js → cli-3ee5z0q0.js} +2 -2
- package/dist/{cli-k8g16gz3.js → cli-3qv8naq8.js} +115 -119
- package/dist/{cli-60cgh1rv.js → cli-459fk97x.js} +7 -7
- package/dist/{cli-h7gc0b4r.js → cli-5m84zd2k.js} +55 -18
- package/dist/{cli-dvkmp9bt.js → cli-6ctwrf1z.js} +20 -10
- package/dist/{cli-848hxdwj.js → cli-6rg2jn2y.js} +2 -1
- package/dist/{cli-dk44dxec.js → cli-9mm5ade4.js} +1 -1
- package/dist/{cli-7c9qs530.js → cli-ajqhxtnz.js} +5 -5
- package/dist/{cli-be2161h1.js → cli-cah5detr.js} +6 -6
- package/dist/{cli-v8fjakwf.js → cli-cwyafhw1.js} +1 -1
- package/dist/{cli-wxbn3yfx.js → cli-cz5nmdxt.js} +2 -2
- package/dist/{cli-wt645v7q.js → cli-dabehxhp.js} +1 -1
- package/dist/{cli-vfha21c9.js → cli-e5bxnjps.js} +2 -2
- package/dist/{cli-37j04k05.js → cli-e9btqw4y.js} +13 -13
- package/dist/{cli-1syn2xy1.js → cli-eym3jg7w.js} +32 -18
- package/dist/{cli-ftc1g5tj.js → cli-fes51ya2.js} +3 -3
- package/dist/{cli-s95dknxh.js → cli-g1cw7xtt.js} +1 -1
- package/dist/{cli-74c1wpm0.js → cli-gpv60278.js} +1 -1
- package/dist/{cli-1f3qzw6y.js → cli-gwcf52gz.js} +2 -2
- package/dist/{cli-pemywhfq.js → cli-ha9rmwgq.js} +2 -1
- package/dist/{cli-v0yrfmdh.js → cli-hadv0725.js} +3 -3
- package/dist/{cli-g35m2xwm.js → cli-j1eghqfm.js} +2 -2
- package/dist/{cli-qfxc84gh.js → cli-jpxsrxcb.js} +1 -1
- package/dist/{cli-n72rg53p.js → cli-kcsd1ez8.js} +848 -426
- package/dist/{cli-ejs3m1sx.js → cli-kxpfx2xr.js} +1 -1
- package/dist/{cli-pnp2j5zg.js → cli-mmhj8vd7.js} +2 -2
- package/dist/{cli-st8aw1m6.js → cli-mq7kg1b1.js} +4 -4
- package/dist/{cli-bnes4z6b.js → cli-mz2ygeyq.js} +3 -3
- package/dist/{cli-xf234ws8.js → cli-n4c8e3s5.js} +2 -0
- package/dist/{cli-f01h25yt.js → cli-n6kmqngw.js} +2 -2
- package/dist/cli-nj12tn2c.js +1193 -0
- package/dist/{cli-1dmcq2eh.js → cli-nzfnt2gs.js} +1 -1
- package/dist/{cli-625tb7aq.js → cli-p859hcc8.js} +2 -2
- package/dist/{cli-smvcw9z5.js → cli-pasyvjmm.js} +1 -1
- package/dist/cli-pkaqk57w.js +128 -0
- package/dist/{cli-xpa64rek.js → cli-pyy4c9ch.js} +2362 -159
- package/dist/{cli-wt0jf9hm.js → cli-q9pzwxvk.js} +553 -193
- package/dist/{cli-z7d29rw9.js → cli-qfjm4gvt.js} +4 -4
- package/dist/{cli-p14m2cnp.js → cli-qfm6my86.js} +1 -1
- package/dist/{cli-8nyhf7za.js → cli-qqzmjxkf.js} +129 -105
- package/dist/{cli-4zfqgjc5.js → cli-r9fy0ddc.js} +2 -2
- package/dist/{cli-eww120g8.js → cli-rh5smt8t.js} +18 -4
- package/dist/{cli-a92r1127.js → cli-rngde2jv.js} +2 -2
- package/dist/{cli-qwkcwjdn.js → cli-rycdaj0a.js} +1 -1
- package/dist/{cli-fv5hepyy.js → cli-sn1vbtg2.js} +3 -3
- package/dist/{cli-36ckw0wx.js → cli-stxdrqs2.js} +2 -2
- package/dist/{cli-1m17dc9d.js → cli-ta8bd7th.js} +2 -2
- package/dist/{cli-43x64hv3.js → cli-v2g93k4v.js} +4 -4
- package/dist/{cli-d2mb5s8a.js → cli-x77gen2p.js} +680 -440
- package/dist/{cli-3a45zcgm.js → cli-xc65x52q.js} +2 -2
- package/dist/{cli-f0g3pgvf.js → cli-xd4eqtr2.js} +2 -2
- package/dist/{cli-018r4jq6.js → cli-y3zyaee5.js} +8 -8
- package/dist/{cli-kpw04va0.js → cli-z2dv25mf.js} +1 -1
- package/dist/{cli-qwhy2qma.js → cli-z63a269p.js} +2 -2
- package/dist/{cli-sm8rses9.js → cli-zfdp01hn.js} +8 -5
- package/dist/{cli-tw4p90jb.js → cli-znvq0k3t.js} +5 -5
- package/dist/cli.js +29 -27
- package/dist/{cloudflare-workers-ai-system-one-ch2wxfcp.js → cloudflare-workers-ai-system-one-43v9qkjk.js} +7 -2
- package/dist/{codex-adapter-tn6k5mkg.js → codex-adapter-p4ptwar5.js} +6 -4
- package/dist/{codex-login-m819c41r.js → codex-login-rn7c5gxt.js} +1 -1
- package/dist/{codex-session-runner-7vjt7jbw.js → codex-session-runner-964c7dnk.js} +7 -5
- package/dist/{commands-t7rz9146.js → commands-mbvhbrcy.js} +2 -2
- package/dist/{controller-m2jasma5.js → controller-gnq1k1mf.js} +4 -4
- package/dist/{controllers-connect-9ftpex99.js → controllers-connect-6dkm71tg.js} +25 -23
- package/dist/{cursor-adapter-mjv79e4z.js → cursor-adapter-yq5xgfcg.js} +1 -1
- package/dist/{db-6sfrn9g3.js → db-88wcymxt.js} +14 -2
- package/dist/{db-rn673r06.js → db-af9y8nkf.js} +3 -3
- package/dist/{devin-adapter-zgqadvnm.js → devin-adapter-4ycy4vrf.js} +1 -1
- package/dist/{dispatcher-c155xz0p.js → dispatcher-606ydx5v.js} +22 -20
- package/dist/{docker-fkgtr75t.js → docker-nfy2gc8t.js} +2 -2
- package/dist/{dsh-adapter-3mmszc1x.js → dsh-adapter-tvhc4k2d.js} +1 -1
- package/dist/{e2b-16d6ch39.js → e2b-9gkdhm3c.js} +2 -2
- package/dist/{e2b-zn0b4w5w.js → e2b-cjtf8k1z.js} +2 -2
- package/dist/{easter-egg-3d-5cgynaja.js → easter-egg-3d-e4qv8dxj.js} +1 -1
- package/dist/{event-bus-9vpk8gmq.js → event-bus-3z78ep5n.js} +1 -1
- package/dist/{execute-t4e6m3rw.js → execute-0xpz8950.js} +85 -23
- package/dist/{external-channel-35k6tkv8.js → external-channel-y8q5z8z2.js} +2 -2
- package/dist/{google-generative-ai-bmq8gkf3.js → google-generative-ai-mk9vcpe1.js} +15 -15
- package/dist/{google-vertex-b1rvp52s.js → google-vertex-q580kz8k.js} +20 -20
- package/dist/{grok-adapter-tfrq7tg1.js → grok-adapter-39aha52t.js} +9 -7
- package/dist/handlers-rk9dqech.js +41 -0
- package/dist/{heartbeat-dyg4npkp.js → heartbeat-jfe9zfjr.js} +25 -23
- package/dist/{hook-drspbwpe.js → hook-b1mez1m8.js} +9 -7
- package/dist/{hook-x26b31bg.js → hook-ffevzed1.js} +7 -5
- package/dist/{http-pk972xyw.js → http-d5b44f1r.js} +544 -76
- package/dist/{index-g6tbb6ve.js → index-31ceyf42.js} +1 -1
- package/dist/index-4q3vj1yr.js +46 -0
- package/dist/{index-arytgj5q.js → index-5en23s5z.js} +1 -1
- package/dist/index-d2qeem97.js +42 -0
- package/dist/index-mj46rk9k.js +43 -0
- package/dist/{index-jwxkkex2.js → index-nq8hhv28.js} +13 -11
- package/dist/{index-g216q6jr.js → index-zsyx51ap.js} +1 -4
- package/dist/{keepalive-7yrng7px.js → keepalive-wsby1btq.js} +4 -4
- package/dist/lead-paa141j6.js +79 -0
- package/dist/{llama-cpp-classify-vv43gswy.js → llama-cpp-classify-ee7vmd7q.js} +4 -1
- package/dist/{maintenance-e6cemdqt.js → maintenance-vnshcyv9.js} +1 -1
- package/dist/{mistral-conversations-1medfwv7.js → mistral-conversations-sd0xf1tn.js} +13 -13
- package/dist/{node-de6akczr.js → node-jzjj7r9x.js} +1 -1
- package/dist/{oauth-refresh-sweep-yw3xdbcj.js → oauth-refresh-sweep-d6sqn5np.js} +3 -3
- package/dist/{onboard-0a9y5yrc.js → onboard-nr4xhpzy.js} +2 -2
- package/dist/{openai-codex-responses-de9pvs4d.js → openai-codex-responses-79s8xnbh.js} +29 -23
- package/dist/{openai-completions-mtqge3nf.js → openai-completions-tdbyts0x.js} +21 -20
- package/dist/{openai-decisions-ygk4kkxd.js → openai-decisions-bqhnjyfz.js} +2 -1
- package/dist/{openai-responses-dkyng71g.js → openai-responses-dm3t5vqp.js} +26 -17
- package/dist/{opencode-adapter-x4tqzhkh.js → opencode-adapter-e56086m1.js} +7 -5
- package/dist/{openrouter-images-wvv7camj.js → openrouter-images-ssttr1y4.js} +6 -3
- package/dist/{otel-impl-trjpkfb7.js → otel-impl-ytn9wyv9.js} +2 -2
- package/dist/{pi-messages-nhh1pkz2.js → pi-messages-3nf8bq1a.js} +6 -4
- package/dist/{pi-mono-adapter-mcfkn9vf.js → pi-mono-adapter-tzps8f38.js} +9 -37
- package/dist/{pricing-refresh-d2b5my0y.js → pricing-refresh-pva04zee.js} +3 -3
- package/dist/{rbac-roles-nxh5ahwk.js → rbac-roles-7rc1q3g4.js} +1 -1
- package/dist/{rbac-roles-hey3yv9d.js → rbac-roles-ff1ffmec.js} +2 -2
- package/dist/{render-v2-rr3p2atg.js → render-v2-pyfsg9zk.js} +3 -3
- package/dist/{resume-2efkf1s1.js → resume-phj8xhqr.js} +10 -8
- package/dist/{runtime-xe3aqy4x.js → runtime-bt5pkpm1.js} +1 -1
- package/dist/{session-access-s2mttxpw.js → session-access-jzx2z9h5.js} +6 -4
- package/dist/{setup-vypma5yt.js → setup-rfg0f0sg.js} +1 -1
- package/dist/{typesafe-system-one-2hgpayzy.js → typesafe-system-one-bre38hvs.js} +4 -2
- package/dist/{virtual-modules-4r3zkc20.js → virtual-modules-mnfbh5mr.js} +8 -2
- package/dist/{work-objects-rvhckdkp.js → work-objects-44z2yjg8.js} +25 -23
- package/dist/worker-zsfqzxhm.js +79 -0
- package/dist/{x-y45mthwn.js → x-pbpezr0s.js} +2 -2
- package/openapi.json +785 -5
- package/package.json +9 -9
- package/src/assets/key.ts +17 -0
- package/src/azure-devops/handlers.ts +1 -1
- package/src/be/db/approvals.ts +18 -0
- package/src/be/db/session-moves.ts +164 -0
- package/src/be/db/session-tree.ts +384 -0
- package/src/be/db/tasks/read.ts +40 -4
- package/src/be/db/workflow-runs.ts +96 -0
- package/src/be/db.ts +80 -236
- package/src/be/onboarding.ts +3 -0
- package/src/be/skill-sync.ts +43 -2
- package/src/be/swarm-config-guard.ts +1 -0
- package/src/bitbucket/api.ts +81 -0
- package/src/bitbucket/auth.ts +64 -0
- package/src/bitbucket/handlers.ts +434 -0
- package/src/bitbucket/index.ts +28 -0
- package/src/bitbucket/templates.ts +134 -0
- package/src/bitbucket/types.ts +65 -0
- package/src/commands/runner.ts +55 -3
- package/src/e2b/env.ts +1 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +2 -2
- package/src/extensions/post-bridge.ts +1 -0
- package/src/github/handlers.ts +6 -6
- package/src/gitlab/auth.ts +8 -2
- package/src/gitlab/handlers.ts +63 -15
- package/src/gitlab/index.ts +1 -1
- package/src/http/assets.ts +14 -2
- package/src/http/core.ts +12 -0
- package/src/http/index.ts +4 -0
- package/src/http/onboarding.ts +1 -0
- package/src/http/sessions.ts +366 -12
- package/src/http/skills.ts +48 -1
- package/src/http/tasks.ts +1 -1
- package/src/http/users.ts +1 -0
- package/src/http/webhooks.ts +141 -0
- package/src/integrations/chat-sdk/adapters.ts +19 -3
- package/src/integrations/chat-sdk/facts.ts +30 -12
- package/src/integrations/chat-sdk/outbound.ts +38 -1
- package/src/providers/acp-targets.ts +1 -1
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/pi-mono-adapter.ts +5 -53
- package/src/scripts-runtime/types/swarm-extension.d.ts +6 -4
- package/src/slack/handlers.test.ts +158 -0
- package/src/slack/handlers.ts +19 -28
- package/src/tasks/context-key.ts +61 -1
- package/src/tests/bitbucket-auth.test.ts +156 -0
- package/src/tests/bitbucket-handlers.test.ts +425 -0
- package/src/tests/bitbucket-webhook.test.ts +220 -0
- package/src/tests/chat-sdk-inbound.test.ts +39 -0
- package/src/tests/chat-sdk-telegram-markdown.test.ts +92 -0
- package/src/tests/context-key.test.ts +50 -0
- package/src/tests/core-auth.test.ts +5 -0
- package/src/tests/db-task-read-contract.test.ts +7 -0
- package/src/tests/db-task-write-contract.test.ts +6 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/fixtures/bitbucket/pullrequest-comment-created-inline.json +174 -0
- package/src/tests/fixtures/bitbucket/pullrequest-comment-created.json +170 -0
- package/src/tests/fixtures/bitbucket/pullrequest-created-mention.json +132 -0
- package/src/tests/fixtures/bitbucket/pullrequest-created-reviewer.json +140 -0
- package/src/tests/fixtures/bitbucket/pullrequest-fulfilled.json +134 -0
- package/src/tests/fixtures/bitbucket/pullrequest-rejected.json +133 -0
- package/src/tests/generate-mcp-docs.test.ts +101 -0
- package/src/tests/gitlab-auth.test.ts +13 -5
- package/src/tests/gitlab-handlers.test.ts +273 -25
- package/src/tests/gitlab-vcs-db.test.ts +4 -4
- package/src/tests/integration-disable-flags.test.ts +36 -0
- package/src/tests/mcp-tools.test.ts +1 -1
- package/src/tests/onboarding.test.ts +12 -0
- package/src/tests/pi-codemode.test.ts +8 -2
- package/src/tests/preload-env.test.ts +57 -0
- package/src/tests/preload.ts +21 -0
- package/src/tests/prompt-template-remaining.test.ts +38 -0
- package/src/tests/run-root-coverage.test.ts +39 -0
- package/src/tests/runner-bitbucket-vcs.test.ts +191 -0
- package/src/tests/runner-skills-refresh.test.ts +58 -0
- package/src/tests/secret-scrubber.test.ts +15 -0
- package/src/tests/sessions-move.test.ts +576 -0
- package/src/tests/sessions-tree.test.ts +493 -0
- package/src/tests/skill-files-http.test.ts +50 -0
- package/src/tests/skills-bundle.test.ts +99 -0
- package/src/tests/swarm-config-export-to-env.test.ts +2 -1
- package/src/tests/vcs-bitbucket.test.ts +91 -0
- package/src/tests/vcs-provider-isolation.test.ts +123 -0
- package/src/tests/vcs-provider.test.ts +16 -1
- package/src/tests/vcs-tracking.test.ts +3 -3
- package/src/tests/workflow-foreach-bodies.test.ts +637 -0
- package/src/tests/workflow-foreach-concurrency.test.ts +342 -0
- package/src/tests/workflow-foreach-retry.test.ts +537 -0
- package/src/tests/workflow-foreach.test.ts +44 -23
- package/src/tests/workflow-step-claims.test.ts +6 -6
- package/src/tests/workflow-tla-races.test.ts +2 -2
- package/src/tools/script-delete.ts +1 -1
- package/src/tools/workflows/create-workflow.ts +5 -3
- package/src/types.ts +3 -2
- package/src/utils/config-env-export.ts +1 -0
- package/src/utils/secret-scrubber.ts +4 -0
- package/src/utils/skills-refresh.ts +83 -43
- package/src/vcs/bitbucket.ts +58 -0
- package/src/vcs/index.ts +2 -0
- package/src/vcs/types.ts +2 -2
- package/src/workflows/approval-resolution.ts +4 -1
- package/src/workflows/checkpoint.ts +9 -1
- package/src/workflows/constants.ts +3 -0
- package/src/workflows/definition.ts +48 -17
- package/src/workflows/engine.ts +25 -15
- package/src/workflows/executors/foreach.ts +45 -99
- package/src/workflows/foreach-body.ts +146 -0
- package/src/workflows/foreach-driver.ts +552 -0
- package/src/workflows/foreach-join.ts +206 -7
- package/src/workflows/node-timeout.ts +21 -0
- package/src/workflows/recovery.ts +68 -3
- package/src/workflows/resume.ts +221 -43
- package/src/workflows/retry-poller.ts +39 -24
- package/src/workflows/step-input.ts +59 -0
- package/src/workflows/task-step-routing.ts +114 -56
- package/templates/skills/slack-interaction/content.md +5 -0
- package/templates/skills/work-on-task/SKILL.md +1 -1
- package/templates/skills/work-on-task/content.md +1 -1
- package/dist/cli-9hstj09h.js +0 -2657
- package/dist/cli-yw91rnmw.js +0 -13
- package/dist/handlers-7gw64dxw.js +0 -39
- package/dist/index-bgdyvcnv.js +0 -40
- package/dist/index-gabbcdn2.js +0 -43
- package/dist/index-tfb26zhy.js +0 -41
- package/dist/lead-7e02z839.js +0 -77
- package/dist/worker-5snytpbd.js +0 -77
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
gitlabContextKey,
|
|
10
10
|
azureDevOpsContextKey,
|
|
11
11
|
azureDevOpsWorkItemContextKey,
|
|
12
|
+
bitbucketContextKey,
|
|
12
13
|
linearContextKey,
|
|
13
14
|
buildJiraContextKey,
|
|
14
15
|
scheduleContextKey,
|
|
@@ -72,6 +73,7 @@ import {
|
|
|
72
73
|
hasNonTerminalRerouteDecisionChild2,
|
|
73
74
|
getAgentCurrentTask2,
|
|
74
75
|
findTaskByVcs2,
|
|
76
|
+
findActiveTasksByVcs2,
|
|
75
77
|
readableSessionCondition,
|
|
76
78
|
getAllTasks2,
|
|
77
79
|
getPendingChatRelayTasks2,
|
|
@@ -334,19 +336,19 @@ import {
|
|
|
334
336
|
recordInlineScriptRun2,
|
|
335
337
|
exports_db,
|
|
336
338
|
init_db3
|
|
337
|
-
} from "./cli-
|
|
339
|
+
} from "./cli-q9pzwxvk.js";
|
|
338
340
|
import {
|
|
339
341
|
getUserGrant2,
|
|
340
342
|
init_rbac_roles
|
|
341
|
-
} from "./cli-
|
|
343
|
+
} from "./cli-z2dv25mf.js";
|
|
342
344
|
import {
|
|
343
345
|
ensurePricingSeeded2,
|
|
344
346
|
ensureRbacSeeded2,
|
|
345
347
|
ensureModelProfilesSeeded2
|
|
346
|
-
} from "./cli-
|
|
348
|
+
} from "./cli-v2g93k4v.js";
|
|
347
349
|
import {
|
|
348
350
|
loadModelsDevCache
|
|
349
|
-
} from "./cli-
|
|
351
|
+
} from "./cli-9mm5ade4.js";
|
|
350
352
|
import {
|
|
351
353
|
buildCatalogEntries,
|
|
352
354
|
listModelCatalog,
|
|
@@ -356,12 +358,12 @@ import {
|
|
|
356
358
|
loadModelsCatalog,
|
|
357
359
|
requestModelCatalogRefresh2,
|
|
358
360
|
startPricingRefreshLoop2
|
|
359
|
-
} from "./cli-
|
|
361
|
+
} from "./cli-mz2ygeyq.js";
|
|
360
362
|
import {
|
|
361
363
|
ampPinProviderError,
|
|
362
364
|
ampPinCatalogError,
|
|
363
365
|
ampModelError
|
|
364
|
-
} from "./cli-
|
|
366
|
+
} from "./cli-jpxsrxcb.js";
|
|
365
367
|
import {
|
|
366
368
|
notifyAutomationPreflightFailure,
|
|
367
369
|
isNeedsSetupFailure,
|
|
@@ -370,50 +372,50 @@ import {
|
|
|
370
372
|
getAutomationSetupStates,
|
|
371
373
|
schedulePreflightInput,
|
|
372
374
|
recordSchedulePreflightFailure,
|
|
375
|
+
BaseExecutor,
|
|
376
|
+
postApprovalCancellationUpdates,
|
|
377
|
+
createApprovalFollowUpTask,
|
|
378
|
+
HumanInTheLoopExecutor,
|
|
379
|
+
resolveWorkflowLlmConfig,
|
|
380
|
+
SYSTEM_ONE_PROVIDER_IDS,
|
|
381
|
+
SystemOneExtractionExecutor,
|
|
382
|
+
SYSTEM_ONE_DECISION_NODE_TYPE,
|
|
383
|
+
SystemOneDecisionConfigSchema,
|
|
384
|
+
SystemOneDecisionExecutor,
|
|
373
385
|
checkpointStep,
|
|
374
386
|
checkpointStepFailure,
|
|
375
387
|
checkpointStepWaiting,
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
buildForeachAggregate,
|
|
388
|
+
FAILED_TASK_OUTPUT_PREFIX,
|
|
389
|
+
FOREACH_ITEMS_WAIT_FOR,
|
|
379
390
|
loadCompletedStepRouting,
|
|
380
391
|
resolveInputValue,
|
|
381
392
|
getSecretInputKeys,
|
|
382
393
|
validateJsonSchema,
|
|
383
394
|
findJsonSchemaShapeErrors,
|
|
384
|
-
getMaxWorkflowStepsPerRun,
|
|
385
395
|
workflowSaveWarnings,
|
|
386
396
|
withSaveWarnings,
|
|
387
397
|
runStepValidation,
|
|
388
|
-
shapeApprovalResolution,
|
|
389
|
-
FAILED_TASK_OUTPUT_PREFIX,
|
|
390
|
-
SubWorkflowExecutor,
|
|
391
|
-
WaitExecutor,
|
|
392
|
-
failStepAndRunIfWaiting,
|
|
393
|
-
checkpointPortStepAndResolveSuccessors,
|
|
394
|
-
scheduleTaskStepRetry,
|
|
395
|
-
completeTaskStepAndResolveSuccessors,
|
|
396
|
-
setupWorkflowResumeListener2,
|
|
397
|
-
finalizeOrWait2,
|
|
398
|
-
retryFailedRun2,
|
|
399
|
-
cancelWorkflowRunRows2,
|
|
400
|
-
cancelWorkflowRun2,
|
|
401
|
-
resumeWaitState2,
|
|
402
|
-
recoverResolvedWaitState2,
|
|
403
|
-
resumeFromChildRun2,
|
|
404
|
-
initWaitBusSubscriptions2,
|
|
405
398
|
TriggerSchemaError,
|
|
406
399
|
startWorkflowExecution2,
|
|
407
400
|
failRunOnUnreadableReplay,
|
|
408
401
|
isWorkflowRunActive,
|
|
409
402
|
holdWorkflowRun,
|
|
410
403
|
walkGraph,
|
|
411
|
-
rehydrateCompletedStepOutputs,
|
|
412
404
|
findReadyNodes,
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
405
|
+
scriptBodyInterpolationError,
|
|
406
|
+
ForeachExecutor,
|
|
407
|
+
rebuildNodeExecutionInput,
|
|
408
|
+
isForeachChildOwned,
|
|
409
|
+
parkAndDriveForeach,
|
|
410
|
+
runForeachDrive,
|
|
411
|
+
stepFailureMode,
|
|
412
|
+
generateEdges,
|
|
413
|
+
resolveValidationPort,
|
|
414
|
+
getSuccessors,
|
|
415
|
+
definitionNodeIds,
|
|
416
|
+
validateDefinition,
|
|
417
|
+
applyDefinitionPatch
|
|
418
|
+
} from "./cli-pyy4c9ch.js";
|
|
417
419
|
import {
|
|
418
420
|
require_dist2,
|
|
419
421
|
publicEndpointSsrfOptions,
|
|
@@ -473,14 +475,14 @@ import {
|
|
|
473
475
|
deleteApp,
|
|
474
476
|
typecheckScript,
|
|
475
477
|
parseSkillContent
|
|
476
|
-
} from "./cli-
|
|
478
|
+
} from "./cli-mq7kg1b1.js";
|
|
477
479
|
import {
|
|
478
480
|
buildAuthorizationUrl,
|
|
479
481
|
onAuthorizationRefreshed,
|
|
480
482
|
ensureAuthorizationTokenOrThrow,
|
|
481
483
|
ensureToken,
|
|
482
484
|
ensureTokenOrThrow
|
|
483
|
-
} from "./cli-
|
|
485
|
+
} from "./cli-rngde2jv.js";
|
|
484
486
|
import {
|
|
485
487
|
detachedProcessGroup,
|
|
486
488
|
registerProcessGroup,
|
|
@@ -510,36 +512,36 @@ import {
|
|
|
510
512
|
getSlackApp2,
|
|
511
513
|
startSlackApp2,
|
|
512
514
|
stopSlackApp2
|
|
513
|
-
} from "./cli-
|
|
515
|
+
} from "./cli-e9btqw4y.js";
|
|
514
516
|
import {
|
|
515
517
|
slackCode,
|
|
516
518
|
slackMissingScopeMessage,
|
|
517
519
|
withAutoJoin,
|
|
518
520
|
externalChannelToolError2,
|
|
519
521
|
getChannelBlockReason2
|
|
520
|
-
} from "./cli-
|
|
521
|
-
import {
|
|
522
|
-
BaseExecutor,
|
|
523
|
-
postApprovalCancellationUpdates,
|
|
524
|
-
createApprovalFollowUpTask,
|
|
525
|
-
HumanInTheLoopExecutor,
|
|
526
|
-
resolveWorkflowLlmConfig,
|
|
527
|
-
SYSTEM_ONE_PROVIDER_IDS,
|
|
528
|
-
SystemOneExtractionExecutor,
|
|
529
|
-
SYSTEM_ONE_DECISION_NODE_TYPE,
|
|
530
|
-
SystemOneDecisionConfigSchema,
|
|
531
|
-
SystemOneDecisionExecutor,
|
|
532
|
-
generateEdges,
|
|
533
|
-
resolveValidationPort,
|
|
534
|
-
getSuccessors,
|
|
535
|
-
definitionNodeIds,
|
|
536
|
-
validateDefinition,
|
|
537
|
-
applyDefinitionPatch
|
|
538
|
-
} from "./cli-xpa64rek.js";
|
|
522
|
+
} from "./cli-xc65x52q.js";
|
|
539
523
|
import {
|
|
540
524
|
workflowEventBus2,
|
|
541
525
|
init_event_bus
|
|
542
|
-
} from "./cli-
|
|
526
|
+
} from "./cli-dabehxhp.js";
|
|
527
|
+
import {
|
|
528
|
+
shapeApprovalResolution,
|
|
529
|
+
SubWorkflowExecutor,
|
|
530
|
+
WaitExecutor,
|
|
531
|
+
failStepAndRunIfWaiting,
|
|
532
|
+
checkpointPortStepAndResolveSuccessors,
|
|
533
|
+
scheduleTaskStepRetry,
|
|
534
|
+
completeTaskStepAndResolveSuccessors,
|
|
535
|
+
setupWorkflowResumeListener2,
|
|
536
|
+
finalizeOrWait2,
|
|
537
|
+
retryFailedRun2,
|
|
538
|
+
cancelWorkflowRunRows2,
|
|
539
|
+
cancelWorkflowRun2,
|
|
540
|
+
resumeWaitState2,
|
|
541
|
+
recoverResolvedWaitState2,
|
|
542
|
+
resumeFromChildRun2,
|
|
543
|
+
initWaitBusSubscriptions2
|
|
544
|
+
} from "./cli-nj12tn2c.js";
|
|
543
545
|
import {
|
|
544
546
|
duplicateGuardedQueryKey,
|
|
545
547
|
parseQueryParams,
|
|
@@ -566,7 +568,7 @@ import {
|
|
|
566
568
|
isPublicRoute,
|
|
567
569
|
findRoute,
|
|
568
570
|
route
|
|
569
|
-
} from "./cli-
|
|
571
|
+
} from "./cli-y3zyaee5.js";
|
|
570
572
|
import {
|
|
571
573
|
isMultiRuntimeEnabled
|
|
572
574
|
} from "./cli-e8xyjvfc.js";
|
|
@@ -580,7 +582,7 @@ import {
|
|
|
580
582
|
import {
|
|
581
583
|
getRuntimePool2,
|
|
582
584
|
init_db
|
|
583
|
-
} from "./cli-
|
|
585
|
+
} from "./cli-1dp1zj04.js";
|
|
584
586
|
import {
|
|
585
587
|
getMemoryRaterNames,
|
|
586
588
|
REFERENCES_SOURCE_MAX_LENGTH,
|
|
@@ -591,7 +593,7 @@ import {
|
|
|
591
593
|
COMPOSIO_HTTP_METHODS,
|
|
592
594
|
executeComposioRequest,
|
|
593
595
|
composioArgsFromParts
|
|
594
|
-
} from "./cli-
|
|
596
|
+
} from "./cli-pasyvjmm.js";
|
|
595
597
|
import {
|
|
596
598
|
require_fast_deep_equal
|
|
597
599
|
} from "./cli-bhp11egn.js";
|
|
@@ -605,7 +607,7 @@ import {
|
|
|
605
607
|
import {
|
|
606
608
|
canProvisionKind,
|
|
607
609
|
init_runtime_providers
|
|
608
|
-
} from "./cli-
|
|
610
|
+
} from "./cli-p859hcc8.js";
|
|
609
611
|
import {
|
|
610
612
|
findUserById,
|
|
611
613
|
findUserByExternalId,
|
|
@@ -621,7 +623,7 @@ import {
|
|
|
621
623
|
resolveSessionToken,
|
|
622
624
|
fingerprintApiKey,
|
|
623
625
|
init_users
|
|
624
|
-
} from "./cli-
|
|
626
|
+
} from "./cli-gwcf52gz.js";
|
|
625
627
|
import {
|
|
626
628
|
isRbacEnabled,
|
|
627
629
|
decideAdmission,
|
|
@@ -690,7 +692,7 @@ import {
|
|
|
690
692
|
KvNamespaceSchema,
|
|
691
693
|
KvKeySchema,
|
|
692
694
|
init_types
|
|
693
|
-
} from "./cli-
|
|
695
|
+
} from "./cli-rh5smt8t.js";
|
|
694
696
|
import {
|
|
695
697
|
generateDefaultClaudeMd2,
|
|
696
698
|
generateDefaultSoulMd2,
|
|
@@ -699,7 +701,7 @@ import {
|
|
|
699
701
|
taskAttachmentFetchCommand,
|
|
700
702
|
taskAttachmentDisplayUrl,
|
|
701
703
|
init_task_attachment_links
|
|
702
|
-
} from "./cli-
|
|
704
|
+
} from "./cli-gpv60278.js";
|
|
703
705
|
import {
|
|
704
706
|
getSlackConfiguration,
|
|
705
707
|
init_config
|
|
@@ -711,7 +713,6 @@ import {
|
|
|
711
713
|
import {
|
|
712
714
|
findInterpolationTokens,
|
|
713
715
|
interpolate,
|
|
714
|
-
deepInterpolate,
|
|
715
716
|
init_template,
|
|
716
717
|
registerTemplate,
|
|
717
718
|
getTemplateDefinition,
|
|
@@ -737,7 +738,6 @@ import {
|
|
|
737
738
|
_null,
|
|
738
739
|
any,
|
|
739
740
|
unknown,
|
|
740
|
-
never,
|
|
741
741
|
array2,
|
|
742
742
|
object2,
|
|
743
743
|
looseObject,
|
|
@@ -761,7 +761,7 @@ import {
|
|
|
761
761
|
import {
|
|
762
762
|
init_package,
|
|
763
763
|
package_default
|
|
764
|
-
} from "./cli-
|
|
764
|
+
} from "./cli-22rmcjkg.js";
|
|
765
765
|
import {
|
|
766
766
|
realtimeBus,
|
|
767
767
|
init_bus
|
|
@@ -795,7 +795,7 @@ import {
|
|
|
795
795
|
registerVolatileSecret,
|
|
796
796
|
registerSensitiveKeyName,
|
|
797
797
|
init_secret_scrubber
|
|
798
|
-
} from "./cli-
|
|
798
|
+
} from "./cli-n4c8e3s5.js";
|
|
799
799
|
import {
|
|
800
800
|
isAlias,
|
|
801
801
|
parseAlias,
|
|
@@ -20137,6 +20137,7 @@ async function recoverIncompleteRuns(registry) {
|
|
|
20137
20137
|
console.error(`[workflows] Failed to resume sub-workflow step ${parentStepId}:`, err);
|
|
20138
20138
|
}
|
|
20139
20139
|
}
|
|
20140
|
+
recovered += await recoverForeachFanouts(registry);
|
|
20140
20141
|
if (recovered > 0) {
|
|
20141
20142
|
console.log(`[workflows] Recovered ${recovered} incomplete run(s)`);
|
|
20142
20143
|
}
|
|
@@ -20230,10 +20231,10 @@ async function recoverWaitingRuns(registry) {
|
|
|
20230
20231
|
if (retry !== "not-eligible")
|
|
20231
20232
|
continue;
|
|
20232
20233
|
}
|
|
20233
|
-
if (!taskCompleted && (workflow.definition.
|
|
20234
|
+
if (!taskCompleted && stepFailureMode(workflow.definition, stuck.nodeId) === "fail") {
|
|
20234
20235
|
const reason = stuck.taskStatus === "failed" ? "Task failed (recovered)" : "Task cancelled (recovered)";
|
|
20235
|
-
const
|
|
20236
|
-
if (!claimed)
|
|
20236
|
+
const failed = await failStepAndRunIfWaiting(workflow.definition, stuck.stepId, stuck.runId, reason, stuck.taskId, { registry });
|
|
20237
|
+
if (!failed.claimed)
|
|
20237
20238
|
continue;
|
|
20238
20239
|
recovered++;
|
|
20239
20240
|
continue;
|
|
@@ -20247,7 +20248,7 @@ async function recoverWaitingRuns(registry) {
|
|
|
20247
20248
|
const step = await getWorkflowRunStep2(stuck.stepId);
|
|
20248
20249
|
if (!step)
|
|
20249
20250
|
continue;
|
|
20250
|
-
const routing = await completeTaskStepAndResolveSuccessors(workflow.definition, stuck.runId, step, stepOutput, ctx, taskCompleted ? undefined : reason, stuck.taskId);
|
|
20251
|
+
const routing = await completeTaskStepAndResolveSuccessors(workflow.definition, stuck.runId, step, stepOutput, ctx, taskCompleted ? undefined : reason, stuck.taskId, registry);
|
|
20251
20252
|
if (!routing.claimed)
|
|
20252
20253
|
continue;
|
|
20253
20254
|
if (routing.foreachChild && !routing.joined) {
|
|
@@ -20302,7 +20303,7 @@ async function recoverApprovalWaitingRuns(registry) {
|
|
|
20302
20303
|
status: approvalStatus,
|
|
20303
20304
|
responses: approval?.responses ?? null
|
|
20304
20305
|
});
|
|
20305
|
-
return await checkpointPortStepAndResolveSuccessors(workflow.definition, stuck.runId, stuck.stepId, stuck.nodeId, stepOutput, nextPort, ctx);
|
|
20306
|
+
return await checkpointPortStepAndResolveSuccessors(workflow.definition, stuck.runId, stuck.stepId, stuck.nodeId, stepOutput, nextPort, ctx, registry);
|
|
20306
20307
|
});
|
|
20307
20308
|
if (!routing?.claimed)
|
|
20308
20309
|
continue;
|
|
@@ -20341,6 +20342,42 @@ async function recoverWaitStates(registry) {
|
|
|
20341
20342
|
}
|
|
20342
20343
|
return recovered;
|
|
20343
20344
|
}
|
|
20345
|
+
async function recoverForeachFanouts(registry) {
|
|
20346
|
+
const rows = await getDbClient2().query(`SELECT s.runId AS runId, r.workflowId AS workflowId, s.id AS stepId, s.nodeId AS nodeId, s.status AS status
|
|
20347
|
+
FROM workflow_run_steps s
|
|
20348
|
+
JOIN workflow_runs r ON r.id = s.runId
|
|
20349
|
+
WHERE r.status IN ('running', 'waiting')
|
|
20350
|
+
AND s.status IN ('pending', 'running')
|
|
20351
|
+
AND instr(s.nodeId, '#') > 1`);
|
|
20352
|
+
const fanouts = new Map;
|
|
20353
|
+
for (const row of rows) {
|
|
20354
|
+
if (row.status === "running" && isForeachChildOwned(row.stepId))
|
|
20355
|
+
continue;
|
|
20356
|
+
const parentNodeId = row.nodeId.slice(0, row.nodeId.indexOf("#"));
|
|
20357
|
+
fanouts.set(`${row.runId}\x00${parentNodeId}`, {
|
|
20358
|
+
runId: row.runId,
|
|
20359
|
+
workflowId: row.workflowId,
|
|
20360
|
+
parentNodeId
|
|
20361
|
+
});
|
|
20362
|
+
}
|
|
20363
|
+
let recovered = 0;
|
|
20364
|
+
for (const fanout of fanouts.values()) {
|
|
20365
|
+
try {
|
|
20366
|
+
const workflow = await getWorkflow2(fanout.workflowId);
|
|
20367
|
+
const parent = workflow?.definition.nodes.find((node) => node.id === fanout.parentNodeId);
|
|
20368
|
+
if (parent?.type !== "foreach")
|
|
20369
|
+
continue;
|
|
20370
|
+
const drive = await runForeachDrive(fanout.runId, fanout.parentNodeId, registry);
|
|
20371
|
+
if (drive.claimed > 0)
|
|
20372
|
+
recovered++;
|
|
20373
|
+
} catch (err) {
|
|
20374
|
+
if (await failRunOnUnreadableReplay(fanout.runId, err))
|
|
20375
|
+
continue;
|
|
20376
|
+
console.error(`[workflows] Failed to re-drive foreach ${fanout.parentNodeId} of run ${fanout.runId}:`, err);
|
|
20377
|
+
}
|
|
20378
|
+
}
|
|
20379
|
+
return recovered;
|
|
20380
|
+
}
|
|
20344
20381
|
async function getRunIdsByStatus(status) {
|
|
20345
20382
|
const rows = await getDbClient2().query("SELECT id FROM workflow_runs WHERE status = ?", [status]);
|
|
20346
20383
|
return rows.map((r) => r.id);
|
|
@@ -20370,17 +20407,16 @@ function startRetryPoller(registry, intervalMs = 5000) {
|
|
|
20370
20407
|
release = holdWorkflowRun(run.id);
|
|
20371
20408
|
if (!await claimRetry(run.id, step.id))
|
|
20372
20409
|
continue;
|
|
20373
|
-
const
|
|
20374
|
-
|
|
20375
|
-
|
|
20376
|
-
|
|
20377
|
-
|
|
20378
|
-
|
|
20410
|
+
const {
|
|
20411
|
+
ctx,
|
|
20412
|
+
inputCtx,
|
|
20413
|
+
config: interpolatedConfig,
|
|
20414
|
+
scriptBodyUnresolved
|
|
20415
|
+
} = await rebuildNodeExecutionInput(workflow.definition, run, node, registry);
|
|
20379
20416
|
if (scriptBodyUnresolved && scriptBodyUnresolved.length > 0) {
|
|
20380
20417
|
await checkpointStepFailure(run.id, step.id, scriptBodyInterpolationError(node.id, scriptBodyUnresolved), step.retryCount);
|
|
20381
20418
|
continue;
|
|
20382
20419
|
}
|
|
20383
|
-
const interpolatedConfig = interpolatedValue;
|
|
20384
20420
|
const executor = registry.get(node.type);
|
|
20385
20421
|
const meta = {
|
|
20386
20422
|
runId: run.id,
|
|
@@ -20400,6 +20436,21 @@ function startRetryPoller(registry, intervalMs = 5000) {
|
|
|
20400
20436
|
if (result.status === "failed") {
|
|
20401
20437
|
const retryPolicy = node.retry || executor.retryPolicy;
|
|
20402
20438
|
await checkpointStepFailure(run.id, step.id, result.error || "Retry failed", step.retryCount, retryPolicy);
|
|
20439
|
+
} else if ("async" in result && result.async && result.waitFor === FOREACH_ITEMS_WAIT_FOR) {
|
|
20440
|
+
const drive = await parkAndDriveForeach({
|
|
20441
|
+
runId: run.id,
|
|
20442
|
+
stepId: step.id,
|
|
20443
|
+
parentNodeId: node.id,
|
|
20444
|
+
ctx,
|
|
20445
|
+
registry
|
|
20446
|
+
});
|
|
20447
|
+
if (!drive.joined)
|
|
20448
|
+
continue;
|
|
20449
|
+
if (drive.successors.length > 0) {
|
|
20450
|
+
await walkGraph(workflow.definition, run.id, ctx, drive.successors, registry, workflow.id);
|
|
20451
|
+
} else {
|
|
20452
|
+
await completeRunIfSettled(run.id, ctx);
|
|
20453
|
+
}
|
|
20403
20454
|
} else if ("async" in result && result.async) {
|
|
20404
20455
|
const waiting = await checkpointStepWaiting(run.id, step.id, ctx);
|
|
20405
20456
|
if (!waiting)
|
|
@@ -21025,154 +21076,6 @@ class CodeMatchExecutor extends BaseExecutor {
|
|
|
21025
21076
|
}
|
|
21026
21077
|
}
|
|
21027
21078
|
|
|
21028
|
-
// src/workflows/executors/foreach.ts
|
|
21029
|
-
init_zod();
|
|
21030
|
-
init_template();
|
|
21031
|
-
var ForeachBodySchema = object2({
|
|
21032
|
-
type: literal2("agent-task"),
|
|
21033
|
-
config: record2(string2(), unknown())
|
|
21034
|
-
});
|
|
21035
|
-
var ForeachConfigSchema = object2({
|
|
21036
|
-
over: array2(record2(string2(), unknown())),
|
|
21037
|
-
itemKey: string2().min(1),
|
|
21038
|
-
body: ForeachBodySchema,
|
|
21039
|
-
concurrency: never().optional()
|
|
21040
|
-
});
|
|
21041
|
-
var ForeachResultSchema = object2({
|
|
21042
|
-
itemKey: string2(),
|
|
21043
|
-
status: _enum2(["completed", "failed", "cancelled", "skipped"]),
|
|
21044
|
-
output: unknown().optional()
|
|
21045
|
-
});
|
|
21046
|
-
var ForeachOutputSchema = object2({
|
|
21047
|
-
results: array2(ForeachResultSchema),
|
|
21048
|
-
okCount: number2().int().nonnegative(),
|
|
21049
|
-
failedCount: number2().int().nonnegative()
|
|
21050
|
-
});
|
|
21051
|
-
|
|
21052
|
-
class ForeachExecutor extends BaseExecutor {
|
|
21053
|
-
type = "foreach";
|
|
21054
|
-
mode = "async";
|
|
21055
|
-
configSchema = ForeachConfigSchema;
|
|
21056
|
-
outputSchema = ForeachOutputSchema;
|
|
21057
|
-
async execute(config, context, meta) {
|
|
21058
|
-
if (config.over.length === 0) {
|
|
21059
|
-
return {
|
|
21060
|
-
status: "success",
|
|
21061
|
-
output: { results: [], okCount: 0, failedCount: 0 }
|
|
21062
|
-
};
|
|
21063
|
-
}
|
|
21064
|
-
const items = config.over.map((item, index) => {
|
|
21065
|
-
const rawItemKey = item[config.itemKey];
|
|
21066
|
-
if (typeof rawItemKey !== "string" || rawItemKey.length === 0) {
|
|
21067
|
-
throw new Error(`foreach item at index ${index} is missing non-empty string itemKey property "${config.itemKey}"`);
|
|
21068
|
-
}
|
|
21069
|
-
return { item, index, itemKey: rawItemKey };
|
|
21070
|
-
});
|
|
21071
|
-
const seenItemKeys = new Set;
|
|
21072
|
-
for (const { itemKey } of items) {
|
|
21073
|
-
if (seenItemKeys.has(itemKey)) {
|
|
21074
|
-
throw new Error(`foreach itemKey "${itemKey}" is duplicated`);
|
|
21075
|
-
}
|
|
21076
|
-
seenItemKeys.add(itemKey);
|
|
21077
|
-
}
|
|
21078
|
-
const agentTaskExecutor = new AgentTaskExecutor(this.deps);
|
|
21079
|
-
const runSteps = await this.deps.db.getWorkflowRunStepsByRunId(meta.runId);
|
|
21080
|
-
const childStepsByNodeId = new Map(runSteps.filter((step) => parseSyntheticNodeId(step.nodeId)?.parentNodeId === meta.nodeId).map((step) => [step.nodeId, step]));
|
|
21081
|
-
const childCountToCreate = items.filter(({ itemKey }) => !childStepsByNodeId.has(`${meta.nodeId}#${itemKey}`)).length;
|
|
21082
|
-
const maxSteps = getMaxWorkflowStepsPerRun();
|
|
21083
|
-
const workflow = await this.deps.db.getWorkflow(meta.workflowId);
|
|
21084
|
-
const hasSuccessors = workflow ? getSuccessors(workflow.definition, meta.nodeId).length > 0 : true;
|
|
21085
|
-
const totalSteps = runSteps.length + childCountToCreate;
|
|
21086
|
-
const capBreached = hasSuccessors ? totalSteps >= maxSteps : totalSteps > maxSteps;
|
|
21087
|
-
if (childCountToCreate > 0 && capBreached) {
|
|
21088
|
-
return {
|
|
21089
|
-
status: "failed",
|
|
21090
|
-
error: `foreach would reach ${maxSteps} total steps (WORKFLOW_MAX_STEPS_PER_RUN): ${runSteps.length} existing + ${childCountToCreate} children${hasSuccessors ? " leaves no room for the post-join walk" : " exceeds the per-run cap"}`
|
|
21091
|
-
};
|
|
21092
|
-
}
|
|
21093
|
-
for (const { index, itemKey } of items) {
|
|
21094
|
-
const childNodeId = `${meta.nodeId}#${itemKey}`;
|
|
21095
|
-
if (childStepsByNodeId.has(childNodeId))
|
|
21096
|
-
continue;
|
|
21097
|
-
const childStepId = crypto.randomUUID();
|
|
21098
|
-
const childStep = await this.deps.db.createWorkflowRunStep({
|
|
21099
|
-
id: childStepId,
|
|
21100
|
-
runId: meta.runId,
|
|
21101
|
-
nodeId: childNodeId,
|
|
21102
|
-
nodeType: "agent-task",
|
|
21103
|
-
input: { itemKey, index }
|
|
21104
|
-
});
|
|
21105
|
-
await this.deps.db.updateWorkflowRunStep(childStepId, {
|
|
21106
|
-
idempotencyKey: `${meta.runId}:${childNodeId}:0`
|
|
21107
|
-
});
|
|
21108
|
-
childStepsByNodeId.set(childNodeId, childStep);
|
|
21109
|
-
}
|
|
21110
|
-
for (const { item, index, itemKey } of items) {
|
|
21111
|
-
const childNodeId = `${meta.nodeId}#${itemKey}`;
|
|
21112
|
-
const childStep = childStepsByNodeId.get(childNodeId);
|
|
21113
|
-
if (FOREACH_TERMINAL_STEP_STATUSES.has(childStep.status))
|
|
21114
|
-
continue;
|
|
21115
|
-
const bodyCtx = { ...meta.inputCtx ?? context, item, index };
|
|
21116
|
-
const childInterpolation = deepInterpolate(config.body.config, bodyCtx);
|
|
21117
|
-
if (childInterpolation.unresolved.length > 0) {
|
|
21118
|
-
console.warn(`[workflow] Step ${childNodeId}: unresolved interpolation tokens: ${childInterpolation.unresolved.join(", ")}`);
|
|
21119
|
-
await this.deps.db.updateWorkflowRunStep(childStep.id, {
|
|
21120
|
-
diagnostics: JSON.stringify({ unresolvedTokens: childInterpolation.unresolved })
|
|
21121
|
-
});
|
|
21122
|
-
}
|
|
21123
|
-
const linkedTask = await this.deps.db.getTaskByWorkflowRunStepId(childStep.id);
|
|
21124
|
-
if (linkedTask?.status === "failed" || linkedTask?.status === "cancelled") {
|
|
21125
|
-
await this.deps.db.detachTaskFromWorkflowRunStep(linkedTask.id);
|
|
21126
|
-
}
|
|
21127
|
-
const childResult = await agentTaskExecutor.run({
|
|
21128
|
-
config: childInterpolation.value,
|
|
21129
|
-
context,
|
|
21130
|
-
meta: {
|
|
21131
|
-
...meta,
|
|
21132
|
-
stepId: childStep.id,
|
|
21133
|
-
nodeId: childNodeId
|
|
21134
|
-
}
|
|
21135
|
-
});
|
|
21136
|
-
if (childResult.status !== "success") {
|
|
21137
|
-
throw new Error(childResult.error ?? `foreach child "${itemKey}" failed to start`);
|
|
21138
|
-
}
|
|
21139
|
-
if ("async" in childResult) {
|
|
21140
|
-
await this.deps.db.updateWorkflowRunStep(childStep.id, { status: "waiting" });
|
|
21141
|
-
} else {
|
|
21142
|
-
await this.deps.db.updateWorkflowRunStep(childStep.id, {
|
|
21143
|
-
status: "completed",
|
|
21144
|
-
output: normalizeExistingTaskOutput(childResult.output),
|
|
21145
|
-
finishedAt: new Date().toISOString()
|
|
21146
|
-
});
|
|
21147
|
-
}
|
|
21148
|
-
}
|
|
21149
|
-
const childSteps = (await this.deps.db.getWorkflowRunStepsByRunId(meta.runId)).filter((step) => parseSyntheticNodeId(step.nodeId)?.parentNodeId === meta.nodeId);
|
|
21150
|
-
if (childSteps.every((step) => FOREACH_TERMINAL_STEP_STATUSES.has(step.status))) {
|
|
21151
|
-
return { status: "success", output: buildForeachAggregate(childSteps) };
|
|
21152
|
-
}
|
|
21153
|
-
return {
|
|
21154
|
-
status: "success",
|
|
21155
|
-
async: true,
|
|
21156
|
-
waitFor: "task.completed",
|
|
21157
|
-
correlationId: meta.stepId
|
|
21158
|
-
};
|
|
21159
|
-
}
|
|
21160
|
-
}
|
|
21161
|
-
function normalizeExistingTaskOutput(output) {
|
|
21162
|
-
if (typeof output !== "object" || output === null)
|
|
21163
|
-
return output;
|
|
21164
|
-
const record = output;
|
|
21165
|
-
if (typeof record.taskOutput !== "string")
|
|
21166
|
-
return output;
|
|
21167
|
-
try {
|
|
21168
|
-
const parsed = JSON.parse(record.taskOutput);
|
|
21169
|
-
if (typeof parsed === "object" && parsed !== null) {
|
|
21170
|
-
return { ...record, taskOutput: parsed };
|
|
21171
|
-
}
|
|
21172
|
-
} catch {}
|
|
21173
|
-
return output;
|
|
21174
|
-
}
|
|
21175
|
-
|
|
21176
21079
|
// src/workflows/executors/notify.ts
|
|
21177
21080
|
init_zod();
|
|
21178
21081
|
init_secret_scrubber();
|
|
@@ -21216,7 +21119,7 @@ class NotifyExecutor extends BaseExecutor {
|
|
|
21216
21119
|
}
|
|
21217
21120
|
}
|
|
21218
21121
|
case "slack": {
|
|
21219
|
-
const { getSlackApp } = await import("./app-
|
|
21122
|
+
const { getSlackApp } = await import("./app-nndcvftq.js");
|
|
21220
21123
|
const app = getSlackApp();
|
|
21221
21124
|
if (!app) {
|
|
21222
21125
|
return {
|
|
@@ -24579,7 +24482,7 @@ function setPreloadedTools(server, names) {
|
|
|
24579
24482
|
async function applyPreToolCall(name, args, requestInfo, inputSchema) {
|
|
24580
24483
|
if (requestInfo.callOrigin !== "mcp")
|
|
24581
24484
|
return { args };
|
|
24582
|
-
const dispatcher = await import("./dispatcher-
|
|
24485
|
+
const dispatcher = await import("./dispatcher-606ydx5v.js");
|
|
24583
24486
|
const result = await dispatcher.dispatchPre("pre.tool.call", { tool: name, args, requestInfo }, inputSchema ? {
|
|
24584
24487
|
validateModify: async (data) => {
|
|
24585
24488
|
const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
|
|
@@ -25789,7 +25692,8 @@ var onChatMessageSent = chatMessageBridge("chat.message.sent", "outbound");
|
|
|
25789
25692
|
var VCS_PROVIDERS = new Set([
|
|
25790
25693
|
"github",
|
|
25791
25694
|
"gitlab",
|
|
25792
|
-
"azure-devops"
|
|
25695
|
+
"azure-devops",
|
|
25696
|
+
"bitbucket"
|
|
25793
25697
|
]);
|
|
25794
25698
|
var VCS_KINDS = new Set([
|
|
25795
25699
|
"pull_request",
|
|
@@ -28080,7 +27984,7 @@ async function handlePullRequestCommented(event) {
|
|
|
28080
27984
|
return { created: false };
|
|
28081
27985
|
}
|
|
28082
27986
|
const requestedByUserId = await resolveAzureDevOpsSender(comment.author, "pull_request_comment", comment.content);
|
|
28083
|
-
const existingTask = await findTaskByVcs2(repo, pr.pullRequestId);
|
|
27987
|
+
const existingTask = await findTaskByVcs2(repo, pr.pullRequestId, "azure-devops");
|
|
28084
27988
|
const existingTaskNote = existingTask ? `
|
|
28085
27989
|
|
|
28086
27990
|
_Note: There's an active task (${existingTask.id}) for this PR #${pr.pullRequestId}._` : "";
|
|
@@ -29194,6 +29098,456 @@ async function syncTelemetryEnabled(via) {
|
|
|
29194
29098
|
track({ event: "telemetry.enabled", properties: { via } });
|
|
29195
29099
|
return true;
|
|
29196
29100
|
}
|
|
29101
|
+
|
|
29102
|
+
// src/bitbucket/api.ts
|
|
29103
|
+
init_secret_scrubber();
|
|
29104
|
+
|
|
29105
|
+
// src/bitbucket/auth.ts
|
|
29106
|
+
init_env_flag();
|
|
29107
|
+
var initialized4 = false;
|
|
29108
|
+
var webhookSecret4 = null;
|
|
29109
|
+
var apiToken2 = null;
|
|
29110
|
+
function isBitbucketEnabled() {
|
|
29111
|
+
return !!process.env.BITBUCKET_WEBHOOK_SECRET && !isEnvFlagEnabled("BITBUCKET_DISABLE", false);
|
|
29112
|
+
}
|
|
29113
|
+
function initBitbucket() {
|
|
29114
|
+
if (initialized4)
|
|
29115
|
+
return;
|
|
29116
|
+
if (!isBitbucketEnabled()) {
|
|
29117
|
+
console.log("[Bitbucket] Integration disabled (BITBUCKET_WEBHOOK_SECRET not set)");
|
|
29118
|
+
return;
|
|
29119
|
+
}
|
|
29120
|
+
webhookSecret4 = process.env.BITBUCKET_WEBHOOK_SECRET;
|
|
29121
|
+
apiToken2 = process.env.BITBUCKET_TOKEN ?? null;
|
|
29122
|
+
initialized4 = true;
|
|
29123
|
+
console.log(`[Bitbucket] Integration initialized (API token: ${apiToken2 ? "set" : "not set"})`);
|
|
29124
|
+
}
|
|
29125
|
+
function verifyBitbucketWebhook(rawBody, signatureHeader) {
|
|
29126
|
+
if (!webhookSecret4)
|
|
29127
|
+
return false;
|
|
29128
|
+
if (!signatureHeader?.startsWith("sha256="))
|
|
29129
|
+
return false;
|
|
29130
|
+
return verifyHmacSignature(webhookSecret4, rawBody, signatureHeader);
|
|
29131
|
+
}
|
|
29132
|
+
function getBitbucketToken() {
|
|
29133
|
+
return apiToken2;
|
|
29134
|
+
}
|
|
29135
|
+
function getBitbucketBotName() {
|
|
29136
|
+
return process.env.BITBUCKET_BOT_NAME || "agent-swarm-bot";
|
|
29137
|
+
}
|
|
29138
|
+
function resetBitbucket() {
|
|
29139
|
+
initialized4 = false;
|
|
29140
|
+
webhookSecret4 = null;
|
|
29141
|
+
apiToken2 = null;
|
|
29142
|
+
}
|
|
29143
|
+
|
|
29144
|
+
// src/bitbucket/api.ts
|
|
29145
|
+
var BITBUCKET_API = "https://api.bitbucket.org/2.0";
|
|
29146
|
+
function headers3() {
|
|
29147
|
+
const token = getBitbucketToken();
|
|
29148
|
+
if (!token)
|
|
29149
|
+
throw new Error("[Bitbucket] No API token configured");
|
|
29150
|
+
return {
|
|
29151
|
+
Authorization: `Bearer ${token}`,
|
|
29152
|
+
"Content-Type": "application/json",
|
|
29153
|
+
Accept: "application/json"
|
|
29154
|
+
};
|
|
29155
|
+
}
|
|
29156
|
+
var cachedBotAccountId = null;
|
|
29157
|
+
async function resolveBitbucketBotAccountId() {
|
|
29158
|
+
const fromEnv = process.env.BITBUCKET_BOT_ACCOUNT_ID?.trim();
|
|
29159
|
+
if (fromEnv)
|
|
29160
|
+
return fromEnv;
|
|
29161
|
+
if (cachedBotAccountId)
|
|
29162
|
+
return cachedBotAccountId;
|
|
29163
|
+
if (!getBitbucketToken())
|
|
29164
|
+
return null;
|
|
29165
|
+
try {
|
|
29166
|
+
const resp = await fetch(`${BITBUCKET_API}/user`, { headers: headers3(), redirect: "error" });
|
|
29167
|
+
if (!resp.ok) {
|
|
29168
|
+
console.error(`[Bitbucket] GET /user returned ${resp.status}`);
|
|
29169
|
+
return null;
|
|
29170
|
+
}
|
|
29171
|
+
const data = await resp.json();
|
|
29172
|
+
cachedBotAccountId = data.account_id?.trim() || null;
|
|
29173
|
+
return cachedBotAccountId;
|
|
29174
|
+
} catch (err) {
|
|
29175
|
+
console.error(`[Bitbucket] Failed to resolve bot identity: ${scrubSecrets(String(err))}`);
|
|
29176
|
+
return null;
|
|
29177
|
+
}
|
|
29178
|
+
}
|
|
29179
|
+
function resetBitbucketBotCache() {
|
|
29180
|
+
cachedBotAccountId = null;
|
|
29181
|
+
}
|
|
29182
|
+
// src/bitbucket/handlers.ts
|
|
29183
|
+
init_db3();
|
|
29184
|
+
init_users();
|
|
29185
|
+
init_resolver();
|
|
29186
|
+
init_context_key();
|
|
29187
|
+
|
|
29188
|
+
// src/bitbucket/templates.ts
|
|
29189
|
+
init_registry();
|
|
29190
|
+
registerTemplate({
|
|
29191
|
+
eventType: "common.delegation_instruction.bitbucket",
|
|
29192
|
+
header: "",
|
|
29193
|
+
defaultBody: "\n\n**Delegation instruction:** As the lead agent, analyze this and decide whether to handle it yourself or delegate to a worker agent. Use `send-task` to delegate with clear instructions.",
|
|
29194
|
+
variables: [],
|
|
29195
|
+
category: "common"
|
|
29196
|
+
});
|
|
29197
|
+
registerTemplate({
|
|
29198
|
+
eventType: "common.command_suggestions.bitbucket_pr",
|
|
29199
|
+
header: "",
|
|
29200
|
+
defaultBody: 'Workers have `git` authenticated for bitbucket.org and `BITBUCKET_TOKEN` in env; there is no Bitbucket CLI, so use curl against `https://api.bitbucket.org/2.0/repositories/{{repo}}` with `-H "Authorization: Bearer $BITBUCKET_TOKEN"`. Inspect the PR with `GET .../pullrequests/{{pr_id}}` and its diff with `GET .../pullrequests/{{pr_id}}/diff`. Reply with `POST .../pullrequests/{{pr_id}}/comments` and JSON body `{"content":{"raw":"<reply>"}}`. Find a PR by branch with `GET .../pullrequests?q=source.branch.name="<branch>"`. Open a PR with `POST .../pullrequests` and JSON body `{"title":"<title>","source":{"branch":{"name":"<branch>"}},"destination":{"branch":{"name":"<base>"}}}`.',
|
|
29201
|
+
variables: [
|
|
29202
|
+
{ name: "repo", description: "Repository full name (<workspace>/<repo_slug>)" },
|
|
29203
|
+
{ name: "pr_id", description: "Pull request ID" }
|
|
29204
|
+
],
|
|
29205
|
+
category: "common"
|
|
29206
|
+
});
|
|
29207
|
+
var SHARED_VARIABLES2 = [
|
|
29208
|
+
{ name: "pr_id", description: "Pull request ID" },
|
|
29209
|
+
{ name: "pr_title", description: "Pull request title" },
|
|
29210
|
+
{ name: "repo", description: "Repository full name (<workspace>/<repo_slug>)" },
|
|
29211
|
+
{ name: "pr_url", description: "Pull request web URL" }
|
|
29212
|
+
];
|
|
29213
|
+
var PR_BRANCH_VARIABLES = [
|
|
29214
|
+
{ name: "source_branch", description: "Source branch name" },
|
|
29215
|
+
{ name: "target_branch", description: "Target branch name" },
|
|
29216
|
+
{ name: "context_section", description: "Context section with description or empty string" }
|
|
29217
|
+
];
|
|
29218
|
+
registerTemplate({
|
|
29219
|
+
eventType: "bitbucket.pull_request.opened",
|
|
29220
|
+
header: "[Bitbucket PR #{{pr_id}}] {{pr_title}}",
|
|
29221
|
+
defaultBody: `Repo: {{repo}}
|
|
29222
|
+
Author: {{username}}
|
|
29223
|
+
Branch: {{source_branch}} → {{target_branch}}
|
|
29224
|
+
URL: {{pr_url}}
|
|
29225
|
+
|
|
29226
|
+
{{context_section}}{{@template[common.command_suggestions.bitbucket_pr]}}{{@template[common.delegation_instruction.bitbucket]}}`,
|
|
29227
|
+
variables: [
|
|
29228
|
+
...SHARED_VARIABLES2,
|
|
29229
|
+
{
|
|
29230
|
+
name: "username",
|
|
29231
|
+
description: "Author identity — resolved canonical name (e.g. 'Luis (bitbucket:557058:…)') or the UNKNOWN sentinel"
|
|
29232
|
+
},
|
|
29233
|
+
...PR_BRANCH_VARIABLES
|
|
29234
|
+
],
|
|
29235
|
+
category: "event"
|
|
29236
|
+
});
|
|
29237
|
+
registerTemplate({
|
|
29238
|
+
eventType: "bitbucket.pull_request.review_requested",
|
|
29239
|
+
header: "[Bitbucket PR #{{pr_id}}] Review requested: {{pr_title}}",
|
|
29240
|
+
defaultBody: `Repo: {{repo}}
|
|
29241
|
+
Author: {{username}}
|
|
29242
|
+
Branch: {{source_branch}} → {{target_branch}}
|
|
29243
|
+
URL: {{pr_url}}
|
|
29244
|
+
|
|
29245
|
+
You were added as a reviewer on this pull request.
|
|
29246
|
+
|
|
29247
|
+
{{context_section}}{{@template[common.command_suggestions.bitbucket_pr]}}{{@template[common.delegation_instruction.bitbucket]}}`,
|
|
29248
|
+
variables: [
|
|
29249
|
+
...SHARED_VARIABLES2,
|
|
29250
|
+
{
|
|
29251
|
+
name: "username",
|
|
29252
|
+
description: "Author identity — resolved canonical name (e.g. 'Luis (bitbucket:557058:…)') or the UNKNOWN sentinel"
|
|
29253
|
+
},
|
|
29254
|
+
...PR_BRANCH_VARIABLES
|
|
29255
|
+
],
|
|
29256
|
+
category: "event"
|
|
29257
|
+
});
|
|
29258
|
+
registerTemplate({
|
|
29259
|
+
eventType: "bitbucket.comment.mentioned",
|
|
29260
|
+
header: "[Bitbucket Comment on PR #{{pr_id}}] {{username}} mentioned bot",
|
|
29261
|
+
defaultBody: `Repo: {{repo}}
|
|
29262
|
+
PR: {{pr_title}}
|
|
29263
|
+
URL: {{pr_url}}
|
|
29264
|
+
{{location_section}}
|
|
29265
|
+
Comment:
|
|
29266
|
+
{{context}}{{existing_task_note}}
|
|
29267
|
+
|
|
29268
|
+
{{@template[common.command_suggestions.bitbucket_pr]}}{{@template[common.delegation_instruction.bitbucket]}}`,
|
|
29269
|
+
variables: [
|
|
29270
|
+
...SHARED_VARIABLES2,
|
|
29271
|
+
{
|
|
29272
|
+
name: "username",
|
|
29273
|
+
description: "Comment author identity — resolved canonical name (e.g. 'Luis (bitbucket:557058:…)') or the UNKNOWN sentinel"
|
|
29274
|
+
},
|
|
29275
|
+
{
|
|
29276
|
+
name: "location_section",
|
|
29277
|
+
description: "`File: <path>:<line>` line for inline comments, or empty string"
|
|
29278
|
+
},
|
|
29279
|
+
{ name: "context", description: "Extracted mention context from comment" },
|
|
29280
|
+
{
|
|
29281
|
+
name: "existing_task_note",
|
|
29282
|
+
description: "Note about existing active task, or empty string"
|
|
29283
|
+
}
|
|
29284
|
+
],
|
|
29285
|
+
category: "event"
|
|
29286
|
+
});
|
|
29287
|
+
|
|
29288
|
+
// src/bitbucket/handlers.ts
|
|
29289
|
+
var DEDUP_TTL_MS2 = 60000;
|
|
29290
|
+
var processedEvents3 = new Map;
|
|
29291
|
+
var processedDeliveries = new Map;
|
|
29292
|
+
function sweep(cache, now) {
|
|
29293
|
+
for (const [k, ts] of cache) {
|
|
29294
|
+
if (now - ts > DEDUP_TTL_MS2)
|
|
29295
|
+
cache.delete(k);
|
|
29296
|
+
}
|
|
29297
|
+
}
|
|
29298
|
+
function isDuplicate3(key) {
|
|
29299
|
+
const now = Date.now();
|
|
29300
|
+
sweep(processedEvents3, now);
|
|
29301
|
+
if (processedEvents3.has(key))
|
|
29302
|
+
return true;
|
|
29303
|
+
processedEvents3.set(key, now);
|
|
29304
|
+
return false;
|
|
29305
|
+
}
|
|
29306
|
+
async function withDedupReservation(key, fn) {
|
|
29307
|
+
if (isDuplicate3(key))
|
|
29308
|
+
return null;
|
|
29309
|
+
try {
|
|
29310
|
+
return await fn();
|
|
29311
|
+
} catch (err) {
|
|
29312
|
+
processedEvents3.delete(key);
|
|
29313
|
+
throw err;
|
|
29314
|
+
}
|
|
29315
|
+
}
|
|
29316
|
+
function isDuplicateDelivery(requestUuid) {
|
|
29317
|
+
if (!requestUuid)
|
|
29318
|
+
return false;
|
|
29319
|
+
sweep(processedDeliveries, Date.now());
|
|
29320
|
+
return processedDeliveries.has(requestUuid);
|
|
29321
|
+
}
|
|
29322
|
+
function markDeliveryProcessed(requestUuid) {
|
|
29323
|
+
if (requestUuid)
|
|
29324
|
+
processedDeliveries.set(requestUuid, Date.now());
|
|
29325
|
+
}
|
|
29326
|
+
function escapeRegExp2(value) {
|
|
29327
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
29328
|
+
}
|
|
29329
|
+
function mentionPatterns2(botAccountId) {
|
|
29330
|
+
const patterns = [new RegExp(`@${escapeRegExp2(getBitbucketBotName())}(?![\\w-])`, "gi")];
|
|
29331
|
+
if (botAccountId)
|
|
29332
|
+
patterns.push(new RegExp(`@\\{${escapeRegExp2(botAccountId)}\\}`, "gi"));
|
|
29333
|
+
return patterns;
|
|
29334
|
+
}
|
|
29335
|
+
function detectMention2(text, botAccountId) {
|
|
29336
|
+
if (!text)
|
|
29337
|
+
return false;
|
|
29338
|
+
return mentionPatterns2(botAccountId).some((re) => {
|
|
29339
|
+
re.lastIndex = 0;
|
|
29340
|
+
return re.test(text);
|
|
29341
|
+
});
|
|
29342
|
+
}
|
|
29343
|
+
function extractMentionContext2(text, botAccountId) {
|
|
29344
|
+
return mentionPatterns2(botAccountId).reduce((acc, re) => acc.replace(re, ""), text).trim();
|
|
29345
|
+
}
|
|
29346
|
+
function isBot2(account, botAccountId) {
|
|
29347
|
+
return !!botAccountId && account?.account_id === botAccountId;
|
|
29348
|
+
}
|
|
29349
|
+
function pullRequestWebUrl2(repo, pr) {
|
|
29350
|
+
return pr.links?.html?.href ?? `https://bitbucket.org/${repo}/pull-requests/${pr.id}`;
|
|
29351
|
+
}
|
|
29352
|
+
function contextKeyOf(event) {
|
|
29353
|
+
return bitbucketContextKey({
|
|
29354
|
+
repoUuid: event.repository.uuid,
|
|
29355
|
+
pullRequestId: event.pullrequest.id
|
|
29356
|
+
});
|
|
29357
|
+
}
|
|
29358
|
+
function pullRequestEventOf(body) {
|
|
29359
|
+
const event = body;
|
|
29360
|
+
const pr = event?.pullrequest;
|
|
29361
|
+
const repo = event?.repository;
|
|
29362
|
+
if (typeof pr?.id !== "number" || typeof pr.title !== "string" || typeof repo?.uuid !== "string" || typeof repo.full_name !== "string" || !event?.actor) {
|
|
29363
|
+
return null;
|
|
29364
|
+
}
|
|
29365
|
+
return event;
|
|
29366
|
+
}
|
|
29367
|
+
function pullRequestCommentEventOf(body) {
|
|
29368
|
+
const event = pullRequestEventOf(body);
|
|
29369
|
+
const comment = event?.comment;
|
|
29370
|
+
if (!event || typeof comment?.id !== "number" || typeof comment.content?.raw !== "string") {
|
|
29371
|
+
return null;
|
|
29372
|
+
}
|
|
29373
|
+
return event;
|
|
29374
|
+
}
|
|
29375
|
+
function warnMalformed2(eventKey) {
|
|
29376
|
+
console.warn(`[Bitbucket] Ignoring ${eventKey} event: required payload fields are missing`);
|
|
29377
|
+
}
|
|
29378
|
+
async function findLeadAgent3() {
|
|
29379
|
+
const agents = await getAllAgents2();
|
|
29380
|
+
return agents.find((a) => a.role === "lead" && a.status === "idle") ?? agents.find((a) => a.role === "lead") ?? null;
|
|
29381
|
+
}
|
|
29382
|
+
var UNMAPPED_NAMESPACE2 = "integration:unmapped:bitbucket";
|
|
29383
|
+
var UNMAPPED_TTL_MS2 = 30 * 24 * 60 * 60 * 1000;
|
|
29384
|
+
function externalIdOf2(account) {
|
|
29385
|
+
return account?.account_id?.trim() || account?.uuid?.trim() || null;
|
|
29386
|
+
}
|
|
29387
|
+
async function resolveBitbucketSender(account, sampleEventType, sampleContext) {
|
|
29388
|
+
const externalId = externalIdOf2(account);
|
|
29389
|
+
if (!externalId)
|
|
29390
|
+
return;
|
|
29391
|
+
const existing = await findUserByExternalId("bitbucket", externalId);
|
|
29392
|
+
if (existing)
|
|
29393
|
+
return existing.id;
|
|
29394
|
+
await upsertKv2({
|
|
29395
|
+
namespace: UNMAPPED_NAMESPACE2,
|
|
29396
|
+
key: `${externalId}:meta`,
|
|
29397
|
+
value: {
|
|
29398
|
+
lastSeenAt: new Date().toISOString(),
|
|
29399
|
+
displayName: account?.display_name,
|
|
29400
|
+
sampleEventType,
|
|
29401
|
+
sampleContext: sampleContext.slice(0, 100)
|
|
29402
|
+
},
|
|
29403
|
+
valueType: "json",
|
|
29404
|
+
expiresAt: Date.now() + UNMAPPED_TTL_MS2
|
|
29405
|
+
});
|
|
29406
|
+
await incrKv2(UNMAPPED_NAMESPACE2, `${externalId}:count`, 1);
|
|
29407
|
+
return;
|
|
29408
|
+
}
|
|
29409
|
+
async function renderBitbucketIdentity(account) {
|
|
29410
|
+
return renderIdentity(await resolveIdentity("bitbucket", externalIdOf2(account) ?? ""));
|
|
29411
|
+
}
|
|
29412
|
+
async function createBitbucketTask(text, event, fields) {
|
|
29413
|
+
const { pullrequest: pr, repository } = event;
|
|
29414
|
+
const lead = await findLeadAgent3();
|
|
29415
|
+
const task = await createTaskWithSiblingAwareness(text, {
|
|
29416
|
+
agentId: lead?.id ?? null,
|
|
29417
|
+
routingReason: lead ? "skill" : undefined,
|
|
29418
|
+
routingSource: lead ? "engine_default" : undefined,
|
|
29419
|
+
source: "bitbucket",
|
|
29420
|
+
vcsProvider: "bitbucket",
|
|
29421
|
+
taskType: fields.taskType,
|
|
29422
|
+
vcsRepo: repository.full_name,
|
|
29423
|
+
vcsEventType: fields.vcsEventType,
|
|
29424
|
+
vcsNumber: pr.id,
|
|
29425
|
+
vcsCommentId: fields.vcsCommentId,
|
|
29426
|
+
vcsAuthor: externalIdOf2(fields.author) ?? undefined,
|
|
29427
|
+
requestedByUserId: fields.requestedByUserId,
|
|
29428
|
+
vcsUrl: pullRequestWebUrl2(repository.full_name, pr),
|
|
29429
|
+
parentTaskId: fields.parentTaskId,
|
|
29430
|
+
contextKey: contextKeyOf(event)
|
|
29431
|
+
}, { origin: "webhook" });
|
|
29432
|
+
return { created: true, taskId: task.id };
|
|
29433
|
+
}
|
|
29434
|
+
async function handlePullRequestCreated2(body) {
|
|
29435
|
+
const event = pullRequestEventOf(body);
|
|
29436
|
+
if (!event) {
|
|
29437
|
+
warnMalformed2("pullrequest:created");
|
|
29438
|
+
return { created: false };
|
|
29439
|
+
}
|
|
29440
|
+
const { pullrequest: pr, repository } = event;
|
|
29441
|
+
const repo = repository.full_name;
|
|
29442
|
+
const author = pr.author ?? event.actor;
|
|
29443
|
+
console.log(`[Bitbucket] PR #${pr.id} created by ${author.display_name} in ${repo}`);
|
|
29444
|
+
const botAccountId = await resolveBitbucketBotAccountId();
|
|
29445
|
+
if (isBot2(author, botAccountId)) {
|
|
29446
|
+
console.log(`[Bitbucket] PR opened by the bot itself, skipping`);
|
|
29447
|
+
return { created: false };
|
|
29448
|
+
}
|
|
29449
|
+
const mentioned = detectMention2(pr.description, botAccountId);
|
|
29450
|
+
const reviewRequested = !!botAccountId && (pr.reviewers ?? []).some((r) => r.account_id === botAccountId);
|
|
29451
|
+
if (!mentioned && !reviewRequested) {
|
|
29452
|
+
console.log(`[Bitbucket] PR opened without bot mention or review request, skipping`);
|
|
29453
|
+
return { created: false };
|
|
29454
|
+
}
|
|
29455
|
+
const dedupKey = `bitbucket-pr-${repository.uuid}-${pr.id}-created`;
|
|
29456
|
+
const outcome = await withDedupReservation(dedupKey, async () => {
|
|
29457
|
+
const requestedByUserId = await resolveBitbucketSender(author, "pull_request", `PR #${pr.id}: ${pr.title}`);
|
|
29458
|
+
const context = pr.description ? extractMentionContext2(pr.description, botAccountId) : "";
|
|
29459
|
+
const templateId = mentioned ? "bitbucket.pull_request.opened" : "bitbucket.pull_request.review_requested";
|
|
29460
|
+
const result = resolveTemplate(templateId, {
|
|
29461
|
+
pr_id: pr.id,
|
|
29462
|
+
pr_title: pr.title,
|
|
29463
|
+
repo,
|
|
29464
|
+
username: await renderBitbucketIdentity(author),
|
|
29465
|
+
source_branch: pr.source?.branch?.name ?? "",
|
|
29466
|
+
target_branch: pr.destination?.branch?.name ?? "",
|
|
29467
|
+
pr_url: pullRequestWebUrl2(repo, pr),
|
|
29468
|
+
context_section: context ? `Context: ${context}
|
|
29469
|
+
|
|
29470
|
+
` : ""
|
|
29471
|
+
});
|
|
29472
|
+
if (result.skipped) {
|
|
29473
|
+
return { created: false };
|
|
29474
|
+
}
|
|
29475
|
+
return createBitbucketTask(result.text, event, {
|
|
29476
|
+
taskType: "bitbucket-pr",
|
|
29477
|
+
vcsEventType: "pull_request",
|
|
29478
|
+
author,
|
|
29479
|
+
requestedByUserId
|
|
29480
|
+
});
|
|
29481
|
+
});
|
|
29482
|
+
if (!outcome)
|
|
29483
|
+
console.log(`[Bitbucket] Skipping duplicate PR event`);
|
|
29484
|
+
return outcome ?? { created: false };
|
|
29485
|
+
}
|
|
29486
|
+
async function handlePullRequestCommentCreated(body) {
|
|
29487
|
+
const event = pullRequestCommentEventOf(body);
|
|
29488
|
+
if (!event) {
|
|
29489
|
+
warnMalformed2("pullrequest:comment_created");
|
|
29490
|
+
return { created: false };
|
|
29491
|
+
}
|
|
29492
|
+
const { pullrequest: pr, repository, comment } = event;
|
|
29493
|
+
const repo = repository.full_name;
|
|
29494
|
+
const author = comment.user ?? event.actor;
|
|
29495
|
+
const botAccountId = await resolveBitbucketBotAccountId();
|
|
29496
|
+
if (isBot2(author, botAccountId)) {
|
|
29497
|
+
return { created: false };
|
|
29498
|
+
}
|
|
29499
|
+
if (!detectMention2(comment.content.raw, botAccountId)) {
|
|
29500
|
+
return { created: false };
|
|
29501
|
+
}
|
|
29502
|
+
console.log(`[Bitbucket] Comment by ${author.display_name} on PR #${pr.id} in ${repo}`);
|
|
29503
|
+
const dedupKey = `bitbucket-comment-${repository.uuid}-${pr.id}-${comment.id}`;
|
|
29504
|
+
const outcome = await withDedupReservation(dedupKey, async () => {
|
|
29505
|
+
const requestedByUserId = await resolveBitbucketSender(author, "pull_request_comment", comment.content.raw);
|
|
29506
|
+
const existingTask = await findTaskByVcs2(repo, pr.id, "bitbucket");
|
|
29507
|
+
const existingTaskNote = existingTask ? `
|
|
29508
|
+
|
|
29509
|
+
_Note: There's an active task (${existingTask.id}) for this PR #${pr.id}._` : "";
|
|
29510
|
+
const line = comment.inline?.to ?? comment.inline?.from;
|
|
29511
|
+
const locationSection = comment.inline ? `File: ${comment.inline.path}${line != null ? `:${line}` : ""}
|
|
29512
|
+
` : "";
|
|
29513
|
+
const result = resolveTemplate("bitbucket.comment.mentioned", {
|
|
29514
|
+
pr_id: pr.id,
|
|
29515
|
+
pr_title: pr.title,
|
|
29516
|
+
username: await renderBitbucketIdentity(author),
|
|
29517
|
+
repo,
|
|
29518
|
+
pr_url: comment.links?.html?.href ?? pullRequestWebUrl2(repo, pr),
|
|
29519
|
+
location_section: locationSection,
|
|
29520
|
+
context: extractMentionContext2(comment.content.raw, botAccountId),
|
|
29521
|
+
existing_task_note: existingTaskNote
|
|
29522
|
+
});
|
|
29523
|
+
if (result.skipped) {
|
|
29524
|
+
return { created: false };
|
|
29525
|
+
}
|
|
29526
|
+
return createBitbucketTask(result.text, event, {
|
|
29527
|
+
taskType: "bitbucket-comment",
|
|
29528
|
+
vcsEventType: "pull_request_comment",
|
|
29529
|
+
author,
|
|
29530
|
+
requestedByUserId,
|
|
29531
|
+
vcsCommentId: comment.id,
|
|
29532
|
+
parentTaskId: existingTask?.id
|
|
29533
|
+
});
|
|
29534
|
+
});
|
|
29535
|
+
return outcome ?? { created: false };
|
|
29536
|
+
}
|
|
29537
|
+
async function handlePullRequestClosed(body, outcome) {
|
|
29538
|
+
const event = pullRequestEventOf(body);
|
|
29539
|
+
if (!event) {
|
|
29540
|
+
warnMalformed2(outcome === "merged" ? "pullrequest:fulfilled" : "pullrequest:rejected");
|
|
29541
|
+
return { created: false };
|
|
29542
|
+
}
|
|
29543
|
+
const { pullrequest: pr, repository } = event;
|
|
29544
|
+
const reason = outcome === "merged" ? "PR was merged" : "PR was declined";
|
|
29545
|
+
for (const task of await findActiveTasksByVcs2(repository.full_name, pr.id, "bitbucket")) {
|
|
29546
|
+
console.log(`[Bitbucket] Cancelling task ${task.id} — ${reason}`);
|
|
29547
|
+
await failTask2(task.id, reason);
|
|
29548
|
+
}
|
|
29549
|
+
return { created: false };
|
|
29550
|
+
}
|
|
29197
29551
|
// src/github/handlers.ts
|
|
29198
29552
|
init_db3();
|
|
29199
29553
|
init_users();
|
|
@@ -29218,12 +29572,12 @@ function computeMentionPattern(names) {
|
|
|
29218
29572
|
}
|
|
29219
29573
|
var BOT_NAMES = computeBotNames();
|
|
29220
29574
|
var MENTION_PATTERN = computeMentionPattern(BOT_NAMES);
|
|
29221
|
-
function
|
|
29575
|
+
function detectMention3(text) {
|
|
29222
29576
|
if (!text)
|
|
29223
29577
|
return false;
|
|
29224
29578
|
return MENTION_PATTERN.test(text);
|
|
29225
29579
|
}
|
|
29226
|
-
function
|
|
29580
|
+
function extractMentionContext3(text) {
|
|
29227
29581
|
if (!text)
|
|
29228
29582
|
return "";
|
|
29229
29583
|
return text.replace(MENTION_PATTERN, "").trim();
|
|
@@ -29666,7 +30020,7 @@ Related task: {{related_task_id}}
|
|
|
29666
30020
|
});
|
|
29667
30021
|
|
|
29668
30022
|
// src/github/handlers.ts
|
|
29669
|
-
var
|
|
30023
|
+
var processedEvents4 = new Map;
|
|
29670
30024
|
var EVENT_TTL2 = 60000;
|
|
29671
30025
|
function buildGithubContextKey(fullName, kind, number) {
|
|
29672
30026
|
const [owner, repo] = fullName.split("/");
|
|
@@ -29710,34 +30064,34 @@ function getCommandSuggestions(taskType, targetType) {
|
|
|
29710
30064
|
return "";
|
|
29711
30065
|
}
|
|
29712
30066
|
}
|
|
29713
|
-
function
|
|
30067
|
+
function isDuplicate4(eventKey) {
|
|
29714
30068
|
const now = Date.now();
|
|
29715
|
-
for (const [key, timestamp] of
|
|
30069
|
+
for (const [key, timestamp] of processedEvents4) {
|
|
29716
30070
|
if (now - timestamp > EVENT_TTL2) {
|
|
29717
|
-
|
|
30071
|
+
processedEvents4.delete(key);
|
|
29718
30072
|
}
|
|
29719
30073
|
}
|
|
29720
|
-
if (
|
|
30074
|
+
if (processedEvents4.has(eventKey)) {
|
|
29721
30075
|
return true;
|
|
29722
30076
|
}
|
|
29723
|
-
|
|
30077
|
+
processedEvents4.set(eventKey, now);
|
|
29724
30078
|
return false;
|
|
29725
30079
|
}
|
|
29726
|
-
async function
|
|
30080
|
+
async function findLeadAgent4() {
|
|
29727
30081
|
const agents = await getAllAgents2();
|
|
29728
30082
|
const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
|
|
29729
30083
|
if (onlineLead)
|
|
29730
30084
|
return onlineLead;
|
|
29731
30085
|
return agents.find((a) => a.isLead) ?? null;
|
|
29732
30086
|
}
|
|
29733
|
-
var
|
|
29734
|
-
var
|
|
30087
|
+
var UNMAPPED_NAMESPACE3 = "integration:unmapped:github";
|
|
30088
|
+
var UNMAPPED_TTL_MS3 = 30 * 24 * 60 * 60 * 1000;
|
|
29735
30089
|
async function resolveGitHubSender(login, sampleEventType, sampleContext) {
|
|
29736
30090
|
const existing = await findUserByExternalId("github", login);
|
|
29737
30091
|
if (existing)
|
|
29738
30092
|
return existing.id;
|
|
29739
30093
|
await upsertKv2({
|
|
29740
|
-
namespace:
|
|
30094
|
+
namespace: UNMAPPED_NAMESPACE3,
|
|
29741
30095
|
key: `${login}:meta`,
|
|
29742
30096
|
value: {
|
|
29743
30097
|
lastSeenAt: new Date().toISOString(),
|
|
@@ -29745,9 +30099,9 @@ async function resolveGitHubSender(login, sampleEventType, sampleContext) {
|
|
|
29745
30099
|
sampleContext: sampleContext.slice(0, 100)
|
|
29746
30100
|
},
|
|
29747
30101
|
valueType: "json",
|
|
29748
|
-
expiresAt: Date.now() +
|
|
30102
|
+
expiresAt: Date.now() + UNMAPPED_TTL_MS3
|
|
29749
30103
|
});
|
|
29750
|
-
await incrKv2(
|
|
30104
|
+
await incrKv2(UNMAPPED_NAMESPACE3, `${login}:count`, 1);
|
|
29751
30105
|
return;
|
|
29752
30106
|
}
|
|
29753
30107
|
async function handlePullRequest(event) {
|
|
@@ -29766,10 +30120,10 @@ async function handlePullRequest(event) {
|
|
|
29766
30120
|
return { created: false };
|
|
29767
30121
|
}
|
|
29768
30122
|
const eventKey = `pr-assigned:${repository.full_name}:${pr.number}`;
|
|
29769
|
-
if (
|
|
30123
|
+
if (isDuplicate4(eventKey)) {
|
|
29770
30124
|
return { created: false };
|
|
29771
30125
|
}
|
|
29772
|
-
const lead = await
|
|
30126
|
+
const lead = await findLeadAgent4();
|
|
29773
30127
|
const result = resolveTemplate("github.pull_request.assigned", {
|
|
29774
30128
|
pr_number: pr.number,
|
|
29775
30129
|
pr_title: pr.title,
|
|
@@ -29816,7 +30170,7 @@ async function handlePullRequest(event) {
|
|
|
29816
30170
|
console.log(`[GitHub] unassign cancel disabled by config — leaving task untouched (PR #${pr.number})`);
|
|
29817
30171
|
return { created: false };
|
|
29818
30172
|
}
|
|
29819
|
-
const task = await findTaskByVcs2(repository.full_name, pr.number);
|
|
30173
|
+
const task = await findTaskByVcs2(repository.full_name, pr.number, "github");
|
|
29820
30174
|
if (!task) {
|
|
29821
30175
|
console.log(`[GitHub] No active task found for PR #${pr.number} to cancel`);
|
|
29822
30176
|
return { created: false };
|
|
@@ -29833,15 +30187,15 @@ async function handlePullRequest(event) {
|
|
|
29833
30187
|
return { created: false };
|
|
29834
30188
|
}
|
|
29835
30189
|
const eventKey = `pr-review-requested:${repository.full_name}:${pr.number}`;
|
|
29836
|
-
if (
|
|
30190
|
+
if (isDuplicate4(eventKey)) {
|
|
29837
30191
|
return { created: false };
|
|
29838
30192
|
}
|
|
29839
|
-
const existingTask = await findTaskByVcs2(repository.full_name, pr.number);
|
|
30193
|
+
const existingTask = await findTaskByVcs2(repository.full_name, pr.number, "github");
|
|
29840
30194
|
if (existingTask) {
|
|
29841
30195
|
console.log(`[GitHub] Skipping review task for PR #${pr.number} — active task ${existingTask.id} already exists`);
|
|
29842
30196
|
return { created: false };
|
|
29843
30197
|
}
|
|
29844
|
-
const lead = await
|
|
30198
|
+
const lead = await findLeadAgent4();
|
|
29845
30199
|
const result = resolveTemplate("github.pull_request.review_requested", {
|
|
29846
30200
|
pr_number: pr.number,
|
|
29847
30201
|
pr_title: pr.title,
|
|
@@ -29888,7 +30242,7 @@ async function handlePullRequest(event) {
|
|
|
29888
30242
|
console.log(`[GitHub] review-request-removed cancel disabled by config — leaving task untouched (PR #${pr.number})`);
|
|
29889
30243
|
return { created: false };
|
|
29890
30244
|
}
|
|
29891
|
-
const task = await findTaskByVcs2(repository.full_name, pr.number);
|
|
30245
|
+
const task = await findTaskByVcs2(repository.full_name, pr.number, "github");
|
|
29892
30246
|
if (!task) {
|
|
29893
30247
|
console.log(`[GitHub] No active task found for PR #${pr.number} to cancel`);
|
|
29894
30248
|
return { created: false };
|
|
@@ -29906,10 +30260,10 @@ async function handlePullRequest(event) {
|
|
|
29906
30260
|
return { created: false };
|
|
29907
30261
|
}
|
|
29908
30262
|
const eventKey = `pr-labeled:${repository.full_name}:${pr.number}:${labelName}`;
|
|
29909
|
-
if (
|
|
30263
|
+
if (isDuplicate4(eventKey)) {
|
|
29910
30264
|
return { created: false };
|
|
29911
30265
|
}
|
|
29912
|
-
const lead = await
|
|
30266
|
+
const lead = await findLeadAgent4();
|
|
29913
30267
|
const result = resolveTemplate("github.pull_request.labeled", {
|
|
29914
30268
|
pr_number: pr.number,
|
|
29915
30269
|
pr_title: pr.title,
|
|
@@ -29959,16 +30313,16 @@ async function handlePullRequest(event) {
|
|
|
29959
30313
|
if (action !== "opened" && action !== "edited") {
|
|
29960
30314
|
return { created: false };
|
|
29961
30315
|
}
|
|
29962
|
-
const hasMention =
|
|
30316
|
+
const hasMention = detectMention3(pr.title) || detectMention3(pr.body);
|
|
29963
30317
|
if (!hasMention) {
|
|
29964
30318
|
return { created: false };
|
|
29965
30319
|
}
|
|
29966
30320
|
const eventKey = `pr:${repository.full_name}:${pr.number}:${action}`;
|
|
29967
|
-
if (
|
|
30321
|
+
if (isDuplicate4(eventKey)) {
|
|
29968
30322
|
return { created: false };
|
|
29969
30323
|
}
|
|
29970
|
-
const lead = await
|
|
29971
|
-
const context =
|
|
30324
|
+
const lead = await findLeadAgent4();
|
|
30325
|
+
const context = extractMentionContext3(pr.body) || pr.title;
|
|
29972
30326
|
const result = resolveTemplate("github.pull_request.mentioned", {
|
|
29973
30327
|
pr_number: pr.number,
|
|
29974
30328
|
pr_title: pr.title,
|
|
@@ -30014,10 +30368,10 @@ async function handleIssue(event) {
|
|
|
30014
30368
|
return { created: false };
|
|
30015
30369
|
}
|
|
30016
30370
|
const eventKey = `issue-assigned:${repository.full_name}:${issue.number}`;
|
|
30017
|
-
if (
|
|
30371
|
+
if (isDuplicate4(eventKey)) {
|
|
30018
30372
|
return { created: false };
|
|
30019
30373
|
}
|
|
30020
|
-
const lead = await
|
|
30374
|
+
const lead = await findLeadAgent4();
|
|
30021
30375
|
const result = resolveTemplate("github.issue.assigned", {
|
|
30022
30376
|
issue_number: issue.number,
|
|
30023
30377
|
issue_title: issue.title,
|
|
@@ -30062,7 +30416,7 @@ async function handleIssue(event) {
|
|
|
30062
30416
|
console.log(`[GitHub] unassign cancel disabled by config — leaving task untouched (issue #${issue.number})`);
|
|
30063
30417
|
return { created: false };
|
|
30064
30418
|
}
|
|
30065
|
-
const task = await findTaskByVcs2(repository.full_name, issue.number);
|
|
30419
|
+
const task = await findTaskByVcs2(repository.full_name, issue.number, "github");
|
|
30066
30420
|
if (!task) {
|
|
30067
30421
|
console.log(`[GitHub] No active task found for issue #${issue.number} to cancel`);
|
|
30068
30422
|
return { created: false };
|
|
@@ -30080,10 +30434,10 @@ async function handleIssue(event) {
|
|
|
30080
30434
|
return { created: false };
|
|
30081
30435
|
}
|
|
30082
30436
|
const eventKey = `issue-labeled:${repository.full_name}:${issue.number}:${labelName}`;
|
|
30083
|
-
if (
|
|
30437
|
+
if (isDuplicate4(eventKey)) {
|
|
30084
30438
|
return { created: false };
|
|
30085
30439
|
}
|
|
30086
|
-
const lead = await
|
|
30440
|
+
const lead = await findLeadAgent4();
|
|
30087
30441
|
const result = resolveTemplate("github.issue.labeled", {
|
|
30088
30442
|
issue_number: issue.number,
|
|
30089
30443
|
issue_title: issue.title,
|
|
@@ -30123,16 +30477,16 @@ async function handleIssue(event) {
|
|
|
30123
30477
|
if (action !== "opened" && action !== "edited") {
|
|
30124
30478
|
return { created: false };
|
|
30125
30479
|
}
|
|
30126
|
-
const hasMention =
|
|
30480
|
+
const hasMention = detectMention3(issue.title) || detectMention3(issue.body);
|
|
30127
30481
|
if (!hasMention) {
|
|
30128
30482
|
return { created: false };
|
|
30129
30483
|
}
|
|
30130
30484
|
const eventKey = `issue:${repository.full_name}:${issue.number}:${action}`;
|
|
30131
|
-
if (
|
|
30485
|
+
if (isDuplicate4(eventKey)) {
|
|
30132
30486
|
return { created: false };
|
|
30133
30487
|
}
|
|
30134
|
-
const lead = await
|
|
30135
|
-
const context =
|
|
30488
|
+
const lead = await findLeadAgent4();
|
|
30489
|
+
const context = extractMentionContext3(issue.body) || issue.title;
|
|
30136
30490
|
const result = resolveTemplate("github.issue.mentioned", {
|
|
30137
30491
|
issue_number: issue.number,
|
|
30138
30492
|
issue_title: issue.title,
|
|
@@ -30178,21 +30532,21 @@ async function handleComment(event, eventType) {
|
|
|
30178
30532
|
if (action !== "created") {
|
|
30179
30533
|
return skip("action is not created");
|
|
30180
30534
|
}
|
|
30181
|
-
if (!
|
|
30535
|
+
if (!detectMention3(comment.body)) {
|
|
30182
30536
|
return skip("no bot mention");
|
|
30183
30537
|
}
|
|
30184
30538
|
const eventKey = `comment:${repository.full_name}:${comment.id}`;
|
|
30185
|
-
if (
|
|
30539
|
+
if (isDuplicate4(eventKey)) {
|
|
30186
30540
|
return skip("duplicate delivery");
|
|
30187
30541
|
}
|
|
30188
|
-
const lead = await
|
|
30542
|
+
const lead = await findLeadAgent4();
|
|
30189
30543
|
const target = pull_request || issue;
|
|
30190
30544
|
const targetType = pull_request ? "PR" : "Issue";
|
|
30191
30545
|
const targetNumber = target?.number ?? 0;
|
|
30192
30546
|
const targetTitle = target?.title ?? "Unknown";
|
|
30193
30547
|
const targetUrl = target?.html_url ?? comment.html_url;
|
|
30194
|
-
const existingTask = targetNumber ? await findTaskByVcs2(repository.full_name, targetNumber) : null;
|
|
30195
|
-
const context =
|
|
30548
|
+
const existingTask = targetNumber ? await findTaskByVcs2(repository.full_name, targetNumber, "github") : null;
|
|
30549
|
+
const context = extractMentionContext3(comment.body);
|
|
30196
30550
|
const suggestions = getCommandSuggestions("github-comment", targetType);
|
|
30197
30551
|
const relatedTaskSection = existingTask ? `Related task: ${existingTask.id}
|
|
30198
30552
|
\uD83D\uDD00 Consider routing to the same agent working on the related task.
|
|
@@ -30426,7 +30780,7 @@ async function handlePullRequestReview(event) {
|
|
|
30426
30780
|
return { created: false };
|
|
30427
30781
|
}
|
|
30428
30782
|
const eventKey = `pr-review:${repository.full_name}:${pr.number}:${review.id}`;
|
|
30429
|
-
if (
|
|
30783
|
+
if (isDuplicate4(eventKey)) {
|
|
30430
30784
|
return { created: false };
|
|
30431
30785
|
}
|
|
30432
30786
|
const { comments: inlineComments, degraded } = await fetchReviewComments(repository.full_name, pr.number, review.id, installation?.id);
|
|
@@ -30441,12 +30795,12 @@ async function handlePullRequestReview(event) {
|
|
|
30441
30795
|
return { created: false };
|
|
30442
30796
|
}
|
|
30443
30797
|
}
|
|
30444
|
-
const existingTask = await findTaskByVcs2(repository.full_name, pr.number);
|
|
30798
|
+
const existingTask = await findTaskByVcs2(repository.full_name, pr.number, "github");
|
|
30445
30799
|
const isBotCreator = isBotAssignee(pr.user.login);
|
|
30446
30800
|
if (!isBotCreator && !existingTask) {
|
|
30447
30801
|
return { created: false };
|
|
30448
30802
|
}
|
|
30449
|
-
const lead = await
|
|
30803
|
+
const lead = await findLeadAgent4();
|
|
30450
30804
|
const { emoji, label } = getReviewStateInfo(review.state);
|
|
30451
30805
|
const reviewBodySection = review.body ? `
|
|
30452
30806
|
|
|
@@ -30523,46 +30877,48 @@ async function handleWorkflowRun(event) {
|
|
|
30523
30877
|
}
|
|
30524
30878
|
// src/gitlab/auth.ts
|
|
30525
30879
|
init_env_flag();
|
|
30526
|
-
var
|
|
30527
|
-
var
|
|
30528
|
-
var
|
|
30880
|
+
var initialized5 = false;
|
|
30881
|
+
var webhookSecret5 = null;
|
|
30882
|
+
var apiToken3 = null;
|
|
30529
30883
|
var gitlabUrl = "https://gitlab.com";
|
|
30530
30884
|
function isGitLabEnabled() {
|
|
30531
30885
|
return !!process.env.GITLAB_WEBHOOK_SECRET && !isEnvFlagEnabled("GITLAB_DISABLE", false);
|
|
30532
30886
|
}
|
|
30533
30887
|
function initGitLab() {
|
|
30534
|
-
if (
|
|
30888
|
+
if (initialized5)
|
|
30535
30889
|
return;
|
|
30536
30890
|
if (!isGitLabEnabled()) {
|
|
30537
30891
|
console.log("[GitLab] Integration disabled (GITLAB_WEBHOOK_SECRET not set)");
|
|
30538
30892
|
return;
|
|
30539
30893
|
}
|
|
30540
|
-
|
|
30541
|
-
|
|
30894
|
+
webhookSecret5 = process.env.GITLAB_WEBHOOK_SECRET;
|
|
30895
|
+
apiToken3 = process.env.GITLAB_TOKEN ?? null;
|
|
30542
30896
|
gitlabUrl = process.env.GITLAB_URL ?? "https://gitlab.com";
|
|
30543
|
-
|
|
30897
|
+
initialized5 = true;
|
|
30544
30898
|
console.log(`[GitLab] Integration initialized (url: ${gitlabUrl})`);
|
|
30545
30899
|
}
|
|
30546
30900
|
function verifyGitLabWebhook(tokenHeader) {
|
|
30547
|
-
if (!
|
|
30901
|
+
if (!webhookSecret5)
|
|
30548
30902
|
return false;
|
|
30549
30903
|
if (!tokenHeader)
|
|
30550
30904
|
return false;
|
|
30551
|
-
if (tokenHeader.length !==
|
|
30905
|
+
if (tokenHeader.length !== webhookSecret5.length)
|
|
30552
30906
|
return false;
|
|
30553
|
-
return crypto.timingSafeEqual(Buffer.from(tokenHeader), Buffer.from(
|
|
30907
|
+
return crypto.timingSafeEqual(Buffer.from(tokenHeader), Buffer.from(webhookSecret5));
|
|
30554
30908
|
}
|
|
30555
30909
|
function getGitLabToken() {
|
|
30556
|
-
return
|
|
30910
|
+
return apiToken3;
|
|
30557
30911
|
}
|
|
30558
30912
|
function getGitLabUrl() {
|
|
30559
30913
|
return gitlabUrl;
|
|
30560
30914
|
}
|
|
30561
|
-
|
|
30915
|
+
function getGitLabBotName() {
|
|
30916
|
+
return process.env.GITLAB_BOT_NAME || "agent-swarm-bot";
|
|
30917
|
+
}
|
|
30562
30918
|
function resetGitLab() {
|
|
30563
|
-
|
|
30564
|
-
|
|
30565
|
-
|
|
30919
|
+
initialized5 = false;
|
|
30920
|
+
webhookSecret5 = null;
|
|
30921
|
+
apiToken3 = null;
|
|
30566
30922
|
gitlabUrl = "https://gitlab.com";
|
|
30567
30923
|
}
|
|
30568
30924
|
// src/gitlab/handlers.ts
|
|
@@ -30572,7 +30928,7 @@ init_resolver();
|
|
|
30572
30928
|
init_context_key();
|
|
30573
30929
|
|
|
30574
30930
|
// src/gitlab/reactions.ts
|
|
30575
|
-
function
|
|
30931
|
+
function headers4() {
|
|
30576
30932
|
const token = getGitLabToken();
|
|
30577
30933
|
if (!token)
|
|
30578
30934
|
throw new Error("[GitLab] No API token configured");
|
|
@@ -30593,7 +30949,7 @@ async function addGitLabReaction(project, entityType, iid, emojiName) {
|
|
|
30593
30949
|
try {
|
|
30594
30950
|
const resp = await fetch(url, {
|
|
30595
30951
|
method: "POST",
|
|
30596
|
-
headers:
|
|
30952
|
+
headers: headers4(),
|
|
30597
30953
|
body: JSON.stringify({ name: emojiName })
|
|
30598
30954
|
});
|
|
30599
30955
|
if (!resp.ok) {
|
|
@@ -30609,7 +30965,7 @@ async function addGitLabNoteReaction(project, entityType, iid, noteId, emojiName
|
|
|
30609
30965
|
try {
|
|
30610
30966
|
const resp = await fetch(url, {
|
|
30611
30967
|
method: "POST",
|
|
30612
|
-
headers:
|
|
30968
|
+
headers: headers4(),
|
|
30613
30969
|
body: JSON.stringify({ name: emojiName })
|
|
30614
30970
|
});
|
|
30615
30971
|
if (!resp.ok) {
|
|
@@ -30733,33 +31089,49 @@ The CI pipeline has failed. Please investigate and fix the issues.{{@template[co
|
|
|
30733
31089
|
});
|
|
30734
31090
|
|
|
30735
31091
|
// src/gitlab/handlers.ts
|
|
30736
|
-
var
|
|
30737
|
-
var
|
|
30738
|
-
function
|
|
31092
|
+
var processedEvents5 = new Map;
|
|
31093
|
+
var DEDUP_TTL_MS3 = 60000;
|
|
31094
|
+
function isDuplicate5(key) {
|
|
30739
31095
|
const now = Date.now();
|
|
30740
|
-
for (const [k, ts] of
|
|
30741
|
-
if (now - ts >
|
|
30742
|
-
|
|
31096
|
+
for (const [k, ts] of processedEvents5) {
|
|
31097
|
+
if (now - ts > DEDUP_TTL_MS3)
|
|
31098
|
+
processedEvents5.delete(k);
|
|
30743
31099
|
}
|
|
30744
|
-
if (
|
|
31100
|
+
if (processedEvents5.has(key))
|
|
30745
31101
|
return true;
|
|
30746
|
-
|
|
31102
|
+
processedEvents5.set(key, now);
|
|
30747
31103
|
return false;
|
|
30748
31104
|
}
|
|
30749
|
-
function
|
|
31105
|
+
function detectMention4(text) {
|
|
30750
31106
|
if (!text)
|
|
30751
31107
|
return false;
|
|
30752
|
-
return new RegExp(`@${
|
|
31108
|
+
return new RegExp(`@${getGitLabBotName()}\\b`, "i").test(text);
|
|
30753
31109
|
}
|
|
30754
|
-
function
|
|
30755
|
-
return text.replace(new RegExp(`@${
|
|
31110
|
+
function extractMentionContext4(text) {
|
|
31111
|
+
return text.replace(new RegExp(`@${getGitLabBotName()}\\b`, "gi"), "").trim();
|
|
30756
31112
|
}
|
|
30757
|
-
|
|
31113
|
+
var LEGACY_SCOPE = {
|
|
31114
|
+
mr: {
|
|
31115
|
+
taskTypes: new Set(["gitlab-mr", "gitlab-ci"]),
|
|
31116
|
+
eventTypes: new Set(["merge_request", "note_on_mr", "pipeline"])
|
|
31117
|
+
},
|
|
31118
|
+
issue: {
|
|
31119
|
+
taskTypes: new Set(["gitlab-issue"]),
|
|
31120
|
+
eventTypes: new Set(["issue", "note_on_issue"])
|
|
31121
|
+
}
|
|
31122
|
+
};
|
|
31123
|
+
function isScopedTask(task, kind, contextKey) {
|
|
31124
|
+
if (task.contextKey)
|
|
31125
|
+
return task.contextKey === contextKey;
|
|
31126
|
+
const legacy = LEGACY_SCOPE[kind];
|
|
31127
|
+
return task.taskType !== undefined && legacy.taskTypes.has(task.taskType) || task.vcsEventType !== undefined && legacy.eventTypes.has(task.vcsEventType);
|
|
31128
|
+
}
|
|
31129
|
+
async function findLeadAgent5() {
|
|
30758
31130
|
const agents = await getAllAgents2();
|
|
30759
31131
|
return agents.find((a) => a.role === "lead" && a.status === "idle") ?? agents.find((a) => a.role === "lead") ?? null;
|
|
30760
31132
|
}
|
|
30761
|
-
var
|
|
30762
|
-
var
|
|
31133
|
+
var UNMAPPED_NAMESPACE4 = "integration:unmapped:gitlab";
|
|
31134
|
+
var UNMAPPED_TTL_MS4 = 30 * 24 * 60 * 60 * 1000;
|
|
30763
31135
|
var GITLAB_WEBHOOK_ACTOR = { kind: "system", id: "webhook:gitlab" };
|
|
30764
31136
|
async function resolveGitLabSender(user, sampleEventType, sampleContext) {
|
|
30765
31137
|
const existing = await findUserByExternalId("gitlab", user.username);
|
|
@@ -30772,7 +31144,7 @@ async function resolveGitLabSender(user, sampleEventType, sampleContext) {
|
|
|
30772
31144
|
return linked.id;
|
|
30773
31145
|
}
|
|
30774
31146
|
await upsertKv2({
|
|
30775
|
-
namespace:
|
|
31147
|
+
namespace: UNMAPPED_NAMESPACE4,
|
|
30776
31148
|
key: `${user.username}:meta`,
|
|
30777
31149
|
value: {
|
|
30778
31150
|
lastSeenAt: new Date().toISOString(),
|
|
@@ -30780,9 +31152,9 @@ async function resolveGitLabSender(user, sampleEventType, sampleContext) {
|
|
|
30780
31152
|
sampleContext: sampleContext.slice(0, 100)
|
|
30781
31153
|
},
|
|
30782
31154
|
valueType: "json",
|
|
30783
|
-
expiresAt: Date.now() +
|
|
31155
|
+
expiresAt: Date.now() + UNMAPPED_TTL_MS4
|
|
30784
31156
|
});
|
|
30785
|
-
await incrKv2(
|
|
31157
|
+
await incrKv2(UNMAPPED_NAMESPACE4, `${user.username}:count`, 1);
|
|
30786
31158
|
return;
|
|
30787
31159
|
}
|
|
30788
31160
|
async function renderGitLabIdentity(username) {
|
|
@@ -30795,19 +31167,19 @@ async function handleMergeRequest(event) {
|
|
|
30795
31167
|
const requestedByUserId = await resolveGitLabSender(user, "merge_request", `MR !${mr.iid}: ${mr.title}`);
|
|
30796
31168
|
console.log(`[GitLab] MR #${mr.iid} ${action} by ${user.username} in ${repo}`);
|
|
30797
31169
|
const dedupKey = `gitlab-mr-${repo}-${mr.iid}-${action}-${user.username}`;
|
|
30798
|
-
if (
|
|
31170
|
+
if (isDuplicate5(dedupKey)) {
|
|
30799
31171
|
console.log(`[GitLab] Skipping duplicate MR event`);
|
|
30800
31172
|
return { created: false };
|
|
30801
31173
|
}
|
|
30802
|
-
const lead = await
|
|
31174
|
+
const lead = await findLeadAgent5();
|
|
30803
31175
|
switch (action) {
|
|
30804
31176
|
case "open": {
|
|
30805
|
-
const hasMention =
|
|
31177
|
+
const hasMention = detectMention4(mr.description);
|
|
30806
31178
|
if (!hasMention) {
|
|
30807
31179
|
console.log(`[GitLab] MR opened without bot mention, skipping`);
|
|
30808
31180
|
return { created: false };
|
|
30809
31181
|
}
|
|
30810
|
-
const context = mr.description ?
|
|
31182
|
+
const context = mr.description ? extractMentionContext4(mr.description) : "";
|
|
30811
31183
|
const contextSection = context ? `Context: ${context}
|
|
30812
31184
|
|
|
30813
31185
|
` : "";
|
|
@@ -30851,16 +31223,21 @@ async function handleMergeRequest(event) {
|
|
|
30851
31223
|
}
|
|
30852
31224
|
case "close":
|
|
30853
31225
|
case "merge": {
|
|
30854
|
-
const
|
|
30855
|
-
|
|
30856
|
-
|
|
30857
|
-
|
|
30858
|
-
|
|
31226
|
+
const reason = action === "merge" ? "MR was merged" : "MR was closed";
|
|
31227
|
+
const mrContextKey = gitlabContextKey({
|
|
31228
|
+
projectId: String(project.id),
|
|
31229
|
+
kind: "mr",
|
|
31230
|
+
iid: mr.iid
|
|
31231
|
+
});
|
|
31232
|
+
const tasks = await findActiveTasksByVcs2(repo, mr.iid, "gitlab");
|
|
31233
|
+
for (const task of tasks.filter((t) => isScopedTask(t, "mr", mrContextKey))) {
|
|
31234
|
+
console.log(`[GitLab] Cancelling task ${task.id} — ${reason}`);
|
|
31235
|
+
await failTask2(task.id, reason);
|
|
30859
31236
|
}
|
|
30860
31237
|
return { created: false };
|
|
30861
31238
|
}
|
|
30862
31239
|
case "update": {
|
|
30863
|
-
const task = await findTaskByVcs2(repo, mr.iid);
|
|
31240
|
+
const task = await findTaskByVcs2(repo, mr.iid, "gitlab");
|
|
30864
31241
|
if (task) {
|
|
30865
31242
|
console.log(`[GitLab] MR #${mr.iid} updated, active task exists: ${task.id}`);
|
|
30866
31243
|
return { created: false };
|
|
@@ -30879,21 +31256,21 @@ async function handleIssue2(event) {
|
|
|
30879
31256
|
const requestedByUserId = await resolveGitLabSender(user, "issue", `Issue #${issue.iid}: ${issue.title}`);
|
|
30880
31257
|
console.log(`[GitLab] Issue #${issue.iid} ${action} by ${user.username} in ${repo}`);
|
|
30881
31258
|
const dedupKey = `gitlab-issue-${repo}-${issue.iid}-${action}-${user.username}`;
|
|
30882
|
-
if (
|
|
31259
|
+
if (isDuplicate5(dedupKey)) {
|
|
30883
31260
|
return { created: false };
|
|
30884
31261
|
}
|
|
30885
|
-
const lead = await
|
|
31262
|
+
const lead = await findLeadAgent5();
|
|
30886
31263
|
switch (action) {
|
|
30887
31264
|
case "open": {
|
|
30888
|
-
const hasMention =
|
|
31265
|
+
const hasMention = detectMention4(issue.description);
|
|
30889
31266
|
if (!hasMention) {
|
|
30890
|
-
const isBotAssigned = event.assignees?.some((a) => a.username.toLowerCase() ===
|
|
31267
|
+
const isBotAssigned = event.assignees?.some((a) => a.username.toLowerCase() === getGitLabBotName().toLowerCase());
|
|
30891
31268
|
if (!isBotAssigned) {
|
|
30892
31269
|
console.log(`[GitLab] Issue opened without bot mention/assignment, skipping`);
|
|
30893
31270
|
return { created: false };
|
|
30894
31271
|
}
|
|
30895
31272
|
}
|
|
30896
|
-
const context = issue.description ?
|
|
31273
|
+
const context = issue.description ? extractMentionContext4(issue.description) : "";
|
|
30897
31274
|
const contextSection = context ? `Context: ${context}
|
|
30898
31275
|
|
|
30899
31276
|
` : "";
|
|
@@ -30934,7 +31311,12 @@ async function handleIssue2(event) {
|
|
|
30934
31311
|
return { created: true, taskId: task.id };
|
|
30935
31312
|
}
|
|
30936
31313
|
case "close": {
|
|
30937
|
-
const
|
|
31314
|
+
const issueContextKey = gitlabContextKey({
|
|
31315
|
+
projectId: String(project.id),
|
|
31316
|
+
kind: "issue",
|
|
31317
|
+
iid: issue.iid
|
|
31318
|
+
});
|
|
31319
|
+
const existingTask = (await findActiveTasksByVcs2(repo, issue.iid, "gitlab")).find((t) => isScopedTask(t, "issue", issueContextKey));
|
|
30938
31320
|
if (existingTask) {
|
|
30939
31321
|
console.log(`[GitLab] Cancelling task ${existingTask.id} — issue closed`);
|
|
30940
31322
|
await failTask2(existingTask.id, "Issue was closed");
|
|
@@ -30949,16 +31331,16 @@ async function handleNote(event) {
|
|
|
30949
31331
|
const { user, project, object_attributes: note } = event;
|
|
30950
31332
|
const repo = project.path_with_namespace;
|
|
30951
31333
|
const requestedByUserId = await resolveGitLabSender(user, "note", note.note);
|
|
30952
|
-
if (!
|
|
31334
|
+
if (!detectMention4(note.note)) {
|
|
30953
31335
|
return { created: false };
|
|
30954
31336
|
}
|
|
30955
31337
|
console.log(`[GitLab] Note by ${user.username} in ${repo} (${note.noteable_type})`);
|
|
30956
31338
|
const dedupKey = `gitlab-note-${note.id}`;
|
|
30957
|
-
if (
|
|
31339
|
+
if (isDuplicate5(dedupKey)) {
|
|
30958
31340
|
return { created: false };
|
|
30959
31341
|
}
|
|
30960
|
-
const lead = await
|
|
30961
|
-
const context =
|
|
31342
|
+
const lead = await findLeadAgent5();
|
|
31343
|
+
const context = extractMentionContext4(note.note);
|
|
30962
31344
|
let targetNumber;
|
|
30963
31345
|
let targetUrl;
|
|
30964
31346
|
let eventType;
|
|
@@ -30977,7 +31359,7 @@ async function handleNote(event) {
|
|
|
30977
31359
|
console.log(`[GitLab] Ignoring note on ${note.noteable_type}`);
|
|
30978
31360
|
return { created: false };
|
|
30979
31361
|
}
|
|
30980
|
-
const existingTask = targetNumber ? await findTaskByVcs2(repo, targetNumber) : null;
|
|
31362
|
+
const existingTask = targetNumber ? await findTaskByVcs2(repo, targetNumber, "gitlab") : null;
|
|
30981
31363
|
const existingTaskNote = existingTask ? `
|
|
30982
31364
|
|
|
30983
31365
|
_Note: There's an active task (${existingTask.id}) for this ${entityLabel}._` : "";
|
|
@@ -31032,14 +31414,14 @@ async function handlePipeline(event) {
|
|
|
31032
31414
|
}
|
|
31033
31415
|
const mrIid = event.merge_request.iid;
|
|
31034
31416
|
const dedupKey = `gitlab-pipeline-${pipeline.id}`;
|
|
31035
|
-
if (
|
|
31417
|
+
if (isDuplicate5(dedupKey)) {
|
|
31036
31418
|
return { created: false };
|
|
31037
31419
|
}
|
|
31038
|
-
const existingTask = await findTaskByVcs2(repo, mrIid);
|
|
31420
|
+
const existingTask = await findTaskByVcs2(repo, mrIid, "gitlab");
|
|
31039
31421
|
if (!existingTask) {
|
|
31040
31422
|
return { created: false };
|
|
31041
31423
|
}
|
|
31042
|
-
const lead = await
|
|
31424
|
+
const lead = await findLeadAgent5();
|
|
31043
31425
|
const pipelineResult = resolveTemplate("gitlab.pipeline.failed", {
|
|
31044
31426
|
pipeline_id: pipeline.id,
|
|
31045
31427
|
mr_iid: mrIid,
|
|
@@ -31243,6 +31625,71 @@ function readApiUrlOverrides() {
|
|
|
31243
31625
|
}
|
|
31244
31626
|
}
|
|
31245
31627
|
|
|
31628
|
+
// src/integrations/chat-sdk/facts.ts
|
|
31629
|
+
var SNIPPET_MAX = 80;
|
|
31630
|
+
function snippet2(text) {
|
|
31631
|
+
const flat = text?.replace(/\s+/g, " ").trim();
|
|
31632
|
+
if (!flat)
|
|
31633
|
+
return;
|
|
31634
|
+
return flat.length > SNIPPET_MAX ? `${flat.slice(0, SNIPPET_MAX)}...` : flat;
|
|
31635
|
+
}
|
|
31636
|
+
function personLabel(name, username, fallback) {
|
|
31637
|
+
if (name && username && name !== username)
|
|
31638
|
+
return `${name} (@${username})`;
|
|
31639
|
+
if (username)
|
|
31640
|
+
return `@${username}`;
|
|
31641
|
+
return name || fallback;
|
|
31642
|
+
}
|
|
31643
|
+
function replyIsTopicRoot(raw) {
|
|
31644
|
+
const reply = raw.reply_to_message;
|
|
31645
|
+
return reply !== undefined && (reply.forum_topic_created !== undefined || raw.is_topic_message === true && reply.message_id === raw.message_thread_id);
|
|
31646
|
+
}
|
|
31647
|
+
function isTelegramReplyToBot(raw, botUserId) {
|
|
31648
|
+
const fromId = raw.reply_to_message?.from?.id;
|
|
31649
|
+
return !replyIsTopicRoot(raw) && fromId !== undefined && botUserId !== undefined && String(fromId) === botUserId;
|
|
31650
|
+
}
|
|
31651
|
+
function telegramFacts(raw, message, botUserId) {
|
|
31652
|
+
const reply = raw.reply_to_message;
|
|
31653
|
+
const topicRoot = replyIsTopicRoot(raw);
|
|
31654
|
+
const realReply = reply && !topicRoot ? reply : undefined;
|
|
31655
|
+
const topicName = topicRoot ? reply?.forum_topic_created?.name : undefined;
|
|
31656
|
+
const name = [raw.from?.first_name, raw.from?.last_name].filter(Boolean).join(" ").trim();
|
|
31657
|
+
return {
|
|
31658
|
+
chatType: raw.chat?.type,
|
|
31659
|
+
isForum: raw.chat?.is_forum === true ? true : undefined,
|
|
31660
|
+
title: raw.chat?.title,
|
|
31661
|
+
topic: raw.is_topic_message === true && raw.message_thread_id !== undefined ? topicName ? `"${topicName}"` : `#${raw.message_thread_id}` : undefined,
|
|
31662
|
+
from: personLabel(name || undefined, raw.from?.username, message.author.userId),
|
|
31663
|
+
replyToBot: isTelegramReplyToBot(raw, botUserId),
|
|
31664
|
+
replyToSnippet: snippet2(realReply?.text ?? realReply?.caption)
|
|
31665
|
+
};
|
|
31666
|
+
}
|
|
31667
|
+
function readChatMessageFacts(thread, message) {
|
|
31668
|
+
const raw = message.raw;
|
|
31669
|
+
if (thread.adapter.name === "telegram" && raw && typeof raw === "object") {
|
|
31670
|
+
return telegramFacts(raw, message, thread.adapter.botUserId);
|
|
31671
|
+
}
|
|
31672
|
+
const { fullName, userName, userId } = message.author;
|
|
31673
|
+
return {
|
|
31674
|
+
chatType: thread.isDM ? "dm" : undefined,
|
|
31675
|
+
from: personLabel(fullName || undefined, userName || undefined, userId),
|
|
31676
|
+
replyToBot: message.replyTo?.author.isMe === true,
|
|
31677
|
+
replyToSnippet: snippet2(message.replyTo?.text)
|
|
31678
|
+
};
|
|
31679
|
+
}
|
|
31680
|
+
function formatChatHeaderFacts(adapter, facts, addressed) {
|
|
31681
|
+
const oneLine = (text) => text.replace(/\s+/g, " ").trim();
|
|
31682
|
+
const parts = [adapter];
|
|
31683
|
+
if (facts.chatType)
|
|
31684
|
+
parts.push(facts.title ? `${facts.chatType} "${oneLine(facts.title)}"` : facts.chatType);
|
|
31685
|
+
if (facts.isForum)
|
|
31686
|
+
parts.push(facts.topic ? `forum topic ${oneLine(facts.topic)}` : "forum");
|
|
31687
|
+
parts.push(`from: ${oneLine(facts.from)}`, `addressed: ${addressed}`);
|
|
31688
|
+
if (facts.replyToSnippet)
|
|
31689
|
+
parts.push(`reply-to: "${facts.replyToSnippet}"`);
|
|
31690
|
+
return parts.join(" · ");
|
|
31691
|
+
}
|
|
31692
|
+
|
|
31246
31693
|
// src/integrations/chat-sdk/logger.ts
|
|
31247
31694
|
init_secret_scrubber();
|
|
31248
31695
|
var MAX_ISSUE_CHARS = 300;
|
|
@@ -31334,8 +31781,14 @@ async function loadAdapter(name, config, logger) {
|
|
|
31334
31781
|
const base = { ...config, apiUrl, logger };
|
|
31335
31782
|
switch (name) {
|
|
31336
31783
|
case "telegram": {
|
|
31337
|
-
const {
|
|
31338
|
-
|
|
31784
|
+
const { TelegramAdapter } = await import("./index-zsyx51ap.js");
|
|
31785
|
+
|
|
31786
|
+
class SwarmTelegramAdapter extends TelegramAdapter {
|
|
31787
|
+
isBotMentioned(message, text) {
|
|
31788
|
+
return super.isBotMentioned(message, text) || String(message.from?.id) !== this.botUserId && isTelegramReplyToBot(message, this.botUserId);
|
|
31789
|
+
}
|
|
31790
|
+
}
|
|
31791
|
+
return new SwarmTelegramAdapter({
|
|
31339
31792
|
...base,
|
|
31340
31793
|
allowUnverifiedWebhooks: false,
|
|
31341
31794
|
mentionOnReply: true
|
|
@@ -32383,63 +32836,6 @@ async function attachChatFilesToTask(taskId, fetched) {
|
|
|
32383
32836
|
return unattached;
|
|
32384
32837
|
}
|
|
32385
32838
|
|
|
32386
|
-
// src/integrations/chat-sdk/facts.ts
|
|
32387
|
-
var SNIPPET_MAX = 80;
|
|
32388
|
-
function snippet2(text) {
|
|
32389
|
-
const flat = text?.replace(/\s+/g, " ").trim();
|
|
32390
|
-
if (!flat)
|
|
32391
|
-
return;
|
|
32392
|
-
return flat.length > SNIPPET_MAX ? `${flat.slice(0, SNIPPET_MAX)}...` : flat;
|
|
32393
|
-
}
|
|
32394
|
-
function personLabel(name, username, fallback) {
|
|
32395
|
-
if (name && username && name !== username)
|
|
32396
|
-
return `${name} (@${username})`;
|
|
32397
|
-
if (username)
|
|
32398
|
-
return `@${username}`;
|
|
32399
|
-
return name || fallback;
|
|
32400
|
-
}
|
|
32401
|
-
function telegramFacts(raw, message, botUserId) {
|
|
32402
|
-
const reply = raw.reply_to_message;
|
|
32403
|
-
const replyIsTopicRoot = reply !== undefined && (reply.forum_topic_created !== undefined || raw.is_topic_message === true && reply.message_id === raw.message_thread_id);
|
|
32404
|
-
const realReply = reply && !replyIsTopicRoot ? reply : undefined;
|
|
32405
|
-
const topicName = replyIsTopicRoot ? reply?.forum_topic_created?.name : undefined;
|
|
32406
|
-
const name = [raw.from?.first_name, raw.from?.last_name].filter(Boolean).join(" ").trim();
|
|
32407
|
-
return {
|
|
32408
|
-
chatType: raw.chat?.type,
|
|
32409
|
-
isForum: raw.chat?.is_forum === true ? true : undefined,
|
|
32410
|
-
title: raw.chat?.title,
|
|
32411
|
-
topic: raw.is_topic_message === true && raw.message_thread_id !== undefined ? topicName ? `"${topicName}"` : `#${raw.message_thread_id}` : undefined,
|
|
32412
|
-
from: personLabel(name || undefined, raw.from?.username, message.author.userId),
|
|
32413
|
-
replyToBot: realReply?.from?.id !== undefined && botUserId !== undefined && String(realReply.from.id) === botUserId,
|
|
32414
|
-
replyToSnippet: snippet2(realReply?.text ?? realReply?.caption)
|
|
32415
|
-
};
|
|
32416
|
-
}
|
|
32417
|
-
function readChatMessageFacts(thread, message) {
|
|
32418
|
-
const raw = message.raw;
|
|
32419
|
-
if (thread.adapter.name === "telegram" && raw && typeof raw === "object") {
|
|
32420
|
-
return telegramFacts(raw, message, thread.adapter.botUserId);
|
|
32421
|
-
}
|
|
32422
|
-
const { fullName, userName, userId } = message.author;
|
|
32423
|
-
return {
|
|
32424
|
-
chatType: thread.isDM ? "dm" : undefined,
|
|
32425
|
-
from: personLabel(fullName || undefined, userName || undefined, userId),
|
|
32426
|
-
replyToBot: message.replyTo?.author.isMe === true,
|
|
32427
|
-
replyToSnippet: snippet2(message.replyTo?.text)
|
|
32428
|
-
};
|
|
32429
|
-
}
|
|
32430
|
-
function formatChatHeaderFacts(adapter, facts, addressed) {
|
|
32431
|
-
const oneLine = (text) => text.replace(/\s+/g, " ").trim();
|
|
32432
|
-
const parts = [adapter];
|
|
32433
|
-
if (facts.chatType)
|
|
32434
|
-
parts.push(facts.title ? `${facts.chatType} "${oneLine(facts.title)}"` : facts.chatType);
|
|
32435
|
-
if (facts.isForum)
|
|
32436
|
-
parts.push(facts.topic ? `forum topic ${oneLine(facts.topic)}` : "forum");
|
|
32437
|
-
parts.push(`from: ${oneLine(facts.from)}`, `addressed: ${addressed}`);
|
|
32438
|
-
if (facts.replyToSnippet)
|
|
32439
|
-
parts.push(`reply-to: "${facts.replyToSnippet}"`);
|
|
32440
|
-
return parts.join(" · ");
|
|
32441
|
-
}
|
|
32442
|
-
|
|
32443
32839
|
// src/integrations/chat-sdk/outbound.ts
|
|
32444
32840
|
init_secret_scrubber();
|
|
32445
32841
|
init_event_bus();
|
|
@@ -32515,11 +32911,32 @@ class ChatFileTooLargeError extends Error {
|
|
|
32515
32911
|
this.name = "ChatFileTooLargeError";
|
|
32516
32912
|
}
|
|
32517
32913
|
}
|
|
32914
|
+
var FENCE_LINE = /^ {0,3}(`{3,}|~{3,})/;
|
|
32915
|
+
var NON_HEADING_HASH = /^( {0,3}(?:>[ \t]?)*[ \t]*(?:(?:[-*+]|\d{1,9}[.)])[ \t]+(?:\[[ xX]\][ \t]+)?)?)(#{7,}|#{1,6}(?=[^\s#]))/;
|
|
32916
|
+
function escapeTelegramHashLines(markdown) {
|
|
32917
|
+
let fence;
|
|
32918
|
+
return markdown.split(`
|
|
32919
|
+
`).map((line) => {
|
|
32920
|
+
const marker = FENCE_LINE.exec(line)?.[1];
|
|
32921
|
+
if (fence) {
|
|
32922
|
+
if (marker && marker[0] === fence[0] && marker.length >= fence.length)
|
|
32923
|
+
fence = undefined;
|
|
32924
|
+
return line;
|
|
32925
|
+
}
|
|
32926
|
+
if (marker) {
|
|
32927
|
+
fence = marker;
|
|
32928
|
+
return line;
|
|
32929
|
+
}
|
|
32930
|
+
return line.replace(NON_HEADING_HASH, "$1\\$2");
|
|
32931
|
+
}).join(`
|
|
32932
|
+
`);
|
|
32933
|
+
}
|
|
32518
32934
|
async function postChunks(adapter, target, text) {
|
|
32519
32935
|
const messageIds = [];
|
|
32520
32936
|
let threadId;
|
|
32521
32937
|
for (const chunk of splitChatMessage(text, chatMessageLimit(adapter))) {
|
|
32522
|
-
const
|
|
32938
|
+
const markdown = adapter === "telegram" ? escapeTelegramHashLines(chunk) : chunk;
|
|
32939
|
+
const sent = await target.post({ markdown });
|
|
32523
32940
|
messageIds.push(sent.id);
|
|
32524
32941
|
threadId ??= sent.threadId;
|
|
32525
32942
|
}
|
|
@@ -34251,7 +34668,7 @@ async function resolveBotAccountId() {
|
|
|
34251
34668
|
function resetBotAccountIdCache() {
|
|
34252
34669
|
setCachedBotAccountId(null);
|
|
34253
34670
|
}
|
|
34254
|
-
async function
|
|
34671
|
+
async function findLeadAgent6() {
|
|
34255
34672
|
const agents = await getAllAgents2();
|
|
34256
34673
|
const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
|
|
34257
34674
|
if (onlineLead)
|
|
@@ -34455,7 +34872,7 @@ async function handleIssueDeleteEvent(event) {
|
|
|
34455
34872
|
}
|
|
34456
34873
|
}
|
|
34457
34874
|
async function createInitialJiraTask(input) {
|
|
34458
|
-
const lead = await
|
|
34875
|
+
const lead = await findLeadAgent6();
|
|
34459
34876
|
const descriptionSection = input.descriptionText ? `
|
|
34460
34877
|
Description:
|
|
34461
34878
|
${input.descriptionText}
|
|
@@ -34493,7 +34910,7 @@ ${input.descriptionText}
|
|
|
34493
34910
|
console.log(`[Jira Sync] Created ${action} task ${task.id} for ${input.issueKey} -> ${lead?.name ?? "unassigned"}`);
|
|
34494
34911
|
}
|
|
34495
34912
|
async function createCommentMentionTask(input) {
|
|
34496
|
-
const lead = await
|
|
34913
|
+
const lead = await findLeadAgent6();
|
|
34497
34914
|
const descriptionSection = input.descriptionText ? `
|
|
34498
34915
|
Description:
|
|
34499
34916
|
${input.descriptionText}
|
|
@@ -34553,7 +34970,7 @@ async function notifySlack(text) {
|
|
|
34553
34970
|
return;
|
|
34554
34971
|
}
|
|
34555
34972
|
try {
|
|
34556
|
-
const { getSlackApp } = await import("./app-
|
|
34973
|
+
const { getSlackApp } = await import("./app-nndcvftq.js");
|
|
34557
34974
|
const app = getSlackApp();
|
|
34558
34975
|
if (!app) {
|
|
34559
34976
|
console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
|
|
@@ -34624,7 +35041,7 @@ async function deleteJiraWebhook(webhookId) {
|
|
|
34624
35041
|
console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
|
|
34625
35042
|
}
|
|
34626
35043
|
async function overwriteWebhookIds(next) {
|
|
34627
|
-
const { getDbClient } = await import("./db-
|
|
35044
|
+
const { getDbClient } = await import("./db-88wcymxt.js");
|
|
34628
35045
|
await getDbClient().transaction(async (tx) => {
|
|
34629
35046
|
const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
|
|
34630
35047
|
if (!row) {
|
|
@@ -34731,7 +35148,7 @@ function stopJiraWebhookKeepalive() {
|
|
|
34731
35148
|
}
|
|
34732
35149
|
|
|
34733
35150
|
// src/jira/app.ts
|
|
34734
|
-
var
|
|
35151
|
+
var initialized6 = false;
|
|
34735
35152
|
function isJiraEnabled() {
|
|
34736
35153
|
if (isEnvFlagEnabled("JIRA_DISABLE", false))
|
|
34737
35154
|
return false;
|
|
@@ -34743,12 +35160,12 @@ function resetJira() {
|
|
|
34743
35160
|
resetBotAccountIdCache();
|
|
34744
35161
|
teardownJiraOutboundSync();
|
|
34745
35162
|
stopJiraWebhookKeepalive();
|
|
34746
|
-
|
|
35163
|
+
initialized6 = false;
|
|
34747
35164
|
}
|
|
34748
35165
|
async function initJira() {
|
|
34749
|
-
if (
|
|
35166
|
+
if (initialized6)
|
|
34750
35167
|
return isJiraEnabled();
|
|
34751
|
-
|
|
35168
|
+
initialized6 = true;
|
|
34752
35169
|
if (!isJiraEnabled()) {
|
|
34753
35170
|
console.log("[Jira] Integration disabled or JIRA_CLIENT_ID not set");
|
|
34754
35171
|
return false;
|
|
@@ -34805,7 +35222,7 @@ function synthesizeDeliveryId(body, rawBody) {
|
|
|
34805
35222
|
const hash = createHash2("sha256").update(rawBody).digest("hex").slice(0, 16);
|
|
34806
35223
|
return `${event}:${ts}:${entityId}:${hash}`;
|
|
34807
35224
|
}
|
|
34808
|
-
async function
|
|
35225
|
+
async function isDuplicateDelivery2(deliveryId) {
|
|
34809
35226
|
return await hasTrackerDelivery("jira", deliveryId);
|
|
34810
35227
|
}
|
|
34811
35228
|
async function markDelivery(externalId, deliveryId) {
|
|
@@ -34828,7 +35245,7 @@ async function handleJiraWebhook(pathToken, rawBody) {
|
|
|
34828
35245
|
return { status: 200, body: { status: "ignored", reason: "invalid-json" } };
|
|
34829
35246
|
}
|
|
34830
35247
|
const deliveryId = synthesizeDeliveryId(parsed, rawBody);
|
|
34831
|
-
if (await
|
|
35248
|
+
if (await isDuplicateDelivery2(deliveryId)) {
|
|
34832
35249
|
return { status: 200, body: { status: "duplicate" } };
|
|
34833
35250
|
}
|
|
34834
35251
|
const event = String(parsed.webhookEvent ?? "");
|
|
@@ -106647,15 +107064,15 @@ async function _fetchIssueGatingInfo(issueId) {
|
|
|
106647
107064
|
const labelNames = (json.data?.issue?.labels?.nodes ?? []).map((n) => n?.name ?? "").filter((n) => n.length > 0);
|
|
106648
107065
|
return { stateType, labelNames };
|
|
106649
107066
|
}
|
|
106650
|
-
async function
|
|
107067
|
+
async function findLeadAgent7() {
|
|
106651
107068
|
const agents = await getAllAgents2();
|
|
106652
107069
|
const onlineLead = agents.find((a) => a.isLead && a.status !== "offline");
|
|
106653
107070
|
if (onlineLead)
|
|
106654
107071
|
return onlineLead;
|
|
106655
107072
|
return agents.find((a) => a.isLead) ?? null;
|
|
106656
107073
|
}
|
|
106657
|
-
var
|
|
106658
|
-
var
|
|
107074
|
+
var UNMAPPED_NAMESPACE5 = "integration:unmapped:linear";
|
|
107075
|
+
var UNMAPPED_TTL_MS5 = 30 * 24 * 60 * 60 * 1000;
|
|
106659
107076
|
var LINEAR_WEBHOOK_ACTOR = { kind: "system", id: "webhook:linear" };
|
|
106660
107077
|
var APP_USER_ID_NAMESPACE = "integration:linear:bot-app-user-id";
|
|
106661
107078
|
async function getStoredAppUserId(workspaceId) {
|
|
@@ -106686,7 +107103,7 @@ async function resolveLinearActor(linearUserId, email, name, workspaceId, sample
|
|
|
106686
107103
|
return linked.id;
|
|
106687
107104
|
}
|
|
106688
107105
|
await upsertKv2({
|
|
106689
|
-
namespace:
|
|
107106
|
+
namespace: UNMAPPED_NAMESPACE5,
|
|
106690
107107
|
key: `${linearUserId}:meta`,
|
|
106691
107108
|
value: {
|
|
106692
107109
|
lastSeenAt: new Date().toISOString(),
|
|
@@ -106694,9 +107111,9 @@ async function resolveLinearActor(linearUserId, email, name, workspaceId, sample
|
|
|
106694
107111
|
sampleContext: sampleContext ? sampleContext.slice(0, 100) : null
|
|
106695
107112
|
},
|
|
106696
107113
|
valueType: "json",
|
|
106697
|
-
expiresAt: Date.now() +
|
|
107114
|
+
expiresAt: Date.now() + UNMAPPED_TTL_MS5
|
|
106698
107115
|
});
|
|
106699
|
-
await incrKv2(
|
|
107116
|
+
await incrKv2(UNMAPPED_NAMESPACE5, `${linearUserId}:count`, 1);
|
|
106700
107117
|
return;
|
|
106701
107118
|
}
|
|
106702
107119
|
var REQUEST_SECTION_LABEL = "Request (comment that opened this session)";
|
|
@@ -106808,7 +107225,7 @@ async function handleAgentSessionEvent(event) {
|
|
|
106808
107225
|
}
|
|
106809
107226
|
return;
|
|
106810
107227
|
}
|
|
106811
|
-
const lead = await
|
|
107228
|
+
const lead = await findLeadAgent7();
|
|
106812
107229
|
const sessionSection = sessionUrl ? `
|
|
106813
107230
|
Session: ${sessionUrl}` : "";
|
|
106814
107231
|
const requestSection = buildSessionRequestSection(event, actorName);
|
|
@@ -107012,7 +107429,7 @@ async function handleAgentSessionPrompted(event) {
|
|
|
107012
107429
|
return;
|
|
107013
107430
|
}
|
|
107014
107431
|
}
|
|
107015
|
-
const lead = await
|
|
107432
|
+
const lead = await findLeadAgent7();
|
|
107016
107433
|
const activity = event.agentActivity;
|
|
107017
107434
|
const promptUser = activity?.user;
|
|
107018
107435
|
const promptedActorLinearId = promptUser ? String(promptUser.id ?? "") : "";
|
|
@@ -107294,7 +107711,7 @@ function shouldSkipForLoopPrevention2(sync) {
|
|
|
107294
107711
|
}
|
|
107295
107712
|
|
|
107296
107713
|
// src/linear/app.ts
|
|
107297
|
-
var
|
|
107714
|
+
var initialized7 = false;
|
|
107298
107715
|
var unsubscribeRefresh = null;
|
|
107299
107716
|
function isLinearEnabled() {
|
|
107300
107717
|
if (isEnvFlagEnabled("LINEAR_DISABLE", false))
|
|
@@ -107309,12 +107726,12 @@ function resetLinear() {
|
|
|
107309
107726
|
unsubscribeRefresh();
|
|
107310
107727
|
unsubscribeRefresh = null;
|
|
107311
107728
|
}
|
|
107312
|
-
|
|
107729
|
+
initialized7 = false;
|
|
107313
107730
|
}
|
|
107314
107731
|
async function initLinear() {
|
|
107315
|
-
if (
|
|
107732
|
+
if (initialized7)
|
|
107316
107733
|
return isLinearEnabled();
|
|
107317
|
-
|
|
107734
|
+
initialized7 = true;
|
|
107318
107735
|
if (!isLinearEnabled()) {
|
|
107319
107736
|
console.log("[Linear] Integration disabled or LINEAR_CLIENT_ID not set");
|
|
107320
107737
|
return false;
|
|
@@ -108019,7 +108436,7 @@ async function reloadGlobalConfigsAndIntegrations() {
|
|
|
108019
108436
|
return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
|
|
108020
108437
|
}
|
|
108021
108438
|
async function reloadGlobalConfigsAndIntegrationsInner() {
|
|
108022
|
-
const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-
|
|
108439
|
+
const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-5en23s5z.js");
|
|
108023
108440
|
const wasEmbeddingsConfigured = getEmbeddingProvider().isConfigured();
|
|
108024
108441
|
const updated = await loadGlobalConfigsIntoEnv(true);
|
|
108025
108442
|
await syncTelemetryEnabled("settings").catch((err) => {
|
|
@@ -108035,10 +108452,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
|
|
|
108035
108452
|
integrations.push("embeddings");
|
|
108036
108453
|
}
|
|
108037
108454
|
if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
|
|
108038
|
-
import("./boot-reembed-
|
|
108455
|
+
import("./boot-reembed-r8rhf9h8.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
|
|
108039
108456
|
console.error("[config-reload] memory backfill failed (non-fatal):", err);
|
|
108040
108457
|
});
|
|
108041
|
-
import("./boot-reembed-
|
|
108458
|
+
import("./boot-reembed-vwcj2y5d.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
|
|
108042
108459
|
console.error("[config-reload] script backfill failed (non-fatal):", err);
|
|
108043
108460
|
});
|
|
108044
108461
|
}
|
|
@@ -108060,6 +108477,11 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
|
|
|
108060
108477
|
teardownAzureDevOpsOutbound();
|
|
108061
108478
|
if (isAzureDevOpsEnabled())
|
|
108062
108479
|
initAzureDevOpsOutbound();
|
|
108480
|
+
resetBitbucket();
|
|
108481
|
+
resetBitbucketBotCache();
|
|
108482
|
+
initBitbucket();
|
|
108483
|
+
if (isBitbucketEnabled())
|
|
108484
|
+
integrations.push("bitbucket");
|
|
108063
108485
|
resetLinear();
|
|
108064
108486
|
if (await initLinear())
|
|
108065
108487
|
integrations.push("linear");
|
|
@@ -115538,14 +115960,14 @@ var prMatcher = (content) => {
|
|
|
115538
115960
|
}
|
|
115539
115961
|
return results;
|
|
115540
115962
|
};
|
|
115541
|
-
function
|
|
115963
|
+
function escapeRegExp3(value) {
|
|
115542
115964
|
return value.replace(/[.*+?^${}()|[\]\\/]/g, "\\$&");
|
|
115543
115965
|
}
|
|
115544
115966
|
function agentFsPathRegex() {
|
|
115545
115967
|
const appHosts = getConfiguredAppUrls().flatMap((value) => {
|
|
115546
115968
|
try {
|
|
115547
115969
|
const url = new URL(value);
|
|
115548
|
-
return [
|
|
115970
|
+
return [escapeRegExp3(`${url.host}${url.pathname.replace(/\/+$/, "")}`)];
|
|
115549
115971
|
} catch {
|
|
115550
115972
|
return [];
|
|
115551
115973
|
}
|
|
@@ -130365,7 +130787,7 @@ var registerScriptConnectionsTool = (server) => {
|
|
|
130365
130787
|
};
|
|
130366
130788
|
// src/tools/script-delete.ts
|
|
130367
130789
|
init_zod();
|
|
130368
|
-
var SCRIPT_DELETE_DESCRIPTION = "
|
|
130790
|
+
var SCRIPT_DELETE_DESCRIPTION = "Permanently remove a swarm-shared script and all its versions from the catalog. This cannot be undone.";
|
|
130369
130791
|
var registerScriptDeleteTool = (server) => {
|
|
130370
130792
|
createToolRegistrar(server)("script-delete", {
|
|
130371
130793
|
title: "Script Delete",
|
|
@@ -134934,7 +135356,7 @@ async function emitBudgetRefusalSideEffects(ctx, inserted) {
|
|
|
134934
135356
|
console.warn(`[budget-refusal-notify] Failed to create follow-up task for budget refusal (task=${ctx.task.id.slice(0, 8)}): ${err}`);
|
|
134935
135357
|
}
|
|
134936
135358
|
}
|
|
134937
|
-
import("./event-bus-
|
|
135359
|
+
import("./event-bus-3z78ep5n.js").then(({ workflowEventBus }) => {
|
|
134938
135360
|
workflowEventBus.emit("task.budget_refused", {
|
|
134939
135361
|
taskId: ctx.task.id,
|
|
134940
135362
|
agentId: ctx.agentId,
|
|
@@ -135985,7 +136407,7 @@ var registerCreateWorkflowTool = (server) => {
|
|
|
135985
136407
|
` + "- CROSS-NODE DATA: To use output from an upstream node, you MUST declare an 'inputs' mapping on the downstream node. " + 'Example: inputs: { "cityData": "generate-city" } → then use {{cityData.taskOutput.field}} in config templates. ' + "Without 'inputs', built-in trigger/input/workflow/swarm/run context remains available, but upstream outputs do not. " + "Agent-task templates may interpolate trigger and declared upstream aliases. SECURITY: executable source for script/swarm-script nodes does not: " + "inline script source allows only input/workflow/swarm/run values, while named swarm-script source is not workflow-interpolated. " + `Pass dynamic trigger or upstream values through config.args (argv for inline scripts; the args object for swarm-script).
|
|
135986
136408
|
` + "- STRUCTURED OUTPUT: For agent-task nodes, put outputSchema inside 'config' to validate the agent's raw JSON output. " + `Node-level outputSchema validates the executor's return ({taskId, taskOutput}), which is different.
|
|
135987
136409
|
` + `- Agent-task config: { template, outputSchema?, agentId?, tags?, priority?, dir?, vcsRepo?, model? }.
|
|
135988
|
-
` + "- FOREACH NODE: type 'foreach'
|
|
136410
|
+
` + "- FOREACH NODE: type 'foreach' runs its body once per item. Config: " + "{ over: <array or exact {{input}} token>, itemKey: <property name>, body: { type: <any executor except foreach>, config: {...} }, " + "concurrency?: <integer >= 1, items in flight; unbounded when absent>, failurePolicy?: 'fail-fast' | 'collect-outcomes' }. " + "The body config is interpolated once per item with {{item.*}} and {{index}}. Child steps use synthetic IDs " + "'<foreachNodeId>#<itemKey>'; the parent waits for every child and exposes one aggregate result to successors. " + "failurePolicy defaults from onNodeFailure ('continue' = collect-outcomes, else fail-fast); fail-fast cancels queued items. " + `retry-workflow-run on a failed fan-out reruns only failed and cancelled items.
|
|
135989
136411
|
` + "- TRIGGER SCHEMA: Optional 'triggerSchema' is a JSON-Schema object that validates incoming trigger payloads. " + "Supported keywords: type, required, properties, enum, const, items (recursive into arrays). " + `Other JSON-Schema keywords (oneOf/anyOf/$ref/pattern/format/additionalProperties) are silently ignored.
|
|
135990
136412
|
` + "- WEBHOOK VERIFICATION: Webhook triggers use hmacSecret for all verification formats. " + "Omit verification for legacy HMAC-SHA256 over the raw body with fallback header scanning; " + "or set verification to { format: 'hmac-sha256', header }, { format: 'timestamped-hmac-sha256', header, toleranceSeconds? }, " + "{ format: 'token-equality', header }, or { format: 'standard-webhooks', toleranceSeconds? } " + "(standardwebhooks.com: webhook-id/webhook-timestamp/webhook-signature headers, hmacSecret is the whsec_ signing secret). Example: { type: 'webhook', hmacSecret: 'secret.SUPERAGENT_WEBHOOK_SECRET', " + `verification: { format: 'timestamped-hmac-sha256', header: 'X-Superagent-Signature', toleranceSeconds: 300 } }.
|
|
135991
136413
|
` + "- WAIT NODE: type 'wait' pauses a workflow for a duration or until a named workflowEventBus event arrives. " + "See runbooks/workflows.md#wait-nodes for config shapes, ordering caveats, and built-in event names.",
|
|
@@ -137032,4 +137454,4 @@ async function createServer(opts = {}) {
|
|
|
137032
137454
|
return server;
|
|
137033
137455
|
}
|
|
137034
137456
|
|
|
137035
|
-
export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, taskModelPin, resumedTaskModelSelection, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, scopeFromAttachment, backingProviderId, transcribeAudioNotes, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, handleWebhookTrigger, verifyHmacSignature, WebhookError, snapshotAndUpdateWorkflow, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry2, initWorkflows2, dispatchScheduleTarget, calculateNextRun2, startScheduler2, stopScheduler2, runScheduleNow2, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError2, isRegistered2, isExtensionAgentId2, getExtensionBridgeToken2, resolveBridgeCallOrigin2, extensionIdForAgent2, runContext2, registerLoaded2, unregister2, listRegistered2, dispatchPre2, dispatchPost2, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, repointTrackerSyncBySwarmId, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, handleWorkItemCreated, handleWorkItemUpdated, handleWorkItemCommented, handleWorkItemDeleted, handleWorkItemRestored, initAzureDevOpsOutbound, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, insertProvisioningRuntime, markRuntimeTerminated, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, listRuntimeInstancesForPool, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2, handleNote, handlePipeline, isChatSdkEnabled, getChatSdkConfig, errorMessage, resolveAdapterApiUrl, trackBackground, TelegramBotApiError, callTelegramBotApi, isTrustedTeamsServiceUrl, isChatSdkStopping, startChatSdk, getChatInstance, isChatAdapterConfigured, getChatSdkHealth, stopChatSdk, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, isCookieSafePageId, extractPageSession, extractLegacyPageSession, extractAndVerifyCookie, pageSessionSetCookies, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, MCP_MAX_TOOL_INPUT_ELEMENTS, MCP_MAX_REQUEST_BODY_BYTES, userCtx, requestPrincipal, agentFirstPrincipal, rejectGuest, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, getPageEditCounter, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, MemoryKeyError, refreshLinks, indexMemoryContent, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, sessionAccessTopic, sessionPresenceRoot, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };
|
|
137457
|
+
export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, taskModelPin, resumedTaskModelSelection, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, scopeFromAttachment, backingProviderId, transcribeAudioNotes, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, handleWebhookTrigger, verifyHmacSignature, WebhookError, snapshotAndUpdateWorkflow, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry2, initWorkflows2, dispatchScheduleTarget, calculateNextRun2, startScheduler2, stopScheduler2, runScheduleNow2, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError2, isRegistered2, isExtensionAgentId2, getExtensionBridgeToken2, resolveBridgeCallOrigin2, extensionIdForAgent2, runContext2, registerLoaded2, unregister2, listRegistered2, dispatchPre2, dispatchPost2, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, repointTrackerSyncBySwarmId, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, handleWorkItemCreated, handleWorkItemUpdated, handleWorkItemCommented, handleWorkItemDeleted, handleWorkItemRestored, initAzureDevOpsOutbound, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, insertProvisioningRuntime, markRuntimeTerminated, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, listRuntimeInstancesForPool, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, isBitbucketEnabled, initBitbucket, verifyBitbucketWebhook, isDuplicateDelivery, markDeliveryProcessed, pullRequestEventOf, pullRequestCommentEventOf, handlePullRequestCreated2, handlePullRequestCommentCreated, handlePullRequestClosed, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2, handleNote, handlePipeline, isChatSdkEnabled, getChatSdkConfig, errorMessage, resolveAdapterApiUrl, trackBackground, TelegramBotApiError, callTelegramBotApi, isTrustedTeamsServiceUrl, isChatSdkStopping, startChatSdk, getChatInstance, isChatAdapterConfigured, getChatSdkHealth, stopChatSdk, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, isCookieSafePageId, extractPageSession, extractLegacyPageSession, extractAndVerifyCookie, pageSessionSetCookies, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, MCP_MAX_TOOL_INPUT_ELEMENTS, MCP_MAX_REQUEST_BODY_BYTES, userCtx, requestPrincipal, agentFirstPrincipal, rejectGuest, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, getPageEditCounter, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, MemoryKeyError, refreshLinks, indexMemoryContent, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, sessionAccessTopic, sessionPresenceRoot, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };
|