@desplega.ai/agent-swarm 1.166.0 → 1.168.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-zhejfecx.js +34 -0
- package/dist/{actions-qz3m692w.js → actions-7jg840nr.js} +25 -25
- package/dist/{amp-adapter-j1xbmsqz.js → amp-adapter-ye6rnetm.js} +4 -4
- package/dist/{anthropic-messages-hst62ws9.js → anthropic-messages-13yn502s.js} +4 -4
- package/dist/{app-43vrdmv8.js → app-ffes2kyf.js} +10 -9
- package/dist/{assistant-ertffmka.js → assistant-fhm5smyz.js} +26 -26
- package/dist/{azure-openai-responses-mh8tvf78.js → azure-openai-responses-9st34pfz.js} +5 -5
- package/dist/{boot-reembed-998jtpdg.js → boot-reembed-20q3nzvg.js} +9 -8
- package/dist/{boot-reembed-s7k7c6v2.js → boot-reembed-jvfadhsk.js} +9 -8
- package/dist/{boot-scrub-sweep-nepsk4t1.js → boot-scrub-sweep-jtfajzve.js} +10 -9
- package/dist/{boot-seeds-vvzs1zhk.js → boot-seeds-9qt0j8j2.js} +12 -11
- package/dist/{claude-adapter-2zvmekrp.js → claude-adapter-a8znhthz.js} +24 -22
- package/dist/{claude-managed-adapter-s49wbk8t.js → claude-managed-adapter-tzwxy803.js} +4 -4
- package/dist/{claude-managed-setup-cvhqq8qn.js → claude-managed-setup-nrhfx5b0.js} +3 -3
- package/dist/{claude-sdk-session-kkbxtw5q.js → claude-sdk-session-7x7chdrs.js} +7608 -7596
- package/dist/{cli-zsh093hk.js → cli-014vns2y.js} +63 -1
- package/dist/{cli-8kgvmkak.js → cli-0jngabtb.js} +1 -1
- package/dist/{cli-qvfk83fy.js → cli-13xwcqvj.js} +2 -2
- package/dist/{cli-0nhdwxd5.js → cli-43jg9xdw.js} +3 -3
- package/dist/{cli-cpfmqz3n.js → cli-47zfzshm.js} +5 -5
- package/dist/{cli-zy7vwsne.js → cli-5qkcdv8c.js} +16 -9
- package/dist/{cli-cwxhbf43.js → cli-5t5my0h8.js} +85 -2
- package/dist/{cli-y59h2pk9.js → cli-69egj654.js} +1 -1
- package/dist/{cli-68r1j4sg.js → cli-6bpvv8h4.js} +3 -3
- package/dist/{cli-yshaazs1.js → cli-74ez9b66.js} +63 -20
- package/dist/{cli-32bca7nr.js → cli-7avy4v8w.js} +1 -1
- package/dist/{cli-f2n17zhp.js → cli-7mhy3ths.js} +21 -18
- package/dist/{cli-q38n4bq0.js → cli-95zs84qw.js} +3 -3
- package/dist/{cli-fn697bnt.js → cli-9q0bh411.js} +21 -8
- package/dist/{cli-rggdq8wq.js → cli-9q24yyvs.js} +3 -3
- package/dist/cli-a35hzdve.js +33 -0
- package/dist/{cli-3qn4r334.js → cli-aj1e0h0d.js} +20 -14
- package/dist/{cli-rsy933yz.js → cli-bcspch6h.js} +30 -19
- package/dist/{cli-x3x0qwky.js → cli-bxqez1p0.js} +51 -23
- package/dist/{cli-ng97fjq7.js → cli-cmxkbzzs.js} +33 -7
- package/dist/{cli-df56tqdw.js → cli-ee0402n1.js} +198 -70
- package/dist/{cli-mwegs4af.js → cli-ew0c3a1j.js} +3 -3
- package/dist/{cli-ysnyhws9.js → cli-ewhwpyrb.js} +54 -51
- package/dist/{cli-j2jbr8af.js → cli-fhj4y16f.js} +1 -1
- package/dist/{cli-8t229cmr.js → cli-fqq06kkb.js} +30 -17
- package/dist/{cli-jvj6a0cv.js → cli-g6gx2dn1.js} +54 -19
- package/dist/{cli-nexwh8zg.js → cli-g7k7zbcz.js} +12 -5
- package/dist/{cli-ecknp7p1.js → cli-j05x7pnb.js} +10 -10
- package/dist/{cli-gt8azyet.js → cli-jb931ba2.js} +1 -1
- package/dist/{cli-nvvfd8bq.js → cli-jbzbr36n.js} +4091 -3793
- package/dist/{cli-3ddybbbx.js → cli-jvmtxqtc.js} +26 -14
- package/dist/{cli-pkke6geq.js → cli-km4x66j0.js} +83 -65
- package/dist/{cli-b0f70z24.js → cli-mn8qkd8v.js} +1 -1
- package/dist/{cli-0qjcsxgz.js → cli-nctfv2yy.js} +99 -9
- package/dist/{cli-4r1sjfc4.js → cli-ng1pmdx6.js} +10 -10
- package/dist/cli-nkqjj42q.js +104 -0
- package/dist/{cli-aqcey741.js → cli-p5jqk8fr.js} +1 -1
- package/dist/{cli-66zh26sp.js → cli-pgehz8e1.js} +57 -17
- package/dist/cli-q1vnz8wv.js +96 -0
- package/dist/{cli-fj86xr3c.js → cli-qd97v6z2.js} +2 -2
- package/dist/{cli-p4ztb80h.js → cli-r7eeddkq.js} +13 -8
- package/dist/{cli-8ssjez7e.js → cli-rhy7z1rp.js} +22 -11
- package/dist/{cli-vzc73wet.js → cli-rr5z1j4p.js} +87 -69
- package/dist/{cli-4mevd1hf.js → cli-s9y81s7j.js} +5 -5
- package/dist/{cli-dw2q9f7g.js → cli-svah6b6w.js} +4 -4
- package/dist/{cli-h3x613ze.js → cli-tc5zec7v.js} +6 -6
- package/dist/{cli-ttbsse3f.js → cli-tmhsxhb8.js} +1 -1
- package/dist/{cli-feh3dkah.js → cli-v1w7pbd8.js} +2 -1
- package/dist/{cli-10zmp1p7.js → cli-vr5avem2.js} +27 -32
- package/dist/{cli-bzr0ftht.js → cli-wnb9b2g3.js} +19 -0
- package/dist/{cli-krqm5f11.js → cli-xezn9nkh.js} +16 -13
- package/dist/{cli-8kt0bmgx.js → cli-xf713zz0.js} +2 -2
- package/dist/{cli-6zcfw0x7.js → cli-y195hv1a.js} +1 -1
- package/dist/{cli-x7kpr72a.js → cli-ytmmyj7f.js} +2 -2
- package/dist/{cli-v2a8x45d.js → cli-z48ggfyq.js} +11 -6
- package/dist/{cli-qbksc292.js → cli-zy39d433.js} +2 -0
- package/dist/cli.js +28 -28
- package/dist/{cloudflare-workers-ai-system-one-tt484t61.js → cloudflare-workers-ai-system-one-sta45jf9.js} +7 -5
- package/dist/{codex-adapter-dw1wxqt8.js → codex-adapter-n63k33d3.js} +18 -18
- package/dist/{codex-login-terbdsqq.js → codex-login-g1cyt5zm.js} +1 -1
- package/dist/{codex-session-runner-3cgb8y1g.js → codex-session-runner-xkxfd81a.js} +18 -18
- package/dist/{commands-mhxam6z2.js → commands-q4mfhn51.js} +9 -8
- package/dist/{cursor-adapter-2qda3st7.js → cursor-adapter-v8mm6bp5.js} +5 -5
- package/dist/{db-sjks418k.js → db-1t0bj3pc.js} +9 -8
- package/dist/{dispatcher-1es759rn.js → dispatcher-k1fhavcf.js} +24 -24
- package/dist/{dsh-adapter-bek4cyw9.js → dsh-adapter-5423p70m.js} +5 -5
- package/dist/{easter-egg-3d-mtpnw06s.js → easter-egg-3d-66zxervv.js} +2 -2
- package/dist/{execute-s4ccjq3n.js → execute-h4jgevyw.js} +61 -11
- package/dist/{google-generative-ai-d6nphg3q.js → google-generative-ai-b8zxrpax.js} +5 -5
- package/dist/{google-vertex-cpshkref.js → google-vertex-nrdd697t.js} +5 -5
- package/dist/{grok-adapter-ar9cw9jg.js → grok-adapter-phrndeb8.js} +18 -8
- package/dist/{handlers-1gkbhktr.js → handlers-59ywqwzh.js} +27 -27
- package/dist/{hook-vxa3tcsy.js → hook-atj0swc2.js} +14 -14
- package/dist/{hook-ds2zxq9v.js → hook-mew1chq9.js} +42 -31
- package/dist/{http-3h21z9md.js → http-ef2fnn9v.js} +953 -98
- package/dist/{index-n99fycq7.js → index-48pb9erw.js} +24 -24
- package/dist/{index-bn6cy8ps.js → index-9fc2h7ww.js} +24 -24
- package/dist/{index-9b65j1m5.js → index-gr69c43q.js} +9 -8
- package/dist/{index-f8xnqrye.js → index-h26wjcfy.js} +43 -24
- package/dist/{index-dkfxpkmm.js → index-w2yhye23.js} +25 -25
- package/dist/{keepalive-3xspa9jw.js → keepalive-qhcqz56v.js} +11 -10
- package/dist/{lead-6qphc124.js → lead-hpk5r3b1.js} +47 -47
- package/dist/{llama-cpp-classify-tgj35k8d.js → llama-cpp-classify-6erb7wwv.js} +3 -1
- package/dist/{maintenance-0teem1bb.js → maintenance-nvkyp2xe.js} +9 -8
- package/dist/{mistral-conversations-8445ddjn.js → mistral-conversations-059y51zt.js} +4 -4
- package/dist/{node-9sg7ajby.js → node-qm9eb6z0.js} +1 -1
- package/dist/{oauth-refresh-sweep-sh9q25xp.js → oauth-refresh-sweep-ngskthwh.js} +10 -9
- package/dist/{onboard-54qmnqxe.js → onboard-yfnkqhxc.js} +2 -2
- package/dist/{openai-codex-responses-9ynm88zy.js → openai-codex-responses-jzxkta9b.js} +8 -7
- package/dist/{openai-completions-nhqwjmaw.js → openai-completions-663yncfq.js} +4 -4
- package/dist/openai-decisions-vj9nkpf8.js +162 -0
- package/dist/{openai-responses-xx1c4kgm.js → openai-responses-m3g43rrt.js} +5 -5
- package/dist/{opencode-adapter-wjfa2wvd.js → opencode-adapter-yjyqynzf.js} +7 -7
- package/dist/{openrouter-images-8yx3487g.js → openrouter-images-kr60n6b9.js} +1 -1
- package/dist/{otel-impl-ycqzp2a1.js → otel-impl-hhm64r6m.js} +1 -1
- package/dist/{pi-messages-vxdt8v7j.js → pi-messages-xszk613n.js} +1 -1
- package/dist/{pi-mono-adapter-e77e9zst.js → pi-mono-adapter-0eg8kw2c.js} +68 -51
- package/dist/{pricing-refresh-atnkngqs.js → pricing-refresh-35f91nx2.js} +11 -10
- package/dist/{rbac-roles-j78wdksm.js → rbac-roles-97w370qj.js} +10 -9
- package/dist/{rbac-roles-9pjphh9q.js → rbac-roles-z6sje3gy.js} +9 -8
- package/dist/{render-v2-pxjs49fx.js → render-v2-n4v66bj3.js} +10 -9
- package/dist/{runtime-v2t1r79e.js → runtime-h9ha1mq6.js} +4 -4
- package/dist/{setup-ymej0xtx.js → setup-m3hhyv5f.js} +2 -2
- package/dist/{typesafe-system-one-datfr82p.js → typesafe-system-one-e988vty7.js} +7 -5
- package/dist/{virtual-modules-wm8mxdxx.js → virtual-modules-ftr9kwe8.js} +11 -11
- package/dist/{work-objects-3nh4ymzb.js → work-objects-mxf2c842.js} +27 -27
- package/dist/{worker-qa9fkz5s.js → worker-9t07z1gq.js} +47 -47
- package/openapi.json +72 -1
- package/package.json +10 -10
- package/src/be/memory/providers/openai-embedding.ts +7 -2
- package/src/be/memory/raters/llm-summarizer.ts +7 -2
- package/src/be/modelsdev-cache.json +61 -0
- package/src/be/script-connections.ts +40 -6
- package/src/be/seed-pricing.ts +84 -53
- package/src/be/swarm-config-guard.ts +14 -0
- package/src/commands/provider-credentials.ts +28 -5
- package/src/commands/runner.ts +7 -12
- package/src/extensions/catalog.generated.json +17 -0
- package/src/heartbeat/heartbeat.ts +91 -19
- package/src/hooks/hook.ts +72 -27
- package/src/http/mcp.ts +5 -0
- package/src/http/onboarding.ts +2 -0
- package/src/http/script-connections.ts +35 -0
- package/src/providers/acp-targets.ts +10 -5
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/claude-adapter.ts +32 -0
- package/src/providers/claude-background-keepalive.ts +100 -0
- package/src/providers/claude-sdk-session.ts +6 -0
- package/src/providers/codex-adapter.ts +30 -3
- package/src/providers/codex-oauth/auth-json.ts +21 -4
- package/src/providers/codex-oauth/types.ts +2 -0
- package/src/providers/dsh-adapter.ts +11 -2
- package/src/providers/grok-adapter.ts +18 -2
- package/src/providers/opencode-adapter.ts +21 -5
- package/src/providers/pi-mono-extension.ts +56 -25
- package/src/providers/pricing-sources.md +2 -0
- package/src/scheduler/scheduler.ts +82 -13
- package/src/scripts-runtime/executors/registry.ts +1 -1
- package/src/server.ts +63 -3
- package/src/tests/acp-adapter.test.ts +152 -12
- package/src/tests/ci-unit-test-report.test.ts +73 -0
- package/src/tests/claude-background-keepalive-wiring.test.ts +220 -0
- package/src/tests/claude-background-keepalive.fixture.ts +162 -0
- package/src/tests/claude-background-keepalive.test.ts +139 -0
- package/src/tests/claude-default-route.test.ts +75 -0
- package/src/tests/claude-hook-output.test.ts +233 -0
- package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +4 -2
- package/src/tests/codex-adapter.test.ts +166 -26
- package/src/tests/codex-oauth-auth-timestamps.test.ts +76 -0
- package/src/tests/codex-oauth.test.ts +4 -1
- package/src/tests/connection-embedded-auth.test.ts +51 -0
- package/src/tests/context-window.test.ts +2 -2
- package/src/tests/credential-check.test.ts +51 -1
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/dsh-adapter.test.ts +24 -2
- package/src/tests/enabled-tools.test.ts +269 -0
- package/src/tests/entrypoint-codex-oauth-seed.test.ts +12 -0
- package/src/tests/extensions-catalog.test.ts +1 -0
- package/src/tests/extensions-example-slack-reply-gate.test.ts +756 -0
- package/src/tests/grok-adapter.test.ts +13 -0
- package/src/tests/haiku-5-5-pricing.test.ts +38 -0
- package/src/tests/heartbeat-checklist.test.ts +158 -1
- package/src/tests/onboarding.test.ts +44 -0
- package/src/tests/opencode-adapter.test.ts +66 -3
- package/src/tests/opencode-plugin.test.ts +37 -0
- package/src/tests/openrouter-attribution-call-sites.test.ts +204 -0
- package/src/tests/openrouter-base-url.test.ts +30 -39
- package/src/tests/pi-mono-extension.test.ts +161 -2
- package/src/tests/pricing-refresh.test.ts +70 -1
- package/src/tests/reasoning-effort.test.ts +3 -1
- package/src/tests/schedule-target-type.test.ts +136 -0
- package/src/tests/script-connections-http.test.ts +45 -0
- package/src/tests/script-connections-mcp.test.ts +41 -0
- package/src/tests/script-executor-registry.test.ts +18 -0
- package/src/tests/send-task-self-send.test.ts +107 -0
- package/src/tests/telemetry-trigger.test.ts +12 -1
- package/src/tests/workflow-llm.test.ts +14 -0
- package/src/tests/workflow-system-one-decision-providers.test.ts +33 -0
- package/src/tools/request-human-input.ts +7 -2
- package/src/tools/script-connections/tool.ts +35 -3
- package/src/tools/send-task.ts +9 -1
- package/src/utils/enabled-tools.ts +27 -0
- package/src/utils/internal-ai/complete-structured.ts +11 -3
- package/src/utils/openrouter-base-url.ts +23 -0
- package/src/workflows/executors/raw-llm.ts +1 -0
- package/src/workflows/executors/system-one-decision.ts +2 -0
- package/src/workflows/executors/validate.ts +1 -0
- package/src/workflows/executors/workflow-llm.ts +9 -2
- package/templates/extensions/README.md +1 -0
- package/templates/extensions/slack-reply-gate/README.md +98 -0
- package/templates/extensions/slack-reply-gate/hooks.ts +582 -0
- package/templates/extensions/slack-reply-gate/manifest.json +8 -0
- package/templates/skills/agent-browser/SKILL.md +2 -0
- package/templates/skills/agent-browser/content.md +2 -0
- package/templates/skills/code-quality/content.md +1 -0
- package/templates/skills/heartbeat-runbook/content.md +1 -1
- package/templates/skills/swarm-scripts/SKILL.md +10 -0
- package/templates/skills/swarm-scripts/content.md +10 -0
- package/templates/skills/work-on-task/SKILL.md +4 -0
- package/templates/skills/work-on-task/content.md +4 -0
- package/templates/skills/workflow-iterate/content.md +9 -0
- package/dist/acp-adapter-yzfxn8vj.js +0 -23
- package/dist/cli-3dpj7atn.js +0 -11
- package/dist/cli-gvcgmx69.js +0 -183
- package/dist/{cli-jhm6hzjn.js → cli-mxvnnv5q.js} +7 -7
- package/dist/{codex-hook-d2rkvf39.js → codex-hook-15dgc4cb.js} +1 -1
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runStopHookSessionSummarySubprocess
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-bcspch6h.js";
|
|
4
4
|
import {
|
|
5
5
|
buildOtelTraceparentEnv,
|
|
6
6
|
isHarnessOtelEnabled
|
|
7
7
|
} from "./cli-q2j38vre.js";
|
|
8
|
+
import {
|
|
9
|
+
fetchInstalledMcpServers
|
|
10
|
+
} from "./cli-tng3131n.js";
|
|
8
11
|
import {
|
|
9
12
|
CTX_MODE_NUDGE_EVERY
|
|
10
13
|
} from "./cli-zm7njwzd.js";
|
|
@@ -16,10 +19,7 @@ import {
|
|
|
16
19
|
clampContextPercent,
|
|
17
20
|
computeContextUsedUnified,
|
|
18
21
|
getContextWindowSize
|
|
19
|
-
} from "./cli-
|
|
20
|
-
import {
|
|
21
|
-
fetchInstalledMcpServers
|
|
22
|
-
} from "./cli-tng3131n.js";
|
|
22
|
+
} from "./cli-7avy4v8w.js";
|
|
23
23
|
import {
|
|
24
24
|
isClaudeBridgeEffective,
|
|
25
25
|
resolveClaudeTransport
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
} from "./cli-2pdaysab.js";
|
|
33
33
|
import {
|
|
34
34
|
applyReasoningEffort
|
|
35
|
-
} from "./cli-
|
|
35
|
+
} from "./cli-tmhsxhb8.js";
|
|
36
36
|
import {
|
|
37
37
|
swarmRuntimeInstanceId
|
|
38
38
|
} from "./cli-re8z5p8p.js";
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
import {
|
|
45
45
|
init_file_lock,
|
|
46
46
|
withFileLock
|
|
47
|
-
} from "./cli-
|
|
47
|
+
} from "./cli-mxvnnv5q.js";
|
|
48
48
|
import {
|
|
49
49
|
CLAUDE_CREDENTIALS_HINT,
|
|
50
50
|
init_credentials,
|
|
@@ -56,6 +56,10 @@ import {
|
|
|
56
56
|
routeCredentialStatus,
|
|
57
57
|
routeUnsetEnv
|
|
58
58
|
} from "./cli-f9w1semm.js";
|
|
59
|
+
import {
|
|
60
|
+
getOpenRouterAttributionHeaders,
|
|
61
|
+
init_openrouter_base_url
|
|
62
|
+
} from "./cli-a35hzdve.js";
|
|
59
63
|
import {
|
|
60
64
|
init_env_flag,
|
|
61
65
|
isEnvFlagEnabled
|
|
@@ -95,8 +99,74 @@ import { promisify } from "node:util";
|
|
|
95
99
|
init_credentials();
|
|
96
100
|
init_env_flag();
|
|
97
101
|
init_file_lock();
|
|
102
|
+
init_openrouter_base_url();
|
|
98
103
|
init_secret_scrubber();
|
|
99
104
|
|
|
105
|
+
// src/providers/claude-background-keepalive.ts
|
|
106
|
+
var BACKGROUND_KEEPALIVE_INTERVAL_MS = 60000;
|
|
107
|
+
var BACKGROUND_KEEPALIVE_MAX_IDLE_MS = 2 * 60 * 60000;
|
|
108
|
+
|
|
109
|
+
class ClaudeBackgroundKeepalive {
|
|
110
|
+
options;
|
|
111
|
+
liveTaskIds = [];
|
|
112
|
+
timer;
|
|
113
|
+
lastMessageAt = Date.now();
|
|
114
|
+
stopped = false;
|
|
115
|
+
intervalMs;
|
|
116
|
+
maxIdleMs;
|
|
117
|
+
constructor(options) {
|
|
118
|
+
this.options = options;
|
|
119
|
+
this.intervalMs = options.intervalMs ?? BACKGROUND_KEEPALIVE_INTERVAL_MS;
|
|
120
|
+
this.maxIdleMs = options.maxIdleMs ?? BACKGROUND_KEEPALIVE_MAX_IDLE_MS;
|
|
121
|
+
}
|
|
122
|
+
observe(message) {
|
|
123
|
+
if (this.stopped)
|
|
124
|
+
return;
|
|
125
|
+
this.lastMessageAt = Date.now();
|
|
126
|
+
if (message.type === "system" && message.subtype === "background_tasks_changed") {
|
|
127
|
+
const tasks = Array.isArray(message.tasks) ? message.tasks : [];
|
|
128
|
+
this.liveTaskIds = tasks.filter((task) => task && task.ambient !== true && typeof task.task_id === "string").map((task) => task.task_id);
|
|
129
|
+
}
|
|
130
|
+
if (this.liveTaskIds.length > 0)
|
|
131
|
+
this.start();
|
|
132
|
+
else
|
|
133
|
+
this.clearTimer();
|
|
134
|
+
}
|
|
135
|
+
stop() {
|
|
136
|
+
this.stopped = true;
|
|
137
|
+
this.liveTaskIds = [];
|
|
138
|
+
this.clearTimer();
|
|
139
|
+
}
|
|
140
|
+
start() {
|
|
141
|
+
if (this.timer !== undefined)
|
|
142
|
+
return;
|
|
143
|
+
if (!this.options.apiUrl || !this.options.taskId)
|
|
144
|
+
return;
|
|
145
|
+
this.timer = setInterval(() => this.tick(), this.intervalMs);
|
|
146
|
+
}
|
|
147
|
+
tick() {
|
|
148
|
+
if (Date.now() - this.lastMessageAt > this.maxIdleMs) {
|
|
149
|
+
this.clearTimer();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const { apiUrl, apiKey, agentId, taskId } = this.options;
|
|
153
|
+
fetch(`${apiUrl}/api/active-sessions/heartbeat/${encodeURIComponent(taskId)}`, {
|
|
154
|
+
method: "PUT",
|
|
155
|
+
headers: {
|
|
156
|
+
"Content-Type": "application/json",
|
|
157
|
+
Authorization: `Bearer ${apiKey}`,
|
|
158
|
+
"X-Agent-ID": agentId
|
|
159
|
+
}
|
|
160
|
+
}).catch(() => {});
|
|
161
|
+
}
|
|
162
|
+
clearTimer() {
|
|
163
|
+
if (this.timer === undefined)
|
|
164
|
+
return;
|
|
165
|
+
clearInterval(this.timer);
|
|
166
|
+
this.timer = undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
100
170
|
// src/providers/claude-session-events.ts
|
|
101
171
|
init_secret_scrubber();
|
|
102
172
|
function finiteNumber(value) {
|
|
@@ -628,6 +698,21 @@ function buildClaudeCodeRuntimeEnv(_sourceEnv) {
|
|
|
628
698
|
DISABLE_BUG_COMMAND: "1"
|
|
629
699
|
};
|
|
630
700
|
}
|
|
701
|
+
function claudeOpenRouterAttributionEnv(env) {
|
|
702
|
+
const headers = getOpenRouterAttributionHeaders(env.ANTHROPIC_BASE_URL ?? "", env);
|
|
703
|
+
const names = new Set(Object.keys(headers).map((name) => name.toLowerCase()));
|
|
704
|
+
if (names.size === 0)
|
|
705
|
+
return {};
|
|
706
|
+
const kept = (env.ANTHROPIC_CUSTOM_HEADERS ?? "").split(`
|
|
707
|
+
`).filter((line) => {
|
|
708
|
+
const colon = line.indexOf(":");
|
|
709
|
+
const name = colon === -1 ? "" : line.slice(0, colon).trim().toLowerCase();
|
|
710
|
+
return line.trim() !== "" && !names.has(name);
|
|
711
|
+
});
|
|
712
|
+
const ours = Object.entries(headers).map(([name, value]) => `${name}: ${value}`);
|
|
713
|
+
return { ANTHROPIC_CUSTOM_HEADERS: [...kept, ...ours].join(`
|
|
714
|
+
`) };
|
|
715
|
+
}
|
|
631
716
|
function buildClaudeSessionEnvironment(config, model, taskFilePath) {
|
|
632
717
|
const sourceEnv = { ...withClaudeRouteEnv(config.env || process.env) };
|
|
633
718
|
delete sourceEnv.AGENT_SWARM_CLAUDE_OAUTH_TOKEN;
|
|
@@ -636,6 +721,7 @@ function buildClaudeSessionEnvironment(config, model, taskFilePath) {
|
|
|
636
721
|
env: {
|
|
637
722
|
ENABLE_PROMPT_CACHING_1H: "1",
|
|
638
723
|
...sourceEnv,
|
|
724
|
+
...claudeOpenRouterAttributionEnv(sourceEnv),
|
|
639
725
|
...buildClaudeCodeRuntimeEnv(sourceEnv),
|
|
640
726
|
...buildClaudeCodeOtelEnv(sourceEnv),
|
|
641
727
|
...reasoningApplication.kind === "claude-env" ? reasoningApplication.env : {},
|
|
@@ -709,6 +795,7 @@ class ClaudeSession {
|
|
|
709
795
|
appliedReasoningEffort;
|
|
710
796
|
lastAssistantText = "";
|
|
711
797
|
transcript;
|
|
798
|
+
backgroundKeepalive;
|
|
712
799
|
deliverSteering;
|
|
713
800
|
constructor(config, model, taskFilePath, taskFileKey, sessionMcpConfig = null, claudeBinaryArgv = ["claude"], systemPromptFile = null, harnessVariant, harnessVariantMeta, queueSteeringSupported = false, runSessionSummary = runStopHookSessionSummarySubprocess) {
|
|
714
801
|
this.config = config;
|
|
@@ -723,6 +810,7 @@ class ClaudeSession {
|
|
|
723
810
|
this.contextWindowSize = getContextWindowSize(model);
|
|
724
811
|
this.systemPromptFile = systemPromptFile;
|
|
725
812
|
this.transcript = [`User: ${scrubSecrets(config.prompt)}`];
|
|
813
|
+
this.backgroundKeepalive = new ClaudeBackgroundKeepalive(config);
|
|
726
814
|
const cmd = this.buildCommand();
|
|
727
815
|
console.log(`\x1B[2m[${config.role}]\x1B[0m \x1B[36m▸\x1B[0m Spawning Claude (model: ${model}) for task ${config.taskId.slice(0, 8)}`);
|
|
728
816
|
const sessionEnvironment = buildClaudeSessionEnvironment(config, model, taskFilePath);
|
|
@@ -897,6 +985,7 @@ class ClaudeSession {
|
|
|
897
985
|
try {
|
|
898
986
|
await Promise.all([stdoutPromise, stderrPromise]);
|
|
899
987
|
} finally {
|
|
988
|
+
this.backgroundKeepalive.stop();
|
|
900
989
|
this.closeStdin();
|
|
901
990
|
}
|
|
902
991
|
await logFileHandle.end();
|
|
@@ -945,6 +1034,7 @@ ${scrubSecrets(stderrOutput)}`);
|
|
|
945
1034
|
if (json.type === "result") {
|
|
946
1035
|
this.closeStdin();
|
|
947
1036
|
}
|
|
1037
|
+
this.backgroundKeepalive.observe(json);
|
|
948
1038
|
const normalized = normalizeClaudeMessage(json, {
|
|
949
1039
|
taskId: this.config.taskId,
|
|
950
1040
|
agentId: this.config.agentId,
|
|
@@ -1026,7 +1116,7 @@ class ClaudeAdapter {
|
|
|
1026
1116
|
if (transport === "sdk" && isClaudeBridgeEffective(sourceEnv)) {
|
|
1027
1117
|
throw new Error("CLAUDE_TRANSPORT=sdk cannot run with an effective Claude Bridge configuration. Select CLI transport or disable the bridge.");
|
|
1028
1118
|
}
|
|
1029
|
-
const claudeSdk = transport === "sdk" ? await import("./claude-sdk-session-
|
|
1119
|
+
const claudeSdk = transport === "sdk" ? await import("./claude-sdk-session-7x7chdrs.js") : undefined;
|
|
1030
1120
|
claudeSdk?.validateClaudeSdkAdditionalArgs([
|
|
1031
1121
|
...claudeBinaryArgv.slice(1),
|
|
1032
1122
|
...config.additionalArgs ?? []
|
|
@@ -1133,4 +1223,4 @@ ${stderr}`.trim();
|
|
|
1133
1223
|
}
|
|
1134
1224
|
}
|
|
1135
1225
|
|
|
1136
|
-
export { normalizeClaudeMessage, checkClaudeCredentials, withClaudeRouteEnv, getTaskFilePath, cleanupTaskFile, parseClaudeBinary, resolveClaudeQueueSteeringOverride, resolveClaudeBinary, parseClaudeBridgeEnabled, resolveClaudeBridgeEnabled, resolveClaudeBinaryArgv, preseedClaudeTrustDialog, resolveClaudeTrustDirs, mergeMcpConfig, createSessionMcpConfig, buildClaudeCodeOtelEnv, buildClaudeCodeRuntimeEnv, buildClaudeSessionEnvironment, runClaudeSessionSummary, getSystemPromptFilePath, resolveClaudePrompt, ClaudeAdapter };
|
|
1226
|
+
export { ClaudeBackgroundKeepalive, normalizeClaudeMessage, checkClaudeCredentials, withClaudeRouteEnv, getTaskFilePath, cleanupTaskFile, parseClaudeBinary, resolveClaudeQueueSteeringOverride, resolveClaudeBinary, parseClaudeBridgeEnabled, resolveClaudeBridgeEnabled, resolveClaudeBinaryArgv, preseedClaudeTrustDialog, resolveClaudeTrustDirs, mergeMcpConfig, createSessionMcpConfig, buildClaudeCodeOtelEnv, buildClaudeCodeRuntimeEnv, claudeOpenRouterAttributionEnv, buildClaudeSessionEnvironment, runClaudeSessionSummary, getSystemPromptFilePath, resolveClaudePrompt, ClaudeAdapter };
|
|
@@ -7,7 +7,7 @@ var package_default;
|
|
|
7
7
|
var init_package = __esm(() => {
|
|
8
8
|
package_default = {
|
|
9
9
|
name: "@desplega.ai/agent-swarm",
|
|
10
|
-
version: "1.
|
|
10
|
+
version: "1.168.0",
|
|
11
11
|
description: "agent-swarm.dev — an open-source operating system for AI work: a lead agent breaks goals into tasks, routes them to specialized workers such as Claude Code or Codex, runs each worker in an isolated container, and preserves shared memory, tools, schedules, and review gates so delegated work compounds across sessions.",
|
|
12
12
|
keywords: [
|
|
13
13
|
"agent-swarm.dev",
|
|
@@ -154,8 +154,8 @@ var init_package = __esm(() => {
|
|
|
154
154
|
"start:portless": "portless api.swarm bun --expose-gc src/http.ts",
|
|
155
155
|
inspector: "bunx @modelcontextprotocol/inspector --transport stdio bun src/stdio.ts",
|
|
156
156
|
"inspector:http": "bunx @modelcontextprotocol/inspector --transport http https://api.swarm.localhost:1355/mcp",
|
|
157
|
-
lint: "biome check src apps/evals packages/ui-e2e packages/model-routing",
|
|
158
|
-
"lint:fix": "biome check --write src apps/evals packages/ui-e2e packages/model-routing",
|
|
157
|
+
lint: "biome check src apps/evals packages/ui-e2e packages/model-routing packages/model-catalog",
|
|
158
|
+
"lint:fix": "biome check --write src apps/evals packages/ui-e2e packages/model-routing packages/model-catalog",
|
|
159
159
|
format: "biome format --write src",
|
|
160
160
|
"build:binary": "bun build ./src/cli.tsx ./src/providers/pi-binary-root/src/extensions/codemode/worker.ts --root ./src/providers/pi-binary-root --compile --bytecode --format=esm --compile-exec-argv='--expose-gc' --target=bun-linux-x64 --outfile ./dist/agent-swarm",
|
|
161
161
|
"build:binary:arm64": "bun build ./src/cli.tsx ./src/providers/pi-binary-root/src/extensions/codemode/worker.ts --root ./src/providers/pi-binary-root --compile --bytecode --format=esm --compile-exec-argv='--expose-gc' --target=bun-linux-arm64 --outfile ./dist/agent-swarm",
|
|
@@ -209,21 +209,21 @@ var init_package = __esm(() => {
|
|
|
209
209
|
dependencies: {
|
|
210
210
|
"@agentclientprotocol/sdk": "1.7.0",
|
|
211
211
|
"@ai-sdk/openai": "^3.0.41",
|
|
212
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
213
|
-
"@anthropic-ai/sdk": "^0.132.
|
|
212
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.295",
|
|
213
|
+
"@anthropic-ai/sdk": "^0.132.1",
|
|
214
214
|
"@asteasolutions/zod-to-openapi": "^8.0.0",
|
|
215
215
|
"@aws-sdk/client-bedrock": "3.1048.0",
|
|
216
216
|
"@cursor/sdk": "1.0.37",
|
|
217
217
|
"@desplega.ai/business-use": "^0.4.2",
|
|
218
218
|
"@desplega.ai/localtunnel": "^2.2.0",
|
|
219
|
-
"@earendil-works/pi-agent-core": "^1.0
|
|
220
|
-
"@earendil-works/pi-ai": "^1.0
|
|
221
|
-
"@earendil-works/pi-coding-agent": "^1.0
|
|
219
|
+
"@earendil-works/pi-agent-core": "^1.1.0",
|
|
220
|
+
"@earendil-works/pi-ai": "^1.1.0",
|
|
221
|
+
"@earendil-works/pi-coding-agent": "^1.1.0",
|
|
222
222
|
"@inkjs/ui": "^2.0.0",
|
|
223
223
|
"@jitl/quickjs-singlefile-mjs-release-sync": "0.32.0",
|
|
224
224
|
"@linear/sdk": "^77.0.0",
|
|
225
|
-
"@modelcontextprotocol/sdk": "1.
|
|
226
|
-
"@openai/codex": "0.
|
|
225
|
+
"@modelcontextprotocol/sdk": "1.31.0",
|
|
226
|
+
"@openai/codex": "0.162.0",
|
|
227
227
|
"@opencode-ai/sdk": "^1.18.35",
|
|
228
228
|
"@openfort/openfort-node": "^0.9.1",
|
|
229
229
|
"@opentelemetry/api": "^1.9.1",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isRecord,
|
|
3
|
+
parseClassifierUsage,
|
|
4
|
+
postClassifierRequest,
|
|
5
|
+
requiredNumber
|
|
6
|
+
} from "./cli-q1vnz8wv.js";
|
|
7
|
+
import {
|
|
8
|
+
formatProviderError,
|
|
9
|
+
normalizeProviderError
|
|
10
|
+
} from "./cli-6map995v.js";
|
|
11
|
+
|
|
12
|
+
// node_modules/@earendil-works/pi-ai/dist/api/system-one-shared.js
|
|
13
|
+
function probabilities(label, value, id) {
|
|
14
|
+
if (!isRecord(value))
|
|
15
|
+
throw new Error(`${label} returned invalid probabilities for ${id}`);
|
|
16
|
+
return Object.fromEntries(Object.entries(value).map(([key, probability]) => [
|
|
17
|
+
key,
|
|
18
|
+
requiredNumber(label, probability, `probability for ${id}.${key}`)
|
|
19
|
+
]));
|
|
20
|
+
}
|
|
21
|
+
function parseAnswers(label, value, context) {
|
|
22
|
+
if (!isRecord(value))
|
|
23
|
+
throw new Error(`${label} returned an unexpected response`);
|
|
24
|
+
const answers = [];
|
|
25
|
+
for (const [id, question] of Object.entries(context.questions)) {
|
|
26
|
+
const answer = value[id];
|
|
27
|
+
if (!isRecord(answer))
|
|
28
|
+
throw new Error(`${label} did not return an answer for ${id}`);
|
|
29
|
+
if (question.type === "choice") {
|
|
30
|
+
if (answer.type !== "choice" || typeof answer.choice !== "string") {
|
|
31
|
+
throw new Error(`${label} did not return a choice answer for ${id}`);
|
|
32
|
+
}
|
|
33
|
+
answers.push([
|
|
34
|
+
id,
|
|
35
|
+
{
|
|
36
|
+
type: "choice",
|
|
37
|
+
choice: answer.choice,
|
|
38
|
+
probabilities: probabilities(label, answer.probabilities, id),
|
|
39
|
+
confidence: requiredNumber(label, answer.confidence, `confidence for ${id}`)
|
|
40
|
+
}
|
|
41
|
+
]);
|
|
42
|
+
} else if (question.type === "score") {
|
|
43
|
+
if (answer.type !== "score")
|
|
44
|
+
throw new Error(`${label} did not return a score answer for ${id}`);
|
|
45
|
+
answers.push([
|
|
46
|
+
id,
|
|
47
|
+
{
|
|
48
|
+
type: "score",
|
|
49
|
+
score: requiredNumber(label, answer.score, `score for ${id}`),
|
|
50
|
+
confidence: requiredNumber(label, answer.confidence, `confidence for ${id}`)
|
|
51
|
+
}
|
|
52
|
+
]);
|
|
53
|
+
} else {
|
|
54
|
+
if (answer.type !== "noul")
|
|
55
|
+
throw new Error(`${label} did not return a bool answer for ${id}`);
|
|
56
|
+
answers.push([
|
|
57
|
+
id,
|
|
58
|
+
{
|
|
59
|
+
type: "bool",
|
|
60
|
+
probability: requiredNumber(label, answer.noul, `probability for ${id}`)
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return Object.fromEntries(answers);
|
|
66
|
+
}
|
|
67
|
+
function wireRequest(context) {
|
|
68
|
+
return {
|
|
69
|
+
state: context.state,
|
|
70
|
+
questions: Object.fromEntries(Object.entries(context.questions).map(([id, question]) => [
|
|
71
|
+
id,
|
|
72
|
+
question.type === "bool" ? { ...question, type: "noul" } : question
|
|
73
|
+
]))
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function classifySystemOne(transport, model, context, options) {
|
|
77
|
+
const output = {
|
|
78
|
+
api: model.api,
|
|
79
|
+
provider: model.provider,
|
|
80
|
+
model: model.id,
|
|
81
|
+
answers: {},
|
|
82
|
+
stopReason: "stop",
|
|
83
|
+
timestamp: Date.now()
|
|
84
|
+
};
|
|
85
|
+
try {
|
|
86
|
+
if (model.api !== transport.api)
|
|
87
|
+
throw new Error(`Unsupported classifier API: ${model.api}`);
|
|
88
|
+
if (context.images?.length)
|
|
89
|
+
throw new Error(`${transport.label} does not support image input`);
|
|
90
|
+
const body = await postClassifierRequest(transport.label, transport.url(model), model, transport.payload(model, wireRequest(context)), options);
|
|
91
|
+
const result = transport.output(body);
|
|
92
|
+
const usage = parseClassifierUsage(result.usage, model);
|
|
93
|
+
if (usage)
|
|
94
|
+
output.usage = usage;
|
|
95
|
+
output.answers = parseAnswers(transport.label, result.answers, context);
|
|
96
|
+
return output;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
99
|
+
output.errorMessage = formatProviderError(normalizeProviderError(error), `${transport.label} error`);
|
|
100
|
+
return output;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export { classifySystemOne };
|
|
@@ -18,13 +18,13 @@ import {
|
|
|
18
18
|
recoverIncompleteRuns,
|
|
19
19
|
repointTrackerSyncBySwarmId,
|
|
20
20
|
resolveLeadOnlyRecoveryAssignment
|
|
21
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-ee0402n1.js";
|
|
22
22
|
import {
|
|
23
23
|
isMultiRuntimeEnabled
|
|
24
24
|
} from "./cli-re8z5p8p.js";
|
|
25
25
|
import {
|
|
26
26
|
createApprovalFollowUpTask
|
|
27
|
-
} from "./cli-
|
|
27
|
+
} from "./cli-g6gx2dn1.js";
|
|
28
28
|
import {
|
|
29
29
|
MAX_EMPTY_POLLS,
|
|
30
30
|
assignUnassignedTaskPending,
|
|
@@ -75,7 +75,7 @@ import {
|
|
|
75
75
|
settleSupersededTaskDependents,
|
|
76
76
|
supersedeTask,
|
|
77
77
|
updateAgentStatus
|
|
78
|
-
} from "./cli-
|
|
78
|
+
} from "./cli-74ez9b66.js";
|
|
79
79
|
import {
|
|
80
80
|
TERMINAL_TASK_STATUSES,
|
|
81
81
|
init_types
|
|
@@ -90,11 +90,18 @@ import {
|
|
|
90
90
|
init_env_flag,
|
|
91
91
|
isEnvFlagEnabled
|
|
92
92
|
} from "./cli-ej6gbxfb.js";
|
|
93
|
+
import {
|
|
94
|
+
init_package,
|
|
95
|
+
package_default
|
|
96
|
+
} from "./cli-ng1pmdx6.js";
|
|
93
97
|
import {
|
|
94
98
|
init_secret_scrubber,
|
|
95
99
|
scrubSecrets
|
|
96
100
|
} from "./cli-wt7ccy4r.js";
|
|
97
101
|
|
|
102
|
+
// src/heartbeat/heartbeat.ts
|
|
103
|
+
init_package();
|
|
104
|
+
|
|
98
105
|
// src/be/approval-sweeps.ts
|
|
99
106
|
init_db();
|
|
100
107
|
var DEFAULT_APPROVAL_REQUEST_AUTO_CANCELLATION_DAYS = 7;
|
|
@@ -356,6 +363,9 @@ function heartbeatChecklistIntervalMs() {
|
|
|
356
363
|
function isHeartbeatChecklistDisabled() {
|
|
357
364
|
return isEnvFlagEnabled("HEARTBEAT_CHECKLIST_DISABLE", false);
|
|
358
365
|
}
|
|
366
|
+
function isBootTriageAlways() {
|
|
367
|
+
return isEnvFlagEnabled("HEARTBEAT_BOOT_TRIAGE_ALWAYS", false);
|
|
368
|
+
}
|
|
359
369
|
var heartbeatInterval = null;
|
|
360
370
|
var checklistInterval = null;
|
|
361
371
|
var bootTriageTimeout = null;
|
|
@@ -1130,19 +1140,7 @@ async function gatherSystemStatus(options) {
|
|
|
1130
1140
|
sections.push("- If the retry failed or the work is no longer needed, cancel it");
|
|
1131
1141
|
sections.push("- Do NOT mark this boot triage as complete until all items are triaged");
|
|
1132
1142
|
}
|
|
1133
|
-
const orphanedTasks =
|
|
1134
|
-
for (const status of ["pending", "offered"]) {
|
|
1135
|
-
const tasks = await getTasksByStatus(status);
|
|
1136
|
-
for (const task of tasks) {
|
|
1137
|
-
const holderId = status === "offered" ? task.offeredTo : task.agentId;
|
|
1138
|
-
if (!holderId)
|
|
1139
|
-
continue;
|
|
1140
|
-
const agent = agents.find((a) => a.id === holderId);
|
|
1141
|
-
if (!agent || agent.status === "offline") {
|
|
1142
|
-
orphanedTasks.push(task);
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1143
|
+
const orphanedTasks = await getOrphanedPendingOrOfferedTasks(agents);
|
|
1146
1144
|
if (orphanedTasks.length > 0) {
|
|
1147
1145
|
sections.push("");
|
|
1148
1146
|
sections.push("## Orphaned Tasks [auto-generated, NEEDS ATTENTION]");
|
|
@@ -1160,6 +1158,32 @@ async function gatherSystemStatus(options) {
|
|
|
1160
1158
|
return sections.join(`
|
|
1161
1159
|
`);
|
|
1162
1160
|
}
|
|
1161
|
+
async function getOrphanedPendingOrOfferedTasks(agents) {
|
|
1162
|
+
const orphanedTasks = [];
|
|
1163
|
+
for (const status of ["pending", "offered"]) {
|
|
1164
|
+
const tasks = await getTasksByStatus(status);
|
|
1165
|
+
for (const task of tasks) {
|
|
1166
|
+
const holderId = status === "offered" ? task.offeredTo : task.agentId;
|
|
1167
|
+
if (!holderId)
|
|
1168
|
+
continue;
|
|
1169
|
+
const agent = agents.find((a) => a.id === holderId);
|
|
1170
|
+
if (!agent || agent.status === "offline") {
|
|
1171
|
+
orphanedTasks.push(task);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
return orphanedTasks;
|
|
1176
|
+
}
|
|
1177
|
+
async function getBootTriageFindings() {
|
|
1178
|
+
const now = Date.now();
|
|
1179
|
+
const agents = await getAllAgents();
|
|
1180
|
+
return {
|
|
1181
|
+
rebootInterrupted: getRebootAffectedTasks().length,
|
|
1182
|
+
stalled: (await getStalledInProgressTasks(stallThresholdMinutes())).length,
|
|
1183
|
+
orphaned: (await getOrphanedPendingOrOfferedTasks(agents)).length,
|
|
1184
|
+
supersededWithoutResume: (await getSupersededTasksWithoutResume(new Date(now - ORPHAN_SUPERSEDE_MIN_AGE_MS).toISOString(), new Date(now - ORPHAN_SUPERSEDE_MAX_AGE_MS).toISOString())).length
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1163
1187
|
async function checkHeartbeatChecklist() {
|
|
1164
1188
|
const lead = await getLeadAgent();
|
|
1165
1189
|
if (!lead)
|
|
@@ -1323,7 +1347,23 @@ async function createBootTriageTask() {
|
|
|
1323
1347
|
LIMIT 1`, [lead.id, ...TERMINAL_TASK_STATUSES]);
|
|
1324
1348
|
if (existing)
|
|
1325
1349
|
return;
|
|
1326
|
-
|
|
1350
|
+
if (!isBootTriageAlways()) {
|
|
1351
|
+
const findings = await getBootTriageFindings().catch((err) => {
|
|
1352
|
+
console.error("[Heartbeat] Boot triage findings failed, creating Lead task:", scrubSecrets(err instanceof Error ? err.message : String(err)));
|
|
1353
|
+
return null;
|
|
1354
|
+
});
|
|
1355
|
+
if (findings && Object.values(findings).every((count) => count === 0)) {
|
|
1356
|
+
console.log(`[Heartbeat] Clean boot (v${package_default.version}): 0 interrupted, stalled, orphaned, or resume-less superseded tasks; no boot-triage task for lead ${lead.name}`);
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
const systemStatus = await gatherSystemStatus({ isBootTriage: true }).catch((err) => {
|
|
1361
|
+
const reason = scrubSecrets(err instanceof Error ? err.message : String(err));
|
|
1362
|
+
console.error("[Heartbeat] Boot triage status gathering failed:", reason);
|
|
1363
|
+
return `## System status unavailable
|
|
1364
|
+
|
|
1365
|
+
Status gathering failed after this boot (${reason}). Investigate the task, agent, and DB state directly.`;
|
|
1366
|
+
});
|
|
1327
1367
|
const result = resolveTemplate("heartbeat.boot-triage", {
|
|
1328
1368
|
system_status: systemStatus,
|
|
1329
1369
|
heartbeat_content: isEffectivelyEmpty(heartbeatMd) ? "_No standing orders configured._" : heartbeatMd
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
retryProviderRequest
|
|
3
|
+
} from "./cli-zy39d433.js";
|
|
4
|
+
import {
|
|
5
|
+
headersToRecord,
|
|
6
|
+
providerHeadersToRecord
|
|
7
|
+
} from "./cli-7kyk9jr3.js";
|
|
8
|
+
import {
|
|
9
|
+
calculateCost
|
|
10
|
+
} from "./cli-g7k7zbcz.js";
|
|
11
|
+
|
|
12
|
+
// node_modules/@earendil-works/pi-ai/dist/api/classifier-shared.js
|
|
13
|
+
function httpError(label, response, body) {
|
|
14
|
+
const error = new Error(`${label} returned ${response.status}`);
|
|
15
|
+
error.status = response.status;
|
|
16
|
+
error.headers = response.headers;
|
|
17
|
+
error.body = body;
|
|
18
|
+
return error;
|
|
19
|
+
}
|
|
20
|
+
function timeoutError(timeoutMs) {
|
|
21
|
+
const error = new Error(`Request timed out after ${timeoutMs}ms`);
|
|
22
|
+
error.name = "TimeoutError";
|
|
23
|
+
error.status = undefined;
|
|
24
|
+
error.headers = undefined;
|
|
25
|
+
error.body = "";
|
|
26
|
+
return error;
|
|
27
|
+
}
|
|
28
|
+
function isRecord(value) {
|
|
29
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function requiredNumber(label, value, field) {
|
|
32
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
33
|
+
throw new Error(`${label} returned an invalid ${field}`);
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
function requestHeaders(model, apiKey, optionsHeaders) {
|
|
38
|
+
return providerHeadersToRecord({ authorization: `Bearer ${apiKey}`, "content-type": "application/json" }, model.headers, optionsHeaders) ?? {};
|
|
39
|
+
}
|
|
40
|
+
async function postClassifierRequest(label, url, model, body, options, noRetryStatuses) {
|
|
41
|
+
if (!options?.apiKey)
|
|
42
|
+
throw new Error(`No API key for provider: ${model.provider}`);
|
|
43
|
+
const apiKey = options.apiKey;
|
|
44
|
+
let payload = body;
|
|
45
|
+
const transformed = await options.onPayload?.(payload, model);
|
|
46
|
+
if (transformed !== undefined)
|
|
47
|
+
payload = transformed;
|
|
48
|
+
const requestFetch = options.fetch ?? globalThis.fetch;
|
|
49
|
+
const { response, json } = await retryProviderRequest(async () => {
|
|
50
|
+
const timeoutSignal = options.timeoutMs !== undefined ? AbortSignal.timeout(options.timeoutMs) : undefined;
|
|
51
|
+
const signal = options.signal && timeoutSignal ? AbortSignal.any([options.signal, timeoutSignal]) : options.signal ?? timeoutSignal;
|
|
52
|
+
try {
|
|
53
|
+
const next = await requestFetch(url, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: requestHeaders(model, apiKey, options.headers),
|
|
56
|
+
body: JSON.stringify(payload),
|
|
57
|
+
signal
|
|
58
|
+
});
|
|
59
|
+
if (!next.ok)
|
|
60
|
+
throw httpError(label, next, await next.text());
|
|
61
|
+
return { response: next, json: await next.json() };
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (timeoutSignal?.aborted && !options.signal?.aborted)
|
|
64
|
+
throw timeoutError(options.timeoutMs);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}, {
|
|
68
|
+
maxRetries: options.maxRetries ?? 2,
|
|
69
|
+
maxRetryDelayMs: options.maxRetryDelayMs,
|
|
70
|
+
signal: options.signal,
|
|
71
|
+
noRetryStatuses
|
|
72
|
+
});
|
|
73
|
+
await options.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
|
|
74
|
+
return json;
|
|
75
|
+
}
|
|
76
|
+
function tokenCount(value) {
|
|
77
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
78
|
+
}
|
|
79
|
+
function parseClassifierUsage(value, model) {
|
|
80
|
+
if (!isRecord(value) || value.input_tokens === undefined && value.output_tokens === undefined)
|
|
81
|
+
return;
|
|
82
|
+
const input = tokenCount(value.input_tokens);
|
|
83
|
+
const output = tokenCount(value.output_tokens);
|
|
84
|
+
const usage = {
|
|
85
|
+
input,
|
|
86
|
+
output,
|
|
87
|
+
cacheRead: 0,
|
|
88
|
+
cacheWrite: 0,
|
|
89
|
+
totalTokens: input + output,
|
|
90
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
91
|
+
};
|
|
92
|
+
calculateCost(model, usage);
|
|
93
|
+
return usage;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { isRecord, requiredNumber, postClassifierRequest, parseClassifierUsage };
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
resolveGrammarConstrainedSampling,
|
|
9
9
|
resolveJsonSchemaStrictSampling,
|
|
10
10
|
transformMessages
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-xf713zz0.js";
|
|
12
12
|
import {
|
|
13
13
|
sanitizeSurrogates
|
|
14
14
|
} from "./cli-y2apkfe2.js";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
renderSystemMessageUpdate,
|
|
19
19
|
resolveTranscript,
|
|
20
20
|
resolveTranscriptTools
|
|
21
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-g7k7zbcz.js";
|
|
22
22
|
import {
|
|
23
23
|
parseStreamingJson
|
|
24
24
|
} from "./cli-1m2e086m.js";
|
|
@@ -6,18 +6,20 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
parseModelStr,
|
|
8
8
|
resolveCredential
|
|
9
|
-
} from "./cli-
|
|
10
|
-
import {
|
|
11
|
-
DEFAULT_OPENROUTER_BASE_URL,
|
|
12
|
-
getOpenRouterBaseUrl
|
|
13
|
-
} from "./cli-3dpj7atn.js";
|
|
9
|
+
} from "./cli-7mhy3ths.js";
|
|
14
10
|
import {
|
|
15
11
|
complete,
|
|
16
12
|
getBuiltinModel
|
|
17
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-km4x66j0.js";
|
|
18
14
|
import {
|
|
19
15
|
exports_typebox
|
|
20
16
|
} from "./cli-rb9m6rpe.js";
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_OPENROUTER_BASE_URL,
|
|
19
|
+
getOpenRouterAttributionHeaders,
|
|
20
|
+
getOpenRouterBaseUrl,
|
|
21
|
+
init_openrouter_base_url
|
|
22
|
+
} from "./cli-a35hzdve.js";
|
|
21
23
|
import {
|
|
22
24
|
init_zod
|
|
23
25
|
} from "./cli-sd0mxa3c.js";
|
|
@@ -31,6 +33,7 @@ import {
|
|
|
31
33
|
|
|
32
34
|
// src/utils/internal-ai/complete-structured.ts
|
|
33
35
|
init_zod();
|
|
36
|
+
init_openrouter_base_url();
|
|
34
37
|
init_secret_scrubber();
|
|
35
38
|
var CLAUDE_CLI_TIMEOUT_MS = 30000;
|
|
36
39
|
function stripJsonFences(raw) {
|
|
@@ -169,10 +172,12 @@ ${claudeUserPrompt}`, cred.modelDefault, opts.signal, jsonSchema);
|
|
|
169
172
|
console.error(scrubSecrets(`internal-ai: unknown model ${provider}/${modelId} (callerTag=${callerTag})`));
|
|
170
173
|
return null;
|
|
171
174
|
}
|
|
172
|
-
const
|
|
175
|
+
const env = opts.env ?? process.env;
|
|
176
|
+
const openRouterBaseUrl = getOpenRouterBaseUrl(env);
|
|
173
177
|
if (provider === "openrouter" && openRouterBaseUrl !== DEFAULT_OPENROUTER_BASE_URL) {
|
|
174
178
|
model = { ...model, baseUrl: openRouterBaseUrl };
|
|
175
179
|
}
|
|
180
|
+
const headers = provider === "openrouter" ? getOpenRouterAttributionHeaders(model.baseUrl, env) : {};
|
|
176
181
|
const completeFn = opts._complete ?? complete;
|
|
177
182
|
const toolChoice = model.api === "anthropic-messages" ? { type: "tool", name: opts.toolName } : "required";
|
|
178
183
|
let userPrompt = opts.userPrompt;
|
|
@@ -189,7 +194,7 @@ ${claudeUserPrompt}`, cred.modelDefault, opts.signal, jsonSchema);
|
|
|
189
194
|
parameters: opts.toolSchema
|
|
190
195
|
}
|
|
191
196
|
]
|
|
192
|
-
}, { apiKey: cred.apiKey, signal: opts.signal, toolChoice });
|
|
197
|
+
}, { apiKey: cred.apiKey, signal: opts.signal, toolChoice, headers });
|
|
193
198
|
const toolCall = msg.content.find((c) => c.type === "toolCall" && c.name === opts.toolName);
|
|
194
199
|
if (!toolCall) {
|
|
195
200
|
const assistantText = msg.content.filter((content) => content.type === "text").map((content) => content.text).join(`
|