@desplega.ai/agent-swarm 2.4.4 → 2.4.5
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/dist/{acp-adapter-thq04adh.js → acp-adapter-2wdkktv6.js} +1 -1
- package/dist/{actions-j6ywh6x5.js → actions-c40ebcm4.js} +18 -18
- package/dist/{amp-adapter-k8b5xmj8.js → amp-adapter-wb67m95z.js} +2 -2
- package/dist/{app-rb7vc02s.js → app-353vre8g.js} +3 -3
- package/dist/{assistant-ftta1zjf.js → assistant-sj1njh23.js} +21 -21
- package/dist/{boot-reembed-srp6v6af.js → boot-reembed-b9c3az3c.js} +1 -1
- package/dist/{boot-reembed-xns7h5h9.js → boot-reembed-qdkvxeem.js} +1 -1
- package/dist/{boot-scrub-sweep-3qqrh2mz.js → boot-scrub-sweep-m3wh8eks.js} +2 -2
- package/dist/{boot-seeds-9ks8hce7.js → boot-seeds-j2273s54.js} +4 -4
- package/dist/{claude-adapter-k5ksyres.js → claude-adapter-m7q0a085.js} +2 -2
- package/dist/{claude-managed-adapter-h2y889ge.js → claude-managed-adapter-5ptb6tzs.js} +2 -2
- package/dist/{claude-managed-setup-n5a5eqks.js → claude-managed-setup-smrqk5j5.js} +3 -3
- package/dist/{claude-sdk-session-2j3j4kwn.js → claude-sdk-session-38xnz21e.js} +8284 -8267
- package/dist/{cli-cynvc9fj.js → cli-018r4jq6.js} +5 -5
- package/dist/{cli-9fhkkpj5.js → cli-1f3qzw6y.js} +1 -1
- package/dist/{cli-dqb4n629.js → cli-1sp861s4.js} +7 -7
- package/dist/{cli-gqvh8d8a.js → cli-1syn2xy1.js} +10 -10
- package/dist/{cli-qkhc5aqy.js → cli-37j04k05.js} +11 -11
- package/dist/{cli-1d70crsy.js → cli-3a45zcgm.js} +1 -1
- package/dist/{cli-t7cyef5g.js → cli-43x64hv3.js} +4 -4
- package/dist/{cli-hj3debgw.js → cli-4zfqgjc5.js} +2 -2
- package/dist/{cli-55qmbp6z.js → cli-7c9qs530.js} +1 -1
- package/dist/{cli-9qtjfd60.js → cli-848hxdwj.js} +1 -1
- package/dist/{cli-pccfmtb5.js → cli-94gwyg7m.js} +7 -7
- package/dist/{cli-51y09c6p.js → cli-9hstj09h.js} +5 -5
- package/dist/{cli-zrwpctp4.js → cli-9yqgm9nd.js} +22 -22
- package/dist/{cli-esxerzg7.js → cli-a92r1127.js} +1 -1
- package/dist/{cli-b8k7epj1.js → cli-be2161h1.js} +7 -7
- package/dist/{cli-xc27fwzg.js → cli-bnes4z6b.js} +2 -2
- package/dist/{cli-zrk6jxv8.js → cli-cxxe61f6.js} +1 -1
- package/dist/{cli-amyhm3gj.js → cli-dk44dxec.js} +1 -1
- package/dist/{cli-nc35pxb7.js → cli-eww120g8.js} +1 -0
- package/dist/{cli-a0kcty51.js → cli-f01h25yt.js} +1 -1
- package/dist/{cli-82d3nkc3.js → cli-f0g3pgvf.js} +1 -1
- package/dist/{cli-1ephgwnq.js → cli-ftc1g5tj.js} +2 -2
- package/dist/{cli-2v045xyf.js → cli-fv5hepyy.js} +3 -3
- package/dist/{cli-bnz0r3kc.js → cli-g35m2xwm.js} +4 -4
- package/dist/{cli-qje9k2nh.js → cli-g9ypd5en.js} +12 -2
- package/dist/{cli-w6nadkh4.js → cli-j99azg3g.js} +3 -3
- package/dist/{cli-er83cjbn.js → cli-k8g16gz3.js} +416 -116
- package/dist/{cli-4dg55wsk.js → cli-kpw04va0.js} +1 -1
- package/dist/{cli-3cgngyd8.js → cli-ms85309d.js} +33 -15
- package/dist/{cli-v3yr2gbg.js → cli-n72rg53p.js} +1471 -635
- package/dist/{cli-37yb7307.js → cli-p14m2cnp.js} +1 -1
- package/dist/{cli-2zqpkvtt.js → cli-qfxc84gh.js} +1 -1
- package/dist/{cli-44159k28.js → cli-qwhy2qma.js} +1 -1
- package/dist/{cli-2y91wnbh.js → cli-st8aw1m6.js} +221 -9
- package/dist/{cli-vq97g1jq.js → cli-tw4p90jb.js} +92 -192
- package/dist/{cli-te6b5wvg.js → cli-v0yrfmdh.js} +1 -1
- package/dist/{cli-xj0re5tm.js → cli-v8fjakwf.js} +1 -1
- package/dist/{cli-p20r8w42.js → cli-wt0jf9hm.js} +215 -80
- package/dist/{cli-q6r7t299.js → cli-xpa64rek.js} +33 -11
- package/dist/{cli-vdm20wej.js → cli-z7d29rw9.js} +2 -2
- package/dist/cli.js +19 -19
- package/dist/{codex-adapter-968xwfy7.js → codex-adapter-tn6k5mkg.js} +1 -1
- package/dist/{codex-session-runner-ht4z99fa.js → codex-session-runner-7vjt7jbw.js} +1 -1
- package/dist/{commands-pcymaeg9.js → commands-t7rz9146.js} +2 -2
- package/dist/{controller-fpjyk46r.js → controller-m2jasma5.js} +2 -2
- package/dist/{controllers-connect-mwzx1fh6.js → controllers-connect-9ftpex99.js} +19 -19
- package/dist/{cursor-adapter-cp4s2e2f.js → cursor-adapter-mjv79e4z.js} +1 -1
- package/dist/{db-xsjg9jqq.js → db-6sfrn9g3.js} +1 -1
- package/dist/{db-sgd12bt9.js → db-rn673r06.js} +3 -3
- package/dist/{dispatcher-x0jfw2c9.js → dispatcher-c155xz0p.js} +17 -17
- package/dist/{dsh-adapter-jrq7ma7h.js → dsh-adapter-3mmszc1x.js} +1 -1
- package/dist/{external-channel-8njj4h3b.js → external-channel-35k6tkv8.js} +2 -2
- package/dist/{grok-adapter-kkr97v2f.js → grok-adapter-tfrq7tg1.js} +2 -2
- package/dist/handlers-7gw64dxw.js +39 -0
- package/dist/{heartbeat-wd03zhn0.js → heartbeat-dyg4npkp.js} +20 -20
- package/dist/{hook-f0vghj42.js → hook-drspbwpe.js} +1 -1
- package/dist/{hook-xzj2ts2p.js → hook-x26b31bg.js} +1 -1
- package/dist/{http-4hwxv62p.js → http-pk972xyw.js} +355 -216
- package/dist/{index-ww2vznkp.js → index-arytgj5q.js} +1 -1
- package/dist/{index-hg0x2cdv.js → index-bgdyvcnv.js} +17 -17
- package/dist/{index-c4ykd0f1.js → index-dr94zbnh.js} +13348 -11611
- package/dist/{index-gdh8jrdm.js → index-gabbcdn2.js} +17 -17
- package/dist/{index-97q4xn03.js → index-jwxkkex2.js} +129 -75
- package/dist/index-tfb26zhy.js +41 -0
- package/dist/{keepalive-hrh7xnr9.js → keepalive-7yrng7px.js} +3 -3
- package/dist/{lead-ee8vazz2.js → lead-7e02z839.js} +29 -29
- package/dist/{maintenance-e8wnwnqx.js → maintenance-e6cemdqt.js} +1 -1
- package/dist/{node-3v3f08f7.js → node-de6akczr.js} +10 -9
- package/dist/{oauth-refresh-sweep-zm0yj4sj.js → oauth-refresh-sweep-yw3xdbcj.js} +2 -2
- package/dist/{onboard-dtwcq603.js → onboard-0a9y5yrc.js} +2 -2
- package/dist/{otel-impl-w3fbhpn0.js → otel-impl-trjpkfb7.js} +1 -1
- package/dist/{pricing-refresh-j38dehfs.js → pricing-refresh-d2b5my0y.js} +3 -3
- package/dist/{rbac-roles-ejxx9b35.js → rbac-roles-hey3yv9d.js} +2 -2
- package/dist/{rbac-roles-ae8yttq4.js → rbac-roles-nxh5ahwk.js} +1 -1
- package/dist/{registry-rxw10xzg.js → registry-ajhexe44.js} +1 -1
- package/dist/{render-v2-n16n0phe.js → render-v2-rr3p2atg.js} +3 -3
- package/dist/{resume-z0fgjc38.js → resume-2efkf1s1.js} +5 -5
- package/dist/{session-access-cv3mq6mc.js → session-access-s2mttxpw.js} +4 -4
- package/dist/{setup-mafhj3yt.js → setup-vypma5yt.js} +1 -1
- package/dist/{work-objects-8b86mgjp.js → work-objects-rvhckdkp.js} +20 -20
- package/dist/{worker-16s75hm5.js → worker-5snytpbd.js} +29 -29
- package/openapi.json +9 -2
- package/package.json +7 -7
- package/src/apps/catalog.generated.json +206 -4
- package/src/apps/page-validator.ts +13 -1
- package/src/be/chunking.ts +42 -9
- package/src/be/db/tasks/draft-text.ts +15 -0
- package/src/be/db/tasks/read.ts +14 -1
- package/src/be/db.ts +5 -1
- package/src/be/memory/index-content.ts +36 -17
- package/src/be/memory/providers/openai-embedding.ts +115 -61
- package/src/be/memory/providers/sqlite-store.ts +69 -23
- package/src/be/memory/reranker.ts +31 -1
- package/src/be/memory/search-candidates.ts +47 -0
- package/src/be/memory/types.ts +14 -0
- package/src/be/scripts/typecheck.ts +2 -0
- package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +106 -54
- package/src/be/seed-scripts/index.ts +2 -2
- package/src/be/swarm-config-guard.ts +24 -1
- package/src/be/task-attachment-store.ts +30 -0
- package/src/extensions/catalog.generated.json +4 -4
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/contract.ts +7 -0
- package/src/fs/provider.ts +13 -1
- package/src/heartbeat/heartbeat.ts +31 -11
- package/src/http/fs.ts +54 -34
- package/src/http/mcp-body.ts +37 -0
- package/src/http/mcp-user.ts +3 -5
- package/src/http/mcp.ts +6 -7
- package/src/http/memory.ts +26 -15
- package/src/http/page-proxy.ts +61 -5
- package/src/http/pages-public.ts +27 -44
- package/src/http/pages.ts +4 -4
- package/src/http/script-runs.ts +2 -0
- package/src/http/users.ts +12 -1
- package/src/integrations/chat-sdk/adapters.ts +7 -3
- package/src/integrations/chat-sdk/attachments.ts +90 -12
- package/src/integrations/chat-sdk/facts.ts +120 -0
- package/src/integrations/chat-sdk/inbound.ts +156 -8
- package/src/integrations/chat-sdk/limits.ts +24 -0
- package/src/integrations/chat-sdk/outbound-files.ts +186 -0
- package/src/integrations/chat-sdk/outbound.ts +234 -4
- package/src/integrations/chat-sdk/relay.ts +4 -1
- package/src/integrations/chat-sdk/router.ts +28 -2
- package/src/integrations/chat-sdk/steering.ts +9 -0
- package/src/integrations/chat-sdk/templates.ts +14 -0
- package/src/integrations/chat-sdk/thread-buffer.ts +4 -0
- package/src/mcp-limits.ts +20 -0
- package/src/pages/browser-sdk.ts +8 -3
- package/src/pages/feedback-overlay.ts +1 -1
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/codex-adapter.ts +106 -119
- package/src/providers/codex-agents-md.ts +35 -229
- package/src/providers/cursor-adapter.ts +1 -1
- package/src/realtime/transport.ts +1 -2
- package/src/script-workflows/workflow-ctx.ts +1 -0
- package/src/scripts-runtime/types/stdlib.d.ts +2 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +8 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +2 -0
- package/src/server-user.ts +2 -0
- package/src/server.ts +2 -0
- package/src/slack/assistant.ts +2 -2
- package/src/slack/files.ts +2 -0
- package/src/slack/handlers.ts +4 -4
- package/src/slack/inbound-files.ts +39 -6
- package/src/slack/thread-buffer.ts +2 -1
- package/src/tasks/task-terminal-effects.ts +21 -17
- package/src/tests/apps-card-grid.test.ts +197 -0
- package/src/tests/apps-catalog-additions.test.ts +120 -0
- package/src/tests/apps-tree.test.ts +129 -0
- package/src/tests/chat-sdk-attachments-reply.test.ts +52 -0
- package/src/tests/chat-sdk-config.test.ts +11 -0
- package/src/tests/chat-sdk-facts.test.ts +23 -0
- package/src/tests/chat-sdk-inbound.test.ts +558 -4
- package/src/tests/chat-sdk-outbound-files.test.ts +652 -0
- package/src/tests/codex-adapter.test.ts +167 -242
- package/src/tests/config-api-only-keys.test.ts +9 -0
- package/src/tests/cors-allowlist.test.ts +1 -1
- package/src/tests/extensions-example-slack-reply-gate.test.ts +262 -91
- package/src/tests/heartbeat-checklist.test.ts +33 -0
- package/src/tests/heartbeat-jev-gate-credentials.test.ts +44 -0
- package/src/tests/heartbeat-jev-gate.test.ts +242 -1
- package/src/tests/kv-page-proxy.test.ts +91 -5
- package/src/tests/launch-password-rejection.test.ts +2 -2
- package/src/tests/mcp-input-caps.test.ts +294 -0
- package/src/tests/memory-chunked-search-starvation.test.ts +200 -0
- package/src/tests/memory-embedding-input-cap.test.ts +114 -0
- package/src/tests/memory.test.ts +14 -0
- package/src/tests/page-guest-session.test.ts +19 -8
- package/src/tests/page-proxy-authed.test.ts +1 -1
- package/src/tests/page-proxy.test.ts +17 -10
- package/src/tests/page-session.test.ts +102 -1
- package/src/tests/pages-authed-mode.test.ts +82 -12
- package/src/tests/pages-password-mode.test.ts +5 -5
- package/src/tests/realtime-transport.test.ts +13 -7
- package/src/tests/script-runs-http.test.ts +84 -0
- package/src/tests/scripts-http.test.ts +10 -1
- package/src/tests/swarm-config-export-to-env.test.ts +22 -3
- package/src/tests/task-audio-transcription.test.ts +299 -0
- package/src/tests/task-completion-memory-chunking.test.ts +434 -0
- package/src/tests/task-terminal-secret-scrub.test.ts +6 -1
- package/src/tests/transcription.test.ts +299 -0
- package/src/tests/workflow-system-one-decision-providers.test.ts +98 -1
- package/src/tests/workflow-system-one-decision.test.ts +2 -1
- package/src/tools/chat-access.ts +10 -0
- package/src/tools/chat-post.ts +31 -11
- package/src/tools/chat-reply.ts +32 -10
- package/src/tools/memory-search.ts +3 -1
- package/src/tools/system-one-decide.ts +17 -4
- package/src/types.ts +6 -0
- package/src/utils/config-env-export.ts +3 -1
- package/src/utils/page-session.ts +133 -20
- package/src/utils/transcription.ts +246 -0
- package/src/workflows/executors/system-one-decision.ts +28 -7
- package/src/workflows/executors/system-one-providers.ts +39 -4
- package/templates/extensions/slack-reply-gate/README.md +24 -22
- package/templates/extensions/slack-reply-gate/hooks.ts +146 -95
- package/templates/extensions/slack-reply-gate/manifest.json +2 -2
- package/templates/skills/apps/SKILL.md +28 -6
- package/templates/skills/apps/content.md +28 -6
- package/templates/skills/chat-sdk/content.md +6 -2
- package/templates/skills/code-quality/content.md +2 -1
- package/templates/skills/heartbeat-runbook/content.md +5 -5
- package/templates/skills/pages/content.md +6 -4
- package/templates/skills/swarm-scripts/SKILL.md +2 -2
- package/templates/skills/swarm-scripts/content.md +2 -2
- package/dist/handlers-0pvee9nw.js +0 -39
- package/dist/index-thm0y6a8.js +0 -41
|
@@ -42,6 +42,9 @@ import {
|
|
|
42
42
|
recordUnmappedIdentity,
|
|
43
43
|
MAX_TASK_ATTACHMENT_BYTES,
|
|
44
44
|
recordTaskAttachmentUpload,
|
|
45
|
+
scopeFromAttachment,
|
|
46
|
+
backingProviderId,
|
|
47
|
+
transcribeAudioNotes,
|
|
45
48
|
handleWebhookTrigger,
|
|
46
49
|
verifyHmacSignature,
|
|
47
50
|
WebhookError,
|
|
@@ -168,14 +171,18 @@ import {
|
|
|
168
171
|
handleAgentSessionPrompted,
|
|
169
172
|
isLinearEnabled,
|
|
170
173
|
initLinear,
|
|
171
|
-
|
|
174
|
+
isCookieSafePageId,
|
|
175
|
+
extractPageSession,
|
|
176
|
+
extractLegacyPageSession,
|
|
172
177
|
extractAndVerifyCookie,
|
|
173
|
-
|
|
178
|
+
pageSessionSetCookies,
|
|
174
179
|
resolveHttpRequestAuth,
|
|
175
180
|
loadGlobalConfigsIntoEnv,
|
|
176
181
|
reloadGlobalConfigsAndIntegrations,
|
|
177
182
|
scheduleIntegrationsReload,
|
|
178
183
|
handleCore,
|
|
184
|
+
MCP_MAX_TOOL_INPUT_ELEMENTS,
|
|
185
|
+
MCP_MAX_REQUEST_BODY_BYTES,
|
|
179
186
|
userCtx,
|
|
180
187
|
requestPrincipal,
|
|
181
188
|
agentFirstPrincipal,
|
|
@@ -205,6 +212,9 @@ import {
|
|
|
205
212
|
hydrateOAuthAppFromPreset,
|
|
206
213
|
scopedResourceScopeIdSchema,
|
|
207
214
|
resolveScopedResourceId,
|
|
215
|
+
MemoryKeyError,
|
|
216
|
+
refreshLinks,
|
|
217
|
+
indexMemoryContent,
|
|
208
218
|
dedupeMemoryDocumentIds,
|
|
209
219
|
recordMemoryAccesses,
|
|
210
220
|
recordRetrievals,
|
|
@@ -221,12 +231,9 @@ import {
|
|
|
221
231
|
reservedRoomKeyError,
|
|
222
232
|
updateMcpServerChecked,
|
|
223
233
|
updateTouchesStdioExecution,
|
|
224
|
-
MemoryKeyError,
|
|
225
|
-
refreshLinks,
|
|
226
234
|
canReadMemory,
|
|
227
235
|
getLinksForMemory,
|
|
228
236
|
expandCandidatesWithGraph,
|
|
229
|
-
indexMemoryContent,
|
|
230
237
|
isApiDraining,
|
|
231
238
|
drainApi,
|
|
232
239
|
markKapsoMessageRead,
|
|
@@ -283,7 +290,7 @@ import {
|
|
|
283
290
|
hasCapability,
|
|
284
291
|
getEnabledCapabilities,
|
|
285
292
|
createServer
|
|
286
|
-
} from "./cli-
|
|
293
|
+
} from "./cli-n72rg53p.js";
|
|
287
294
|
import {
|
|
288
295
|
chatThreadOfContextKey,
|
|
289
296
|
agentContextKey,
|
|
@@ -480,6 +487,8 @@ import {
|
|
|
480
487
|
init_key_paths,
|
|
481
488
|
rerank,
|
|
482
489
|
init_reranker,
|
|
490
|
+
searchMemoryCandidates,
|
|
491
|
+
init_search_candidates,
|
|
483
492
|
getEmbeddingProvider2,
|
|
484
493
|
getMemoryStore2,
|
|
485
494
|
init_memory,
|
|
@@ -720,26 +729,26 @@ import {
|
|
|
720
729
|
countScriptRunJournalSteps2,
|
|
721
730
|
countScriptRunJournalAgentTaskSteps2,
|
|
722
731
|
init_db3
|
|
723
|
-
} from "./cli-
|
|
732
|
+
} from "./cli-wt0jf9hm.js";
|
|
724
733
|
import {
|
|
725
734
|
getUserGrant2,
|
|
726
735
|
init_rbac_roles
|
|
727
|
-
} from "./cli-
|
|
728
|
-
import"./cli-
|
|
736
|
+
} from "./cli-kpw04va0.js";
|
|
737
|
+
import"./cli-43x64hv3.js";
|
|
729
738
|
import {
|
|
730
739
|
normalizeModelKey
|
|
731
|
-
} from "./cli-
|
|
740
|
+
} from "./cli-dk44dxec.js";
|
|
732
741
|
import {
|
|
733
742
|
upsertModelCatalogOverlay,
|
|
734
743
|
deleteModelCatalogOverlay,
|
|
735
744
|
loadModelsCatalog,
|
|
736
745
|
requestModelCatalogRefresh2
|
|
737
|
-
} from "./cli-
|
|
746
|
+
} from "./cli-bnes4z6b.js";
|
|
738
747
|
import {
|
|
739
748
|
AMP_ESTIMATE_MODELS,
|
|
740
749
|
ampBillsCacheWrites,
|
|
741
750
|
resolveAmpModel
|
|
742
|
-
} from "./cli-
|
|
751
|
+
} from "./cli-qfxc84gh.js";
|
|
743
752
|
import {
|
|
744
753
|
automationIntegrationFixUrl,
|
|
745
754
|
preflightAutomation,
|
|
@@ -751,7 +760,7 @@ import {
|
|
|
751
760
|
cancelWorkflowRun2,
|
|
752
761
|
TriggerSchemaError,
|
|
753
762
|
startWorkflowExecution2
|
|
754
|
-
} from "./cli-
|
|
763
|
+
} from "./cli-9hstj09h.js";
|
|
755
764
|
import {
|
|
756
765
|
require_dist2,
|
|
757
766
|
isInvalidClientError,
|
|
@@ -831,14 +840,14 @@ import {
|
|
|
831
840
|
typecheckWithAmbient,
|
|
832
841
|
typecheckScript,
|
|
833
842
|
parseSkillContent
|
|
834
|
-
} from "./cli-
|
|
843
|
+
} from "./cli-st8aw1m6.js";
|
|
835
844
|
import {
|
|
836
845
|
buildAuthorizationUrl,
|
|
837
846
|
exchangeAuthorizationCode,
|
|
838
847
|
oauthAppRowToProviderConfig,
|
|
839
848
|
forceRefreshAuthorizationOrThrow,
|
|
840
849
|
forceRefreshTokenOrThrow
|
|
841
|
-
} from "./cli-
|
|
850
|
+
} from "./cli-a92r1127.js";
|
|
842
851
|
import {
|
|
843
852
|
signalProcessGroup,
|
|
844
853
|
detachedProcessGroup,
|
|
@@ -866,14 +875,14 @@ import {
|
|
|
866
875
|
getSlackApp2,
|
|
867
876
|
startSlackApp2,
|
|
868
877
|
stopSlackApp2
|
|
869
|
-
} from "./cli-
|
|
870
|
-
import"./cli-
|
|
878
|
+
} from "./cli-37j04k05.js";
|
|
879
|
+
import"./cli-3a45zcgm.js";
|
|
871
880
|
import {
|
|
872
881
|
createApprovalFollowUpTask,
|
|
873
882
|
generateEdges,
|
|
874
883
|
definitionNodeIds,
|
|
875
884
|
validateDefinition
|
|
876
|
-
} from "./cli-
|
|
885
|
+
} from "./cli-xpa64rek.js";
|
|
877
886
|
import"./cli-8nyhf7za.js";
|
|
878
887
|
import {
|
|
879
888
|
_fetchHolder,
|
|
@@ -901,6 +910,7 @@ import {
|
|
|
901
910
|
wireHttpSpanLifecycle,
|
|
902
911
|
safeRequestUrlForLog,
|
|
903
912
|
agentWithCapacity,
|
|
913
|
+
RequestBodyTooLargeError,
|
|
904
914
|
parseBody,
|
|
905
915
|
BODY_TOO_LARGE,
|
|
906
916
|
enforceContentLengthCap,
|
|
@@ -932,7 +942,7 @@ import {
|
|
|
932
942
|
bodyListTask,
|
|
933
943
|
describeRequestRoute,
|
|
934
944
|
route
|
|
935
|
-
} from "./cli-
|
|
945
|
+
} from "./cli-018r4jq6.js";
|
|
936
946
|
import {
|
|
937
947
|
isMultiRuntimeEnabled
|
|
938
948
|
} from "./cli-e8xyjvfc.js";
|
|
@@ -942,7 +952,7 @@ import {
|
|
|
942
952
|
agentFsRequestTimeoutMs,
|
|
943
953
|
AgentFsProvider,
|
|
944
954
|
getFileStorageProvider2
|
|
945
|
-
} from "./cli-
|
|
955
|
+
} from "./cli-g9ypd5en.js";
|
|
946
956
|
import {
|
|
947
957
|
RuntimePoolError2,
|
|
948
958
|
mintControllerToken,
|
|
@@ -963,7 +973,7 @@ import {
|
|
|
963
973
|
resolvePoolDelivery2,
|
|
964
974
|
createPoolAgent2,
|
|
965
975
|
init_db
|
|
966
|
-
} from "./cli-
|
|
976
|
+
} from "./cli-j99azg3g.js";
|
|
967
977
|
import {
|
|
968
978
|
RATING_MODEL_MAX_LENGTH,
|
|
969
979
|
REFERENCES_SOURCE_MAX_LENGTH,
|
|
@@ -979,8 +989,8 @@ import {
|
|
|
979
989
|
checkHeartbeatChecklist2,
|
|
980
990
|
runHeartbeatSweep2,
|
|
981
991
|
stopHeartbeat2
|
|
982
|
-
} from "./cli-
|
|
983
|
-
import"./cli-
|
|
992
|
+
} from "./cli-ms85309d.js";
|
|
993
|
+
import"./cli-f0g3pgvf.js";
|
|
984
994
|
import {
|
|
985
995
|
import_websocket,
|
|
986
996
|
import_websocket_server
|
|
@@ -989,7 +999,7 @@ import {
|
|
|
989
999
|
runtimeSupervisorStatus,
|
|
990
1000
|
startRuntimeSupervisor,
|
|
991
1001
|
stopRuntimeSupervisor
|
|
992
|
-
} from "./cli-
|
|
1002
|
+
} from "./cli-1sp861s4.js";
|
|
993
1003
|
import"./cli-ns59dc6r.js";
|
|
994
1004
|
import {
|
|
995
1005
|
ACP_TARGET_IDS
|
|
@@ -1009,14 +1019,14 @@ import {
|
|
|
1009
1019
|
memoryRelevance,
|
|
1010
1020
|
isUnknownModelError,
|
|
1011
1021
|
writeSkillsToFilesystem
|
|
1012
|
-
} from "./cli-
|
|
1022
|
+
} from "./cli-v8fjakwf.js";
|
|
1013
1023
|
import {
|
|
1014
1024
|
inviteEmailToSharedOrg,
|
|
1015
1025
|
ensureAgentFsCredentialsForAgent
|
|
1016
|
-
} from "./cli-
|
|
1026
|
+
} from "./cli-4zfqgjc5.js";
|
|
1017
1027
|
import {
|
|
1018
1028
|
Anthropic
|
|
1019
|
-
} from "./cli-
|
|
1029
|
+
} from "./cli-k8g16gz3.js";
|
|
1020
1030
|
import {
|
|
1021
1031
|
isCodexOAuthConfigKey
|
|
1022
1032
|
} from "./cli-j4bwnpkm.js";
|
|
@@ -1052,7 +1062,7 @@ import {
|
|
|
1052
1062
|
revokeAgentTokens,
|
|
1053
1063
|
fingerprintApiKey,
|
|
1054
1064
|
init_users
|
|
1055
|
-
} from "./cli-
|
|
1065
|
+
} from "./cli-1f3qzw6y.js";
|
|
1056
1066
|
import"./cli-v41kn3cd.js";
|
|
1057
1067
|
import"./cli-wgtk7xxr.js";
|
|
1058
1068
|
import {
|
|
@@ -1208,7 +1218,7 @@ import {
|
|
|
1208
1218
|
KvKeySchema,
|
|
1209
1219
|
KvEntrySchema,
|
|
1210
1220
|
init_types
|
|
1211
|
-
} from "./cli-
|
|
1221
|
+
} from "./cli-eww120g8.js";
|
|
1212
1222
|
import {
|
|
1213
1223
|
IDENTITY_FIELD_BUDGETS,
|
|
1214
1224
|
IdentityFieldBudgetError,
|
|
@@ -1281,7 +1291,7 @@ import {
|
|
|
1281
1291
|
import {
|
|
1282
1292
|
init_package,
|
|
1283
1293
|
package_default
|
|
1284
|
-
} from "./cli-
|
|
1294
|
+
} from "./cli-94gwyg7m.js";
|
|
1285
1295
|
import {
|
|
1286
1296
|
realtimeBus,
|
|
1287
1297
|
init_bus
|
|
@@ -2463,8 +2473,7 @@ async function authenticate(req) {
|
|
|
2463
2473
|
const page = await getPage2(pageId);
|
|
2464
2474
|
if (!page)
|
|
2465
2475
|
throw new Error("Page not found");
|
|
2466
|
-
const
|
|
2467
|
-
const session = cookie?.pageId === pageId ? cookie : null;
|
|
2476
|
+
const session = await extractAndVerifyCookie(req, pageId);
|
|
2468
2477
|
if (!session && page.authMode !== "public")
|
|
2469
2478
|
throw new Error("Page session required");
|
|
2470
2479
|
if (session?.uid && (await findUserById(session.uid))?.status !== "active")
|
|
@@ -9696,6 +9705,7 @@ declare module "swarm-extension" {
|
|
|
9696
9705
|
sourceTaskId?: string | undefined;
|
|
9697
9706
|
outputSchema?: Record<string, unknown> | undefined;
|
|
9698
9707
|
inheritParentOutputSchema?: boolean | undefined;
|
|
9708
|
+
inheritParentRequester?: boolean | undefined;
|
|
9699
9709
|
inheritParentRoutingAffinity?: boolean | undefined;
|
|
9700
9710
|
inheritParentFollowUpConfig?: boolean | undefined;
|
|
9701
9711
|
followUpConfig?:
|
|
@@ -10114,8 +10124,15 @@ declare module "swarm-extension" {
|
|
|
10114
10124
|
userName?: string;
|
|
10115
10125
|
/** The buffered messages, joined. */
|
|
10116
10126
|
text: string;
|
|
10127
|
+
/** True for an @mention and for a reply to one of the bot's messages. */
|
|
10117
10128
|
botMentioned: boolean;
|
|
10118
10129
|
isDirectMessage: boolean;
|
|
10130
|
+
/** Platform chat type, such as Telegram \`private\`, \`group\`, \`supergroup\` or \`channel\`. */
|
|
10131
|
+
chatType?: string;
|
|
10132
|
+
/** Set for a Telegram supergroup with topics. */
|
|
10133
|
+
isForum?: boolean;
|
|
10134
|
+
/** A buffered message replies to one of the bot's own messages. */
|
|
10135
|
+
replyToBot: boolean;
|
|
10119
10136
|
/** Set when earlier swarm tasks exist in this thread. */
|
|
10120
10137
|
threadContext?: {
|
|
10121
10138
|
adapter: string;
|
|
@@ -11442,8 +11459,8 @@ export default extension;
|
|
|
11442
11459
|
manifest: {
|
|
11443
11460
|
$schema: "../manifest.schema.json",
|
|
11444
11461
|
name: "slack-reply-gate",
|
|
11445
|
-
description: "Asks
|
|
11446
|
-
version: "1.
|
|
11462
|
+
description: "Asks a SystemOne decision model (Jev or Clef) whether Lead should answer a buffered Slack thread follow-up, and drops the wake-up when it should not",
|
|
11463
|
+
version: "1.3.0",
|
|
11447
11464
|
runtime: "api",
|
|
11448
11465
|
assets: {
|
|
11449
11466
|
hooks: "hooks.ts"
|
|
@@ -11458,8 +11475,9 @@ import { z } from "zod";
|
|
|
11458
11475
|
*
|
|
11459
11476
|
* Every human message in a Slack thread the swarm takes part in is buffered and
|
|
11460
11477
|
* flushed into a Lead task ("[Thread follow-up — N message(s) buffered]"), even
|
|
11461
|
-
* "lol", ":joy:" or two people bantering. This hook asks
|
|
11462
|
-
* Lead should answer, and drops the wake-up when the
|
|
11478
|
+
* "lol", ":joy:" or two people bantering. This hook asks a SystemOne decision
|
|
11479
|
+
* model (Jev or Clef) whether Lead should answer, and drops the wake-up when the
|
|
11480
|
+
* answer is no.
|
|
11463
11481
|
*
|
|
11464
11482
|
* Hook: \`pre.task.create\`, origin "slack", description carrying the
|
|
11465
11483
|
* thread-buffer header. \`pre.slack.route\` cannot be used: the buffered thread
|
|
@@ -11467,17 +11485,20 @@ import { z } from "zod";
|
|
|
11467
11485
|
* re-target a message, never drop it.
|
|
11468
11486
|
*
|
|
11469
11487
|
* Rules:
|
|
11470
|
-
* - A message that @mentions Lead passes without a
|
|
11471
|
-
* - Otherwise one
|
|
11488
|
+
* - A message that @mentions Lead passes without a decision call.
|
|
11489
|
+
* - Otherwise one \`choice\` question classifies the message into a reason;
|
|
11472
11490
|
* reply=false only for reaction_only | banter_between_others |
|
|
11473
11491
|
* not_addressed_to_lead, and only when the summed probability of those
|
|
11474
11492
|
* three labels is >= minConfidence (a banter/reaction split is still a skip).
|
|
11475
11493
|
* - Fails OPEN on every error, timeout or missing key.
|
|
11476
11494
|
*
|
|
11477
|
-
*
|
|
11478
|
-
*
|
|
11479
|
-
*
|
|
11480
|
-
*
|
|
11495
|
+
* Provider (config.provider): the decision is made server-side by the
|
|
11496
|
+
* \`system-one-decide\` tool (\`ctx.swarm.systemOne_decide\`), the same path as a
|
|
11497
|
+
* \`system-one-decision\` workflow node, so every SystemOne host works and no key
|
|
11498
|
+
* enters this hook. \`auto\` picks the first host with a configured credential:
|
|
11499
|
+
* typesafe (Jev, TYPESAFE_API_KEY), openrouter (Jev, OPENROUTER_API_KEY), then
|
|
11500
|
+
* cloudflare (Clef, CLOUDFLARE_API_TOKEN or CLOUDFLARE_API_KEY, plus
|
|
11501
|
+
* CLOUDFLARE_ACCOUNT_ID). laya and openai are explicit choices only.
|
|
11481
11502
|
*
|
|
11482
11503
|
* modes (config.mode):
|
|
11483
11504
|
* off -> never evaluate
|
|
@@ -11500,17 +11521,19 @@ import { z } from "zod";
|
|
|
11500
11521
|
export const config = z.object({
|
|
11501
11522
|
mode: z.enum(["off", "shadow", "enforce"]).default("shadow"),
|
|
11502
11523
|
timeoutMs: z.number().int().positive().default(3000),
|
|
11503
|
-
provider: z
|
|
11504
|
-
|
|
11524
|
+
provider: z
|
|
11525
|
+
.enum(["auto", "typesafe", "openrouter", "cloudflare", "laya", "openai"])
|
|
11526
|
+
.default("auto"),
|
|
11527
|
+
/** Jev model on TypeSafe. */
|
|
11505
11528
|
model: z.string().default("jev-latest"),
|
|
11506
|
-
/** Jev model on
|
|
11529
|
+
/** Jev model on OpenRouter. */
|
|
11507
11530
|
openrouterModel: z.string().default("typesafe/jev-1.13"),
|
|
11531
|
+
/** Clef model on Cloudflare Workers AI: clef or clef-flash. */
|
|
11532
|
+
cloudflareModel: z.string().default("clef"),
|
|
11508
11533
|
minConfidence: z.number().min(0).max(1).default(0.55),
|
|
11509
11534
|
contextMessages: z.number().int().min(0).max(20).default(6),
|
|
11510
11535
|
leadAliases: z.array(z.string()).default(["lead"]),
|
|
11511
11536
|
botSlackUserIds: z.array(z.string()).default([]),
|
|
11512
|
-
/** Explicit TypeSafe key; otherwise TYPESAFE_API_KEY from the API process env. */
|
|
11513
|
-
apiKey: z.string().optional(),
|
|
11514
11537
|
/**
|
|
11515
11538
|
* Reaction for a dropped message in enforce mode. "" only removes the bot's
|
|
11516
11539
|
* acceptance reaction(s) and adds nothing.
|
|
@@ -11523,13 +11546,13 @@ type Cfg = z.infer<typeof config>;
|
|
|
11523
11546
|
type Swarm = ApiCtx["swarm"];
|
|
11524
11547
|
|
|
11525
11548
|
const NS = "ext:slack-reply-gate";
|
|
11526
|
-
const TYPESAFE_ENDPOINT = "https://api.typesafe.ai/v1/systemone";
|
|
11527
|
-
const OPENROUTER_ENDPOINT = "https://openrouter.ai/api/alpha/decisions";
|
|
11528
11549
|
const HEADER_LINE_RE = /(?:^|\\n)\\[Thread follow-up — \\d+ message\\(s\\) buffered\\]\\n/g;
|
|
11529
11550
|
const CTX_OPEN = "<thread_context>";
|
|
11530
11551
|
const CTX_CLOSE = "</thread_context>";
|
|
11531
11552
|
// The dispatcher cancels a handler after 5 s; leave room for the KV writes.
|
|
11532
11553
|
const MAX_TIMEOUT_MS = 4000;
|
|
11554
|
+
// The smallest time budget system-one-decide accepts.
|
|
11555
|
+
const MIN_DECIDE_TIMEOUT_MS = 1000;
|
|
11533
11556
|
|
|
11534
11557
|
export const REASONS = {
|
|
11535
11558
|
direct_ask:
|
|
@@ -11631,14 +11654,14 @@ const usable = (v: string): boolean => Boolean(v) && !v.startsWith("[REDACTED");
|
|
|
11631
11654
|
const envOf = (name: string): string => String(process.env[name] ?? "");
|
|
11632
11655
|
|
|
11633
11656
|
/**
|
|
11634
|
-
* Resolve a secret
|
|
11635
|
-
*
|
|
11657
|
+
* Resolve a secret from the API process env. The API process loads global
|
|
11658
|
+
* swarm_config rows into process.env at boot and on config reload.
|
|
11636
11659
|
* ctx.swarm.config_get cannot serve it: the SDK scrubs secrets to "[REDACTED:<name>]".
|
|
11637
11660
|
*/
|
|
11638
|
-
const secret = (name: string
|
|
11661
|
+
const secret = (name: string): string => {
|
|
11639
11662
|
const cached = secretCache.get(name);
|
|
11640
11663
|
if (cached && Date.now() - cached.at < KEY_TTL_MS) return cached.value;
|
|
11641
|
-
const value =
|
|
11664
|
+
const value = usable(envOf(name)) ? envOf(name) : "";
|
|
11642
11665
|
if (usable(value)) secretCache.set(name, { value, at: Date.now() });
|
|
11643
11666
|
return value;
|
|
11644
11667
|
};
|
|
@@ -11648,46 +11671,51 @@ export const resetKeyCache = (): void => {
|
|
|
11648
11671
|
secretCache.clear();
|
|
11649
11672
|
};
|
|
11650
11673
|
|
|
11651
|
-
export type
|
|
11652
|
-
|
|
11653
|
-
|
|
11654
|
-
|
|
11655
|
-
|
|
11656
|
-
|
|
11674
|
+
export type ProviderId = Exclude<Cfg["provider"], "auto">;
|
|
11675
|
+
|
|
11676
|
+
/** Where the decision is made. No model means the provider's own default. */
|
|
11677
|
+
export type DecisionTarget = { provider: ProviderId; model?: string };
|
|
11678
|
+
|
|
11679
|
+
/** What \`auto\` needs per provider: every group must have one usable value. */
|
|
11680
|
+
const AUTO_CREDENTIALS: ReadonlyArray<[ProviderId, string[][]]> = [
|
|
11681
|
+
["typesafe", [["TYPESAFE_API_KEY"]]],
|
|
11682
|
+
["openrouter", [["OPENROUTER_API_KEY"]]],
|
|
11683
|
+
["cloudflare", [["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_API_KEY"], ["CLOUDFLARE_ACCOUNT_ID"]]],
|
|
11684
|
+
];
|
|
11685
|
+
|
|
11686
|
+
const modelFor = (provider: ProviderId, cfg: Cfg): string | undefined =>
|
|
11687
|
+
provider === "typesafe"
|
|
11688
|
+
? cfg.model
|
|
11689
|
+
: provider === "openrouter"
|
|
11690
|
+
? cfg.openrouterModel
|
|
11691
|
+
: provider === "cloudflare"
|
|
11692
|
+
? cfg.cloudflareModel
|
|
11693
|
+
: undefined;
|
|
11657
11694
|
|
|
11658
11695
|
/**
|
|
11659
|
-
*
|
|
11660
|
-
*
|
|
11696
|
+
* The decision providers to try, in order. An explicit one is used as is: the
|
|
11697
|
+
* server checks its credential. \`auto\` lists every provider in \`AUTO_CREDENTIALS\`
|
|
11698
|
+
* whose credential is set and throws when none is; the handler then fails open.
|
|
11661
11699
|
*/
|
|
11662
|
-
export const
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
};
|
|
11669
|
-
|
|
11670
|
-
const key = secret("OPENROUTER_API_KEY");
|
|
11671
|
-
return usable(key)
|
|
11672
|
-
? { provider: "openrouter", endpoint: OPENROUTER_ENDPOINT, key, model: cfg.openrouterModel }
|
|
11673
|
-
: null;
|
|
11674
|
-
};
|
|
11675
|
-
const transport =
|
|
11676
|
-
cfg.provider === "typesafe"
|
|
11677
|
-
? typesafe()
|
|
11678
|
-
: cfg.provider === "openrouter"
|
|
11679
|
-
? openrouter()
|
|
11680
|
-
: (typesafe() ?? openrouter());
|
|
11681
|
-
if (transport) return transport;
|
|
11700
|
+
export const resolveProviders = (cfg: Cfg): DecisionTarget[] => {
|
|
11701
|
+
if (cfg.provider !== "auto") {
|
|
11702
|
+
return [{ provider: cfg.provider, model: modelFor(cfg.provider, cfg) }];
|
|
11703
|
+
}
|
|
11704
|
+
const targets = AUTO_CREDENTIALS.filter(([, groups]) =>
|
|
11705
|
+
groups.every((keys) => keys.some((key) => usable(secret(key)))),
|
|
11706
|
+
).map(([provider]) => ({ provider, model: modelFor(provider, cfg) }));
|
|
11707
|
+
if (targets.length > 0) return targets;
|
|
11682
11708
|
throw new Error(
|
|
11683
|
-
|
|
11684
|
-
? "no TYPESAFE_API_KEY"
|
|
11685
|
-
: cfg.provider === "openrouter"
|
|
11686
|
-
? "no OPENROUTER_API_KEY"
|
|
11687
|
-
: "no TYPESAFE_API_KEY or OPENROUTER_API_KEY",
|
|
11709
|
+
"no TYPESAFE_API_KEY, OPENROUTER_API_KEY, or CLOUDFLARE_API_TOKEN with CLOUDFLARE_ACCOUNT_ID",
|
|
11688
11710
|
);
|
|
11689
11711
|
};
|
|
11690
11712
|
|
|
11713
|
+
/** The first provider \`resolveProviders\` would try. */
|
|
11714
|
+
export const resolveProvider = (cfg: Cfg): DecisionTarget => resolveProviders(cfg)[0]!;
|
|
11715
|
+
|
|
11716
|
+
/** The server refused the provider for a deployment setting and sent nothing. */
|
|
11717
|
+
export class ProviderUnavailableError extends Error {}
|
|
11718
|
+
|
|
11691
11719
|
const SLACK_API = "https://slack.com/api";
|
|
11692
11720
|
// The engine's acceptance reactions (src/slack/reaction-shortcode.ts), by config key.
|
|
11693
11721
|
const ACCEPTANCE_REACTIONS: ReadonlyArray<[string, string]> = [
|
|
@@ -11775,7 +11803,7 @@ export const settleMutes = async (): Promise<void> => {
|
|
|
11775
11803
|
await Promise.allSettled([...pendingMutes]);
|
|
11776
11804
|
};
|
|
11777
11805
|
|
|
11778
|
-
export type
|
|
11806
|
+
export type Verdict = {
|
|
11779
11807
|
reason: string;
|
|
11780
11808
|
confidence: number | null;
|
|
11781
11809
|
probabilities: Record<string, number> | null;
|
|
@@ -11783,56 +11811,73 @@ export type JevVerdict = {
|
|
|
11783
11811
|
};
|
|
11784
11812
|
|
|
11785
11813
|
/**
|
|
11786
|
-
* One
|
|
11787
|
-
*
|
|
11814
|
+
* One decision: classify the newest message into a reason. Throws on any failure.
|
|
11815
|
+
* The server makes the call (\`system-one-decide\`), so every provider returns the
|
|
11816
|
+
* same \`answers\` shape. The time budget is enforced here and on the server.
|
|
11788
11817
|
*/
|
|
11789
|
-
export const
|
|
11818
|
+
export const askModel = async (
|
|
11819
|
+
swarm: Swarm,
|
|
11790
11820
|
input: {
|
|
11791
11821
|
messages: string[];
|
|
11792
11822
|
context: string[];
|
|
11793
11823
|
sender: string;
|
|
11794
11824
|
leadNames: readonly string[];
|
|
11795
11825
|
},
|
|
11796
|
-
|
|
11826
|
+
target: DecisionTarget,
|
|
11797
11827
|
cfg: Cfg,
|
|
11798
11828
|
outer?: AbortSignal,
|
|
11799
|
-
): Promise<
|
|
11800
|
-
const
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11829
|
+
): Promise<Verdict> => {
|
|
11830
|
+
const budgetMs = Math.min(cfg.timeoutMs, MAX_TIMEOUT_MS);
|
|
11831
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
11832
|
+
let onOuterAbort: (() => void) | undefined;
|
|
11833
|
+
const stop = new Promise<never>((_resolve, reject) => {
|
|
11834
|
+
timer = setTimeout(() => reject(new Error(\`timed out after \${budgetMs}ms\`)), budgetMs);
|
|
11835
|
+
onOuterAbort = () => reject(new Error("aborted"));
|
|
11836
|
+
outer?.addEventListener("abort", onOuterAbort);
|
|
11837
|
+
});
|
|
11804
11838
|
const t0 = Date.now();
|
|
11805
11839
|
try {
|
|
11806
|
-
const
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11840
|
+
const call = swarm.systemOne_decide({
|
|
11841
|
+
provider: target.provider,
|
|
11842
|
+
...(target.model ? { model: target.model } : {}),
|
|
11843
|
+
state: {
|
|
11844
|
+
role: "Decide whether Lead, the coordinating AI agent of a team's agent swarm, should answer a new Slack message in a thread it takes part in. Lead is woken by every message in the thread, including ones not meant for it. Answering noise wastes everyone's time; missing a real ask is worse.",
|
|
11845
|
+
lead_names: [...input.leadNames],
|
|
11846
|
+
recent_thread_messages: input.context,
|
|
11847
|
+
new_message: input.messages.join("\\n---\\n"),
|
|
11848
|
+
new_message_sender: input.sender,
|
|
11811
11849
|
},
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
new_message_sender: input.sender,
|
|
11819
|
-
},
|
|
11820
|
-
model: transport.model,
|
|
11821
|
-
questions: {
|
|
11822
|
-
reason: {
|
|
11823
|
-
type: "choice",
|
|
11824
|
-
instructions:
|
|
11825
|
-
"Which label best describes new_message from Lead's point of view? Use recent_thread_messages to tell who it is talking to. Lines starting with [Agent] are swarm bots.",
|
|
11826
|
-
criteria: REASONS,
|
|
11827
|
-
},
|
|
11850
|
+
questions: {
|
|
11851
|
+
reason: {
|
|
11852
|
+
type: "choice",
|
|
11853
|
+
instructions:
|
|
11854
|
+
"Which label best describes new_message from Lead's point of view? Use recent_thread_messages to tell who it is talking to. Lines starting with [Agent] are swarm bots.",
|
|
11855
|
+
criteria: REASONS,
|
|
11828
11856
|
},
|
|
11829
|
-
}
|
|
11830
|
-
|
|
11857
|
+
},
|
|
11858
|
+
timeoutMs: Math.max(budgetMs, MIN_DECIDE_TIMEOUT_MS),
|
|
11859
|
+
maxRetries: 0,
|
|
11831
11860
|
});
|
|
11832
|
-
|
|
11833
|
-
|
|
11861
|
+
// After a timeout nobody awaits the call; its late failure must not go unhandled.
|
|
11862
|
+
call.catch(() => {});
|
|
11863
|
+
const res = (await Promise.race([call, stop])) as {
|
|
11864
|
+
success?: boolean;
|
|
11865
|
+
status?: number;
|
|
11866
|
+
data?: unknown;
|
|
11867
|
+
} | null;
|
|
11868
|
+
const body = (res?.data ?? res) as {
|
|
11869
|
+
success?: boolean;
|
|
11870
|
+
message?: unknown;
|
|
11871
|
+
error?: unknown;
|
|
11872
|
+
providerUnavailable?: unknown;
|
|
11834
11873
|
answers?: { reason?: { choice?: unknown; confidence?: unknown; probabilities?: unknown } };
|
|
11835
11874
|
} | null;
|
|
11875
|
+
if (res?.success === false || body?.success === false) {
|
|
11876
|
+
const why = \`\${target.provider}: \${String(body?.message ?? body?.error ?? \`HTTP \${res?.status}\`).slice(0, 200)}\`;
|
|
11877
|
+
throw body?.providerUnavailable === true
|
|
11878
|
+
? new ProviderUnavailableError(why)
|
|
11879
|
+
: new Error(why);
|
|
11880
|
+
}
|
|
11836
11881
|
const answer = body?.answers?.reason;
|
|
11837
11882
|
const reason = typeof answer?.choice === "string" ? answer.choice : "";
|
|
11838
11883
|
if (!(reason in REASONS)) throw new Error(\`unexpected choice: \${String(reason).slice(0, 60)}\`);
|
|
@@ -11844,12 +11889,34 @@ export const askJev = async (
|
|
|
11844
11889
|
return { reason, confidence, probabilities, latencyMs: Date.now() - t0 };
|
|
11845
11890
|
} finally {
|
|
11846
11891
|
clearTimeout(timer);
|
|
11847
|
-
outer?.removeEventListener("abort", onOuterAbort);
|
|
11892
|
+
if (onOuterAbort) outer?.removeEventListener("abort", onOuterAbort);
|
|
11848
11893
|
}
|
|
11849
11894
|
};
|
|
11850
11895
|
|
|
11896
|
+
/**
|
|
11897
|
+
* \`askModel\` on each target in turn, moving on only when the server refused the
|
|
11898
|
+
* provider for a deployment setting (no request was sent). Any other failure, or
|
|
11899
|
+
* a refusal of the last target, throws.
|
|
11900
|
+
*/
|
|
11901
|
+
export const askFirstAvailable = async (
|
|
11902
|
+
swarm: Swarm,
|
|
11903
|
+
input: Parameters<typeof askModel>[1],
|
|
11904
|
+
targets: readonly DecisionTarget[],
|
|
11905
|
+
cfg: Cfg,
|
|
11906
|
+
outer?: AbortSignal,
|
|
11907
|
+
): Promise<{ verdict: Verdict; target: DecisionTarget }> => {
|
|
11908
|
+
for (const [i, target] of targets.entries()) {
|
|
11909
|
+
try {
|
|
11910
|
+
return { verdict: await askModel(swarm, input, target, cfg, outer), target };
|
|
11911
|
+
} catch (err) {
|
|
11912
|
+
if (!(err instanceof ProviderUnavailableError) || i === targets.length - 1) throw err;
|
|
11913
|
+
}
|
|
11914
|
+
}
|
|
11915
|
+
throw new Error("no decision provider");
|
|
11916
|
+
};
|
|
11917
|
+
|
|
11851
11918
|
/** Probability that the message needs no reply: the summed mass of the skip labels. */
|
|
11852
|
-
export const skipProbability = (verdict:
|
|
11919
|
+
export const skipProbability = (verdict: Verdict): number | null => {
|
|
11853
11920
|
if (verdict.probabilities) {
|
|
11854
11921
|
let sum = 0;
|
|
11855
11922
|
for (const [label, p] of Object.entries(verdict.probabilities)) {
|
|
@@ -11860,9 +11927,9 @@ export const skipProbability = (verdict: JevVerdict): number | null => {
|
|
|
11860
11927
|
return verdict.confidence;
|
|
11861
11928
|
};
|
|
11862
11929
|
|
|
11863
|
-
/** Map a
|
|
11930
|
+
/** Map a verdict to the typed decision. An unsure skip verdict replies. */
|
|
11864
11931
|
export const decide = (
|
|
11865
|
-
verdict:
|
|
11932
|
+
verdict: Verdict,
|
|
11866
11933
|
minConfidence: number,
|
|
11867
11934
|
): { reply: boolean; reason: Reason; skipP: number | null; lowConfidence: boolean } => {
|
|
11868
11935
|
const reason = verdict.reason as Reason;
|
|
@@ -11959,7 +12026,7 @@ const extension: SwarmExtension = (api) => {
|
|
|
11959
12026
|
return;
|
|
11960
12027
|
}
|
|
11961
12028
|
|
|
11962
|
-
const
|
|
12029
|
+
const targets = resolveProviders(cfg);
|
|
11963
12030
|
|
|
11964
12031
|
const sender =
|
|
11965
12032
|
opts.slackUserId && cfg.botSlackUserIds.includes(opts.slackUserId)
|
|
@@ -11968,14 +12035,15 @@ const extension: SwarmExtension = (api) => {
|
|
|
11968
12035
|
? "human (known teammate)"
|
|
11969
12036
|
: "unknown (not a known teammate; may be a bot or an external person)";
|
|
11970
12037
|
|
|
11971
|
-
const verdict = await
|
|
12038
|
+
const { verdict, target } = await askFirstAvailable(
|
|
12039
|
+
ctx.swarm,
|
|
11972
12040
|
{
|
|
11973
12041
|
messages,
|
|
11974
12042
|
context: context.slice(-cfg.contextMessages).map((m) => m.slice(0, 500)),
|
|
11975
12043
|
sender,
|
|
11976
12044
|
leadNames: cfg.leadAliases,
|
|
11977
12045
|
},
|
|
11978
|
-
|
|
12046
|
+
targets,
|
|
11979
12047
|
cfg,
|
|
11980
12048
|
ctx.signal,
|
|
11981
12049
|
);
|
|
@@ -11994,7 +12062,7 @@ const extension: SwarmExtension = (api) => {
|
|
|
11994
12062
|
skipP: decision.skipP,
|
|
11995
12063
|
lowConfidence: decision.lowConfidence,
|
|
11996
12064
|
latencyMs: verdict.latencyMs,
|
|
11997
|
-
provider:
|
|
12065
|
+
provider: target.provider,
|
|
11998
12066
|
sender,
|
|
11999
12067
|
preview,
|
|
12000
12068
|
},
|
|
@@ -12034,7 +12102,7 @@ const extension: SwarmExtension = (api) => {
|
|
|
12034
12102
|
export default extension;
|
|
12035
12103
|
`
|
|
12036
12104
|
},
|
|
12037
|
-
readme: '# slack-reply-gate\n\nLead is woken by every human message in a Slack thread the swarm takes part in, including "lol", an emoji, or two people chatting with each other. This extension asks
|
|
12105
|
+
readme: '# slack-reply-gate\n\nLead is woken by every human message in a Slack thread the swarm takes part in, including "lol", an emoji, or two people chatting with each other. This extension asks a SystemOne decision model, Jev ([TypeSafe](https://typesafe.ai)) or Clef (Cloudflare Workers AI), whether Lead should answer a new thread message, and drops the wake-up when it should not.\n\nInstall config:\n\n```json\n{ "mode": "shadow" }\n```\n\nStart in `shadow`, read the decisions in KV for a few days, then switch to `enforce`.\n\n## Modes\n\n| `mode` | Effect |\n|---|---|\n| `off` | Never evaluates. |\n| `shadow` (default) | Asks the model and records the verdict. Never blocks. |\n| `enforce` | Asks the model, records the verdict, and blocks the Lead task when the answer is no. The message gets :mute: instead: no Lead task, no reply, no outcome card. |\n\n## What it gates\n\nHook: `pre.task.create`, for tasks with origin `slack` whose description carries the thread buffer\'s header `[Thread follow-up — N message(s) buffered]`. Those are the non-mention thread replies that `src/slack/thread-buffer.ts` batches into a Lead task. A direct @mention of the bot creates a task without that header and is never gated.\n\nThe header counts only at the start of the description or right after the closing `</thread_context>`. Thread context quotes old messages verbatim, and an older Lead reply can quote the header itself, so a header inside the context is ignored. Only the text after the real header is treated as new.\n\n## Decision\n\n1. A follow-up with downloaded files (status `draft`) passes without a decision call.\n2. **@mention pass-through.** A new message that @mentions Lead passes without a decision call. A mention is the bot mention the engine rewrites to `<@U…> (that\'s you)`, a resolved `<@U…|lead>`, or a literal `@lead` (any name in `leadAliases`). Only the new messages are scanned, never the thread context, so an old mention earlier in the thread does not pass later banter.\n3. Otherwise one decision call (one `choice` question, see [Provider](#provider)) with the new message(s), the sender kind, and the last `contextMessages` thread messages. Labels: `direct_ask`, `followup_to_lead`, `instruction_to_lead`, `reaction_only`, `banter_between_others`, `not_addressed_to_lead`, `other`.\n4. The answer is no only when the top label is `reaction_only`, `banter_between_others`, or `not_addressed_to_lead`, and the summed probability of those three labels is at least `minConfidence`. A split between two skip labels is still a skip. An unsure verdict replies.\n\nSeveral buffered messages are judged together. One mention in any of them passes the batch.\n\n## Provider\n\nThe decision is made on the API server by the `system-one-decide` tool (`ctx.swarm.systemOne_decide`), the same path a `system-one-decision` workflow node takes. The server reads the provider\'s credential, sends the request, and validates the answer, so every SystemOne host works and no key enters the hook.\n\n| `provider` | Model | Credential |\n|---|---|---|\n| `typesafe` | Jev, `model` (default `jev-latest`) | `TYPESAFE_API_KEY` |\n| `openrouter` | Jev, `openrouterModel` (default `typesafe/jev-1.13`) | `OPENROUTER_API_KEY` |\n| `cloudflare` | Clef, `cloudflareModel` (default `clef`, or `clef-flash`) | `CLOUDFLARE_API_TOKEN` (or `CLOUDFLARE_API_KEY`) and `CLOUDFLARE_ACCOUNT_ID` |\n| `laya`, `openai` | The host\'s default model | See the workflows guide |\n| `auto` (default) | The first of typesafe, openrouter, cloudflare whose credential is set. A provider the server refuses for a deployment setting (openrouter when `OPENROUTER_BASE_URL` points at a gateway) is skipped for the next one | |\n\nWith no credential for `auto`, every message fails open and the KV row names the secrets. Each decision row records the `provider` that answered. `minConfidence` was tuned on Jev; check Clef\'s verdicts in `shadow` before you enforce on it.\n\n## Fail open\n\nEvery error lets the task through: a missing key, a provider error relayed by the server, a network error, a timeout, a malformed answer, or an unknown label. The handler never throws, so an outage cannot auto-disable the extension. Each failure is recorded as `fail-open` in KV and logged as a warning.\n\n## :mute: on drop (enforce)\n\nNo swarm tool or extension `ctx` method adds a Slack reaction, so the hook calls the Slack Web API with the bot token. It needs the `reactions:write` scope, which the Slack app already uses for its acceptance reactions.\n\n1. `reactions.remove` for each acceptance reaction the engine may have put on the triggering message: `eyes`, `heavy_plus_sign`, `zap`, `speech_balloon`, or their `SLACK_REACTION_ACCEPTED`, `SLACK_REACTION_BUFFERED`, `SLACK_REACTION_NOW`, and `SLACK_REACTION_STEERED` overrides. Slack only removes the bot\'s own reaction, so a human\'s :eyes: stays.\n2. `reactions.add` with `muteReaction` (default `mute`). `already_reacted` counts as success. Skipped when `muteReaction` is `""`.\n\nThe block returns first and the Slack calls run after it. A slow or failing Slack call never delays the drop or turns it back into a task. Set `muteReaction` to `""` for a true no-op: step 1 still clears the bot\'s acceptance reaction(s), and nothing is added.\n\n## Config\n\n| Key | Default | Notes |\n|---|---|---|\n| `mode` | `shadow` | `off`, `shadow`, or `enforce` |\n| `timeoutMs` | `3000` | Decision call timeout, capped at 4000 (the dispatcher cancels a handler at 5 s) |\n| `provider` | `auto` | `auto`, `typesafe`, `openrouter`, `cloudflare`, `laya`, or `openai`. See [Provider](#provider) |\n| `model` | `jev-latest` | Jev model on TypeSafe |\n| `openrouterModel` | `typesafe/jev-1.13` | Jev model on OpenRouter |\n| `cloudflareModel` | `clef` | Clef model on Cloudflare Workers AI |\n| `minConfidence` | `0.55` | Minimum summed skip probability to skip |\n| `contextMessages` | `6` | Thread messages sent to the model, 0 to 20 |\n| `leadAliases` | `["lead"]` | A literal `@alias` in a new message counts as a mention |\n| `botSlackUserIds` | `[]` | Slack user ids labelled `bot` as the sender for the model |\n| `muteReaction` | `mute` | Reaction for a dropped message; `""` only removes the acceptance reaction(s) |\n| `slackTimeoutMs` | `5000` | Timeout per Slack call |\n\n## Required secrets\n\nSet them as global `swarm_config` values. The server reads the provider credential from the global row when it makes the decision. `auto` and the Slack token read the API process environment, which loads global rows at boot and on config reload.\n\n- One provider credential from the [Provider](#provider) table is required for any evaluation. Without one, every message fails open. The `apiKey` config field of earlier versions is gone: the hook never holds a key, so store it as the global `TYPESAFE_API_KEY` secret.\n- `SLACK_BOT_TOKEN`: the Slack app\'s bot token. A swarm with Slack connected already has it. Without it, `enforce` still drops the message but cannot touch its reactions, and logs a `mute-error`.\n\nNo key is written to config, KV, logs, or a description.\n\n## KV namespace `ext:slack-reply-gate`\n\n- `d:<epochMs>:<channel>_<threadTs>`: one row per decision, with `action` (`pass`, `shadow-skip`, `skipped`, `fail-open`), `provider`, `reason`, `confidence`, `skipP`, `latencyMs`, `sender`, and a 300-character `preview`.\n- `m:<epochMs>:<channel>_<threadTs>`: one row per mute attempt, with `action` (`muted`, `unreacted` when `muteReaction` is `""`, `mute-error`), `removed`, `added`, and `errors`.\n- `last`: the latest decision. Mute rows never overwrite it.\n- Counters: `total`, `mention`, `files`, `reply`, `shadow-skip`, `skipped`, `error`, `muted`, `unreacted`, `mute-error`, and `reason:<label>`.\n\n## Known limits\n\n- When Lead already has an active task in the thread, the buffer steers that task instead of creating one, so `pre.task.create` does not fire and the gate does not run.\n- A blocked flush makes the thread buffer log a `TaskCreationBlockedError`. Nothing is lost: the next follow-up\'s `<thread_context>` carries the earlier messages.\n- A flush of several messages mutes only the triggering (last) message. The others keep their acceptance reaction.\n'
|
|
12038
12106
|
},
|
|
12039
12107
|
"task-digest": {
|
|
12040
12108
|
manifestFile: "manifest.yaml",
|
|
@@ -13220,6 +13288,17 @@ async function handleFleetBenchmark(req, res, pathSegments, queryParams) {
|
|
|
13220
13288
|
// src/http/fs.ts
|
|
13221
13289
|
init_zod();
|
|
13222
13290
|
init_db3();
|
|
13291
|
+
|
|
13292
|
+
// src/be/db/tasks/draft-text.ts
|
|
13293
|
+
init_runtime();
|
|
13294
|
+
async function appendDraftTaskText(taskId, block) {
|
|
13295
|
+
const result = await getDbClient2().run("UPDATE agent_tasks SET task = task || ?, lastUpdatedAt = ? WHERE id = ? AND status = 'draft'", [`
|
|
13296
|
+
|
|
13297
|
+
${block}`, new Date().toISOString(), taskId]);
|
|
13298
|
+
return result.changes > 0;
|
|
13299
|
+
}
|
|
13300
|
+
|
|
13301
|
+
// src/http/fs.ts
|
|
13223
13302
|
init_rbac();
|
|
13224
13303
|
init_types();
|
|
13225
13304
|
|
|
@@ -13343,7 +13422,7 @@ var uploadTaskFileRoute = route({
|
|
|
13343
13422
|
pattern: ["api", "fs", "tasks", null, "files"],
|
|
13344
13423
|
session: { taskParam: "taskId" },
|
|
13345
13424
|
summary: "Upload a binary task file attachment",
|
|
13346
|
-
description: "Accepts a raw binary request body. Pass the display/path name as the `name` query parameter.",
|
|
13425
|
+
description: "Accepts a raw binary request body. Pass the display/path name as the `name` query parameter. An `audio/*` file uploaded to a `draft` task gets a `[File: …]` line and its transcript (or why there is none) appended to the task text before the response; a failed transcription never fails the upload.",
|
|
13347
13426
|
tags: ["FS"],
|
|
13348
13427
|
params: taskParams,
|
|
13349
13428
|
query: uploadQuery,
|
|
@@ -13504,7 +13583,7 @@ async function handleFs(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
13504
13583
|
return notFound(res, "Task not found");
|
|
13505
13584
|
if (!await canMutateTask(task, myAgentId, req))
|
|
13506
13585
|
return forbidden(res);
|
|
13507
|
-
return sendUpload(req, res, parsed.params.taskId, parsed.query, myAgentId ?? null);
|
|
13586
|
+
return sendUpload(req, res, parsed.params.taskId, parsed.query, myAgentId ?? null, task.status === "draft");
|
|
13508
13587
|
}
|
|
13509
13588
|
if (listTaskFilesRoute.match(req.method, pathSegments)) {
|
|
13510
13589
|
const parsed = await listTaskFilesRoute.parse(req, res, pathSegments, queryParams);
|
|
@@ -13531,7 +13610,7 @@ async function handleFs(req, res, pathSegments, queryParams, myAgentId) {
|
|
|
13531
13610
|
}
|
|
13532
13611
|
return false;
|
|
13533
13612
|
}
|
|
13534
|
-
async function sendUpload(req, res, taskId, query, agentId) {
|
|
13613
|
+
async function sendUpload(req, res, taskId, query, agentId, isDraft) {
|
|
13535
13614
|
const body = await readRawBody(req, MAX_TASK_ATTACHMENT_BYTES);
|
|
13536
13615
|
if (body === BODY_TOO_LARGE) {
|
|
13537
13616
|
jsonError(res, `Payload too large (max ${MAX_TASK_ATTACHMENT_BYTES} bytes)`, 413);
|
|
@@ -13572,9 +13651,27 @@ async function sendUpload(req, res, taskId, query, agentId) {
|
|
|
13572
13651
|
isPrimary: query.isPrimary === "true",
|
|
13573
13652
|
createdBy: auth?.kind === "user" ? auth.userId : undefined
|
|
13574
13653
|
});
|
|
13654
|
+
const mimeType = contentType.split(";")[0].trim().toLowerCase();
|
|
13655
|
+
if (isDraft && mimeType.startsWith("audio/")) {
|
|
13656
|
+
await appendAudioTranscript(taskId, query.name, mimeType, body);
|
|
13657
|
+
}
|
|
13575
13658
|
uploadTaskFileRoute.respond(res, 201, attachment);
|
|
13576
13659
|
return true;
|
|
13577
13660
|
}
|
|
13661
|
+
async function appendAudioTranscript(taskId, name, mimeType, body) {
|
|
13662
|
+
try {
|
|
13663
|
+
const notes = await transcribeAudioNotes([{ key: name, name, data: new Blob([body], { type: mimeType }), mimeType }], "[fs]");
|
|
13664
|
+
const note = notes.get(name);
|
|
13665
|
+
if (!note)
|
|
13666
|
+
return;
|
|
13667
|
+
if (!await appendDraftTaskText(taskId, `[File: ${name} (${mimeType})]
|
|
13668
|
+
${note}`)) {
|
|
13669
|
+
console.warn(`[fs] task ${taskId} left draft before the transcript of ${name} was added`);
|
|
13670
|
+
}
|
|
13671
|
+
} catch (error) {
|
|
13672
|
+
console.warn(scrubSecrets(`[fs] could not add the transcript of ${name} to task ${taskId}: ${error instanceof Error ? error.message : String(error)}`));
|
|
13673
|
+
}
|
|
13674
|
+
}
|
|
13578
13675
|
async function sendDownload(res, attachment) {
|
|
13579
13676
|
const provider = getFileStorageProvider2();
|
|
13580
13677
|
if (backingProviderId(attachment) !== provider.id) {
|
|
@@ -13634,23 +13731,6 @@ async function sendDelete(res, attachment) {
|
|
|
13634
13731
|
res.end();
|
|
13635
13732
|
return true;
|
|
13636
13733
|
}
|
|
13637
|
-
function scopeFromAttachment(attachment) {
|
|
13638
|
-
const storedKey = attachment.providerKey ?? attachment.path ?? "";
|
|
13639
|
-
return {
|
|
13640
|
-
taskId: attachment.taskId,
|
|
13641
|
-
name: attachment.name,
|
|
13642
|
-
key: storedKey.trim() ? storedKey : undefined,
|
|
13643
|
-
orgId: attachment.orgId,
|
|
13644
|
-
driveId: attachment.driveId
|
|
13645
|
-
};
|
|
13646
|
-
}
|
|
13647
|
-
function backingProviderId(attachment) {
|
|
13648
|
-
if (attachment.kind === "agent-fs")
|
|
13649
|
-
return attachment.providerId ?? "agent-fs";
|
|
13650
|
-
if (attachment.providerId === "local-fs")
|
|
13651
|
-
return "local-fs";
|
|
13652
|
-
return null;
|
|
13653
|
-
}
|
|
13654
13734
|
async function findAttachment(req, myAgentId, taskId, attachmentId, res) {
|
|
13655
13735
|
if (!await getTaskById2(taskId)) {
|
|
13656
13736
|
notFound(res, "Task not found");
|
|
@@ -16408,6 +16488,29 @@ init_db3();
|
|
|
16408
16488
|
init_env_flag();
|
|
16409
16489
|
init_request_auth_context();
|
|
16410
16490
|
init_task_tool_manifest();
|
|
16491
|
+
|
|
16492
|
+
// src/http/mcp-body.ts
|
|
16493
|
+
var MCP_BODY_TOO_LARGE = Symbol("mcp-body-too-large");
|
|
16494
|
+
async function readMcpBody(req, res) {
|
|
16495
|
+
try {
|
|
16496
|
+
return await parseBody(req, MCP_MAX_REQUEST_BODY_BYTES);
|
|
16497
|
+
} catch (error) {
|
|
16498
|
+
if (!(error instanceof RequestBodyTooLargeError))
|
|
16499
|
+
throw error;
|
|
16500
|
+
res.writeHead(413, { "Content-Type": "application/json", Connection: "close" });
|
|
16501
|
+
res.end(JSON.stringify({
|
|
16502
|
+
jsonrpc: "2.0",
|
|
16503
|
+
error: {
|
|
16504
|
+
code: -32000,
|
|
16505
|
+
message: `Payload Too Large: Request body must not exceed ${MCP_MAX_REQUEST_BODY_BYTES} bytes`
|
|
16506
|
+
},
|
|
16507
|
+
id: null
|
|
16508
|
+
}));
|
|
16509
|
+
return MCP_BODY_TOO_LARGE;
|
|
16510
|
+
}
|
|
16511
|
+
}
|
|
16512
|
+
|
|
16513
|
+
// src/http/mcp.ts
|
|
16411
16514
|
var DEFAULT_MCP_TRANSPORT_IDLE_TIMEOUT_MS = 2 * 60 * 60 * 1000;
|
|
16412
16515
|
function respondNoMcpSession(res, sessionId) {
|
|
16413
16516
|
const notFound = Boolean(sessionId);
|
|
@@ -16507,17 +16610,16 @@ async function handleMcp(req, res, transports, sessionActivity = {}, sessionAgen
|
|
|
16507
16610
|
if (agentMismatch)
|
|
16508
16611
|
return true;
|
|
16509
16612
|
if (req.method === "POST") {
|
|
16510
|
-
const
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
if (!sessionId && body.method === "server/discover") {
|
|
16613
|
+
const body = await readMcpBody(req, res);
|
|
16614
|
+
if (body === MCP_BODY_TOO_LARGE)
|
|
16615
|
+
return true;
|
|
16616
|
+
const rpc = body;
|
|
16617
|
+
if (!sessionId && rpc?.method === "server/discover") {
|
|
16516
16618
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
16517
16619
|
res.end(JSON.stringify({
|
|
16518
16620
|
jsonrpc: "2.0",
|
|
16519
16621
|
error: { code: -32601, message: "Method not found" },
|
|
16520
|
-
id:
|
|
16622
|
+
id: rpc.id ?? null
|
|
16521
16623
|
}));
|
|
16522
16624
|
return true;
|
|
16523
16625
|
}
|
|
@@ -17854,7 +17956,8 @@ function createUserServer(user) {
|
|
|
17854
17956
|
}, {
|
|
17855
17957
|
capabilities: {
|
|
17856
17958
|
logging: {}
|
|
17857
|
-
}
|
|
17959
|
+
},
|
|
17960
|
+
maxToolInputElements: MCP_MAX_TOOL_INPUT_ELEMENTS
|
|
17858
17961
|
});
|
|
17859
17962
|
const registerTool = createToolRegistrar(server);
|
|
17860
17963
|
const sendTaskConfig = {
|
|
@@ -17972,11 +18075,9 @@ async function handleMcpUser(req, res, transports, sessionUsers, sessionActivity
|
|
|
17972
18075
|
return unauthorized2(res);
|
|
17973
18076
|
}
|
|
17974
18077
|
if (req.method === "POST") {
|
|
17975
|
-
const
|
|
17976
|
-
|
|
17977
|
-
|
|
17978
|
-
}
|
|
17979
|
-
const body = JSON.parse(Buffer.concat(chunks).toString());
|
|
18078
|
+
const body = await readMcpBody(req, res);
|
|
18079
|
+
if (body === MCP_BODY_TOO_LARGE)
|
|
18080
|
+
return true;
|
|
17980
18081
|
let transport;
|
|
17981
18082
|
if (sessionId && transports[sessionId]) {
|
|
17982
18083
|
transport = transports[sessionId];
|
|
@@ -18118,6 +18219,9 @@ async function hasRetrievalForTask(taskId, memoryId) {
|
|
|
18118
18219
|
return row != null;
|
|
18119
18220
|
}
|
|
18120
18221
|
|
|
18222
|
+
// src/http/memory.ts
|
|
18223
|
+
init_search_candidates();
|
|
18224
|
+
|
|
18121
18225
|
// src/be/memory/usefulness-stats.ts
|
|
18122
18226
|
init_db3();
|
|
18123
18227
|
async function getUsefulnessStats(options = {}) {
|
|
@@ -18958,7 +19062,7 @@ async function handleMemory(req, res, pathSegments, callerAgentId) {
|
|
|
18958
19062
|
const store = getMemoryStore2();
|
|
18959
19063
|
const queryEmbedding = await provider.embed(query);
|
|
18960
19064
|
const candidateLimit = Math.min(limit, 20) * CANDIDATE_SET_MULTIPLIER;
|
|
18961
|
-
const candidates = await store
|
|
19065
|
+
const candidates = await searchMemoryCandidates(store, queryEmbedding ?? new Float32Array(0), myAgentId, {
|
|
18962
19066
|
scope,
|
|
18963
19067
|
limit: candidateLimit,
|
|
18964
19068
|
source,
|
|
@@ -19039,7 +19143,7 @@ async function handleMemory(req, res, pathSegments, callerAgentId) {
|
|
|
19039
19143
|
const provider = getEmbeddingProvider2();
|
|
19040
19144
|
const queryEmbedding = await provider.embed(query.trim());
|
|
19041
19145
|
const candidateLimit = Math.min(4096, Math.max(offset + pageLimit, pageLimit) * CANDIDATE_SET_MULTIPLIER);
|
|
19042
|
-
let candidates = await store
|
|
19146
|
+
let candidates = await searchMemoryCandidates(store, queryEmbedding ?? new Float32Array(0), viewer.agentId, {
|
|
19043
19147
|
scope,
|
|
19044
19148
|
limit: candidateLimit,
|
|
19045
19149
|
isLead: viewer.seesAll,
|
|
@@ -21974,6 +22078,35 @@ route({
|
|
|
21974
22078
|
auth: { apiKey: false }
|
|
21975
22079
|
});
|
|
21976
22080
|
var PROXY_PREFIX = "/@swarm/api/";
|
|
22081
|
+
var PAGE_ID_REQUEST_HEADER = "x-swarm-page-id";
|
|
22082
|
+
var PAGE_PATH_RE = /^\/p\/([^/.]+)/;
|
|
22083
|
+
function requestedPageId(req) {
|
|
22084
|
+
const raw = req.headers[PAGE_ID_REQUEST_HEADER];
|
|
22085
|
+
const fromHeader = Array.isArray(raw) ? raw[0] : raw;
|
|
22086
|
+
if (fromHeader !== undefined)
|
|
22087
|
+
return isCookieSafePageId(fromHeader) ? fromHeader : null;
|
|
22088
|
+
const referer = req.headers.referer;
|
|
22089
|
+
if (!referer)
|
|
22090
|
+
return;
|
|
22091
|
+
let refererUrl;
|
|
22092
|
+
try {
|
|
22093
|
+
refererUrl = new URL(referer);
|
|
22094
|
+
} catch {
|
|
22095
|
+
return;
|
|
22096
|
+
}
|
|
22097
|
+
if (refererUrl.host !== req.headers.host)
|
|
22098
|
+
return;
|
|
22099
|
+
const match = PAGE_PATH_RE.exec(refererUrl.pathname);
|
|
22100
|
+
if (!match)
|
|
22101
|
+
return;
|
|
22102
|
+
let fromReferer;
|
|
22103
|
+
try {
|
|
22104
|
+
fromReferer = decodeURIComponent(match[1]);
|
|
22105
|
+
} catch {
|
|
22106
|
+
return;
|
|
22107
|
+
}
|
|
22108
|
+
return isCookieSafePageId(fromReferer) ? fromReferer : undefined;
|
|
22109
|
+
}
|
|
21977
22110
|
function isSafeProxySuffix(suffix) {
|
|
21978
22111
|
if (suffix.length === 0)
|
|
21979
22112
|
return true;
|
|
@@ -22012,11 +22145,13 @@ async function handlePageProxy(req, res) {
|
|
|
22012
22145
|
jsonError(res, "not found", 404);
|
|
22013
22146
|
return true;
|
|
22014
22147
|
}
|
|
22015
|
-
const
|
|
22016
|
-
|
|
22148
|
+
const claimedPageId = requestedPageId(req);
|
|
22149
|
+
const session = claimedPageId === undefined ? await extractLegacyPageSession(req) : claimedPageId === null ? null : await extractPageSession(req, claimedPageId);
|
|
22150
|
+
if (!session) {
|
|
22017
22151
|
jsonError(res, "no page session", 401);
|
|
22018
22152
|
return true;
|
|
22019
22153
|
}
|
|
22154
|
+
const { payload } = session;
|
|
22020
22155
|
const page = await getPage2(payload.pageId);
|
|
22021
22156
|
if (!page) {
|
|
22022
22157
|
jsonError(res, "page session no longer valid", 401);
|
|
@@ -22034,7 +22169,7 @@ async function handlePageProxy(req, res) {
|
|
|
22034
22169
|
const headers = {
|
|
22035
22170
|
Authorization: `Bearer ${apiKey}`,
|
|
22036
22171
|
"X-Page-Id": page.id,
|
|
22037
|
-
"X-Page-Session":
|
|
22172
|
+
"X-Page-Session": session.token
|
|
22038
22173
|
};
|
|
22039
22174
|
const reqContentType = req.headers["content-type"];
|
|
22040
22175
|
if (reqContentType) {
|
|
@@ -24378,12 +24513,12 @@ ${defuseFeedbackTags(note)}
|
|
|
24378
24513
|
}
|
|
24379
24514
|
const auth = getRequestAuth(req);
|
|
24380
24515
|
const identity = auth?.kind === "user" ? { uid: auth.userId, name: auth.user.name } : auth?.kind === "operator" ? { name: `guest-${randomUUID4().slice(0, 8)}`, op: true } : undefined;
|
|
24381
|
-
const
|
|
24516
|
+
const cookies = await pageSessionSetCookies(req, page.id, {
|
|
24382
24517
|
dev: isDevRequest(req),
|
|
24383
24518
|
...identity
|
|
24384
24519
|
});
|
|
24385
24520
|
applyLaunchCors(req, res);
|
|
24386
|
-
res.setHeader("Set-Cookie",
|
|
24521
|
+
res.setHeader("Set-Cookie", cookies);
|
|
24387
24522
|
res.writeHead(204);
|
|
24388
24523
|
res.end();
|
|
24389
24524
|
return true;
|
|
@@ -24405,10 +24540,15 @@ class SwarmSDK {
|
|
|
24405
24540
|
this.channel = async (name) => (await loadRealtime()).channel(name);
|
|
24406
24541
|
|
|
24407
24542
|
const base = '/@swarm/api';
|
|
24543
|
+
// Each page has its own session cookie. Naming the page tells the proxy
|
|
24544
|
+
// which one to read; the cookie's signed payload must still match it.
|
|
24545
|
+
const pathParts = typeof location === 'undefined' ? [] : location.pathname.split('/');
|
|
24546
|
+
const pageId = pathParts[1] === 'p' && pathParts[2] ? pathParts[2].split('.')[0] : '';
|
|
24408
24547
|
const call = async (method, path, body) => {
|
|
24409
|
-
const init = { method };
|
|
24548
|
+
const init = { method, headers: {} };
|
|
24549
|
+
if (pageId) init.headers['X-Swarm-Page-Id'] = pageId;
|
|
24410
24550
|
if (body !== undefined) {
|
|
24411
|
-
init.headers
|
|
24551
|
+
init.headers['Content-Type'] = 'application/json';
|
|
24412
24552
|
init.body = JSON.stringify(body);
|
|
24413
24553
|
}
|
|
24414
24554
|
const res = await fetch(base + path, init);
|
|
@@ -25593,7 +25733,7 @@ var FEEDBACK_OVERLAY_JS = `
|
|
|
25593
25733
|
return fetch('/@swarm/api/pages/' + encodeURIComponent(pageId) + '/feedback', {
|
|
25594
25734
|
method: 'POST',
|
|
25595
25735
|
credentials: 'same-origin',
|
|
25596
|
-
headers: { 'Content-Type': 'application/json' },
|
|
25736
|
+
headers: { 'Content-Type': 'application/json', 'X-Swarm-Page-Id': pageId },
|
|
25597
25737
|
body: JSON.stringify(payload),
|
|
25598
25738
|
}).then(function (res) {
|
|
25599
25739
|
return res.text().then(function (text) {
|
|
@@ -25979,23 +26119,8 @@ function buildCsp() {
|
|
|
25979
26119
|
function isAccessible(page, cookiePayload) {
|
|
25980
26120
|
if (page.authMode === "public")
|
|
25981
26121
|
return { ok: true };
|
|
25982
|
-
if (cookiePayload)
|
|
25983
|
-
|
|
25984
|
-
return { ok: true };
|
|
25985
|
-
if (page.authMode === "password") {
|
|
25986
|
-
return {
|
|
25987
|
-
ok: false,
|
|
25988
|
-
status: 401,
|
|
25989
|
-
reason: "password required",
|
|
25990
|
-
needsPassword: true
|
|
25991
|
-
};
|
|
25992
|
-
}
|
|
25993
|
-
return {
|
|
25994
|
-
ok: false,
|
|
25995
|
-
status: 403,
|
|
25996
|
-
reason: "page-session cookie scoped to a different page id"
|
|
25997
|
-
};
|
|
25998
|
-
}
|
|
26122
|
+
if (cookiePayload?.pageId === page.id)
|
|
26123
|
+
return { ok: true };
|
|
25999
26124
|
if (page.authMode === "authed") {
|
|
26000
26125
|
return {
|
|
26001
26126
|
ok: false,
|
|
@@ -26070,9 +26195,9 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
|
|
|
26070
26195
|
res.end(JSON.stringify({ error: "Page not found" }));
|
|
26071
26196
|
return true;
|
|
26072
26197
|
}
|
|
26073
|
-
const cookiePayload = await extractAndVerifyCookie(req);
|
|
26198
|
+
const cookiePayload = await extractAndVerifyCookie(req, page.id);
|
|
26074
26199
|
const access = isAccessible(page, cookiePayload);
|
|
26075
|
-
let inlineSetCookie =
|
|
26200
|
+
let inlineSetCookie = [];
|
|
26076
26201
|
if (!access.ok) {
|
|
26077
26202
|
if (access.needsPassword) {
|
|
26078
26203
|
const candidate = extractPasswordCandidate(req, queryParams);
|
|
@@ -26084,7 +26209,7 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
|
|
|
26084
26209
|
matched = false;
|
|
26085
26210
|
}
|
|
26086
26211
|
if (matched) {
|
|
26087
|
-
inlineSetCookie = await
|
|
26212
|
+
inlineSetCookie = await pageSessionSetCookies(req, page.id, {
|
|
26088
26213
|
dev: isLocalhostRequest(req)
|
|
26089
26214
|
});
|
|
26090
26215
|
} else {
|
|
@@ -26111,7 +26236,7 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
|
|
|
26111
26236
|
}
|
|
26112
26237
|
if (isJsonRoute) {
|
|
26113
26238
|
res.setHeader("Cache-Control", "no-store");
|
|
26114
|
-
if (inlineSetCookie)
|
|
26239
|
+
if (inlineSetCookie.length > 0)
|
|
26115
26240
|
res.setHeader("Set-Cookie", inlineSetCookie);
|
|
26116
26241
|
publicPageJsonRoute.respond(res, 200, {
|
|
26117
26242
|
id: page.id,
|
|
@@ -26132,7 +26257,7 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
|
|
|
26132
26257
|
"X-Content-Type-Options": "nosniff",
|
|
26133
26258
|
"Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox"
|
|
26134
26259
|
};
|
|
26135
|
-
if (inlineSetCookie)
|
|
26260
|
+
if (inlineSetCookie.length > 0)
|
|
26136
26261
|
headers["Set-Cookie"] = inlineSetCookie;
|
|
26137
26262
|
res.writeHead(200, headers);
|
|
26138
26263
|
res.end(page.body);
|
|
@@ -26148,15 +26273,17 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
|
|
|
26148
26273
|
"Content-Security-Policy": buildCsp(),
|
|
26149
26274
|
"X-Content-Type-Options": "nosniff"
|
|
26150
26275
|
};
|
|
26151
|
-
if (inlineSetCookie)
|
|
26276
|
+
if (inlineSetCookie.length > 0)
|
|
26152
26277
|
headers["Set-Cookie"] = inlineSetCookie;
|
|
26153
26278
|
res.writeHead(200, headers);
|
|
26154
26279
|
res.end(printableJsonPageHtml(page));
|
|
26155
26280
|
await bumpViewCount(page.id);
|
|
26156
26281
|
return true;
|
|
26157
26282
|
}
|
|
26158
|
-
const headers = {
|
|
26159
|
-
|
|
26283
|
+
const headers = {
|
|
26284
|
+
Location: `${getAppBaseUrl2()}/pages/${page.id}`
|
|
26285
|
+
};
|
|
26286
|
+
if (inlineSetCookie.length > 0)
|
|
26160
26287
|
headers["Set-Cookie"] = inlineSetCookie;
|
|
26161
26288
|
res.writeHead(302, headers);
|
|
26162
26289
|
res.end();
|
|
@@ -26170,7 +26297,7 @@ async function handlePagesPublic(req, res, pathSegments, queryParams) {
|
|
|
26170
26297
|
"Content-Security-Policy": buildCsp(),
|
|
26171
26298
|
"X-Content-Type-Options": "nosniff"
|
|
26172
26299
|
};
|
|
26173
|
-
if (inlineSetCookie)
|
|
26300
|
+
if (inlineSetCookie.length > 0)
|
|
26174
26301
|
headers["Set-Cookie"] = inlineSetCookie;
|
|
26175
26302
|
res.writeHead(200, headers);
|
|
26176
26303
|
res.end(html);
|
|
@@ -31137,6 +31264,7 @@ var agentTaskBodySchema = object2({
|
|
|
31137
31264
|
routingNote: string2().max(200).optional(),
|
|
31138
31265
|
tags: array2(string2()).optional(),
|
|
31139
31266
|
priority: number2().int().min(0).max(100).optional(),
|
|
31267
|
+
dependsOn: array2(uuid()).optional(),
|
|
31140
31268
|
offerMode: boolean().optional(),
|
|
31141
31269
|
dir: string2().min(1).optional(),
|
|
31142
31270
|
vcsRepo: string2().min(1).optional(),
|
|
@@ -31617,6 +31745,7 @@ async function handleScriptRuns(req, res, pathSegments, queryParams, agentId) {
|
|
|
31617
31745
|
routingSource: parsed.body.routingReason ? "declared" : parsed.body.agentId ? "engine_default" : undefined,
|
|
31618
31746
|
tags: parsed.body.tags,
|
|
31619
31747
|
priority: parsed.body.priority,
|
|
31748
|
+
dependsOn: parsed.body.dependsOn,
|
|
31620
31749
|
offeredTo: parsed.body.offerMode ? parsed.body.agentId : undefined,
|
|
31621
31750
|
taskType: "script-run-step",
|
|
31622
31751
|
source: "mcp",
|
|
@@ -36569,7 +36698,17 @@ var deleteIdentityRoute = route({
|
|
|
36569
36698
|
},
|
|
36570
36699
|
auth: { apiKey: true }
|
|
36571
36700
|
});
|
|
36572
|
-
var UNMAPPED_KINDS = [
|
|
36701
|
+
var UNMAPPED_KINDS = [
|
|
36702
|
+
"slack",
|
|
36703
|
+
"github",
|
|
36704
|
+
"gitlab",
|
|
36705
|
+
"azure-devops",
|
|
36706
|
+
"linear",
|
|
36707
|
+
"kapso",
|
|
36708
|
+
"telegram",
|
|
36709
|
+
"discord",
|
|
36710
|
+
"teams"
|
|
36711
|
+
];
|
|
36573
36712
|
async function collectUnmappedForKind(kind, limit) {
|
|
36574
36713
|
const namespace = `integration:unmapped:${kind}`;
|
|
36575
36714
|
const rows = await listKv2(namespace, { limit: Math.min(limit * 2, 1000), offset: 0 });
|
|
@@ -39264,7 +39403,7 @@ var httpServer = createHttpServer(async (req, res) => {
|
|
|
39264
39403
|
});
|
|
39265
39404
|
});
|
|
39266
39405
|
var detachRealtime = attachRealtimeTransport(httpServer);
|
|
39267
|
-
var { attachControllerTransport } = await import("./controllers-connect-
|
|
39406
|
+
var { attachControllerTransport } = await import("./controllers-connect-9ftpex99.js");
|
|
39268
39407
|
var detachControllers = attachControllerTransport(httpServer);
|
|
39269
39408
|
var stopWorkerNudges = startWorkerNudgeListener();
|
|
39270
39409
|
var stopRoomDeletion = realtimeBus.subscribe("room:namespace-deleted", (namespace) => {
|
|
@@ -39293,7 +39432,7 @@ async function shutdown() {
|
|
|
39293
39432
|
sessionsProcessed: getServerSessionsProcessed()
|
|
39294
39433
|
});
|
|
39295
39434
|
if (hasCapability("scheduling")) {
|
|
39296
|
-
const { stopScheduler } = await import("./index-
|
|
39435
|
+
const { stopScheduler } = await import("./index-bgdyvcnv.js");
|
|
39297
39436
|
stopScheduler();
|
|
39298
39437
|
}
|
|
39299
39438
|
stopHeartbeat2();
|
|
@@ -39305,7 +39444,7 @@ async function shutdown() {
|
|
|
39305
39444
|
await stopSlackApp2();
|
|
39306
39445
|
await stopChatSdk();
|
|
39307
39446
|
if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
|
|
39308
|
-
const { stopOAuthKeepalive } = await import("./keepalive-
|
|
39447
|
+
const { stopOAuthKeepalive } = await import("./keepalive-7yrng7px.js");
|
|
39309
39448
|
await stopOAuthKeepalive();
|
|
39310
39449
|
}
|
|
39311
39450
|
stopOAuthPendingGc();
|
|
@@ -39385,21 +39524,21 @@ try {
|
|
|
39385
39524
|
console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
|
|
39386
39525
|
}
|
|
39387
39526
|
try {
|
|
39388
|
-
const { ensurePricingSeeded } = await import("./boot-seeds-
|
|
39527
|
+
const { ensurePricingSeeded } = await import("./boot-seeds-j2273s54.js");
|
|
39389
39528
|
ensurePricingSeeded();
|
|
39390
|
-
const { startPricingRefreshLoop } = await import("./pricing-refresh-
|
|
39529
|
+
const { startPricingRefreshLoop } = await import("./pricing-refresh-d2b5my0y.js");
|
|
39391
39530
|
startPricingRefreshLoop();
|
|
39392
39531
|
} catch (err) {
|
|
39393
39532
|
console.error("[startup] Failed to seed pricing rows:", err);
|
|
39394
39533
|
}
|
|
39395
39534
|
try {
|
|
39396
|
-
const { ensureModelProfilesSeeded } = await import("./boot-seeds-
|
|
39535
|
+
const { ensureModelProfilesSeeded } = await import("./boot-seeds-j2273s54.js");
|
|
39397
39536
|
await ensureModelProfilesSeeded();
|
|
39398
39537
|
} catch (err) {
|
|
39399
39538
|
console.error("[startup] Failed to seed model profiles:", err);
|
|
39400
39539
|
}
|
|
39401
39540
|
try {
|
|
39402
|
-
const { ensureRbacSeeded } = await import("./boot-seeds-
|
|
39541
|
+
const { ensureRbacSeeded } = await import("./boot-seeds-j2273s54.js");
|
|
39403
39542
|
ensureRbacSeeded();
|
|
39404
39543
|
} catch (err) {
|
|
39405
39544
|
console.error("[startup] Failed to sync RBAC seed rows:", err);
|
|
@@ -39407,7 +39546,7 @@ try {
|
|
|
39407
39546
|
throw err;
|
|
39408
39547
|
}
|
|
39409
39548
|
try {
|
|
39410
|
-
const { runAllSeeders } = await import("./index-
|
|
39549
|
+
const { runAllSeeders } = await import("./index-jwxkkex2.js");
|
|
39411
39550
|
await runAllSeeders({ scriptEmbeddingMode: "skip" });
|
|
39412
39551
|
} catch (err) {
|
|
39413
39552
|
console.error("[startup] Failed to seed built-in entities:", err);
|
|
@@ -39469,39 +39608,39 @@ httpServer.listen(port, async () => {
|
|
|
39469
39608
|
await initWorkflows2();
|
|
39470
39609
|
await startScriptRunSupervisor(getMcpBaseUrl());
|
|
39471
39610
|
if (hasCapability("scheduling")) {
|
|
39472
|
-
const { startScheduler } = await import("./index-
|
|
39473
|
-
const { getExecutorRegistry } = await import("./index-
|
|
39611
|
+
const { startScheduler } = await import("./index-bgdyvcnv.js");
|
|
39612
|
+
const { getExecutorRegistry } = await import("./index-gabbcdn2.js");
|
|
39474
39613
|
const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
|
|
39475
39614
|
startScheduler(getExecutorRegistry(), intervalMs, {
|
|
39476
39615
|
runId: globalState.__runId
|
|
39477
39616
|
});
|
|
39478
39617
|
}
|
|
39479
39618
|
if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
|
|
39480
|
-
const { startHeartbeat } = await import("./index-
|
|
39619
|
+
const { startHeartbeat } = await import("./index-tfb26zhy.js");
|
|
39481
39620
|
const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
|
|
39482
39621
|
startHeartbeat(heartbeatMs);
|
|
39483
39622
|
}
|
|
39484
39623
|
startPoolRouting();
|
|
39485
39624
|
startRuntimeSupervisor();
|
|
39486
39625
|
if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
|
|
39487
|
-
const { startOAuthKeepalive } = await import("./keepalive-
|
|
39626
|
+
const { startOAuthKeepalive } = await import("./keepalive-7yrng7px.js");
|
|
39488
39627
|
startOAuthKeepalive();
|
|
39489
39628
|
}
|
|
39490
39629
|
if (process.env.OAUTH_REFRESH_SWEEP_DISABLE !== "true") {
|
|
39491
|
-
const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-
|
|
39630
|
+
const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-yw3xdbcj.js");
|
|
39492
39631
|
startOAuthRefreshSweep();
|
|
39493
39632
|
}
|
|
39494
39633
|
startOAuthPendingGc();
|
|
39495
39634
|
await startMemoryGc();
|
|
39496
39635
|
await startDbRetention();
|
|
39497
39636
|
startHumanFreeDrain();
|
|
39498
|
-
import("./boot-reembed-
|
|
39637
|
+
import("./boot-reembed-b9c3az3c.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
|
|
39499
39638
|
console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
|
|
39500
39639
|
});
|
|
39501
|
-
import("./boot-reembed-
|
|
39640
|
+
import("./boot-reembed-qdkvxeem.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
|
|
39502
39641
|
console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
|
|
39503
39642
|
});
|
|
39504
|
-
import("./boot-scrub-sweep-
|
|
39643
|
+
import("./boot-scrub-sweep-m3wh8eks.js").then(({ runBootScrubSweep }) => runBootScrubSweep()).catch((err) => {
|
|
39505
39644
|
console.error("[boot-scrub-sweep] startup scrub failed (non-fatal):", err);
|
|
39506
39645
|
});
|
|
39507
39646
|
}).on("error", (err) => {
|