@desplega.ai/agent-swarm 2.0.0 → 2.1.0
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-sj2g0m84.js → acp-adapter-kr4abrsk.js} +10 -10
- package/dist/{actions-fegk44gr.js → actions-eh4g6w2r.js} +27 -27
- package/dist/{amp-adapter-ad8ft89x.js → amp-adapter-7h7wdt8q.js} +5 -5
- package/dist/{app-kfvgbvzy.js → app-7k8s9w5p.js} +9 -9
- package/dist/{assistant-z7zdy9ja.js → assistant-wswt2y7p.js} +28 -28
- package/dist/{boot-reembed-j8xa181e.js → boot-reembed-9apm9qw6.js} +7 -7
- package/dist/{boot-reembed-5c2z0mbe.js → boot-reembed-whzbdthj.js} +7 -7
- package/dist/{boot-scrub-sweep-hnkn3rgt.js → boot-scrub-sweep-ndzmvmgt.js} +8 -8
- package/dist/{boot-seeds-kwjq4d2z.js → boot-seeds-e9sta0yt.js} +13 -11
- package/dist/{claude-adapter-9vmvpvgd.js → claude-adapter-4mqd3r6r.js} +11 -11
- package/dist/{claude-managed-adapter-k9qae05j.js → claude-managed-adapter-9wswb52m.js} +3 -3
- package/dist/{claude-managed-setup-q54zx5q2.js → claude-managed-setup-tpe1effx.js} +4 -4
- package/dist/{claude-sdk-session-9jye6cxr.js → claude-sdk-session-q49ghmh9.js} +10340 -10197
- package/dist/{cli-ke896fcf.js → cli-01xvj1rq.js} +10 -10
- package/dist/{cli-tr4sxp68.js → cli-035vekcw.js} +2 -2
- package/dist/{cli-z5jjpaxw.js → cli-0pd8hzhc.js} +3 -3
- package/dist/{cli-n5vwg842.js → cli-0veb92a3.js} +6 -1
- package/dist/{cli-wayw93nt.js → cli-10jesr25.js} +3 -3
- package/dist/{cli-se8w6wny.js → cli-1y7yywmj.js} +1 -1
- package/dist/{cli-v1yb0rqb.js → cli-20krdhz5.js} +47 -19
- package/dist/{cli-d5f9ed5c.js → cli-29rja109.js} +39 -20
- package/dist/{cli-apx87jne.js → cli-2pwa0q4d.js} +15 -4
- package/dist/{cli-ee9gtz70.js → cli-4mengw46.js} +348 -25
- package/dist/{cli-03gedhng.js → cli-5twdke5x.js} +6 -6
- package/dist/{cli-6razj6t4.js → cli-711vwbxn.js} +2 -2
- package/dist/{cli-s2sp957d.js → cli-78vv7446.js} +1 -1
- package/dist/{cli-3fbmmawm.js → cli-7n6s5man.js} +4 -4
- package/dist/{cli-hnhtk6cj.js → cli-8wwxw8a3.js} +1 -1
- package/dist/{cli-hnmhtzvh.js → cli-9jzdj90z.js} +2 -0
- package/dist/{cli-skxvvpap.js → cli-cvv9k0hh.js} +28 -25
- package/dist/{cli-74ahz61x.js → cli-d9286m9h.js} +2 -2
- package/dist/{cli-4jxm2qtz.js → cli-gxzkg1de.js} +28 -16
- package/dist/{cli-zkpks3r3.js → cli-h1arqn31.js} +1 -1
- package/dist/{cli-r62a35ea.js → cli-hqr88ew6.js} +1 -1
- package/dist/{cli-ra0xzggj.js → cli-j67mh2vg.js} +2 -2
- package/dist/{cli-29jc5q7w.js → cli-ksphgh48.js} +2 -2
- package/dist/{cli-eejsgvm4.js → cli-mgz4nbgg.js} +4 -4
- package/dist/{cli-vatyhshy.js → cli-mz5as5ha.js} +4 -4
- package/dist/{cli-f7kr7svz.js → cli-n8ndw8j7.js} +2 -2
- package/dist/{cli-1e4b6bzh.js → cli-naqzr17j.js} +7 -7
- package/dist/{cli-q0ke1yww.js → cli-nm1p8jfr.js} +6 -6
- package/dist/{cli-m50t4309.js → cli-p3zbc1rw.js} +5 -5
- package/dist/{cli-cgtksawx.js → cli-pe05f8yk.js} +23 -3
- package/dist/{cli-vdach5a9.js → cli-qmzsbkvy.js} +4 -4
- package/dist/{cli-n3hzg89b.js → cli-qnm4e9e4.js} +57 -579
- package/dist/{cli-s4setq91.js → cli-qqy4q48b.js} +3 -3
- package/dist/{cli-k382tshb.js → cli-r35rw5de.js} +8 -7
- package/dist/{cli-k3dp5tpf.js → cli-r610p9bs.js} +2 -2
- package/dist/{cli-e6mpjhed.js → cli-rc6pf5kv.js} +1 -1
- package/dist/{cli-3dj8k4vy.js → cli-rdxm77k3.js} +1 -1
- package/dist/{cli-tqaazemc.js → cli-s69nfyeh.js} +1 -1
- package/dist/{cli-6jyj59nb.js → cli-sawv63e8.js} +2 -2
- package/dist/{cli-q50942rs.js → cli-sg19gbf0.js} +1 -1
- package/dist/{cli-p1x85d2t.js → cli-shk7r5cs.js} +12 -9
- package/dist/{cli-przpmdgr.js → cli-sksetb2q.js} +11 -1
- package/dist/{cli-d2qr7aj4.js → cli-t02z59f2.js} +1 -1
- package/dist/{cli-j0pfptdp.js → cli-v7g551te.js} +39 -43
- package/dist/{cli-bzszjf2p.js → cli-vgqzp4em.js} +519 -126
- package/dist/cli-wfnemr1t.js +86 -0
- package/dist/{cli-ne236afy.js → cli-wms6x9db.js} +8 -8
- package/dist/{cli-5hkm7whv.js → cli-x1r545x8.js} +1 -1
- package/dist/{cli-kt6zqg0e.js → cli-xczsgshn.js} +2 -2
- package/dist/{cli-ef1hg1wv.js → cli-y3167wt1.js} +430 -238
- package/dist/{cli-tsde1hdr.js → cli-yjmqpxt3.js} +12 -11
- package/dist/{cli-9nfx44eh.js → cli-z780ec7c.js} +1 -1
- package/dist/{cli-r2pnvj8g.js → cli-zm9t2vde.js} +2 -2
- package/dist/cli.js +24 -23
- package/dist/{codex-adapter-y81sssk0.js → codex-adapter-4z16v9n0.js} +8 -8
- package/dist/{codex-login-f2rcfpp9.js → codex-login-pkepy2j1.js} +2 -2
- package/dist/{codex-session-runner-8vx4j6a9.js → codex-session-runner-rvms9y2x.js} +8 -8
- package/dist/{commands-kcpvpcrr.js → commands-2a9rtyat.js} +8 -8
- package/dist/{controller-ywrmt6yd.js → controller-3k3madbn.js} +4 -4
- package/dist/{controllers-connect-kwpvj3rf.js → controllers-connect-v9yn8zb9.js} +30 -30
- package/dist/{cursor-adapter-cehv1qns.js → cursor-adapter-98gbhyzn.js} +4 -4
- package/dist/{db-ww5d7jq3.js → db-eywwsnjw.js} +9 -7
- package/dist/{db-k8ankj20.js → db-ncypk9np.js} +9 -9
- package/dist/{devin-adapter-x1022qb1.js → devin-adapter-zeq8b9gz.js} +2 -2
- package/dist/{dispatcher-e8gq5m68.js → dispatcher-w94kc575.js} +26 -26
- package/dist/{docker-ff6y1190.js → docker-b1e4cqab.js} +2 -2
- package/dist/{dsh-adapter-3epjm3af.js → dsh-adapter-47ztej36.js} +4 -4
- package/dist/{e2b-8ygwhg0f.js → e2b-bbt8ey45.js} +3 -3
- package/dist/{e2b-swhnpw3n.js → e2b-dp804sen.js} +3 -3
- package/dist/{event-bus-6axnngdj.js → event-bus-j2jdg3qb.js} +2 -2
- package/dist/{external-channel-h3359cwn.js → external-channel-zrkg8ar9.js} +8 -8
- package/dist/{grok-adapter-0d4x7gkx.js → grok-adapter-s9ncp9vy.js} +11 -11
- package/dist/{handlers-an1gzv21.js → handlers-kqftvjgw.js} +29 -29
- package/dist/{heartbeat-6dakeb61.js → heartbeat-9q96p8v9.js} +31 -31
- package/dist/{hook-6v6cv6d5.js → hook-56qe10dp.js} +7 -7
- package/dist/{hook-sa5xye4y.js → hook-yy6rw42k.js} +8 -8
- package/dist/{http-r7f3eky0.js → http-r2dnb8f8.js} +963 -75
- package/dist/{index-7ep4gzdk.js → index-3gtmkhc6.js} +26 -26
- package/dist/{index-v1v6n7hg.js → index-3k5hkz7r.js} +31 -31
- package/dist/{index-rmpw9a8q.js → index-5e101240.js} +26 -26
- package/dist/{index-s2wxgzr0.js → index-5wyfjc2c.js} +392 -15
- package/dist/{index-zk96aq1k.js → index-vxvhxxbn.js} +7 -7
- package/dist/{keepalive-be9vwy5h.js → keepalive-psj6j54c.js} +9 -9
- package/dist/{lead-0861cwrf.js → lead-hajz4688.js} +43 -43
- package/dist/{maintenance-mzzgc8bn.js → maintenance-ps02sb5m.js} +7 -7
- package/dist/{node-mn1zs7an.js → node-mwb5r697.js} +1 -1
- package/dist/{oauth-refresh-sweep-cpdnfwdj.js → oauth-refresh-sweep-0284h93b.js} +8 -8
- package/dist/{onboard-fh8qs4r3.js → onboard-rbf6bg01.js} +2 -2
- package/dist/{opencode-adapter-nm42wwj8.js → opencode-adapter-13dcatgq.js} +8 -8
- package/dist/{otel-impl-x6c1c9g4.js → otel-impl-zvqcbhp7.js} +2 -2
- package/dist/{pi-mono-adapter-9n2ya240.js → pi-mono-adapter-xxy47q4v.js} +7 -7
- package/dist/{pricing-refresh-qb0rv0ap.js → pricing-refresh-kefx9v3t.js} +9 -9
- package/dist/{rbac-roles-1gzdwbh1.js → rbac-roles-3m36rxm2.js} +8 -8
- package/dist/{rbac-roles-3mraey52.js → rbac-roles-z76xv0hq.js} +9 -9
- package/dist/{render-v2-agpa45zz.js → render-v2-wz73bs25.js} +9 -9
- package/dist/{resume-x0ydy9s9.js → resume-k4wzge8w.js} +14 -14
- package/dist/{setup-as9ga0d6.js → setup-2fp2pypp.js} +2 -2
- package/dist/{work-objects-y5g1y7ev.js → work-objects-6k0ywz3m.js} +29 -29
- package/dist/{worker-860c3e38.js → worker-5v3rxsdh.js} +43 -43
- package/dist/{x-m477fr0h.js → x-4mtdeym1.js} +2 -2
- package/openapi.json +777 -6
- package/package.json +8 -7
- package/src/agentmail/handlers.ts +21 -11
- package/src/apps/definition.ts +16 -0
- package/src/azure-devops/api.ts +52 -2
- package/src/azure-devops/boards-sync.ts +50 -20
- package/src/azure-devops/index.ts +1 -0
- package/src/azure-devops/outbound.ts +95 -0
- package/src/be/boot-seeds.ts +11 -0
- package/src/be/db/model-profiles.ts +315 -0
- package/src/be/db/tasks/read.ts +7 -0
- package/src/be/db.ts +53 -47
- package/src/be/migrations/219_relabel_pi_context_compactions.sql +22 -0
- package/src/be/migrations/220_model_profiles.sql +137 -0
- package/src/be/model-tier-resolution.ts +145 -11
- package/src/be/model-validation.ts +8 -1
- package/src/be/scripts/typecheck.ts +12 -0
- package/src/be/secret-registry.ts +6 -2
- package/src/be/seed-model-profiles.ts +41 -0
- package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +368 -0
- package/src/be/seed-scripts/index.ts +9 -0
- package/src/be/swarm-config-guard.ts +1 -0
- package/src/commands/runner.ts +3 -17
- package/src/extensions/catalog.generated.json +17 -0
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/extensions/loader.ts +10 -5
- package/src/heartbeat/heartbeat.ts +2 -1
- package/src/http/agents.ts +49 -2
- package/src/http/all-routes.ts +1 -0
- package/src/http/apps.ts +30 -3
- package/src/http/config.ts +26 -2
- package/src/http/core.ts +4 -0
- package/src/http/index.ts +11 -1
- package/src/http/model-profiles.ts +303 -0
- package/src/http/pages-public.ts +11 -5
- package/src/http/poll.ts +16 -5
- package/src/http/script-runs.ts +1 -1
- package/src/http/scripts.ts +25 -2
- package/src/http/tasks.ts +18 -0
- package/src/http/webhooks.ts +1 -2
- package/src/pages/feedback-overlay.ts +65 -6
- package/src/providers/acp-targets.ts +1 -1
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/dsh-adapter.ts +1 -1
- package/src/providers/pi-mono-extension.ts +17 -3
- package/src/providers/reasoning-effort.ts +10 -0
- package/src/rbac/legacy-policy.ts +8 -0
- package/src/rbac/permissions.ts +5 -0
- package/src/scheduler/deferred-task-waits.ts +18 -5
- package/src/scheduler/scheduler.ts +7 -1
- package/src/scripts-runtime/executors/quickjs-prelude.ts +75 -6
- package/src/scripts-runtime/executors/quickjs-runner.ts +85 -8
- package/src/scripts-runtime/executors/quickjs-web-shims.ts +1041 -0
- package/src/scripts-runtime/extract-args-schema.ts +9 -8
- package/src/scripts-runtime/quickjs-compat.ts +464 -0
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/types/stdlib.d.ts +12 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +12 -0
- package/src/server.ts +10 -1
- package/src/slack/blocks.ts +4 -2
- package/src/slack/reaction-shortcode.ts +14 -0
- package/src/slack/render-v2.ts +12 -7
- package/src/slack/responses.ts +5 -4
- package/src/slack/thread-buffer.ts +41 -22
- package/src/tasks/worker-follow-up.ts +11 -2
- package/src/tests/agentmail-filters.test.ts +47 -0
- package/src/tests/apps-spike2.test.ts +35 -0
- package/src/tests/azure-devops-outbound.test.ts +420 -0
- package/src/tests/db-task-read-contract.test.ts +2 -0
- package/src/tests/db-task-write-contract.test.ts +1 -0
- package/src/tests/deferred-task-wake.test.ts +78 -1
- package/src/tests/docs-index-footprint.test.js +2 -2
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/env-flag.test.ts +1 -0
- package/src/tests/extensions-catalog.test.ts +1 -0
- package/src/tests/extensions-example-comms-adherence-gate.test.ts +413 -0
- package/src/tests/extensions-loader.test.ts +15 -0
- package/src/tests/heartbeat-jev-gate-credentials.test.ts +168 -0
- package/src/tests/heartbeat-jev-gate.test.ts +385 -0
- package/src/tests/model-profile-backcompat.test.ts +327 -0
- package/src/tests/model-profile-providers.test.ts +302 -0
- package/src/tests/model-profile-runtime-secrets.test.ts +223 -0
- package/src/tests/model-profiles-api.test.ts +614 -0
- package/src/tests/pages-feedback-keys.test.ts +121 -0
- package/src/tests/pages-feedback.test.ts +3 -0
- package/src/tests/pi-context-compaction.test.ts +193 -0
- package/src/tests/profile-claim.test.ts +269 -0
- package/src/tests/quickjs-compat.test.ts +213 -0
- package/src/tests/rbac-engine.test.ts +21 -0
- package/src/tests/script-connections.test.ts +4 -0
- package/src/tests/script-executor-conformance.test.ts +252 -1
- package/src/tests/script-executor-quickjs.test.ts +96 -0
- package/src/tests/script-runs-http.test.ts +89 -0
- package/src/tests/scripts-http.test.ts +16 -0
- package/src/tests/secret-scrubber.test.ts +10 -0
- package/src/tests/seed-model-profiles.test.ts +174 -0
- package/src/tests/seed-scripts.test.ts +2 -2
- package/src/tests/skill-invocations.test.ts +4 -2
- package/src/tests/slack-blocks.test.ts +36 -0
- package/src/tests/slack-inline-output.test.ts +14 -0
- package/src/tests/slack-reaction-config.test.ts +20 -0
- package/src/tests/slack-render-v2.test.ts +37 -0
- package/src/tests/slack-thread-buffer.test.ts +98 -1
- package/src/tests/workflow-llm.test.ts +61 -0
- package/src/tools/model-profiles/list-model-profiles.ts +54 -0
- package/src/tools/request-human-input.ts +11 -3
- package/src/tools/script-apis.ts +5 -1
- package/src/tools/script-upsert.ts +4 -1
- package/src/tools/send-task.ts +24 -1
- package/src/tools/system-one-decide.ts +104 -0
- package/src/tools/task-action.ts +22 -1
- package/src/tools/tool-config.ts +6 -0
- package/src/types.ts +36 -1
- package/src/utils/secret-scrubber.ts +19 -12
- package/src/utils/vcs-repo-match.ts +29 -0
- package/src/workflows/executors/raw-llm.ts +8 -3
- package/src/workflows/executors/system-one-decision.ts +21 -11
- package/src/workflows/executors/workflow-llm.ts +22 -0
- package/src/workflows/index.ts +21 -12
- package/templates/extensions/README.md +1 -0
- package/templates/extensions/comms-adherence-gate/README.md +88 -0
- package/templates/extensions/comms-adherence-gate/hooks.ts +489 -0
- package/templates/extensions/comms-adherence-gate/manifest.json +8 -0
- package/dist/cli-5t4f29ez.js +0 -33
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./cli-ep19k3mb.js";
|
|
4
4
|
import {
|
|
5
5
|
agentFsProvisionSeeder
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-zm9t2vde.js";
|
|
7
7
|
import {
|
|
8
8
|
extractArgsJsonSchema,
|
|
9
9
|
extractScriptSignature,
|
|
@@ -11,29 +11,29 @@ import {
|
|
|
11
11
|
require_dist,
|
|
12
12
|
typecheckScript,
|
|
13
13
|
validateScriptImports
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-4mengw46.js";
|
|
15
15
|
import"./cli-epan13p1.js";
|
|
16
16
|
import"./cli-zt3w1cn1.js";
|
|
17
|
-
import"./cli-
|
|
17
|
+
import"./cli-711vwbxn.js";
|
|
18
18
|
import {
|
|
19
19
|
validateDefinition
|
|
20
|
-
} from "./cli-
|
|
21
|
-
import"./cli-
|
|
22
|
-
import"./cli-
|
|
20
|
+
} from "./cli-20krdhz5.js";
|
|
21
|
+
import"./cli-1y7yywmj.js";
|
|
22
|
+
import"./cli-rc6pf5kv.js";
|
|
23
23
|
import"./cli-2x0e561b.js";
|
|
24
24
|
import"./cli-txqb9s38.js";
|
|
25
25
|
import"./cli-h6vtvt5c.js";
|
|
26
26
|
import"./cli-bsakbbkm.js";
|
|
27
27
|
import"./cli-zxg80zs9.js";
|
|
28
28
|
import"./cli-ydt3zkwv.js";
|
|
29
|
-
import"./cli-
|
|
29
|
+
import"./cli-cvv9k0hh.js";
|
|
30
30
|
import"./cli-n2wq4j7m.js";
|
|
31
31
|
import"./cli-wmgrkscj.js";
|
|
32
32
|
import"./cli-3er6gcsn.js";
|
|
33
33
|
import"./cli-hjwmhcg1.js";
|
|
34
34
|
import"./cli-rhs9pz33.js";
|
|
35
35
|
import"./cli-9ha6hs2d.js";
|
|
36
|
-
import"./cli-
|
|
36
|
+
import"./cli-r610p9bs.js";
|
|
37
37
|
import"./cli-61625k3x.js";
|
|
38
38
|
import"./cli-1m2e086m.js";
|
|
39
39
|
import"./cli-btbzvq95.js";
|
|
@@ -61,13 +61,13 @@ import {
|
|
|
61
61
|
updateWorkflow,
|
|
62
62
|
upsertScriptByName,
|
|
63
63
|
upsertSkillFiles
|
|
64
|
-
} from "./cli-
|
|
65
|
-
import"./cli-
|
|
66
|
-
import"./cli-
|
|
67
|
-
import"./cli-
|
|
64
|
+
} from "./cli-y3167wt1.js";
|
|
65
|
+
import"./cli-9jzdj90z.js";
|
|
66
|
+
import"./cli-pe05f8yk.js";
|
|
67
|
+
import"./cli-78vv7446.js";
|
|
68
68
|
import"./cli-dmtrxqhg.js";
|
|
69
69
|
import"./cli-7mm2r1kp.js";
|
|
70
|
-
import"./cli-
|
|
70
|
+
import"./cli-x1r545x8.js";
|
|
71
71
|
import"./cli-mvzyxwg3.js";
|
|
72
72
|
import"./cli-fdvbjtbw.js";
|
|
73
73
|
import"./cli-ywybs5as.js";
|
|
@@ -78,12 +78,12 @@ import"./cli-stfs0k5s.js";
|
|
|
78
78
|
import"./cli-sd0mxa3c.js";
|
|
79
79
|
import"./cli-w5e1d1vv.js";
|
|
80
80
|
import"./cli-p0sg24zp.js";
|
|
81
|
-
import"./cli-
|
|
81
|
+
import"./cli-r35rw5de.js";
|
|
82
82
|
import"./cli-zf8jjwex.js";
|
|
83
83
|
import"./cli-gd4favx9.js";
|
|
84
84
|
import"./cli-ej6gbxfb.js";
|
|
85
85
|
import"./cli-a1b9b32n.js";
|
|
86
|
-
import"./cli-
|
|
86
|
+
import"./cli-shk7r5cs.js";
|
|
87
87
|
import"./cli-e3g5mbkz.js";
|
|
88
88
|
import {
|
|
89
89
|
__toESM
|
|
@@ -2591,6 +2591,377 @@ export default async function groupCount(args: any, _ctx: any) {
|
|
|
2591
2591
|
}
|
|
2592
2592
|
`;
|
|
2593
2593
|
|
|
2594
|
+
// src/be/seed-scripts/catalog/heartbeat-jev-gate.ts
|
|
2595
|
+
var heartbeat_jev_gate_default = `import { z } from "zod";
|
|
2596
|
+
|
|
2597
|
+
export const argsSchema = z.object({
|
|
2598
|
+
leadAgentId: z.string().optional().describe("Lead agent id; the heartbeat passes it"),
|
|
2599
|
+
dryRun: z
|
|
2600
|
+
.boolean()
|
|
2601
|
+
.optional()
|
|
2602
|
+
.describe(
|
|
2603
|
+
"Return the verdict, the compact state and the prompt it would create, without creating a prompt or writing KV",
|
|
2604
|
+
),
|
|
2605
|
+
threshold: z
|
|
2606
|
+
.number()
|
|
2607
|
+
.min(0)
|
|
2608
|
+
.max(1)
|
|
2609
|
+
.optional()
|
|
2610
|
+
.describe("Quiet when Jev's p(needs action) is below this (default 0.5)"),
|
|
2611
|
+
provider: z
|
|
2612
|
+
.enum(["auto", "typesafe", "openrouter"])
|
|
2613
|
+
.optional()
|
|
2614
|
+
.describe("Jev host; auto prefers TypeSafe (default auto)"),
|
|
2615
|
+
timeZone: z
|
|
2616
|
+
.string()
|
|
2617
|
+
.optional()
|
|
2618
|
+
.describe("IANA time zone for the state's current time and dates (default UTC)"),
|
|
2619
|
+
jevTimeoutMs: z
|
|
2620
|
+
.number()
|
|
2621
|
+
.int()
|
|
2622
|
+
.min(1_000)
|
|
2623
|
+
.max(45_000)
|
|
2624
|
+
.optional()
|
|
2625
|
+
.describe("Abandon the Jev call after this many ms (default 25000); the gate deadline is 60 s"),
|
|
2626
|
+
});
|
|
2627
|
+
|
|
2628
|
+
const KV_NAMESPACE = "heartbeat-jev-gate";
|
|
2629
|
+
const KV_KEY = "setup";
|
|
2630
|
+
// Measured per decision in the 2026-10-15 heartbeat replay (229 states).
|
|
2631
|
+
const COST_PER_DECISION = "$0.00004";
|
|
2632
|
+
|
|
2633
|
+
// Jev is called through \`ctx.swarm.systemOne_decide\`: the API server reads the
|
|
2634
|
+
// key and sends the request, so no key ever enters this script's realm. The
|
|
2635
|
+
// server also refuses OpenRouter when the effective OPENROUTER_BASE_URL (stored
|
|
2636
|
+
// config or deployment env) points at a gateway.
|
|
2637
|
+
const PROVIDERS = {
|
|
2638
|
+
typesafe: { keyName: "TYPESAFE_API_KEY", model: "jev-latest" },
|
|
2639
|
+
openrouter: { keyName: "OPENROUTER_API_KEY", model: "~typesafe/jev-latest" },
|
|
2640
|
+
} as const;
|
|
2641
|
+
type ProviderId = keyof typeof PROVIDERS;
|
|
2642
|
+
|
|
2643
|
+
// Worded exactly as in the replay that set the 0.5 threshold; changing it voids that result.
|
|
2644
|
+
const QUESTIONS = {
|
|
2645
|
+
act: {
|
|
2646
|
+
type: "noul",
|
|
2647
|
+
instructions:
|
|
2648
|
+
"This is a 30-minute heartbeat for the Lead agent of an AI agent swarm. Does this state require the Lead to take an action now: message a human, dispatch, resume or fix a task, or act on a tracked item that is due now? Answer false when nothing changed since the previous heartbeat and every failure is already triaged or owned.",
|
|
2649
|
+
criteria: {
|
|
2650
|
+
true: "A new untriaged failure, a tracked item or human ask due now and not yet done, or a problem with no owner",
|
|
2651
|
+
false:
|
|
2652
|
+
"Same state as the previous heartbeat, failures already triaged or owned, nothing due now",
|
|
2653
|
+
},
|
|
2654
|
+
},
|
|
2655
|
+
};
|
|
2656
|
+
|
|
2657
|
+
type SetupState = {
|
|
2658
|
+
status: "asked" | "approved" | "declined" | "expired";
|
|
2659
|
+
requestId?: string;
|
|
2660
|
+
url?: string;
|
|
2661
|
+
askedAt?: string;
|
|
2662
|
+
resolvedAt?: string;
|
|
2663
|
+
};
|
|
2664
|
+
|
|
2665
|
+
function rows(res: any): any[] {
|
|
2666
|
+
const p = res?.data ?? res;
|
|
2667
|
+
if (p?.error) throw new Error(\`db_query: \${String(p.error).slice(0, 200)}\`);
|
|
2668
|
+
if (!Array.isArray(p?.rows)) throw new Error("db_query returned no rows array");
|
|
2669
|
+
const cols: string[] = p.columns ?? [];
|
|
2670
|
+
return p.rows.map((r: any) =>
|
|
2671
|
+
Array.isArray(r) ? Object.fromEntries(cols.map((c, i) => [c, r[i]])) : r,
|
|
2672
|
+
);
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
const oneLine = (s: unknown) => String(s ?? "").replace(/\\s+/g, " ");
|
|
2676
|
+
|
|
2677
|
+
/** \`YYYY-MM-DD HH:MM\` in the zone, falling back to UTC when the runtime has no Intl zone data. */
|
|
2678
|
+
function localStamp(ms: number, timeZone: string): { stamp: string; zone: string } {
|
|
2679
|
+
const utc = { stamp: new Date(ms).toISOString().slice(0, 16).replace("T", " "), zone: "UTC" };
|
|
2680
|
+
if (timeZone === "UTC") return utc;
|
|
2681
|
+
try {
|
|
2682
|
+
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
2683
|
+
timeZone,
|
|
2684
|
+
year: "numeric",
|
|
2685
|
+
month: "2-digit",
|
|
2686
|
+
day: "2-digit",
|
|
2687
|
+
hour: "2-digit",
|
|
2688
|
+
minute: "2-digit",
|
|
2689
|
+
hourCycle: "h23",
|
|
2690
|
+
}).formatToParts(new Date(ms));
|
|
2691
|
+
const v = (t: string) => parts.find((p) => p.type === t)?.value ?? "";
|
|
2692
|
+
return { stamp: \`\${v("year")}-\${v("month")}-\${v("day")} \${v("hour")}:\${v("minute")}\`, zone: timeZone };
|
|
2693
|
+
} catch {
|
|
2694
|
+
return utc;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
// The checklist task renders failures as these lines (gatherSystemStatus in
|
|
2699
|
+
// src/heartbeat/heartbeat.ts). The replay parsed them with this regex, so the
|
|
2700
|
+
// gate renders and parses the same way to keep its fields identical.
|
|
2701
|
+
const FAILURE_LINE_RE =
|
|
2702
|
+
/- \\[([0-9a-f]{8})\\] "([\\s\\S]*?)" — agent: ([0-9a-f]{8}), reason: ([\\s\\S]*?), at: (\\S+)/g;
|
|
2703
|
+
|
|
2704
|
+
function parseFailures(status: string): { id: string; what: string; reason: string }[] {
|
|
2705
|
+
const out: { id: string; what: string; reason: string }[] = [];
|
|
2706
|
+
for (const m of status.matchAll(FAILURE_LINE_RE)) {
|
|
2707
|
+
out.push({
|
|
2708
|
+
id: m[1] ?? "",
|
|
2709
|
+
what: oneLine(m[2]).slice(0, 90),
|
|
2710
|
+
reason: oneLine(m[4]).slice(0, 140),
|
|
2711
|
+
});
|
|
2712
|
+
}
|
|
2713
|
+
return out;
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
function renderFailureLine(t: any): string {
|
|
2717
|
+
const agent = t.agentId ? String(t.agentId).slice(0, 8) : "unassigned";
|
|
2718
|
+
const reason = t.failureReason ? String(t.failureReason).slice(0, 100) : "no reason";
|
|
2719
|
+
return \`- [\${String(t.id).slice(0, 8)}] "\${String(t.task ?? "").slice(0, 50)}" — agent: \${agent}, reason: \${reason}, at: \${t.finishedAt}\`;
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
/**
|
|
2723
|
+
* The compact state Jev scores: the fields of the 2026-10-15 replay, built from
|
|
2724
|
+
* live data because the checklist task body does not exist yet at gate time.
|
|
2725
|
+
*/
|
|
2726
|
+
async function buildState(ctx: any, leadId: string, nowMs: number, timeZone: string) {
|
|
2727
|
+
const q = async (sql: string, params: unknown[] = []) =>
|
|
2728
|
+
rows(await ctx.swarm.db_query({ sql, params }));
|
|
2729
|
+
const since6h = new Date(nowMs - 6 * 3600e3).toISOString();
|
|
2730
|
+
const since24h = new Date(nowMs - 24 * 3600e3).toISOString();
|
|
2731
|
+
// Sequential: db_query caps concurrent queries per caller, and parallel reads fail with
|
|
2732
|
+
// db_query_concurrency_cap on a busy swarm.
|
|
2733
|
+
const lead = await q("SELECT heartbeatMd FROM agents WHERE id = ?", [leadId]);
|
|
2734
|
+
const prev = await q(
|
|
2735
|
+
\`SELECT id, substr(output, 1, 400) AS output,
|
|
2736
|
+
substr(task, 1, instr(task, '## Your Standing Orders')) AS status
|
|
2737
|
+
FROM agent_tasks
|
|
2738
|
+
WHERE agentId = ? AND taskType = 'heartbeat-checklist' AND status = 'completed'
|
|
2739
|
+
ORDER BY createdAt DESC LIMIT 1\`,
|
|
2740
|
+
[leadId],
|
|
2741
|
+
);
|
|
2742
|
+
const failed = await q(
|
|
2743
|
+
\`SELECT id, agentId, substr(task, 1, 60) AS task, substr(failureReason, 1, 120) AS failureReason, finishedAt
|
|
2744
|
+
FROM agent_tasks WHERE status = 'failed' AND finishedAt > ?
|
|
2745
|
+
ORDER BY finishedAt DESC LIMIT 10\`,
|
|
2746
|
+
[since6h],
|
|
2747
|
+
);
|
|
2748
|
+
const overview = await q(
|
|
2749
|
+
\`SELECT SUM(status = 'in_progress') AS inProgress, SUM(status = 'pending') AS pending,
|
|
2750
|
+
SUM(status = 'unassigned') AS unassigned,
|
|
2751
|
+
SUM(status = 'completed' AND finishedAt > ?) AS completed24,
|
|
2752
|
+
SUM(status = 'failed' AND finishedAt > ?) AS failed24
|
|
2753
|
+
FROM agent_tasks\`,
|
|
2754
|
+
[since24h, since24h],
|
|
2755
|
+
);
|
|
2756
|
+
const agents = await q(
|
|
2757
|
+
"SELECT status, COUNT(*) AS n FROM agents WHERE COALESCE(role, '') != 'extension' GROUP BY status",
|
|
2758
|
+
);
|
|
2759
|
+
|
|
2760
|
+
const fails = parseFailures(failed.map(renderFailureLine).join("\\n"));
|
|
2761
|
+
const prevIds = new Set(parseFailures(String(prev[0]?.status ?? "")).map((f) => f.id));
|
|
2762
|
+
const newFails = fails.filter((f) => !prevIds.has(f.id));
|
|
2763
|
+
|
|
2764
|
+
const { stamp, zone } = localStamp(nowMs, timeZone);
|
|
2765
|
+
const mmdd = new Date(nowMs).toISOString().slice(5, 10);
|
|
2766
|
+
const mmddLocal = stamp.slice(5, 10);
|
|
2767
|
+
const due: string[] = [];
|
|
2768
|
+
for (const line of String(lead[0]?.heartbeatMd ?? "").split("\\n")) {
|
|
2769
|
+
const l = line.trim();
|
|
2770
|
+
if (!l) continue;
|
|
2771
|
+
const del = /DELETE <?(\\d\\d-\\d\\d)>?/.exec(l);
|
|
2772
|
+
if (l.includes(mmdd) || l.includes(mmddLocal) || (del?.[1] && del[1] <= mmddLocal)) {
|
|
2773
|
+
due.push(oneLine(l).slice(0, 200));
|
|
2774
|
+
}
|
|
2775
|
+
if (due.length >= 6) break;
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
const o = overview[0] ?? {};
|
|
2779
|
+
const n = (v: unknown) => Number(v ?? 0) || 0;
|
|
2780
|
+
const count = (s: string) => n(agents.find((a) => a.status === s)?.n);
|
|
2781
|
+
const idle = count("idle");
|
|
2782
|
+
const busy = count("busy");
|
|
2783
|
+
|
|
2784
|
+
return {
|
|
2785
|
+
now: \`\${stamp} \${zone}\`,
|
|
2786
|
+
new_failures_since_previous_heartbeat: newFails.length
|
|
2787
|
+
? newFails.map((f) => \`\${f.id}: \${f.what} | \${f.reason}\`)
|
|
2788
|
+
: "none",
|
|
2789
|
+
tracked_items_mentioning_today_or_past_delete_date: due.length ? due : "none",
|
|
2790
|
+
previous_heartbeat_result: prev[0]?.output
|
|
2791
|
+
? oneLine(prev[0].output).slice(0, 350)
|
|
2792
|
+
: "unknown",
|
|
2793
|
+
failures_last_6h_total: fails.length,
|
|
2794
|
+
task_overview: \`- In Progress: \${n(o.inProgress)} - Pending: \${n(o.pending)} - Unassigned: \${n(o.unassigned)} - Completed (24h): \${n(o.completed24)} - Failed (24h): \${n(o.failed24)}\`,
|
|
2795
|
+
agents: \`- Online: \${idle + busy} (\${idle} idle, \${busy} busy), Offline: \${count("offline")}\`,
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
|
|
2799
|
+
function setupPrompt(keys: string[]) {
|
|
2800
|
+
return {
|
|
2801
|
+
title: "Heartbeat Jev gate: add a Jev credential or decline",
|
|
2802
|
+
detached: true,
|
|
2803
|
+
questions: [
|
|
2804
|
+
{
|
|
2805
|
+
id: "enable",
|
|
2806
|
+
type: "approval",
|
|
2807
|
+
label: "Enable the Jev heartbeat gate?",
|
|
2808
|
+
description: [
|
|
2809
|
+
"Before each recurring heartbeat checklist, the \`heartbeat-jev-gate\` script sends a short summary of swarm state (about 1,500 characters: new failures, due tracked items, task and agent counts) to Jev, a small decision model by TypeSafe, and asks whether the Lead needs to act. With \`HEARTBEAT_CHECKLIST_GATE_MODE=enforce\`, quiet ticks skip the Lead's checklist task.",
|
|
2810
|
+
"",
|
|
2811
|
+
\`Cost: about \${COST_PER_DECISION} per decision, one decision per checklist tick.\`,
|
|
2812
|
+
"",
|
|
2813
|
+
\`No Jev credential is configured. To enable, approve and add one of \${keys.map((k) => \`\\\`\${k}\\\`\`).join(" or ")} as a global secret on the Secrets page (Settings > Secrets). Do not paste the key here. The next tick picks it up.\`,
|
|
2814
|
+
"",
|
|
2815
|
+
"Reject to decline. The gate then stays inactive, with no further prompts, until a key is added.",
|
|
2816
|
+
].join("\\n"),
|
|
2817
|
+
},
|
|
2818
|
+
],
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
/**
|
|
2823
|
+
* Heartbeat checklist gate backed by Jev: asks Jev whether a recurring checklist
|
|
2824
|
+
* tick needs the Lead and returns { quiet, reason, summary }. With no Jev
|
|
2825
|
+
* credential it asks a human once, then stays a no-op until a key is added.
|
|
2826
|
+
*/
|
|
2827
|
+
export default async function heartbeatJevGate(args: any, ctx: any) {
|
|
2828
|
+
const parsed = argsSchema.safeParse(args ?? {});
|
|
2829
|
+
if (!parsed.success) throw new Error(\`invalid args: \${parsed.error.message.slice(0, 200)}\`);
|
|
2830
|
+
const a = parsed.data;
|
|
2831
|
+
const dryRun = a.dryRun === true;
|
|
2832
|
+
|
|
2833
|
+
const agentInfo: any = a.leadAgentId ? null : await ctx.swarm.agent_info();
|
|
2834
|
+
const leadId = String(a.leadAgentId ?? agentInfo?.data?.id ?? agentInfo?.id ?? "");
|
|
2835
|
+
if (!leadId) throw new Error("no leadAgentId");
|
|
2836
|
+
|
|
2837
|
+
// Values of secret rows come back masked: presence is all this script reads.
|
|
2838
|
+
const cfgRes: any = await ctx.swarm.config_get({ agentId: leadId });
|
|
2839
|
+
const configs: any[] = cfgRes?.data?.configs ?? cfgRes?.configs ?? [];
|
|
2840
|
+
const cfg = (key: string): string => {
|
|
2841
|
+
const value = configs.find((c) => c?.key === key)?.value;
|
|
2842
|
+
return typeof value === "string" ? value.trim() : "";
|
|
2843
|
+
};
|
|
2844
|
+
|
|
2845
|
+
const cfgThreshold = Number.parseFloat(cfg("HEARTBEAT_JEV_GATE_THRESHOLD"));
|
|
2846
|
+
const threshold =
|
|
2847
|
+
a.threshold ?? (cfgThreshold >= 0 && cfgThreshold <= 1 ? cfgThreshold : 0.5);
|
|
2848
|
+
const providerPref = a.provider ?? (cfg("HEARTBEAT_JEV_GATE_PROVIDER").toLowerCase() || "auto");
|
|
2849
|
+
const timeZone = a.timeZone ?? (cfg("HEARTBEAT_JEV_GATE_TIMEZONE") || "UTC");
|
|
2850
|
+
|
|
2851
|
+
const usable: Record<ProviderId, boolean> = {
|
|
2852
|
+
typesafe: cfg(PROVIDERS.typesafe.keyName) !== "",
|
|
2853
|
+
openrouter: cfg(PROVIDERS.openrouter.keyName) !== "",
|
|
2854
|
+
};
|
|
2855
|
+
const candidates: ProviderId[] =
|
|
2856
|
+
providerPref === "typesafe"
|
|
2857
|
+
? ["typesafe"]
|
|
2858
|
+
: providerPref === "openrouter"
|
|
2859
|
+
? ["openrouter"]
|
|
2860
|
+
: ["typesafe", "openrouter"];
|
|
2861
|
+
const provider = candidates.find((id) => usable[id]);
|
|
2862
|
+
|
|
2863
|
+
if (!provider) {
|
|
2864
|
+
const keys = candidates.map((id) => PROVIDERS[id].keyName);
|
|
2865
|
+
const inactive = (state: string, extra: Record<string, unknown> = {}) => ({
|
|
2866
|
+
quiet: false,
|
|
2867
|
+
reason: \`jev-gate inactive: \${state}\`.slice(0, 300),
|
|
2868
|
+
...(dryRun ? { dryRun: true, ...extra } : {}),
|
|
2869
|
+
});
|
|
2870
|
+
const entry: any = await ctx.swarm.kv_getOrNull({ namespace: KV_NAMESPACE, key: KV_KEY });
|
|
2871
|
+
const stored = entry?.value;
|
|
2872
|
+
let setup: SetupState | null = typeof stored === "string" ? JSON.parse(stored) : (stored ?? null);
|
|
2873
|
+
|
|
2874
|
+
if (!setup) {
|
|
2875
|
+
const prompt = setupPrompt(keys);
|
|
2876
|
+
if (dryRun) {
|
|
2877
|
+
const state = await buildState(ctx, leadId, Date.now(), timeZone);
|
|
2878
|
+
return inactive("no credential, would ask a human", { prompt, state });
|
|
2879
|
+
}
|
|
2880
|
+
const res: any = await ctx.swarm.request_humanInput(prompt);
|
|
2881
|
+
const requestId = res?.data?.requestId ?? res?.requestId;
|
|
2882
|
+
if (!requestId) throw new Error("request_humanInput returned no requestId");
|
|
2883
|
+
setup = {
|
|
2884
|
+
status: "asked",
|
|
2885
|
+
requestId,
|
|
2886
|
+
url: res?.data?.url ?? res?.url,
|
|
2887
|
+
askedAt: new Date().toISOString(),
|
|
2888
|
+
};
|
|
2889
|
+
await ctx.swarm.kv_set({ namespace: KV_NAMESPACE, key: KV_KEY, value: setup });
|
|
2890
|
+
return inactive(\`no credential, asked a human (approval request \${requestId})\`);
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2893
|
+
if (setup.status === "asked" && setup.requestId) {
|
|
2894
|
+
const [req] = rows(
|
|
2895
|
+
await ctx.swarm.db_query({
|
|
2896
|
+
sql: "SELECT status FROM approval_requests WHERE id = ?",
|
|
2897
|
+
params: [setup.requestId],
|
|
2898
|
+
}),
|
|
2899
|
+
);
|
|
2900
|
+
const status = String(req?.status ?? "missing");
|
|
2901
|
+
if (status === "pending") {
|
|
2902
|
+
return inactive(\`no credential, awaiting answer on approval request \${setup.requestId}\`);
|
|
2903
|
+
}
|
|
2904
|
+
const next: SetupState["status"] =
|
|
2905
|
+
status === "approved" ? "approved" : status === "rejected" ? "declined" : "expired";
|
|
2906
|
+
setup = { ...setup, status: next, resolvedAt: new Date().toISOString() };
|
|
2907
|
+
if (!dryRun) await ctx.swarm.kv_set({ namespace: KV_NAMESPACE, key: KV_KEY, value: setup });
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
const why =
|
|
2911
|
+
setup.status === "approved"
|
|
2912
|
+
? \`approved, waiting for \${keys.join(" or ")} on the Secrets page\`
|
|
2913
|
+
: setup.status === "declined"
|
|
2914
|
+
? \`declined; add \${keys.join(" or ")} to enable\`
|
|
2915
|
+
: \`setup request expired unanswered; add \${keys.join(" or ")} to enable\`;
|
|
2916
|
+
return inactive(why, { setup });
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
const target = PROVIDERS[provider];
|
|
2920
|
+
const state = await buildState(ctx, leadId, Date.now(), timeZone);
|
|
2921
|
+
|
|
2922
|
+
// The server enforces the time budget. No retries, as in the replay.
|
|
2923
|
+
const res: any = await ctx.swarm.systemOne_decide({
|
|
2924
|
+
provider,
|
|
2925
|
+
model: target.model,
|
|
2926
|
+
state,
|
|
2927
|
+
questions: QUESTIONS,
|
|
2928
|
+
timeoutMs: a.jevTimeoutMs ?? 25_000,
|
|
2929
|
+
maxRetries: 0,
|
|
2930
|
+
});
|
|
2931
|
+
const body: any = res?.data ?? res;
|
|
2932
|
+
if (res?.success === false || body?.success === false) {
|
|
2933
|
+
throw new Error(\`jev \${provider}: \${String(body?.message ?? body?.error ?? \`HTTP \${res?.status}\`).slice(0, 250)}\`);
|
|
2934
|
+
}
|
|
2935
|
+
const p = body?.answers?.act?.noul;
|
|
2936
|
+
if (typeof p !== "number" || !Number.isFinite(p)) {
|
|
2937
|
+
throw new Error(\`jev \${provider}: response has no numeric answers.act.noul\`);
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
const pText = p.toFixed(3);
|
|
2941
|
+
const quiet = p < threshold;
|
|
2942
|
+
const verdict: Record<string, unknown> = {
|
|
2943
|
+
quiet,
|
|
2944
|
+
reason: \`jev p(needs action)=\${pText} \${quiet ? "<" : ">="} \${threshold} via \${provider}\`,
|
|
2945
|
+
};
|
|
2946
|
+
if (!quiet) {
|
|
2947
|
+
const lines = [\`Jev p(needs action) = \${pText} (threshold \${threshold}, \${provider}).\`];
|
|
2948
|
+
const failures = state.new_failures_since_previous_heartbeat;
|
|
2949
|
+
const tracked = state.tracked_items_mentioning_today_or_past_delete_date;
|
|
2950
|
+
if (Array.isArray(failures)) {
|
|
2951
|
+
lines.push("", "New failures since the previous checklist:", ...failures.map((f) => \`- \${f}\`));
|
|
2952
|
+
}
|
|
2953
|
+
if (Array.isArray(tracked)) {
|
|
2954
|
+
lines.push("", "Tracked items due today or past their DELETE date:", ...tracked.map((t) => \`- \${t.replace(/^[-*] /, "")}\`));
|
|
2955
|
+
}
|
|
2956
|
+
if (!Array.isArray(failures) && !Array.isArray(tracked)) {
|
|
2957
|
+
lines.push("", "No new failures or due tracked items; Jev flagged the overall state.");
|
|
2958
|
+
}
|
|
2959
|
+
verdict.summary = lines.join("\\n").slice(0, 4000);
|
|
2960
|
+
}
|
|
2961
|
+
return dryRun ? { ...verdict, dryRun: true, provider, p, threshold, state } : verdict;
|
|
2962
|
+
}
|
|
2963
|
+
`;
|
|
2964
|
+
|
|
2594
2965
|
// src/be/seed-scripts/catalog/json-query.ts
|
|
2595
2966
|
var json_query_default = `import { z } from "zod";
|
|
2596
2967
|
|
|
@@ -5542,6 +5913,12 @@ var SEED_SCRIPTS = [
|
|
|
5542
5913
|
intent: "Keep an app's synced rows fresh on a schedule or on demand; the script a targetType:'script' schedule points at to sync an app.",
|
|
5543
5914
|
source: asText(app_sync_run_default)
|
|
5544
5915
|
},
|
|
5916
|
+
{
|
|
5917
|
+
name: "heartbeat-jev-gate",
|
|
5918
|
+
description: "Heartbeat checklist gate backed by Jev (TypeSafe or OpenRouter decisions API): scores a compact swarm state and returns {quiet, reason, summary} for HEARTBEAT_CHECKLIST_GATE_SCRIPT.",
|
|
5919
|
+
intent: "Skip quiet Lead heartbeat checklist ticks with a cheap Jev decision; with no Jev credential it asks a human once, then stays a no-op until a key is added.",
|
|
5920
|
+
source: asText(heartbeat_jev_gate_default)
|
|
5921
|
+
},
|
|
5545
5922
|
{
|
|
5546
5923
|
name: "fetch-readable",
|
|
5547
5924
|
description: "Fetch a web page and extract clean readable article text — strips scripts, styles, nav, headers, footers, ads and HTML tags, and decodes entities.",
|
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
getMemoryStore,
|
|
4
4
|
init_memory,
|
|
5
5
|
resetEmbeddingProvider
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
8
|
-
import"./cli-
|
|
9
|
-
import"./cli-
|
|
6
|
+
} from "./cli-y3167wt1.js";
|
|
7
|
+
import"./cli-9jzdj90z.js";
|
|
8
|
+
import"./cli-pe05f8yk.js";
|
|
9
|
+
import"./cli-78vv7446.js";
|
|
10
10
|
import"./cli-dmtrxqhg.js";
|
|
11
11
|
import"./cli-7mm2r1kp.js";
|
|
12
|
-
import"./cli-
|
|
12
|
+
import"./cli-x1r545x8.js";
|
|
13
13
|
import"./cli-mvzyxwg3.js";
|
|
14
14
|
import"./cli-fdvbjtbw.js";
|
|
15
15
|
import"./cli-ywybs5as.js";
|
|
@@ -20,11 +20,11 @@ import"./cli-stfs0k5s.js";
|
|
|
20
20
|
import"./cli-sd0mxa3c.js";
|
|
21
21
|
import"./cli-w5e1d1vv.js";
|
|
22
22
|
import"./cli-p0sg24zp.js";
|
|
23
|
-
import"./cli-
|
|
23
|
+
import"./cli-r35rw5de.js";
|
|
24
24
|
import"./cli-zf8jjwex.js";
|
|
25
25
|
import"./cli-gd4favx9.js";
|
|
26
26
|
import"./cli-ej6gbxfb.js";
|
|
27
|
-
import"./cli-
|
|
27
|
+
import"./cli-shk7r5cs.js";
|
|
28
28
|
import"./cli-e3g5mbkz.js";
|
|
29
29
|
import"./cli-bc05qbss.js";
|
|
30
30
|
init_memory();
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureAuthorizationTokenOrThrow
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-711vwbxn.js";
|
|
4
4
|
import {
|
|
5
5
|
init_oauth,
|
|
6
6
|
listKeepAliveAuthorizations
|
|
7
|
-
} from "./cli-
|
|
8
|
-
import"./cli-
|
|
9
|
-
import"./cli-
|
|
10
|
-
import"./cli-
|
|
7
|
+
} from "./cli-y3167wt1.js";
|
|
8
|
+
import"./cli-9jzdj90z.js";
|
|
9
|
+
import"./cli-pe05f8yk.js";
|
|
10
|
+
import"./cli-78vv7446.js";
|
|
11
11
|
import"./cli-dmtrxqhg.js";
|
|
12
12
|
import"./cli-7mm2r1kp.js";
|
|
13
|
-
import"./cli-
|
|
13
|
+
import"./cli-x1r545x8.js";
|
|
14
14
|
import"./cli-mvzyxwg3.js";
|
|
15
15
|
import"./cli-fdvbjtbw.js";
|
|
16
16
|
import"./cli-ywybs5as.js";
|
|
@@ -21,14 +21,14 @@ import"./cli-stfs0k5s.js";
|
|
|
21
21
|
import"./cli-sd0mxa3c.js";
|
|
22
22
|
import"./cli-w5e1d1vv.js";
|
|
23
23
|
import"./cli-p0sg24zp.js";
|
|
24
|
-
import"./cli-
|
|
24
|
+
import"./cli-r35rw5de.js";
|
|
25
25
|
import"./cli-zf8jjwex.js";
|
|
26
26
|
import"./cli-gd4favx9.js";
|
|
27
27
|
import"./cli-ej6gbxfb.js";
|
|
28
28
|
import {
|
|
29
29
|
init_secret_scrubber,
|
|
30
30
|
scrubSecrets
|
|
31
|
-
} from "./cli-
|
|
31
|
+
} from "./cli-shk7r5cs.js";
|
|
32
32
|
import"./cli-e3g5mbkz.js";
|
|
33
33
|
import {
|
|
34
34
|
__require
|
|
@@ -81,7 +81,7 @@ async function notifySlack(text) {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
try {
|
|
84
|
-
const { getSlackApp } = await import("./app-
|
|
84
|
+
const { getSlackApp } = await import("./app-7k8s9w5p.js");
|
|
85
85
|
const app = getSlackApp();
|
|
86
86
|
if (!app) {
|
|
87
87
|
console.warn("[OAuth Keepalive] Slack not available, cannot send notification");
|