@desplega.ai/agent-swarm 1.122.0 → 1.123.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/README.md +2 -0
- package/dist/{actions-k3bwtmgy.js → actions-e4c9f0xy.js} +6 -6
- package/dist/{app-knevny0f.js → app-vmvmj2v3.js} +4 -4
- package/dist/{assistant-as8087ft.js → assistant-yn7a792a.js} +14 -11
- package/dist/{boot-reembed-j305cpdr.js → boot-reembed-chxty50a.js} +4 -4
- package/dist/{boot-reembed-1dcc1yyk.js → boot-reembed-xg1r86h2.js} +3 -3
- package/dist/{boot-scrub-logs-w9qkjzkm.js → boot-scrub-logs-exwddvp5.js} +2 -2
- package/dist/{claude-adapter-vxvcym3r.js → claude-adapter-zvzp4x76.js} +1 -1
- package/dist/{claude-managed-adapter-g807894s.js → claude-managed-adapter-g92bcm1a.js} +1 -1
- package/dist/{cli-3ptjc655.js → cli-1592nfd6.js} +1 -1
- package/dist/{cli-x4apc9t3.js → cli-36dctyg8.js} +139 -23
- package/dist/{cli-fc1gvt9c.js → cli-3tv9z4wx.js} +6 -3
- package/dist/{cli-wmx631p8.js → cli-4509mwm5.js} +159 -21
- package/dist/{cli-ma04faw5.js → cli-5arfywtm.js} +2 -0
- package/dist/{cli-m7dmk462.js → cli-822d4bjk.js} +18 -14
- package/dist/{cli-mjxnr12j.js → cli-8cq4z4x7.js} +510 -30
- package/dist/{cli-zpa6gjwq.js → cli-8ef5ky75.js} +1 -1
- package/dist/{cli-hjq6c6vz.js → cli-9eka6jwv.js} +2 -2
- package/dist/{cli-z3hcrghs.js → cli-9hj1adgp.js} +1 -1
- package/dist/{cli-60q15ncp.js → cli-byv3720g.js} +2 -2
- package/dist/{cli-tc8xk5zh.js → cli-c9m59f83.js} +1 -1
- package/dist/{cli-zweca3q3.js → cli-exfs8aym.js} +1 -1
- package/dist/{cli-9fhxk91h.js → cli-fjf04hpa.js} +11 -6
- package/dist/{cli-w48hgc2y.js → cli-h2say6xk.js} +3 -3
- package/dist/{cli-586x669g.js → cli-hbbxmhec.js} +4 -4
- package/dist/{cli-5c4327dx.js → cli-jj1arm18.js} +15 -1
- package/dist/{cli-00yr0kxv.js → cli-kmm1rwmp.js} +1 -1
- package/dist/{cli-7jb8mk4n.js → cli-mepk1j0t.js} +1 -1
- package/dist/{cli-y3an9mk7.js → cli-mkpf4ndf.js} +1052 -254
- package/dist/{cli-haeq79yf.js → cli-mngsj9fx.js} +8 -3
- package/dist/{cli-bxdb36d2.js → cli-n8mf7x4b.js} +2 -2
- package/dist/{cli-wwsaj97q.js → cli-ngbsk4yx.js} +16 -1
- package/dist/{cli-8sv69q06.js → cli-np0yhmmk.js} +60 -22
- package/dist/{cli-8x745f40.js → cli-p11rf59d.js} +7 -4
- package/dist/{cli-16dv125e.js → cli-peaqed7c.js} +20 -3
- package/dist/{cli-qnmj37m5.js → cli-vz9drmce.js} +3 -2
- package/dist/{cli-tyfxrrdd.js → cli-w5r4wfm5.js} +11 -1
- package/dist/{cli-kpfsabp2.js → cli-we91ywvy.js} +85 -7
- package/dist/{cli-qf0qxzw5.js → cli-zdp11t8m.js} +22 -17
- package/dist/{cli-j89ph4c4.js → cli-zkj6f2sk.js} +2 -2
- package/dist/cli.js +12 -12
- package/dist/{codex-adapter-0kv2meed.js → codex-adapter-vcseqpwf.js} +1 -1
- package/dist/{codex-session-runner-m1e1v4r0.js → codex-session-runner-jec9e9t1.js} +1 -1
- package/dist/{commands-6j54dz62.js → commands-sjk3zfyr.js} +7 -4
- package/dist/{db-gcnz2tqx.js → db-2je5agjb.js} +24 -2
- package/dist/{devin-adapter-pe1cgpd4.js → devin-adapter-8nmsgff3.js} +1 -1
- package/dist/{handlers-c43sm2h1.js → handlers-yzv369hf.js} +41 -12
- package/dist/{hook-y1p25vm5.js → hook-rfsj2r8x.js} +1 -1
- package/dist/{http-bsz1rze1.js → http-v9rr144m.js} +484 -640
- package/dist/{index-03zn2rz7.js → index-3xtk777g.js} +9 -9
- package/dist/{index-qyzfh62q.js → index-c3tan44f.js} +10 -10
- package/dist/{index-8m5gd1vs.js → index-nr2199m6.js} +11 -11
- package/dist/{index-7swcv6rv.js → index-smjdc3h9.js} +7 -7
- package/dist/{keepalive-69v93p45.js → keepalive-5ds53bjd.js} +5 -5
- package/dist/{lead-xn8kfchy.js → lead-5xhez25b.js} +26 -26
- package/dist/{maintenance-g2x7q13q.js → maintenance-b43d24q6.js} +4 -4
- package/dist/{oauth-refresh-sweep-j80szsyr.js → oauth-refresh-sweep-qe286vn2.js} +4 -4
- package/dist/{onboard-e3xcjt8b.js → onboard-c4r3ds3z.js} +2 -2
- package/dist/{opencode-adapter-s3nhtp9m.js → opencode-adapter-44z93505.js} +1 -1
- package/dist/{otel-impl-24egvjaa.js → otel-impl-nv3rjw61.js} +1 -1
- package/dist/{pi-mono-adapter-k3z6e5fn.js → pi-mono-adapter-2syx1x4d.js} +21 -1
- package/dist/{pricing-refresh-01kg9gky.js → pricing-refresh-5ct2wp4k.js} +4 -4
- package/dist/{rbac-roles-jqfp0zza.js → rbac-roles-b82cxpxn.js} +4 -4
- package/dist/{rbac-roles-f9bdj93y.js → rbac-roles-m502w0qv.js} +3 -3
- package/dist/{seed-pricing-z2t7rank.js → seed-pricing-jhjphbf0.js} +3 -3
- package/dist/{setup-kw2ps002.js → setup-zbaspydq.js} +2 -2
- package/dist/{worker-336w8930.js → worker-snvhpax5.js} +26 -26
- package/openapi.json +311 -16
- package/package.json +3 -3
- package/src/be/budget-admission.ts +2 -1
- package/src/be/db.ts +288 -2
- package/src/be/memory/constants.ts +29 -25
- package/src/be/memory/providers/sqlite-store.ts +3 -3
- package/src/be/memory/reranker.ts +4 -5
- package/src/be/migrations/121_task_steering_messages.sql +24 -0
- package/src/be/migrations/122_steering_handled_note.sql +4 -0
- package/src/be/rbac-audit.ts +2 -1
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/steering.ts +251 -0
- package/src/be/swarm-config-guard.ts +117 -1
- package/src/commands/context-preamble.ts +68 -8
- package/src/commands/provider-credentials.ts +2 -2
- package/src/commands/runner.ts +168 -1
- package/src/gitlab/auth.ts +3 -1
- package/src/heartbeat/heartbeat.ts +79 -20
- package/src/http/active-sessions.ts +1 -1
- package/src/http/core.ts +69 -1
- package/src/http/index.ts +6 -2
- package/src/http/mcp-oauth.ts +2 -1
- package/src/http/memory.ts +2 -2
- package/src/http/schedules.ts +2 -2
- package/src/http/script-runs.ts +1 -1
- package/src/http/sessions.ts +5 -1
- package/src/http/stats.ts +5 -1
- package/src/http/tasks.ts +407 -13
- package/src/oauth/mcp-wrapper.ts +2 -1
- package/src/otel.ts +23 -10
- package/src/prompts/base-prompt.ts +15 -0
- package/src/prompts/session-templates.ts +31 -0
- package/src/providers/claude-adapter.ts +208 -26
- package/src/providers/claude-managed-adapter.ts +20 -1
- package/src/providers/codex-adapter.ts +2 -1
- package/src/providers/devin-adapter.ts +18 -1
- package/src/providers/opencode-adapter.ts +32 -0
- package/src/providers/pi-mono-adapter.ts +33 -1
- package/src/providers/types.ts +11 -1
- package/src/rbac/admission.ts +2 -1
- package/src/rbac/legacy-policy.ts +2 -0
- package/src/rbac/permissions.ts +8 -0
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/types/stdlib.d.ts +6 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +6 -0
- package/src/server-user.ts +22 -0
- package/src/server.ts +11 -0
- package/src/slack/HEURISTICS.md +7 -0
- package/src/slack/assistant.ts +3 -2
- package/src/slack/blocks.ts +2 -0
- package/src/slack/commands.ts +2 -1
- package/src/slack/handlers.ts +39 -4
- package/src/slack/router.ts +5 -2
- package/src/slack/steering.ts +67 -0
- package/src/slack/thread-buffer.ts +39 -0
- package/src/slack/watcher.ts +5 -0
- package/src/tasks/worker-follow-up.ts +9 -2
- package/src/telemetry.ts +2 -1
- package/src/tests/claude-adapter-binary.test.ts +5 -0
- package/src/tests/claude-managed-adapter.test.ts +61 -0
- package/src/tests/devin-adapter.test.ts +41 -0
- package/src/tests/env-flag.test.ts +93 -0
- package/src/tests/heartbeat-reroute-decision.test.ts +10 -10
- package/src/tests/heartbeat-supersede-resume.test.ts +2 -2
- package/src/tests/mcp-user-route.test.ts +14 -2
- package/src/tests/opencode-adapter.test.ts +176 -1
- package/src/tests/pi-mono-adapter.test.ts +80 -0
- package/src/tests/prompt-template-session.test.ts +5 -4
- package/src/tests/provider-steering-capabilities.test.ts +44 -0
- package/src/tests/rbac-engine.test.ts +2 -1
- package/src/tests/reload-config.test.ts +81 -6
- package/src/tests/sdk-allowlist.test.ts +7 -0
- package/src/tests/slack-steering.test.ts +227 -0
- package/src/tests/status.test.ts +20 -0
- package/src/tests/steer-task-tool.test.ts +200 -0
- package/src/tests/steering-core.test.ts +601 -0
- package/src/tests/steering-enabled.test.ts +343 -0
- package/src/tests/steering-promotion.test.ts +205 -0
- package/src/tests/steering-transport.test.ts +338 -0
- package/src/tests/tool-output-agent-id.test.ts +182 -0
- package/src/tests/user-token-rest-auth.test.ts +31 -30
- package/src/tools/accept-steer.ts +148 -0
- package/src/tools/cancel-task.ts +1 -1
- package/src/tools/context-diff.ts +1 -1
- package/src/tools/context-history.ts +2 -3
- package/src/tools/create-channel.ts +2 -2
- package/src/tools/credential-bindings/tool.ts +1 -1
- package/src/tools/delete-channel.ts +1 -1
- package/src/tools/get-swarm.ts +1 -1
- package/src/tools/get-task-details.ts +4 -1
- package/src/tools/get-tasks.ts +4 -1
- package/src/tools/inject-learning.ts +1 -1
- package/src/tools/join-swarm.ts +1 -1
- package/src/tools/kv/kv-delete.ts +1 -1
- package/src/tools/kv/kv-get.ts +1 -1
- package/src/tools/kv/kv-incr.ts +1 -1
- package/src/tools/kv/kv-list.ts +1 -1
- package/src/tools/kv/kv-set.ts +1 -1
- package/src/tools/list-channels.ts +1 -1
- package/src/tools/list-services.ts +2 -2
- package/src/tools/mcp-servers/mcp-server-create.ts +1 -1
- package/src/tools/mcp-servers/mcp-server-delete.ts +1 -1
- package/src/tools/mcp-servers/mcp-server-get.ts +1 -1
- package/src/tools/mcp-servers/mcp-server-install.ts +1 -1
- package/src/tools/mcp-servers/mcp-server-list.ts +1 -1
- package/src/tools/mcp-servers/mcp-server-uninstall.ts +1 -1
- package/src/tools/mcp-servers/mcp-server-update.ts +1 -1
- package/src/tools/memory-delete.ts +1 -1
- package/src/tools/memory-edit.ts +1 -1
- package/src/tools/memory-get.ts +1 -1
- package/src/tools/memory-search.ts +27 -22
- package/src/tools/my-agent-info.ts +1 -1
- package/src/tools/poll-task.ts +1 -1
- package/src/tools/post-message.ts +2 -2
- package/src/tools/prompt-templates/delete.ts +1 -1
- package/src/tools/prompt-templates/get.ts +1 -1
- package/src/tools/prompt-templates/list.ts +1 -1
- package/src/tools/prompt-templates/preview.ts +1 -1
- package/src/tools/prompt-templates/set.ts +1 -1
- package/src/tools/read-messages.ts +1 -1
- package/src/tools/register-agentmail-inbox.ts +1 -1
- package/src/tools/register-kapso-number.ts +2 -3
- package/src/tools/register-service.ts +1 -1
- package/src/tools/request-human-input.ts +1 -1
- package/src/tools/schedules/create-schedule.ts +2 -6
- package/src/tools/schedules/delete-schedule.ts +1 -1
- package/src/tools/schedules/list-schedules.ts +1 -1
- package/src/tools/schedules/patch-schedule.ts +2 -2
- package/src/tools/schedules/run-schedule-now.ts +1 -1
- package/src/tools/schedules/update-schedule.ts +2 -2
- package/src/tools/script-connections/tool.ts +1 -1
- package/src/tools/send-task.ts +4 -2
- package/src/tools/skills/skill-create.ts +1 -1
- package/src/tools/skills/skill-delete.ts +1 -1
- package/src/tools/skills/skill-get-file.ts +1 -1
- package/src/tools/skills/skill-get.ts +1 -1
- package/src/tools/skills/skill-install-remote.ts +1 -1
- package/src/tools/skills/skill-install.ts +1 -1
- package/src/tools/skills/skill-list.ts +1 -1
- package/src/tools/skills/skill-publish.ts +1 -1
- package/src/tools/skills/skill-search.ts +1 -1
- package/src/tools/skills/skill-sync-remote.ts +1 -1
- package/src/tools/skills/skill-uninstall.ts +1 -1
- package/src/tools/skills/skill-update.ts +1 -1
- package/src/tools/steer-task.ts +149 -0
- package/src/tools/store-progress.ts +17 -12
- package/src/tools/swarm-config/delete-config.ts +1 -1
- package/src/tools/swarm-config/get-config.ts +1 -2
- package/src/tools/swarm-config/list-config.ts +2 -2
- package/src/tools/swarm-config/set-config.ts +1 -2
- package/src/tools/task-action.ts +1 -1
- package/src/tools/tool-config.ts +3 -1
- package/src/tools/unregister-service.ts +1 -1
- package/src/tools/update-profile.ts +1 -2
- package/src/tools/update-service-status.ts +1 -1
- package/src/tools/whatsapp-message.ts +1 -1
- package/src/types.ts +106 -22
- package/src/utils/env-flag.ts +55 -0
- package/src/utils/scripts-only-mode.ts +12 -2
- package/src/utils/steering-enabled.ts +12 -0
- package/src/workflows/engine.ts +14 -6
- package/src/workflows/executors/agent-task.ts +3 -1
package/README.md
CHANGED
|
@@ -127,6 +127,8 @@ Check [our templates](https://templates.agent-swarm.dev) for a quick start.
|
|
|
127
127
|
- **Multi-channel inputs** — Slack, GitHub, GitLab, email, WhatsApp, Linear, Jira, and the HTTP API all create tasks. [Integrations](#integrations)
|
|
128
128
|
- **Workflow engine with Human-in-the-Loop** — DAG-based automation with approval gates, retries, and structured I/O. [Workflows →](https://docs.agent-swarm.dev/docs/concepts/workflows)
|
|
129
129
|
- **Scheduled & recurring tasks** — cron-based automation for standing work, with schedules that can target agent tasks, workflows, or catalog scripts. [Scheduling →](https://docs.agent-swarm.dev/docs/concepts/scheduling)
|
|
130
|
+
- **Mid-run task steering** — add context at the next turn boundary, request an immediate interrupt where the harness supports it, or degrade safely to a follow-up task. [Task steering →](https://docs.agent-swarm.dev/docs/guides/task-steering)
|
|
131
|
+
- **Operator configuration UI** — tune non-secret feature flags, limits, integration toggles, and runtime defaults from Settings → Configuration, with source and restart-required indicators. [Configuration →](https://docs.agent-swarm.dev/docs/ui/configuration)
|
|
130
132
|
- **Asset namespaces** — group tasks, workflows, schedules, pages, and mapped files under canonical shared or personal keys, with inheritance, subtree filtering, audited moves, and cross-entity discovery. [Asset namespaces →](https://docs.agent-swarm.dev/docs/guides/asset-namespaces)
|
|
131
133
|
- **Persistent shared files via agent-fs** — co-deploy agent-fs for shared task attachments, previews, and search; late provisioning or config reloads activate the provider without an API restart, and tenant-authenticated control planes can invite shared-org members without receiving the bootstrap key. [Co-deployment guide →](https://docs.agent-swarm.dev/docs/guides/agent-fs-co-deployment)
|
|
132
134
|
- **Durable script workflows** — launch background script runs, inspect their journals, and track them from the dashboard when a one-shot `script-run` is too small. [Guide →](https://docs.agent-swarm.dev/docs/guides/script-workflow-runs)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveSlackUserId
|
|
3
|
-
} from "./cli-
|
|
4
|
-
import"./cli-
|
|
3
|
+
} from "./cli-n8mf7x4b.js";
|
|
4
|
+
import"./cli-1592nfd6.js";
|
|
5
5
|
import {
|
|
6
6
|
createTaskWithSiblingAwareness
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-kmm1rwmp.js";
|
|
8
8
|
import {
|
|
9
9
|
buildCancelledBlocks,
|
|
10
10
|
getTaskLink
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-5arfywtm.js";
|
|
12
12
|
import"./cli-wspgs9bt.js";
|
|
13
13
|
import"./cli-dh55d5fg.js";
|
|
14
14
|
import {
|
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
init_context_key,
|
|
20
20
|
init_db,
|
|
21
21
|
slackContextKey
|
|
22
|
-
} from "./cli-
|
|
22
|
+
} from "./cli-8cq4z4x7.js";
|
|
23
23
|
import"./cli-z2zcxes1.js";
|
|
24
|
-
import"./cli-
|
|
24
|
+
import"./cli-h2say6xk.js";
|
|
25
25
|
import"./cli-4j2mrzag.js";
|
|
26
26
|
import"./cli-bw80ck94.js";
|
|
27
27
|
import"./cli-xz9aq0rf.js";
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
initSlackApp,
|
|
4
4
|
startSlackApp,
|
|
5
5
|
stopSlackApp
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-fjf04hpa.js";
|
|
7
7
|
import"./cli-rkndnn90.js";
|
|
8
8
|
import"./cli-b0p7rfnd.js";
|
|
9
|
-
import"./cli-
|
|
9
|
+
import"./cli-5arfywtm.js";
|
|
10
10
|
import"./cli-wspgs9bt.js";
|
|
11
11
|
import"./cli-dh55d5fg.js";
|
|
12
|
-
import"./cli-
|
|
12
|
+
import"./cli-8cq4z4x7.js";
|
|
13
13
|
import"./cli-z2zcxes1.js";
|
|
14
|
-
import"./cli-
|
|
14
|
+
import"./cli-h2say6xk.js";
|
|
15
15
|
import"./cli-4j2mrzag.js";
|
|
16
16
|
import"./cli-bw80ck94.js";
|
|
17
17
|
import"./cli-xz9aq0rf.js";
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bufferThreadMessage,
|
|
3
3
|
wasEventSeen
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-we91ywvy.js";
|
|
5
5
|
import {
|
|
6
6
|
hasOtherUserMention
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-3tv9z4wx.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveSlackUserId,
|
|
10
10
|
rewriteSlackMentions
|
|
11
|
-
} from "./cli-
|
|
12
|
-
import"./cli-
|
|
11
|
+
} from "./cli-n8mf7x4b.js";
|
|
12
|
+
import"./cli-1592nfd6.js";
|
|
13
13
|
import {
|
|
14
14
|
createTaskWithSiblingAwareness
|
|
15
|
-
} from "./cli-
|
|
15
|
+
} from "./cli-kmm1rwmp.js";
|
|
16
16
|
import {
|
|
17
17
|
require_dist
|
|
18
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-fjf04hpa.js";
|
|
19
19
|
import"./cli-rkndnn90.js";
|
|
20
20
|
import"./cli-b0p7rfnd.js";
|
|
21
|
-
import"./cli-
|
|
21
|
+
import"./cli-5arfywtm.js";
|
|
22
22
|
import"./cli-wspgs9bt.js";
|
|
23
23
|
import"./cli-dh55d5fg.js";
|
|
24
24
|
import {
|
|
@@ -27,12 +27,14 @@ import {
|
|
|
27
27
|
getMostRecentTaskInThread,
|
|
28
28
|
init_context_key,
|
|
29
29
|
init_db,
|
|
30
|
+
init_env_flag,
|
|
30
31
|
init_resolver,
|
|
32
|
+
isEnvFlagEnabled,
|
|
31
33
|
resolveTemplate,
|
|
32
34
|
slackContextKey
|
|
33
|
-
} from "./cli-
|
|
35
|
+
} from "./cli-8cq4z4x7.js";
|
|
34
36
|
import"./cli-z2zcxes1.js";
|
|
35
|
-
import"./cli-
|
|
37
|
+
import"./cli-h2say6xk.js";
|
|
36
38
|
import"./cli-4j2mrzag.js";
|
|
37
39
|
import"./cli-bw80ck94.js";
|
|
38
40
|
import"./cli-xz9aq0rf.js";
|
|
@@ -47,7 +49,8 @@ init_db();
|
|
|
47
49
|
init_resolver();
|
|
48
50
|
init_context_key();
|
|
49
51
|
var import_bolt = __toESM(require_dist(), 1);
|
|
50
|
-
|
|
52
|
+
init_env_flag();
|
|
53
|
+
var isAdditiveSlack = () => isEnvFlagEnabled("ADDITIVE_SLACK", false);
|
|
51
54
|
var cachedBotUserId = null;
|
|
52
55
|
function createAssistant() {
|
|
53
56
|
return new import_bolt.Assistant({
|
|
@@ -119,7 +122,7 @@ function createAssistant() {
|
|
|
119
122
|
}) : undefined;
|
|
120
123
|
const workingAgent = getAgentWorkingOnThread(channelId, threadTs);
|
|
121
124
|
if (workingAgent && workingAgent.status !== "offline") {
|
|
122
|
-
if (
|
|
125
|
+
if (isAdditiveSlack()) {
|
|
123
126
|
bufferThreadMessage(channelId, threadTs, messageText, userId, message.ts);
|
|
124
127
|
await safeSetStatus("Queuing follow-up...");
|
|
125
128
|
return;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
embedScript,
|
|
3
3
|
embeddingProvider
|
|
4
|
-
} from "./cli-
|
|
5
|
-
import"./cli-
|
|
4
|
+
} from "./cli-byv3720g.js";
|
|
5
|
+
import"./cli-zdp11t8m.js";
|
|
6
6
|
import"./cli-q25ejbyn.js";
|
|
7
7
|
import {
|
|
8
8
|
getDb,
|
|
9
9
|
init_db
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-8cq4z4x7.js";
|
|
11
11
|
import"./cli-z2zcxes1.js";
|
|
12
|
-
import"./cli-
|
|
12
|
+
import"./cli-h2say6xk.js";
|
|
13
13
|
import"./cli-4j2mrzag.js";
|
|
14
14
|
import"./cli-bw80ck94.js";
|
|
15
15
|
import"./cli-xz9aq0rf.js";
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
getEmbeddingProvider,
|
|
4
4
|
getMemoryStore,
|
|
5
5
|
init_constants
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-zdp11t8m.js";
|
|
7
7
|
import"./cli-q25ejbyn.js";
|
|
8
8
|
import {
|
|
9
9
|
getDb,
|
|
10
10
|
init_db
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-8cq4z4x7.js";
|
|
12
12
|
import"./cli-z2zcxes1.js";
|
|
13
|
-
import"./cli-
|
|
13
|
+
import"./cli-h2say6xk.js";
|
|
14
14
|
import"./cli-4j2mrzag.js";
|
|
15
15
|
import"./cli-bw80ck94.js";
|
|
16
16
|
import"./cli-xz9aq0rf.js";
|
|
@@ -71,6 +71,38 @@ function parseClaudeBinary(raw) {
|
|
|
71
71
|
return ["claude"];
|
|
72
72
|
return trimmed.split(/\s+/);
|
|
73
73
|
}
|
|
74
|
+
var MIN_CLAUDE_QUEUE_STEERING_VERSION = [2, 1, 205];
|
|
75
|
+
function resolveClaudeQueueSteeringOverride(env) {
|
|
76
|
+
const raw = env.CLAUDE_QUEUE_STEERING?.trim().toLowerCase();
|
|
77
|
+
if (!raw)
|
|
78
|
+
return;
|
|
79
|
+
if (["0", "false", "off", "no"].includes(raw))
|
|
80
|
+
return false;
|
|
81
|
+
if (["1", "true", "on", "yes"].includes(raw))
|
|
82
|
+
return true;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
function supportsClaudeQueueSteering(versionOutput) {
|
|
86
|
+
const match = versionOutput?.match(/claude(?: code)? version:\s*(\d+)\.(\d+)\.(\d+)/i) ?? versionOutput?.match(/(\d+)\.(\d+)\.(\d+)\s*\(Claude Code\)/i);
|
|
87
|
+
if (!match)
|
|
88
|
+
return false;
|
|
89
|
+
const detected = match.slice(1, 4).map(Number);
|
|
90
|
+
for (let index = 0;index < MIN_CLAUDE_QUEUE_STEERING_VERSION.length; index++) {
|
|
91
|
+
const actual = detected[index] ?? 0;
|
|
92
|
+
const minimum = MIN_CLAUDE_QUEUE_STEERING_VERSION[index] ?? 0;
|
|
93
|
+
if (actual !== minimum)
|
|
94
|
+
return actual > minimum;
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
function claudeUserMessage(text) {
|
|
99
|
+
return `${JSON.stringify({
|
|
100
|
+
type: "user",
|
|
101
|
+
message: { role: "user", content: text },
|
|
102
|
+
parent_tool_use_id: null
|
|
103
|
+
})}
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
74
106
|
function resolveClaudeBinary(resolvedEnv, fallbackEnv = process.env) {
|
|
75
107
|
const candidate = resolvedEnv.CLAUDE_BINARY?.trim() || fallbackEnv.CLAUDE_BINARY?.trim();
|
|
76
108
|
return candidate || "claude";
|
|
@@ -247,7 +279,9 @@ class ClaudeSession {
|
|
|
247
279
|
claudeBinaryArgv;
|
|
248
280
|
harnessVariant;
|
|
249
281
|
harnessVariantMeta;
|
|
282
|
+
queueSteeringSupported;
|
|
250
283
|
proc;
|
|
284
|
+
stdinWriter;
|
|
251
285
|
listeners = [];
|
|
252
286
|
eventQueue = [];
|
|
253
287
|
_sessionId;
|
|
@@ -257,13 +291,15 @@ class ClaudeSession {
|
|
|
257
291
|
contextWindowSize;
|
|
258
292
|
systemPromptFile;
|
|
259
293
|
appliedReasoningEffort;
|
|
260
|
-
|
|
294
|
+
deliverSteering;
|
|
295
|
+
constructor(config, model, taskFilePath, taskFilePid, sessionMcpConfig = null, claudeBinaryArgv = ["claude"], systemPromptFile = null, harnessVariant, harnessVariantMeta, queueSteeringSupported = false) {
|
|
261
296
|
this.config = config;
|
|
262
297
|
this.model = model;
|
|
263
298
|
this.sessionMcpConfig = sessionMcpConfig;
|
|
264
299
|
this.claudeBinaryArgv = claudeBinaryArgv;
|
|
265
300
|
this.harnessVariant = harnessVariant;
|
|
266
301
|
this.harnessVariantMeta = harnessVariantMeta;
|
|
302
|
+
this.queueSteeringSupported = queueSteeringSupported;
|
|
267
303
|
this.taskFilePid = taskFilePid;
|
|
268
304
|
this.contextWindowSize = getContextWindowSize(model);
|
|
269
305
|
this.systemPromptFile = systemPromptFile;
|
|
@@ -289,11 +325,60 @@ class ClaudeSession {
|
|
|
289
325
|
...sourceEnv.CLAUDE_CODE_OAUTH_TOKEN ? { AGENT_SWARM_CLAUDE_OAUTH_TOKEN: sourceEnv.CLAUDE_CODE_OAUTH_TOKEN } : {},
|
|
290
326
|
CONTEXT_MODE_EXTERNAL_MCP_NUDGE_EVERY: CTX_MODE_NUDGE_EVERY
|
|
291
327
|
},
|
|
328
|
+
...this.queueSteeringSupported ? { stdin: "pipe" } : {},
|
|
292
329
|
stdout: "pipe",
|
|
293
330
|
stderr: "pipe"
|
|
294
331
|
});
|
|
332
|
+
if (this.queueSteeringSupported) {
|
|
333
|
+
const stdin = this.proc.stdin;
|
|
334
|
+
if (stdin && typeof stdin !== "number") {
|
|
335
|
+
this.stdinWriter = stdin;
|
|
336
|
+
this.writeUserMessage(this.config.prompt).catch((err) => {
|
|
337
|
+
console.warn(`\x1B[33m[claude]\x1B[0m Failed to write initial prompt to Claude stdin: ${scrubSecrets(String(err))}`);
|
|
338
|
+
this.closeStdin();
|
|
339
|
+
try {
|
|
340
|
+
this.proc.kill("SIGTERM");
|
|
341
|
+
} catch {}
|
|
342
|
+
});
|
|
343
|
+
} else {
|
|
344
|
+
console.warn("\x1B[33m[claude]\x1B[0m Claude stdin was not piped; terminating the session to avoid waiting without a prompt.");
|
|
345
|
+
try {
|
|
346
|
+
this.proc.kill("SIGTERM");
|
|
347
|
+
} catch {}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (this.queueSteeringSupported && this.stdinWriter) {
|
|
351
|
+
this.deliverSteering = async ({
|
|
352
|
+
mode,
|
|
353
|
+
text
|
|
354
|
+
}) => {
|
|
355
|
+
if (mode === "steer") {
|
|
356
|
+
console.warn("[claude-adapter] Interrupt requested; raw Claude CLI supports queued steering only, so the message will run at the next turn boundary.");
|
|
357
|
+
}
|
|
358
|
+
if (!this.stdinWriter) {
|
|
359
|
+
return { delivered: false, reason: "Claude stdin is closed" };
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
await this.writeUserMessage(text);
|
|
363
|
+
return { delivered: true, mode: "queue" };
|
|
364
|
+
} catch (err) {
|
|
365
|
+
this.closeStdin();
|
|
366
|
+
return {
|
|
367
|
+
delivered: false,
|
|
368
|
+
reason: `Claude stdin write failed: ${String(err)}`
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
}
|
|
295
373
|
this.completionPromise = this.processStreams();
|
|
296
374
|
}
|
|
375
|
+
async writeUserMessage(text) {
|
|
376
|
+
const writer = this.stdinWriter;
|
|
377
|
+
if (!writer)
|
|
378
|
+
throw new Error("Claude stdin is closed");
|
|
379
|
+
await writer.write(claudeUserMessage(text));
|
|
380
|
+
await writer.flush?.();
|
|
381
|
+
}
|
|
297
382
|
buildCommand() {
|
|
298
383
|
const cmd = [
|
|
299
384
|
...this.claudeBinaryArgv,
|
|
@@ -305,10 +390,13 @@ class ClaudeSession {
|
|
|
305
390
|
"--dangerously-skip-permissions",
|
|
306
391
|
"--allow-dangerously-skip-permissions",
|
|
307
392
|
"--permission-mode",
|
|
308
|
-
"bypassPermissions"
|
|
309
|
-
"-p",
|
|
310
|
-
this.config.prompt
|
|
393
|
+
"bypassPermissions"
|
|
311
394
|
];
|
|
395
|
+
if (this.queueSteeringSupported) {
|
|
396
|
+
cmd.push("--input-format", "stream-json");
|
|
397
|
+
} else {
|
|
398
|
+
cmd.push("-p", this.config.prompt);
|
|
399
|
+
}
|
|
312
400
|
if (this.config.additionalArgs?.length) {
|
|
313
401
|
cmd.push(...this.config.additionalArgs);
|
|
314
402
|
}
|
|
@@ -331,6 +419,16 @@ class ClaudeSession {
|
|
|
331
419
|
this.eventQueue.push(event);
|
|
332
420
|
}
|
|
333
421
|
}
|
|
422
|
+
closeStdin() {
|
|
423
|
+
const writer = this.stdinWriter;
|
|
424
|
+
this.stdinWriter = undefined;
|
|
425
|
+
if (!writer)
|
|
426
|
+
return;
|
|
427
|
+
try {
|
|
428
|
+
const result = writer.end();
|
|
429
|
+
Promise.resolve(result).catch(() => {});
|
|
430
|
+
} catch {}
|
|
431
|
+
}
|
|
334
432
|
async processStreams() {
|
|
335
433
|
const logFileHandle = Bun.file(this.config.logFile).writer();
|
|
336
434
|
let stderrOutput = "";
|
|
@@ -383,7 +481,11 @@ class ClaudeSession {
|
|
|
383
481
|
this.emit({ type: "raw_stderr", content: scrubbedText });
|
|
384
482
|
}
|
|
385
483
|
})();
|
|
386
|
-
|
|
484
|
+
try {
|
|
485
|
+
await Promise.all([stdoutPromise, stderrPromise]);
|
|
486
|
+
} finally {
|
|
487
|
+
this.closeStdin();
|
|
488
|
+
}
|
|
387
489
|
await logFileHandle.end();
|
|
388
490
|
const exitCode = await this.proc.exited;
|
|
389
491
|
await cleanupTaskFile(this.taskFilePid);
|
|
@@ -422,6 +524,9 @@ ${scrubSecrets(stderrOutput)}`);
|
|
|
422
524
|
processJsonLine(trimmed, setCost) {
|
|
423
525
|
try {
|
|
424
526
|
const json = JSON.parse(trimmed);
|
|
527
|
+
if (json.type === "result") {
|
|
528
|
+
this.closeStdin();
|
|
529
|
+
}
|
|
425
530
|
if (json.type === "system" && json.subtype === "init" && json.session_id) {
|
|
426
531
|
this._sessionId = json.session_id;
|
|
427
532
|
this.emit({
|
|
@@ -527,13 +632,20 @@ ${scrubSecrets(stderrOutput)}`);
|
|
|
527
632
|
return this.completionPromise;
|
|
528
633
|
}
|
|
529
634
|
async abort() {
|
|
530
|
-
this.
|
|
635
|
+
this.closeStdin();
|
|
636
|
+
try {
|
|
637
|
+
this.proc.kill("SIGTERM");
|
|
638
|
+
} catch {}
|
|
531
639
|
}
|
|
532
640
|
}
|
|
533
641
|
|
|
534
642
|
class ClaudeAdapter {
|
|
535
643
|
name = "claude";
|
|
536
|
-
traits = {
|
|
644
|
+
traits = {
|
|
645
|
+
hasMcp: true,
|
|
646
|
+
hasLocalEnvironment: true,
|
|
647
|
+
steerModes: ["queue"]
|
|
648
|
+
};
|
|
537
649
|
async createSession(config) {
|
|
538
650
|
if (config.resumeSessionId) {
|
|
539
651
|
console.warn("[claude-adapter] resumeSessionId ignored — native resume is disabled by deprecation plan");
|
|
@@ -594,24 +706,28 @@ class ClaudeAdapter {
|
|
|
594
706
|
}
|
|
595
707
|
const harnessVariant = useClaudeBridge ? "bridge" : "stock";
|
|
596
708
|
let harnessVariantMeta;
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (trimmed)
|
|
709
|
+
const queueSteeringOverride = resolveClaudeQueueSteeringOverride(sourceEnv);
|
|
710
|
+
let harnessVersion;
|
|
711
|
+
try {
|
|
712
|
+
const result = Bun.spawnSync([...effectiveClaudeBinaryArgv, "--version"], {
|
|
713
|
+
env: sourceEnv,
|
|
714
|
+
stdout: "pipe",
|
|
715
|
+
stderr: "pipe"
|
|
716
|
+
});
|
|
717
|
+
if (result.success) {
|
|
718
|
+
const trimmed = `${result.stdout?.toString() ?? ""}
|
|
719
|
+
${result.stderr?.toString() ?? ""}`.trim();
|
|
720
|
+
if (trimmed) {
|
|
721
|
+
harnessVersion = trimmed;
|
|
611
722
|
harnessVariantMeta = { version: trimmed };
|
|
612
|
-
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
} catch {}
|
|
726
|
+
const queueSteeringSupported = queueSteeringOverride ?? (!isInteractiveTmuxClaude && supportsClaudeQueueSteering(harnessVersion));
|
|
727
|
+
if (!queueSteeringSupported && queueSteeringOverride === undefined) {
|
|
728
|
+
console.warn(`\x1B[33m[claude]\x1B[0m Queued steering requires Claude Code >= ${MIN_CLAUDE_QUEUE_STEERING_VERSION.join(".")}; detected ${harnessVersion ?? "an unknown version"}. Steering messages will be promoted to follow-up tasks.`);
|
|
613
729
|
}
|
|
614
|
-
return new ClaudeSession(config, model, taskFilePath, taskFilePid, sessionMcpConfig, effectiveClaudeBinaryArgv, systemPromptFile, harnessVariant, harnessVariantMeta);
|
|
730
|
+
return new ClaudeSession(config, model, taskFilePath, taskFilePid, sessionMcpConfig, effectiveClaudeBinaryArgv, systemPromptFile, harnessVariant, harnessVariantMeta, queueSteeringSupported);
|
|
615
731
|
}
|
|
616
732
|
async canResume(_sessionId) {
|
|
617
733
|
return true;
|
|
@@ -2,18 +2,21 @@ import {
|
|
|
2
2
|
getAgentById,
|
|
3
3
|
getAgentWorkingOnThread,
|
|
4
4
|
getAllAgents,
|
|
5
|
-
init_db
|
|
6
|
-
|
|
5
|
+
init_db,
|
|
6
|
+
init_env_flag,
|
|
7
|
+
isEnvFlagEnabled
|
|
8
|
+
} from "./cli-8cq4z4x7.js";
|
|
7
9
|
|
|
8
10
|
// src/slack/router.ts
|
|
9
11
|
init_db();
|
|
12
|
+
init_env_flag();
|
|
10
13
|
function hasOtherUserMention(text, botUserId) {
|
|
11
14
|
const mentions = text.match(/<@([A-Z0-9]+)>/g) ?? [];
|
|
12
15
|
return mentions.some((m) => m !== `<@${botUserId}>`);
|
|
13
16
|
}
|
|
14
17
|
function routeMessage(text, botUserId, botMentioned, threadContext) {
|
|
15
18
|
const matches = [];
|
|
16
|
-
const requireMentionForThreadFollowup =
|
|
19
|
+
const requireMentionForThreadFollowup = isEnvFlagEnabled("SLACK_THREAD_FOLLOWUP_REQUIRE_MENTION", false);
|
|
17
20
|
const agents = getAllAgents().filter((a) => a.status !== "offline");
|
|
18
21
|
const idMatches = text.matchAll(/swarm#([a-f0-9-]{36})/gi);
|
|
19
22
|
for (const match of idMatches) {
|