@desplega.ai/agent-swarm 2.6.0 → 2.7.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/{acp-adapter-dgfakfpw.js → acp-adapter-ma1js5n7.js} +6 -6
- package/dist/{actions-fbqma8aa.js → actions-1vhmtvg9.js} +18 -18
- package/dist/{amp-adapter-en0jy6hs.js → amp-adapter-sxqqvmdk.js} +3 -3
- package/dist/{app-k8a5cgpp.js → app-mwx1d5a9.js} +3 -3
- package/dist/{assistant-a16433gr.js → assistant-yx1p6g82.js} +20 -20
- package/dist/{boot-reembed-f4nn561n.js → boot-reembed-5h37a2c2.js} +1 -1
- package/dist/{boot-reembed-6c1sjfnr.js → boot-reembed-7h78vmvv.js} +2 -1
- package/dist/{boot-scrub-sweep-d4w9gajf.js → boot-scrub-sweep-8mawd4gw.js} +3 -3
- package/dist/{boot-seeds-9bmkspyw.js → boot-seeds-ca84dhnn.js} +4 -4
- package/dist/{claude-adapter-nys1kjxa.js → claude-adapter-wqt4hfkq.js} +7 -7
- package/dist/{claude-managed-adapter-55207973.js → claude-managed-adapter-6fjqtr2z.js} +2 -2
- package/dist/{claude-managed-setup-3cm35gey.js → claude-managed-setup-rqv98sea.js} +2 -2
- package/dist/{claude-sdk-session-nw5yd8cp.js → claude-sdk-session-f29f3b2x.js} +7 -7
- package/dist/{cli-sxgtf5fw.js → cli-07q03xm2.js} +1 -1
- package/dist/{cli-k21gx5ht.js → cli-1hhbzkbb.js} +6 -6
- package/dist/{cli-v49fkghp.js → cli-1m9x8dr5.js} +1 -1
- package/dist/{cli-24j1jeeb.js → cli-2pvzmas1.js} +3 -3
- package/dist/{cli-w2656ka1.js → cli-2y7v133v.js} +7 -7
- package/dist/{cli-g8ka5j4j.js → cli-48gxjmcz.js} +94 -36
- package/dist/{cli-2sjhpsns.js → cli-54sj64fc.js} +1 -1
- package/dist/{cli-aj8djyqt.js → cli-60sty27p.js} +2 -2
- package/dist/{cli-4hxrf0p4.js → cli-6a9qfa8b.js} +308 -47
- package/dist/{cli-n7asmce6.js → cli-6mgdba42.js} +3 -3
- package/dist/{cli-gf95q3bm.js → cli-6srv653c.js} +3 -3
- package/dist/{cli-9abdgn5t.js → cli-86ehn4s5.js} +3 -3
- package/dist/{cli-bqztfyve.js → cli-8mbc9za9.js} +1 -1
- package/dist/{cli-a2rr0fmg.js → cli-8wmj18cz.js} +1 -1
- package/dist/{cli-c2habvsf.js → cli-9gsm2rzp.js} +8 -8
- package/dist/{cli-4rf0f5vg.js → cli-9pshx6rd.js} +4 -2
- package/dist/{cli-abkm71vr.js → cli-a6ds2epe.js} +1 -1
- package/dist/{cli-esakngh8.js → cli-a89zdqz9.js} +1 -1
- package/dist/{cli-3ndmpxxv.js → cli-ay40dnj3.js} +2 -2
- package/dist/{cli-kf4jree9.js → cli-aypd09nf.js} +1 -1
- package/dist/{cli-6y51ryva.js → cli-b3yzyc57.js} +1 -1
- package/dist/{cli-ag2yrnt5.js → cli-c668vvcf.js} +2 -2
- package/dist/{cli-5sckpqcx.js → cli-d20qvpr2.js} +1 -1
- package/dist/{cli-a34pr3w1.js → cli-e1595bgx.js} +2 -2
- package/dist/{cli-m70bajzr.js → cli-f12mr20z.js} +1 -1
- package/dist/{cli-dqygeeh5.js → cli-f1e0ptjj.js} +10 -1
- package/dist/{cli-mvjz5an3.js → cli-f4dbh7a5.js} +7 -7
- package/dist/{cli-az25fn5f.js → cli-gsfk58nw.js} +2 -2
- package/dist/{cli-1tem6ns9.js → cli-gt4h8cxw.js} +3 -2
- package/dist/{cli-cz37jqss.js → cli-h5jeg46p.js} +2 -2
- package/dist/{cli-emhjcj2y.js → cli-he9gbdx0.js} +60 -10
- package/dist/{cli-3fwqy71j.js → cli-j0ppywdr.js} +38 -31
- package/dist/{cli-5rj83bam.js → cli-j3y0x2n4.js} +34 -33
- package/dist/{cli-3gfvmzht.js → cli-j9bpmykh.js} +73 -25
- package/dist/{cli-m5a9m0ak.js → cli-kv7sbc2c.js} +3 -3
- package/dist/{cli-g20jjwt4.js → cli-m30k9777.js} +12 -12
- package/dist/{cli-683y0b3a.js → cli-m5e802r7.js} +2 -2
- package/dist/{cli-nn6vx2mq.js → cli-ptfq202x.js} +5 -3
- package/dist/{cli-d2dpf95n.js → cli-qj442fws.js} +1 -1
- package/dist/{cli-03gg9pd1.js → cli-rd5m70gj.js} +4 -4
- package/dist/{cli-gnsb1zxa.js → cli-s09j9vp5.js} +1 -1
- package/dist/{cli-zqne1qcj.js → cli-s0mgx214.js} +2 -2
- package/dist/{cli-sqma6vw1.js → cli-sgqm2582.js} +5 -5
- package/dist/{cli-nq677csy.js → cli-sjctjr48.js} +1 -1
- package/dist/{cli-3aqd4jaa.js → cli-twctnkng.js} +3 -3
- package/dist/{cli-j6rktc91.js → cli-v6shg7na.js} +1 -1
- package/dist/{cli-7enjwya9.js → cli-vz78s5wm.js} +1 -1
- package/dist/{cli-art7c1zh.js → cli-wqr7cea4.js} +4 -4
- package/dist/{cli-hfeb68z4.js → cli-x37r7qwf.js} +11 -3
- package/dist/{cli-ffvsj2qw.js → cli-yd2nreqw.js} +2 -2
- package/dist/{cli-ca6banwz.js → cli-ymjpkxgn.js} +6 -6
- package/dist/{cli-mtnj4fwa.js → cli-yxbsmx56.js} +5 -5
- package/dist/cli.js +18 -16
- package/dist/{codex-adapter-d95q4qsn.js → codex-adapter-zk59x2zh.js} +5 -5
- package/dist/{codex-hook-brpnycn5.js → codex-hook-xyjhvxwd.js} +1 -1
- package/dist/{codex-session-runner-gdwd8h0c.js → codex-session-runner-kh6s4j3n.js} +5 -5
- package/dist/{commands-jqmgk54b.js → commands-68et1qv2.js} +2 -2
- package/dist/{controller-z3jq589f.js → controller-fyrbnzg4.js} +2 -2
- package/dist/{controllers-connect-r2za39ef.js → controllers-connect-nep9h2xv.js} +19 -19
- package/dist/{cursor-adapter-4mr4jgkw.js → cursor-adapter-yss3pg7t.js} +1 -1
- package/dist/{db-w36wwb5g.js → db-28gjyvxj.js} +2 -2
- package/dist/{db-ppv2tze7.js → db-8ftwvzba.js} +3 -3
- package/dist/{dispatcher-pv5h77vf.js → dispatcher-hayexmkr.js} +17 -17
- package/dist/{dsh-adapter-d4pdpb3r.js → dsh-adapter-46wawff9.js} +1 -1
- package/dist/{easter-egg-3d-4sp4dvmc.js → easter-egg-3d-8d1e0h4m.js} +1 -1
- package/dist/{execute-jev839y1.js → execute-cjrfxfnm.js} +1 -1
- package/dist/{external-channel-y6nkzhnn.js → external-channel-xbmxcg09.js} +2 -2
- package/dist/{grok-adapter-t08b9ntm.js → grok-adapter-ag4wks2a.js} +7 -7
- package/dist/handlers-tzmevqb5.js +41 -0
- package/dist/{heartbeat-vn31xwdk.js → heartbeat-psfvcgwp.js} +20 -20
- package/dist/{hook-6d0zbvvt.js → hook-8pz04697.js} +5 -5
- package/dist/{hook-cpjs8q51.js → hook-cyq4mryn.js} +6 -6
- package/dist/{http-9c6medda.js → http-haj1nd6k.js} +109 -114
- package/dist/{index-qhjf2htm.js → index-jwt2bj6f.js} +261 -96
- package/dist/{index-g6k9tctj.js → index-q52f47pe.js} +1 -1
- package/dist/{index-pkma1yf8.js → index-syvhnvtw.js} +1 -1
- package/dist/{index-yqgbfgaj.js → index-y1ajx04a.js} +20 -20
- package/dist/{index-k0yt1tvq.js → index-z5h22pes.js} +17 -17
- package/dist/{index-38t35h0n.js → index-zyq8ct52.js} +17 -17
- package/dist/{keepalive-em0117bp.js → keepalive-xdvsamvj.js} +3 -3
- package/dist/{lead-23e7z59t.js → lead-hqg57kdp.js} +35 -35
- package/dist/{maintenance-kbme3qy9.js → maintenance-4y2xzh3a.js} +1 -1
- package/dist/{oauth-refresh-sweep-xysj4yse.js → oauth-refresh-sweep-jd4r7zbs.js} +8 -3
- package/dist/{onboard-p6q0vz97.js → onboard-18447q9q.js} +5 -5
- package/dist/{opencode-adapter-esv3k9yn.js → opencode-adapter-26b2frdf.js} +5 -5
- package/dist/{otel-impl-54qhqh1z.js → otel-impl-f9tgr8yw.js} +1 -1
- package/dist/{pi-mono-adapter-mymbwhj0.js → pi-mono-adapter-qn6qbga1.js} +33 -12
- package/dist/{pricing-refresh-yb75wv33.js → pricing-refresh-dw2tgb53.js} +3 -3
- package/dist/{rbac-roles-1vp2mw4p.js → rbac-roles-aygm2760.js} +2 -2
- package/dist/{rbac-roles-dexhc9x8.js → rbac-roles-s4nwj2m3.js} +1 -1
- package/dist/{render-v2-tjay5hhf.js → render-v2-yfvdfr0x.js} +3 -3
- package/dist/{resume-8ayf37g5.js → resume-1bmvjbf3.js} +7 -7
- package/dist/{runtime-hqe5cqcd.js → runtime-f7tpzedy.js} +1 -1
- package/dist/{session-access-fdhp987s.js → session-access-r5garej6.js} +4 -4
- package/dist/{session-source-backfill-qgtc86z1.js → session-source-backfill-424wzv0r.js} +2 -2
- package/dist/{setup-4rrmqcq3.js → setup-8tygvxkq.js} +1 -1
- package/dist/{virtual-modules-52km00d6.js → virtual-modules-xsw323b3.js} +2 -2
- package/dist/{work-objects-p28fgd70.js → work-objects-ggnghpgf.js} +20 -20
- package/dist/{worker-e3w7vye1.js → worker-sqjd1nqf.js} +35 -35
- package/openapi.json +69 -1
- package/package.json +5 -3
- package/src/be/automation-preflight.ts +2 -0
- package/src/be/db/api-keys.ts +9 -0
- package/src/be/db/workflow-runs.ts +36 -5
- package/src/be/db.ts +80 -22
- package/src/be/memory/task-learning.ts +155 -0
- package/src/be/migrations/245_script_executor.sql +3 -0
- package/src/be/oauth-refresh-sweep.ts +2 -1
- package/src/be/scripts/boot-reembed.ts +2 -0
- package/src/be/scripts/db.ts +14 -4
- package/src/be/scripts/embeddings.ts +2 -0
- package/src/be/scripts/run-saved.ts +1 -0
- package/src/be/scripts/typecheck.ts +9 -3
- package/src/be/seed-skills/index.ts +7 -0
- package/src/commands/onboard/compose-generator.ts +5 -3
- package/src/commands/provider-credentials.ts +2 -1
- package/src/heartbeat/heartbeat.ts +14 -1
- package/src/heartbeat/script-runner-probe.ts +47 -0
- package/src/http/api-keys.ts +24 -9
- package/src/http/idempotency-key.ts +1 -1
- package/src/http/index.ts +3 -3
- package/src/http/pages-public.ts +38 -5
- package/src/http/scripts.ts +27 -0
- package/src/http/workflows.ts +10 -0
- package/src/http/x.ts +5 -0
- package/src/prompts/base-prompt.ts +21 -1
- package/src/prompts/session-templates.ts +17 -3
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/dsh-adapter.ts +1 -1
- package/src/providers/pi-mono-adapter.ts +41 -11
- package/src/scheduler/scheduler.ts +2 -1
- package/src/scripts-runtime/eval-harness.ts +8 -1
- package/src/scripts-runtime/executors/native.ts +22 -16
- package/src/scripts-runtime/executors/quickjs-prelude.ts +103 -1
- package/src/scripts-runtime/executors/quickjs-runner.ts +2 -1
- package/src/scripts-runtime/executors/quickjs.ts +7 -0
- package/src/scripts-runtime/executors/registry.ts +32 -0
- package/src/scripts-runtime/executors/types.ts +7 -0
- package/src/scripts-runtime/host-validated-args.ts +133 -0
- package/src/scripts-runtime/loader.ts +30 -3
- package/src/scripts-runtime/swarm-sdk.ts +9 -2
- package/src/scripts-runtime/types/stdlib.d.ts +9 -1
- package/src/scripts-runtime/types/swarm-sdk.d.ts +9 -1
- package/src/tests/api-key-status-by-suffix.test.ts +242 -0
- package/src/tests/base-prompt.test.ts +70 -2
- package/src/tests/community-linear-delivery-loop.test.ts +2099 -0
- package/src/tests/credential-check.test.ts +4 -2
- package/src/tests/docs-index.test.ts +135 -0
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/fetch-resolved-env.test.ts +16 -2
- package/src/tests/heartbeat-checklist.test.ts +89 -0
- package/src/tests/heartbeat-script-runner-probe.test.ts +83 -0
- package/src/tests/oauth-refresh-sweep.test.ts +34 -1
- package/src/tests/onboard-compose.test.ts +20 -0
- package/src/tests/opencode-adapter.test.ts +2 -1
- package/src/tests/pages-frame-ancestors.test.ts +162 -0
- package/src/tests/pi-codemode.test.ts +2 -1
- package/src/tests/pi-mono-adapter.test.ts +54 -0
- package/src/tests/pi-native-mcp.test.ts +13 -1
- package/src/tests/pi-tool-exposure.test.ts +8 -8
- package/src/tests/probe-tool-schema-tokens.test.ts +144 -0
- package/src/tests/prompt-template-session.test.ts +4 -3
- package/src/tests/request-composition-derive.test.ts +329 -0
- package/src/tests/script-connections.test.ts +2 -0
- package/src/tests/script-executor-conformance.test.ts +36 -1
- package/src/tests/script-executor-quickjs-pool.test.ts +50 -0
- package/src/tests/script-executor-quickjs.test.ts +140 -0
- package/src/tests/script-host-validated-args-native.test.ts +196 -0
- package/src/tests/script-per-script-executor.test.ts +415 -0
- package/src/tests/scripts-external-api.test.ts +45 -0
- package/src/tests/sdk-allowlist.test.ts +3 -2
- package/src/tests/self-improvement.test.ts +4 -4
- package/src/tests/store-progress-learning.test.ts +288 -0
- package/src/tests/ui-logs-parser.test.ts +180 -0
- package/src/tests/workflow-engine-v2.test.ts +116 -1
- package/src/tests/workflow-mcp-trigger-schema.test.ts +209 -0
- package/src/tests/workflow-run-finished-event.test.ts +263 -0
- package/src/tests/workflow-swarm-script.test.ts +34 -0
- package/src/tools/script-common.ts +1 -0
- package/src/tools/script-run.ts +7 -0
- package/src/tools/script-upsert.ts +7 -0
- package/src/tools/store-progress.ts +67 -1
- package/src/tools/workflows/trigger-workflow.ts +104 -10
- package/src/types.ts +12 -1
- package/src/utils/credentials.ts +5 -2
- package/src/workflows/engine.ts +18 -16
- package/src/workflows/executors/swarm-script.ts +5 -0
- package/src/workflows/foreach-driver.ts +5 -11
- package/src/workflows/node-timeout.ts +30 -0
- package/templates/community/linear-delivery-loop/PLAYBOOK.md +323 -0
- package/templates/community/linear-delivery-loop/README.md +38 -0
- package/templates/community/linear-delivery-loop/config.example.json +31 -0
- package/templates/community/linear-delivery-loop/lead-prompt.md +34 -0
- package/templates/community/linear-delivery-loop/schedule.json +10 -0
- package/templates/community/linear-delivery-loop/scripts/linear-delivery-setup.ts +148 -0
- package/templates/community/linear-delivery-loop/scripts/linear-delivery-tick.ts +1781 -0
- package/templates/skills/swarm-docs/config.json +14 -0
- package/templates/skills/swarm-docs/content.md +144 -0
- package/dist/handlers-eqsnmv95.js +0 -41
|
@@ -173,23 +173,21 @@ export class NativeScriptExecutor implements ScriptExecutor {
|
|
|
173
173
|
let removeAbortListener: (() => void) | undefined;
|
|
174
174
|
let proc: Bun.Subprocess<"pipe", "pipe", "pipe"> | undefined;
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
error: "killed",
|
|
186
|
-
};
|
|
187
|
-
}
|
|
176
|
+
const killedOutput = (): ExecutorOutput => ({
|
|
177
|
+
result: undefined,
|
|
178
|
+
stdout: "",
|
|
179
|
+
stderr: "",
|
|
180
|
+
truncated: { stdout: false, stderr: false },
|
|
181
|
+
durationMs: Date.now() - start,
|
|
182
|
+
exitCode: 1,
|
|
183
|
+
error: "killed",
|
|
184
|
+
});
|
|
188
185
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
await writeBareImportShims(tmpdir);
|
|
186
|
+
try {
|
|
187
|
+
if (killed) return killedOutput();
|
|
192
188
|
|
|
189
|
+
// Listen before the first await: an abort during the file writes below
|
|
190
|
+
// must stop the spawn, not land between the writes and the listener.
|
|
193
191
|
const onExternalAbort = () => {
|
|
194
192
|
killed = true;
|
|
195
193
|
if (proc) void terminateProcessGroup(proc.pid);
|
|
@@ -197,12 +195,19 @@ export class NativeScriptExecutor implements ScriptExecutor {
|
|
|
197
195
|
input.signal?.addEventListener("abort", onExternalAbort, { once: true });
|
|
198
196
|
removeAbortListener = () => input.signal?.removeEventListener("abort", onExternalAbort);
|
|
199
197
|
|
|
198
|
+
await Bun.write(argsFile, JSON.stringify(input.args ?? null));
|
|
199
|
+
await Bun.write(sourceFile, input.source);
|
|
200
|
+
await writeBareImportShims(tmpdir);
|
|
201
|
+
|
|
202
|
+
// No await between this check and the spawn below.
|
|
203
|
+
if (killed) return killedOutput();
|
|
204
|
+
|
|
200
205
|
const timeout = setTimeout(() => {
|
|
201
206
|
timedOut = true;
|
|
202
207
|
if (proc) void terminateProcessGroup(proc.pid);
|
|
203
208
|
}, input.resources.wallClockMs);
|
|
204
209
|
|
|
205
|
-
const harnessEnv = {
|
|
210
|
+
const harnessEnv: Record<string, string> = {
|
|
206
211
|
PATH: process.env.PATH ?? "/usr/bin:/bin",
|
|
207
212
|
HOME: process.env.HOME ?? "/tmp",
|
|
208
213
|
LANG: process.env.LANG ?? "C.UTF-8",
|
|
@@ -214,6 +219,7 @@ export class NativeScriptExecutor implements ScriptExecutor {
|
|
|
214
219
|
SWARM_SCRIPT_RESULT_FILE: resultFile,
|
|
215
220
|
SWARM_SCRIPT_ERROR_FILE: errorFile,
|
|
216
221
|
SWARM_SCRIPT_STARTED_FILE: startedFile,
|
|
222
|
+
...(input.hostValidatedArgs ? { SWARM_SCRIPT_HOST_VALIDATED_ARGS: "1" } : {}),
|
|
217
223
|
};
|
|
218
224
|
|
|
219
225
|
proc = registerProcessGroup(
|
|
@@ -308,14 +308,116 @@ define("__swarm_ctx", ctx);
|
|
|
308
308
|
* zod `argsSchema` check, the same contract as `eval-harness.ts`.
|
|
309
309
|
*/
|
|
310
310
|
export const SANDBOX_EPILOGUE = String.raw`(async () => {
|
|
311
|
+
const isStructuralSchemaNode = (schema) => {
|
|
312
|
+
if (!schema || typeof schema !== "object") return false;
|
|
313
|
+
const def = schema._zod && schema._zod.def;
|
|
314
|
+
if (!def || typeof def !== "object") return false;
|
|
315
|
+
if (def.coerce) return false;
|
|
316
|
+
if (Array.isArray(def.checks) && def.checks.length > 0) return false;
|
|
317
|
+
switch (def.type) {
|
|
318
|
+
case "string":
|
|
319
|
+
case "number":
|
|
320
|
+
return !def.format;
|
|
321
|
+
case "boolean":
|
|
322
|
+
case "literal":
|
|
323
|
+
case "enum":
|
|
324
|
+
return true;
|
|
325
|
+
case "optional":
|
|
326
|
+
case "nullable":
|
|
327
|
+
return isStructuralSchemaNode(def.innerType);
|
|
328
|
+
case "array":
|
|
329
|
+
return isStructuralSchemaNode(def.element);
|
|
330
|
+
case "object": {
|
|
331
|
+
const rawShape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
332
|
+
if (!rawShape || typeof rawShape !== "object") return false;
|
|
333
|
+
return Object.values(rawShape).every(isStructuralSchemaNode);
|
|
334
|
+
}
|
|
335
|
+
default:
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
const isHostValidationEquivalent = (schema, value) => {
|
|
340
|
+
if (!schema || typeof schema !== "object") return false;
|
|
341
|
+
const def = schema._zod && schema._zod.def;
|
|
342
|
+
if (!def || typeof def !== "object") return false;
|
|
343
|
+
if (def.coerce) return false;
|
|
344
|
+
if (Array.isArray(def.checks) && def.checks.length > 0) return false;
|
|
345
|
+
switch (def.type) {
|
|
346
|
+
case "string":
|
|
347
|
+
return typeof value === "string" && !def.format;
|
|
348
|
+
case "number":
|
|
349
|
+
return typeof value === "number" && Number.isFinite(value) && !def.format;
|
|
350
|
+
case "boolean":
|
|
351
|
+
return typeof value === "boolean";
|
|
352
|
+
case "literal": {
|
|
353
|
+
const rawValues = def.values;
|
|
354
|
+
const values = Array.isArray(rawValues)
|
|
355
|
+
? rawValues
|
|
356
|
+
: rawValues instanceof Set
|
|
357
|
+
? Array.from(rawValues)
|
|
358
|
+
: [];
|
|
359
|
+
return (
|
|
360
|
+
values.length > 0 &&
|
|
361
|
+
values.some((v) => v === value && typeof v !== "bigint" && typeof v !== "symbol")
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
case "enum": {
|
|
365
|
+
if (schema._zod && schema._zod.values instanceof Set) {
|
|
366
|
+
return schema._zod.values.has(value);
|
|
367
|
+
}
|
|
368
|
+
const entriesObj = def.entries && typeof def.entries === "object" ? def.entries : null;
|
|
369
|
+
if (!entriesObj) return false;
|
|
370
|
+
const entries = Object.values(entriesObj).filter(
|
|
371
|
+
(v) => !(typeof v === "string" && typeof entriesObj[v] === "number"),
|
|
372
|
+
);
|
|
373
|
+
return entries.length > 0 && entries.includes(value);
|
|
374
|
+
}
|
|
375
|
+
case "optional":
|
|
376
|
+
return value === undefined
|
|
377
|
+
? isStructuralSchemaNode(def.innerType)
|
|
378
|
+
: isHostValidationEquivalent(def.innerType, value);
|
|
379
|
+
case "nullable":
|
|
380
|
+
return value === null
|
|
381
|
+
? isStructuralSchemaNode(def.innerType)
|
|
382
|
+
: isHostValidationEquivalent(def.innerType, value);
|
|
383
|
+
case "array":
|
|
384
|
+
return (
|
|
385
|
+
Array.isArray(value) &&
|
|
386
|
+
isStructuralSchemaNode(def.element) &&
|
|
387
|
+
value.every((item) => isHostValidationEquivalent(def.element, item))
|
|
388
|
+
);
|
|
389
|
+
case "object": {
|
|
390
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
391
|
+
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
392
|
+
if (!shape || typeof shape !== "object") return false;
|
|
393
|
+
for (const key of Object.keys(value)) {
|
|
394
|
+
if (!Object.hasOwn(shape, key)) return false;
|
|
395
|
+
}
|
|
396
|
+
for (const [key, propSchema] of Object.entries(shape)) {
|
|
397
|
+
if (!Object.hasOwn(value, key) && key in value) return false;
|
|
398
|
+
const propValue = value[key];
|
|
399
|
+
if (!isHostValidationEquivalent(propSchema, propValue)) return false;
|
|
400
|
+
}
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
default:
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
};
|
|
311
407
|
const mod = globalThis.__swarm_module;
|
|
312
408
|
if (!mod || typeof mod.default !== "function") {
|
|
313
409
|
throw new Error(
|
|
314
410
|
"Swarm script must export a default function. Script must export default async function (args, ctx): args FIRST, ctx second.",
|
|
315
411
|
);
|
|
316
412
|
}
|
|
413
|
+
const hostValidatedArgs = globalThis.__swarm_host_validated_args === true;
|
|
317
414
|
let args = globalThis.__swarm_args;
|
|
318
|
-
if (
|
|
415
|
+
if (
|
|
416
|
+
mod.argsSchema &&
|
|
417
|
+
typeof mod.argsSchema === "object" &&
|
|
418
|
+
"parse" in mod.argsSchema &&
|
|
419
|
+
!(hostValidatedArgs && isHostValidationEquivalent(mod.argsSchema, args))
|
|
420
|
+
) {
|
|
319
421
|
try {
|
|
320
422
|
args = mod.argsSchema.parse(args);
|
|
321
423
|
} catch (error) {
|
|
@@ -29,6 +29,7 @@ import type {
|
|
|
29
29
|
export type QuickJSJob = {
|
|
30
30
|
source: string;
|
|
31
31
|
args: unknown;
|
|
32
|
+
hostValidatedArgs?: boolean;
|
|
32
33
|
configPayload: SwarmConfigPayload;
|
|
33
34
|
resources: ScriptResourcePolicy;
|
|
34
35
|
network: ExecutorInput["network"];
|
|
@@ -656,7 +657,7 @@ async function evaluateJob(
|
|
|
656
657
|
|
|
657
658
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
658
659
|
try {
|
|
659
|
-
const init = `globalThis.__swarm_shape = ${JSON.stringify(shape)};\nglobalThis.__swarm_args = ${JSON.stringify(args)};`;
|
|
660
|
+
const init = `globalThis.__swarm_shape = ${JSON.stringify(shape)};\nglobalThis.__swarm_args = ${JSON.stringify(args)};\nglobalThis.__swarm_host_validated_args = ${Boolean(job.hostValidatedArgs)};`;
|
|
660
661
|
const ok =
|
|
661
662
|
evaluate(init, "swarm-init.js") &&
|
|
662
663
|
evaluate(SANDBOX_WEB_SHIMS, "swarm-web-shims.js") &&
|
|
@@ -146,6 +146,12 @@ export class QuickJSScriptExecutor implements ScriptExecutor {
|
|
|
146
146
|
`quickjs worker failed to start: ${error instanceof Error ? error.message : String(error)}`,
|
|
147
147
|
);
|
|
148
148
|
}
|
|
149
|
+
// An abort while the worker booted fired before the listener below
|
|
150
|
+
// exists. From here to postMessage nothing awaits.
|
|
151
|
+
if (input.signal?.aborted) {
|
|
152
|
+
pool.release(slot);
|
|
153
|
+
return emptyOutput("killed");
|
|
154
|
+
}
|
|
149
155
|
|
|
150
156
|
const id = ++requestSeq;
|
|
151
157
|
const start = performance.now();
|
|
@@ -196,6 +202,7 @@ export class QuickJSScriptExecutor implements ScriptExecutor {
|
|
|
196
202
|
job: {
|
|
197
203
|
source: input.source,
|
|
198
204
|
args: input.args,
|
|
205
|
+
...(input.hostValidatedArgs ? { hostValidatedArgs: true } : {}),
|
|
199
206
|
configPayload: input.configPayload,
|
|
200
207
|
resources: input.resources,
|
|
201
208
|
network: input.network,
|
|
@@ -7,6 +7,27 @@ const EXECUTORS: Record<string, () => ScriptExecutor> = {
|
|
|
7
7
|
quickjs: () => new QuickJSScriptExecutor(),
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
+
export function getDeploymentScriptExecutorName(env: NodeJS.ProcessEnv = process.env): string {
|
|
11
|
+
return (env.SCRIPT_EXECUTOR ?? "native").trim();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Operator sandbox ceiling: when the deployment sets `SCRIPT_EXECUTOR=quickjs`,
|
|
16
|
+
* individual scripts or agent calls may not escalate to the less-restricted
|
|
17
|
+
* `native` executor. When the deployment runs `native` (the default), scripts
|
|
18
|
+
* may opt down into `quickjs`.
|
|
19
|
+
*/
|
|
20
|
+
export function isExecutorAllowedByDeployment(
|
|
21
|
+
requested: string | null | undefined,
|
|
22
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
23
|
+
): boolean {
|
|
24
|
+
if (!requested) return true;
|
|
25
|
+
if (getDeploymentScriptExecutorName(env) === "quickjs" && requested.trim() === "native") {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
10
31
|
export function getScriptExecutor(name = process.env.SCRIPT_EXECUTOR ?? "native"): ScriptExecutor {
|
|
11
32
|
const factory = EXECUTORS[name.trim()];
|
|
12
33
|
if (!factory) {
|
|
@@ -16,3 +37,14 @@ export function getScriptExecutor(name = process.env.SCRIPT_EXECUTOR ?? "native"
|
|
|
16
37
|
}
|
|
17
38
|
return factory();
|
|
18
39
|
}
|
|
40
|
+
|
|
41
|
+
export function resolveScriptExecutor(
|
|
42
|
+
requested?: string | null,
|
|
43
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
44
|
+
): ScriptExecutor {
|
|
45
|
+
if (!isExecutorAllowedByDeployment(requested, env)) {
|
|
46
|
+
throw new Error('Executor "native" is not permitted when deployment SCRIPT_EXECUTOR="quickjs"');
|
|
47
|
+
}
|
|
48
|
+
const effective = requested ?? env.SCRIPT_EXECUTOR ?? "native";
|
|
49
|
+
return getScriptExecutor(effective);
|
|
50
|
+
}
|
|
@@ -3,6 +3,7 @@ import type { ScriptApiConnectionDescriptor, ScriptMcpConnectionDescriptor } fro
|
|
|
3
3
|
import type { FailedCredentialBinding, ResolvedCredentialBinding } from "../credential-broker";
|
|
4
4
|
|
|
5
5
|
export type ScriptFsMode = "none" | "workspace-rw";
|
|
6
|
+
export type ScriptExecutorName = "native" | "quickjs";
|
|
6
7
|
|
|
7
8
|
export type EgressSecretEntry = ResolvedCredentialBinding;
|
|
8
9
|
|
|
@@ -49,6 +50,12 @@ export type ScriptResourcePolicy = {
|
|
|
49
50
|
export type ExecutorInput = {
|
|
50
51
|
source: string;
|
|
51
52
|
args: unknown;
|
|
53
|
+
/**
|
|
54
|
+
* Trusted host-only flag indicating `args` already passed host JSON Schema
|
|
55
|
+
* validation for this run. Executors may skip `argsSchema.parse(args)` only
|
|
56
|
+
* when this flag is true AND the runtime `argsSchema` is purely structural.
|
|
57
|
+
*/
|
|
58
|
+
hostValidatedArgs?: boolean;
|
|
52
59
|
configPayload: SwarmConfigPayload;
|
|
53
60
|
resources: ScriptResourcePolicy;
|
|
54
61
|
fsMode: ScriptFsMode;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unforgeable host-only capability symbol set on `RunScriptInput` strictly at
|
|
3
|
+
* the host boundary (`POST /api/x/script/{endpointId}`) after `validateJsonSchema`
|
|
4
|
+
* succeeds. Because `Symbol` keys cannot be produced by JSON deserialization,
|
|
5
|
+
* callers that forward request-shaped JSON fields into `RunScriptInput` can
|
|
6
|
+
* never opt out of `argsSchema` validation.
|
|
7
|
+
*/
|
|
8
|
+
export const HOST_VALIDATED_ARGS = Symbol("swarm.hostValidatedArgs");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Checks whether a runtime `argsSchema` (Zod v4 / `zod/mini` schema) and its
|
|
12
|
+
* candidate `value` are semantically equivalent to the host-side JSON Schema
|
|
13
|
+
* validation performed by `validateJsonSchema` in `src/http/x.ts`.
|
|
14
|
+
*
|
|
15
|
+
* Returns `true` only when `schema.parse(value)` is guaranteed to succeed and
|
|
16
|
+
* return a value deeply identical to `value` without running any defaults,
|
|
17
|
+
* coercions, transforms, refinements, or unknown-key stripping.
|
|
18
|
+
*/
|
|
19
|
+
export function isHostValidationEquivalent(schema: unknown, value: unknown): boolean {
|
|
20
|
+
if (!schema || typeof schema !== "object") return false;
|
|
21
|
+
const zodInternal = (schema as { _zod?: { def?: Record<string, unknown>; values?: unknown } })
|
|
22
|
+
._zod;
|
|
23
|
+
const def = zodInternal?.def;
|
|
24
|
+
if (!def || typeof def !== "object") return false;
|
|
25
|
+
|
|
26
|
+
if (def.coerce) return false;
|
|
27
|
+
if (Array.isArray(def.checks) && def.checks.length > 0) return false;
|
|
28
|
+
|
|
29
|
+
switch (def.type) {
|
|
30
|
+
case "string":
|
|
31
|
+
return typeof value === "string" && !def.format;
|
|
32
|
+
case "number":
|
|
33
|
+
return typeof value === "number" && Number.isFinite(value) && !def.format;
|
|
34
|
+
case "boolean":
|
|
35
|
+
return typeof value === "boolean";
|
|
36
|
+
case "literal": {
|
|
37
|
+
const rawValues = def.values;
|
|
38
|
+
const values = Array.isArray(rawValues)
|
|
39
|
+
? rawValues
|
|
40
|
+
: rawValues instanceof Set
|
|
41
|
+
? Array.from(rawValues)
|
|
42
|
+
: [];
|
|
43
|
+
return (
|
|
44
|
+
values.length > 0 &&
|
|
45
|
+
values.some((v) => v === value && typeof v !== "bigint" && typeof v !== "symbol")
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
case "enum": {
|
|
49
|
+
if (zodInternal?.values instanceof Set) {
|
|
50
|
+
return zodInternal.values.has(value);
|
|
51
|
+
}
|
|
52
|
+
const entriesObj =
|
|
53
|
+
def.entries && typeof def.entries === "object"
|
|
54
|
+
? (def.entries as Record<string, unknown>)
|
|
55
|
+
: null;
|
|
56
|
+
if (!entriesObj) return false;
|
|
57
|
+
const entries = Object.values(entriesObj).filter(
|
|
58
|
+
(v) => !(typeof v === "string" && typeof entriesObj[v] === "number"),
|
|
59
|
+
);
|
|
60
|
+
return entries.length > 0 && entries.includes(value);
|
|
61
|
+
}
|
|
62
|
+
case "optional":
|
|
63
|
+
return value === undefined
|
|
64
|
+
? isStructuralSchemaNode(def.innerType)
|
|
65
|
+
: isHostValidationEquivalent(def.innerType, value);
|
|
66
|
+
case "nullable":
|
|
67
|
+
return value === null
|
|
68
|
+
? isStructuralSchemaNode(def.innerType)
|
|
69
|
+
: isHostValidationEquivalent(def.innerType, value);
|
|
70
|
+
case "array":
|
|
71
|
+
return (
|
|
72
|
+
Array.isArray(value) &&
|
|
73
|
+
isStructuralSchemaNode(def.element) &&
|
|
74
|
+
value.every((item) => isHostValidationEquivalent(def.element, item))
|
|
75
|
+
);
|
|
76
|
+
case "object": {
|
|
77
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
78
|
+
const rawShape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
79
|
+
if (!rawShape || typeof rawShape !== "object") return false;
|
|
80
|
+
const shape = rawShape as Record<string, unknown>;
|
|
81
|
+
const obj = value as Record<string, unknown>;
|
|
82
|
+
|
|
83
|
+
// If `value` carries extra keys not declared in `shape`, let `.parse()`
|
|
84
|
+
// handle key stripping (`z.object`), passthrough (`z.looseObject`), or
|
|
85
|
+
// rejection (`z.strictObject`).
|
|
86
|
+
for (const key of Object.keys(obj)) {
|
|
87
|
+
if (!Object.hasOwn(shape, key)) return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (const [key, propSchema] of Object.entries(shape)) {
|
|
91
|
+
// Retain Zod's property lookup semantics: if `key` is absent as an own
|
|
92
|
+
// property on `obj` but resolves via `Object.prototype` (e.g. `constructor`,
|
|
93
|
+
// `toString`), fall back to `.parse()` so Zod validates/rejects the
|
|
94
|
+
// inherited prototype value identically to `main`.
|
|
95
|
+
if (!Object.hasOwn(obj, key) && key in obj) return false;
|
|
96
|
+
const propValue = obj[key];
|
|
97
|
+
if (!isHostValidationEquivalent(propSchema, propValue)) return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
default:
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function isStructuralSchemaNode(schema: unknown): boolean {
|
|
107
|
+
if (!schema || typeof schema !== "object") return false;
|
|
108
|
+
const def = (schema as { _zod?: { def?: Record<string, unknown> } })._zod?.def;
|
|
109
|
+
if (!def || typeof def !== "object") return false;
|
|
110
|
+
if (def.coerce) return false;
|
|
111
|
+
if (Array.isArray(def.checks) && def.checks.length > 0) return false;
|
|
112
|
+
switch (def.type) {
|
|
113
|
+
case "string":
|
|
114
|
+
case "number":
|
|
115
|
+
return !def.format;
|
|
116
|
+
case "boolean":
|
|
117
|
+
case "literal":
|
|
118
|
+
case "enum":
|
|
119
|
+
return true;
|
|
120
|
+
case "optional":
|
|
121
|
+
case "nullable":
|
|
122
|
+
return isStructuralSchemaNode(def.innerType);
|
|
123
|
+
case "array":
|
|
124
|
+
return isStructuralSchemaNode(def.element);
|
|
125
|
+
case "object": {
|
|
126
|
+
const rawShape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
127
|
+
if (!rawShape || typeof rawShape !== "object") return false;
|
|
128
|
+
return Object.values(rawShape as Record<string, unknown>).every(isStructuralSchemaNode);
|
|
129
|
+
}
|
|
130
|
+
default:
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -6,16 +6,18 @@ import { createValueScrubber, scrubObject, scrubSecrets } from "../utils/secret-
|
|
|
6
6
|
import type { ScriptApiConnectionDescriptor, ScriptMcpConnectionDescriptor } from "./api-types";
|
|
7
7
|
import type { FailedCredentialBinding } from "./credential-broker";
|
|
8
8
|
import { buildEgressSecrets } from "./egress-secrets";
|
|
9
|
-
import {
|
|
9
|
+
import { isExecutorAllowedByDeployment, resolveScriptExecutor } from "./executors/registry";
|
|
10
10
|
import {
|
|
11
11
|
DEFAULT_SCRIPT_RESOURCES,
|
|
12
12
|
type EgressSecretEntry,
|
|
13
13
|
type ExecutorOutput,
|
|
14
14
|
type ScriptAgentFsDescriptor,
|
|
15
|
+
type ScriptExecutorName,
|
|
15
16
|
type ScriptFsMode,
|
|
16
17
|
type ScriptResourcePolicy,
|
|
17
18
|
type SwarmConfigPayload,
|
|
18
19
|
} from "./executors/types";
|
|
20
|
+
import { HOST_VALIDATED_ARGS } from "./host-validated-args";
|
|
19
21
|
import { validateScriptImports } from "./import-allowlist";
|
|
20
22
|
|
|
21
23
|
/**
|
|
@@ -38,7 +40,19 @@ const CAPACITY_EXCEEDED_RETRY_DELAYS_MS = [200, 750];
|
|
|
38
40
|
export type RunScriptInput = {
|
|
39
41
|
source: string;
|
|
40
42
|
args?: unknown;
|
|
43
|
+
/**
|
|
44
|
+
* Unforgeable host-only capability symbol set only when the host has already
|
|
45
|
+
* validated `args` against the script's `argsJsonSchema` (e.g. `POST /api/x/script/{endpointId}`).
|
|
46
|
+
* Keyed by a `Symbol` so request-shaped JSON inputs forwarded into `RunScriptInput`
|
|
47
|
+
* can never opt out of `argsSchema` validation.
|
|
48
|
+
*/
|
|
49
|
+
[HOST_VALIDATED_ARGS]?: boolean;
|
|
41
50
|
fsMode?: ScriptFsMode;
|
|
51
|
+
/**
|
|
52
|
+
* Optional per-script executor override ("native" | "quickjs"). When null or
|
|
53
|
+
* undefined, `getScriptExecutor` falls back to `SCRIPT_EXECUTOR ?? "native"`.
|
|
54
|
+
*/
|
|
55
|
+
executor?: ScriptExecutorName | null;
|
|
42
56
|
agentId: string;
|
|
43
57
|
/**
|
|
44
58
|
* Bearer for the run's `ctx.swarm` SDK calls. Api-side callers pass a
|
|
@@ -118,6 +132,18 @@ export async function runScript(input: RunScriptInput): Promise<RunScriptOutput>
|
|
|
118
132
|
};
|
|
119
133
|
}
|
|
120
134
|
|
|
135
|
+
if (!isExecutorAllowedByDeployment(input.executor)) {
|
|
136
|
+
return {
|
|
137
|
+
result: undefined,
|
|
138
|
+
stdout: "",
|
|
139
|
+
stderr: 'Executor "native" is not permitted when deployment SCRIPT_EXECUTOR="quickjs"',
|
|
140
|
+
truncated: { stdout: false, stderr: false },
|
|
141
|
+
durationMs: 0,
|
|
142
|
+
exitCode: 1,
|
|
143
|
+
error: "executor_error",
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
121
147
|
// The global scrubber skips values under its length floor, so this run's own
|
|
122
148
|
// secret config is redacted here at any length before the global pass. Built
|
|
123
149
|
// before the import check: its diagnostic quotes source, which can hold a value.
|
|
@@ -150,6 +176,7 @@ export async function runScript(input: RunScriptInput): Promise<RunScriptOutput>
|
|
|
150
176
|
const executorInput = {
|
|
151
177
|
source: input.source,
|
|
152
178
|
args: input.args ?? null,
|
|
179
|
+
...(input[HOST_VALIDATED_ARGS] === true ? { hostValidatedArgs: true } : {}),
|
|
153
180
|
configPayload,
|
|
154
181
|
resources,
|
|
155
182
|
fsMode: input.fsMode ?? "none",
|
|
@@ -157,11 +184,11 @@ export async function runScript(input: RunScriptInput): Promise<RunScriptOutput>
|
|
|
157
184
|
signal: input.signal,
|
|
158
185
|
};
|
|
159
186
|
|
|
160
|
-
let output = await
|
|
187
|
+
let output = await resolveScriptExecutor(input.executor).run(executorInput);
|
|
161
188
|
for (const delayMs of CAPACITY_EXCEEDED_RETRY_DELAYS_MS) {
|
|
162
189
|
if (output.error !== "capacity_exceeded" || input.signal?.aborted) break;
|
|
163
190
|
await Bun.sleep(delayMs);
|
|
164
|
-
output = await
|
|
191
|
+
output = await resolveScriptExecutor(input.executor).run(executorInput);
|
|
165
192
|
}
|
|
166
193
|
|
|
167
194
|
return {
|
|
@@ -8,6 +8,7 @@ type BridgeRequest = {
|
|
|
8
8
|
method: string;
|
|
9
9
|
path: string;
|
|
10
10
|
body?: unknown;
|
|
11
|
+
headers?: Record<string, string>;
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
function headers(config: SwarmConfig): Record<string, string> {
|
|
@@ -362,10 +363,16 @@ function bridgeRequestFor(name: string, args: unknown): BridgeRequest | null {
|
|
|
362
363
|
case "workflow_trigger": {
|
|
363
364
|
const id = typeof body.id === "string" ? body.id : undefined;
|
|
364
365
|
if (!id) throw new Error("workflow_trigger requires string `id`");
|
|
366
|
+
const path = `/api/workflows/${encodeURIComponent(id)}/trigger`;
|
|
365
367
|
return {
|
|
366
368
|
method: "POST",
|
|
367
|
-
path:
|
|
369
|
+
path: body.wait === false ? `${path}?wait=false` : path,
|
|
368
370
|
body: body.triggerData ?? {},
|
|
371
|
+
// The route's own Idempotency-Key: recorded in the run's transaction,
|
|
372
|
+
// so a retry after a kill replays the run instead of starting another.
|
|
373
|
+
...(typeof body.idempotencyKey === "string"
|
|
374
|
+
? { headers: { "Idempotency-Key": body.idempotencyKey } }
|
|
375
|
+
: {}),
|
|
369
376
|
};
|
|
370
377
|
}
|
|
371
378
|
case "workflow_retryRun": {
|
|
@@ -491,7 +498,7 @@ async function callBridgeApi(
|
|
|
491
498
|
|
|
492
499
|
const res = await fetch(`${baseUrl}${request.path}`, {
|
|
493
500
|
method: request.method,
|
|
494
|
-
headers: headers(config),
|
|
501
|
+
headers: { ...headers(config), ...request.headers },
|
|
495
502
|
body: request.body === undefined ? undefined : JSON.stringify(request.body),
|
|
496
503
|
});
|
|
497
504
|
const data = await readScriptSdkJsonResponse(res, `ctx.swarm.${name}`);
|
|
@@ -26,6 +26,7 @@ declare module "swarm-sdk" {
|
|
|
26
26
|
| { [key: string]: JsonValue };
|
|
27
27
|
export type ScriptScope = "agent" | "global";
|
|
28
28
|
export type ScriptFsMode = "none" | "workspace-rw";
|
|
29
|
+
export type ScriptExecutorName = "native" | "quickjs";
|
|
29
30
|
export type ScriptApiRawOptions = { raw: true };
|
|
30
31
|
export type ScriptApiDefaultOptions = { raw?: false };
|
|
31
32
|
export type RoutingReason =
|
|
@@ -304,6 +305,7 @@ declare module "swarm-sdk" {
|
|
|
304
305
|
intent?: string;
|
|
305
306
|
scope?: ScriptScope;
|
|
306
307
|
fsMode?: ScriptFsMode;
|
|
308
|
+
executor?: ScriptExecutorName | null;
|
|
307
309
|
idempotencyKey?: string;
|
|
308
310
|
}): Promise<unknown>;
|
|
309
311
|
// --- swarm / agent ---
|
|
@@ -535,7 +537,12 @@ declare module "swarm-sdk" {
|
|
|
535
537
|
workflow_patch(args: Record<string, unknown>): Promise<unknown>;
|
|
536
538
|
workflow_patchNode(args: Record<string, unknown>): Promise<unknown>;
|
|
537
539
|
workflow_delete(args: { id: string }): Promise<unknown>;
|
|
538
|
-
workflow_trigger(args: {
|
|
540
|
+
workflow_trigger(args: {
|
|
541
|
+
id: string;
|
|
542
|
+
triggerData?: Record<string, unknown>;
|
|
543
|
+
wait?: boolean;
|
|
544
|
+
idempotencyKey?: string;
|
|
545
|
+
}): Promise<unknown>;
|
|
539
546
|
workflow_retryRun(args: { id: string }): Promise<unknown>;
|
|
540
547
|
workflow_cancelRun(args: { id: string }): Promise<unknown>;
|
|
541
548
|
|
|
@@ -552,6 +559,7 @@ declare module "swarm-sdk" {
|
|
|
552
559
|
intent?: string;
|
|
553
560
|
scope?: ScriptScope;
|
|
554
561
|
fsMode?: ScriptFsMode;
|
|
562
|
+
executor?: ScriptExecutorName | null;
|
|
555
563
|
}): Promise<unknown>;
|
|
556
564
|
script_delete(args: { name: string; scope?: ScriptScope }): Promise<unknown>;
|
|
557
565
|
script_queryTypes(args: { name: string; scope?: ScriptScope }): Promise<unknown>;
|
|
@@ -8,6 +8,7 @@ declare module "swarm-sdk" {
|
|
|
8
8
|
| { [key: string]: JsonValue };
|
|
9
9
|
export type ScriptScope = "agent" | "global";
|
|
10
10
|
export type ScriptFsMode = "none" | "workspace-rw";
|
|
11
|
+
export type ScriptExecutorName = "native" | "quickjs";
|
|
11
12
|
export type ScriptApiRawOptions = { raw: true };
|
|
12
13
|
export type ScriptApiDefaultOptions = { raw?: false };
|
|
13
14
|
export type RoutingReason =
|
|
@@ -286,6 +287,7 @@ declare module "swarm-sdk" {
|
|
|
286
287
|
intent?: string;
|
|
287
288
|
scope?: ScriptScope;
|
|
288
289
|
fsMode?: ScriptFsMode;
|
|
290
|
+
executor?: ScriptExecutorName | null;
|
|
289
291
|
idempotencyKey?: string;
|
|
290
292
|
}): Promise<unknown>;
|
|
291
293
|
// --- swarm / agent ---
|
|
@@ -517,7 +519,12 @@ declare module "swarm-sdk" {
|
|
|
517
519
|
workflow_patch(args: Record<string, unknown>): Promise<unknown>;
|
|
518
520
|
workflow_patchNode(args: Record<string, unknown>): Promise<unknown>;
|
|
519
521
|
workflow_delete(args: { id: string }): Promise<unknown>;
|
|
520
|
-
workflow_trigger(args: {
|
|
522
|
+
workflow_trigger(args: {
|
|
523
|
+
id: string;
|
|
524
|
+
triggerData?: Record<string, unknown>;
|
|
525
|
+
wait?: boolean;
|
|
526
|
+
idempotencyKey?: string;
|
|
527
|
+
}): Promise<unknown>;
|
|
521
528
|
workflow_retryRun(args: { id: string }): Promise<unknown>;
|
|
522
529
|
workflow_cancelRun(args: { id: string }): Promise<unknown>;
|
|
523
530
|
|
|
@@ -534,6 +541,7 @@ declare module "swarm-sdk" {
|
|
|
534
541
|
intent?: string;
|
|
535
542
|
scope?: ScriptScope;
|
|
536
543
|
fsMode?: ScriptFsMode;
|
|
544
|
+
executor?: ScriptExecutorName | null;
|
|
537
545
|
}): Promise<unknown>;
|
|
538
546
|
script_delete(args: { name: string; scope?: ScriptScope }): Promise<unknown>;
|
|
539
547
|
script_queryTypes(args: { name: string; scope?: ScriptScope }): Promise<unknown>;
|