@desplega.ai/agent-swarm 1.113.0 → 1.115.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 -2
- package/dist/{actions-q4n7cz6e.js → actions-17ya5wde.js} +8 -9
- package/dist/{app-es4nzc71.js → app-4f718yk0.js} +6 -6
- package/dist/{assistant-0x8ey0vs.js → assistant-ah7csnjz.js} +19 -18
- package/dist/{boot-reembed-69agkhv6.js → boot-reembed-4jpxhb25.js} +6 -6
- package/dist/{boot-reembed-p0ny05t8.js → boot-reembed-qata34xa.js} +5 -5
- package/dist/{boot-scrub-logs-yybrkmvr.js → boot-scrub-logs-tv48nn3z.js} +4 -4
- package/dist/{claude-adapter-mma9a1yr.js → claude-adapter-3csn5bks.js} +3 -3
- package/dist/{claude-managed-adapter-pv2nbqy4.js → claude-managed-adapter-kysmkz89.js} +2 -2
- package/dist/cli-0pygq9r1.js +429 -0
- package/dist/{cli-hsetkkd3.js → cli-12vb0xg6.js} +33 -9
- package/dist/{cli-ncfgsqbd.js → cli-15y7qhzp.js} +262 -33
- package/dist/{cli-7ga43spr.js → cli-1yjrbg1f.js} +1 -1
- package/dist/{cli-36ymmpmp.js → cli-3samkyap.js} +2 -2
- package/dist/cli-52fg7s7x.js +269 -0
- package/dist/{cli-hjhvekf4.js → cli-65ekje01.js} +11 -8
- package/dist/{cli-h3k622d0.js → cli-6aq8xhvm.js} +90 -3
- package/dist/{cli-f3qa069v.js → cli-7xje5amz.js} +1 -1
- package/dist/cli-86fdnerz.js +405 -0
- package/dist/{cli-9cy6nc5m.js → cli-8fjwym53.js} +1 -1
- package/dist/{cli-c3frqf65.js → cli-b23axgz4.js} +3 -3
- package/dist/{cli-a0t7vapf.js → cli-bc89my0z.js} +1 -1
- package/dist/{cli-bnzbn8j8.js → cli-beea4a3y.js} +73 -24
- package/dist/{cli-q21d49ac.js → cli-bw80ck94.js} +1 -1
- package/dist/{cli-pwc5e83c.js → cli-cchksf5q.js} +12 -7
- package/dist/{cli-30bbaveh.js → cli-cmw9rzy5.js} +2 -2
- package/dist/{cli-y6mrptcn.js → cli-cnwssmsr.js} +1 -1
- package/dist/{cli-r5g6ngtn.js → cli-dcca6j8m.js} +46 -5
- package/dist/{cli-tkmm5nf9.js → cli-e61fs2hp.js} +59 -2
- package/dist/{cli-6wscj9z0.js → cli-e7306swv.js} +14 -14
- package/dist/{cli-dcfyyh3t.js → cli-ftyf58xj.js} +2 -2
- package/dist/{cli-4xyj9jtq.js → cli-hrhye2rm.js} +1062 -478
- package/dist/cli-jkhwmmgg.js +136 -0
- package/dist/{cli-y4ycrnjc.js → cli-k3y4z3h5.js} +1 -1
- package/dist/{cli-6xd0bvf8.js → cli-ma04faw5.js} +1 -1
- package/dist/{cli-2fc97xm5.js → cli-mnbgv3w7.js} +4 -4
- package/dist/{cli-trmapn9k.js → cli-pet3aev6.js} +95 -10
- package/dist/{cli-z46pnksz.js → cli-q1rx7g0d.js} +175 -28
- package/dist/{cli-qwgtacd6.js → cli-r9f6ngrf.js} +1244 -336
- package/dist/{cli-gtkqc144.js → cli-shvaxw27.js} +13 -7
- package/dist/{cli-ywez6yps.js → cli-sq7f72d6.js} +1 -1
- package/dist/cli-t0vqevnm.js +393 -0
- package/dist/{cli-tbw13sx8.js → cli-tece6zgm.js} +1 -1
- package/dist/{cli-bgvskydy.js → cli-tffvrh6j.js} +1 -1
- package/dist/cli-wh91zby6.js +187222 -0
- package/dist/{cli-anrj584m.js → cli-xz9aq0rf.js} +1 -1
- package/dist/{cli-mq580e06.js → cli-zsrdty74.js} +18 -18
- package/dist/cli.js +32 -15
- package/dist/{codex-adapter-5cmy858w.js → codex-adapter-de3w0nch.js} +10 -10
- package/dist/{codex-session-runner-46q8mrba.js → codex-session-runner-bnw8cysk.js} +10 -10
- package/dist/{commands-z5dbwta3.js → commands-hch4e2k1.js} +4 -4
- package/dist/{db-bbgahh4z.js → db-p3h2j06x.js} +14 -4
- package/dist/{handlers-6b44317z.js → handlers-9er4zx9q.js} +17 -31
- package/dist/{hook-sbp5fmps.js → hook-4axs756z.js} +7 -7
- package/dist/{http-2xz43gz3.js → http-809fvtz2.js} +1934 -886
- package/dist/{index-wz1ea15p.js → index-2dgfj9av.js} +3 -3
- package/dist/{index-nhat35em.js → index-47em3d2n.js} +14 -11
- package/dist/{index-5ghxn8s6.js → index-9fqaktjr.js} +12 -9
- package/dist/{index-0gzmqj4k.js → index-9ht8gr56.js} +13 -10
- package/dist/{index-vfedgdw6.js → index-rm85cfdx.js} +368 -40
- package/dist/{index-ykvs43z4.js → index-t2snazez.js} +4 -4
- package/dist/{keepalive-62gfj91d.js → keepalive-3cps6e3e.js} +7 -6
- package/dist/{lead-ag0akn0v.js → lead-fkk95wgq.js} +36 -32
- package/dist/{maintenance-xxrrzk5x.js → maintenance-fweqh0yj.js} +6 -6
- package/dist/{mistral-conversations-26yrnbf1.js → mistral-conversations-7gqnz2wt.js} +7 -7
- package/dist/oauth-refresh-sweep-sycqtbph.js +114 -0
- package/dist/{onboard-64zyfcbs.js → onboard-cy0rkgvx.js} +2 -2
- package/dist/{opencode-adapter-mqsxr170.js → opencode-adapter-p6bxnbm4.js} +2 -2
- package/dist/{otel-zjd9zaxs.js → otel-g299k41b.js} +2 -2
- package/dist/{otel-impl-b86qseaa.js → otel-impl-wbns8hf7.js} +1 -1
- package/dist/{pi-mono-adapter-kxjxpfgy.js → pi-mono-adapter-05sck1ds.js} +17 -109
- package/dist/{pricing-refresh-cgtkffpa.js → pricing-refresh-0hvazmkf.js} +6 -6
- package/dist/rbac-roles-kfesjy9y.js +28 -0
- package/dist/rbac-roles-mwcwhbxc.js +283 -0
- package/dist/{seed-pricing-1r1y1xkq.js → seed-pricing-h2kdq4cq.js} +5 -5
- package/dist/{setup-mkcgkjf7.js → setup-8506q97w.js} +2 -2
- package/dist/{worker-351sze63.js → worker-4r5c6zyb.js} +36 -32
- package/openapi.json +1327 -20
- package/package.json +3 -3
- package/src/agentmail/handlers.ts +16 -6
- package/src/agentmail/templates.ts +25 -5
- package/src/be/audit-user.ts +28 -4
- package/src/be/db-queries/oauth.ts +42 -0
- package/src/be/db.ts +314 -28
- package/src/be/identity.ts +79 -0
- package/src/be/mcp-proxy.ts +132 -0
- package/src/be/migrations/109_rbac_roles.sql +79 -0
- package/src/be/migrations/111_oauth_credential_bindings.sql +6 -0
- package/src/be/migrations/112_script_connections_graphql.sql +96 -0
- package/src/be/migrations/113_task_routing_affinity.sql +9 -0
- package/src/be/migrations/114_backfill_gpt_5_6_pricing.sql +15 -0
- package/src/be/modelsdev-cache.json +135 -0
- package/src/be/oauth-credential-bindings.ts +35 -0
- package/src/be/oauth-refresh-sweep.ts +159 -0
- package/src/be/rbac-audit.ts +52 -13
- package/src/be/rbac-roles.ts +424 -0
- package/src/be/script-connections.ts +459 -40
- package/src/be/script-credential-broker.ts +29 -3
- package/src/be/scripts/typecheck.ts +51 -7
- package/src/be/seed-scripts/catalog/catalog-report.inline.ts +325 -24
- package/src/be/seed-scripts/catalog/catalog-report.ts +325 -24
- package/src/be/users.ts +24 -0
- package/src/cli.tsx +17 -0
- package/src/github/handlers.ts +10 -9
- package/src/github/templates.ts +45 -9
- package/src/gitlab/handlers.ts +20 -8
- package/src/gitlab/templates.ts +18 -6
- package/src/heartbeat/heartbeat.ts +143 -21
- package/src/http/all-routes.ts +3 -0
- package/src/http/approval-requests.ts +12 -0
- package/src/http/config.ts +44 -10
- package/src/http/core.ts +30 -3
- package/src/http/favorites.ts +1 -5
- package/src/http/index.ts +25 -1
- package/src/http/mcp-oauth.ts +2 -0
- package/src/http/mcp-servers.ts +44 -3
- package/src/http/oauth-generic.ts +105 -0
- package/src/http/poll.ts +20 -3
- package/src/http/script-connection-proxy.ts +116 -0
- package/src/http/script-connections.ts +1657 -0
- package/src/http/scripts.ts +27 -7
- package/src/http/skills.ts +11 -0
- package/src/http/tasks.ts +27 -13
- package/src/http/x.ts +6 -2
- package/src/integrations/kapso/inbound.ts +23 -6
- package/src/jira/sync.ts +111 -17
- package/src/jira/templates.ts +10 -2
- package/src/mcp-client/http-client.ts +194 -0
- package/src/oauth/app-validation.ts +16 -0
- package/src/oauth/ensure-token.ts +69 -14
- package/src/oauth/mcp-wrapper.ts +15 -0
- package/src/oauth/wrapper.ts +48 -20
- package/src/prompts/session-templates.ts +3 -3
- package/src/providers/codex-models.ts +100 -30
- package/src/providers/modelsdev-reasoning.json +51 -0
- package/src/providers/pi-mono-mcp-client.ts +2 -133
- package/src/providers/reasoning-effort.ts +11 -5
- package/src/rbac/admission.ts +68 -0
- package/src/rbac/index.ts +2 -0
- package/src/rbac/legacy-policy.ts +12 -0
- package/src/rbac/permissions.ts +48 -0
- package/src/scheduler/scheduler.ts +9 -1
- package/src/scripts-runtime/api-client.ts +151 -19
- package/src/scripts-runtime/api-types.ts +38 -6
- package/src/scripts-runtime/credential-broker/default-bindings.ts +1 -0
- package/src/scripts-runtime/credential-broker/types.ts +8 -0
- package/src/scripts-runtime/ctx.ts +11 -1
- package/src/scripts-runtime/eval-harness.ts +5 -1
- package/src/scripts-runtime/executors/types.ts +2 -1
- package/src/scripts-runtime/loader.ts +3 -1
- package/src/scripts-runtime/mcp-client.ts +87 -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 +19 -0
- package/src/server-user.ts +114 -59
- package/src/server.ts +12 -0
- package/src/slack/assistant.ts +14 -6
- package/src/slack/enrich.ts +17 -0
- package/src/slack/handlers.ts +8 -22
- package/src/slack/responses.ts +91 -1
- package/src/slack/thread-buffer.ts +6 -3
- package/src/slack/watcher.ts +9 -6
- package/src/tasks/worker-follow-up.ts +100 -3
- package/src/tests/agentmail-handlers.test.ts +32 -3
- package/src/tests/approval-requests.test.ts +61 -0
- package/src/tests/audit-user.test.ts +47 -1
- package/src/tests/codex-adapter.test.ts +46 -23
- package/src/tests/credential-broker.test.ts +5 -2
- package/src/tests/delete-page-tool.test.ts +197 -0
- package/src/tests/github-handlers.test.ts +28 -2
- package/src/tests/gitlab-handlers.test.ts +125 -0
- package/src/tests/heartbeat.test.ts +48 -3
- package/src/tests/identity.test.ts +117 -0
- package/src/tests/jira-sync.test.ts +99 -1
- package/src/tests/kapso-inbound.test.ts +7 -0
- package/src/tests/mcp-tools-user.test.ts +60 -6
- package/src/tests/model-control.test.ts +8 -2
- package/src/tests/oauth-credential-bindings.test.ts +490 -0
- package/src/tests/oauth-refresh-sweep.test.ts +160 -0
- package/src/tests/pool-affinity.test.ts +401 -0
- package/src/tests/prompt-template-remaining.test.ts +2 -2
- package/src/tests/rbac-admission-e2e.test.ts +386 -0
- package/src/tests/rbac-admission.test.ts +492 -0
- package/src/tests/rbac-e2e-helpers.ts +3 -0
- package/src/tests/rbac-engine.test.ts +50 -0
- package/src/tests/rbac-mcp-admission-e2e.test.ts +362 -0
- package/src/tests/rbac-roles.test.ts +328 -0
- package/src/tests/reasoning-effort.test.ts +15 -2
- package/src/tests/schedule-target-type.test.ts +50 -0
- package/src/tests/scheduled-tasks.test.ts +40 -0
- package/src/tests/script-apis-mcp.test.ts +37 -13
- package/src/tests/script-connections-http.test.ts +1158 -0
- package/src/tests/script-connections-mcp.test.ts +894 -0
- package/src/tests/script-connections.test.ts +754 -6
- package/src/tests/scripts-external-api.test.ts +49 -1
- package/src/tests/scripts-runtime-secret-egress.test.ts +1 -0
- package/src/tests/scripts-runtime.test.ts +291 -0
- package/src/tests/seed-scripts.test.ts +36 -0
- package/src/tests/slack-identity-resolution.test.ts +37 -3
- package/src/tests/slack-inline-output.test.ts +65 -0
- package/src/tests/slack-thread-buffer.test.ts +28 -0
- package/src/tests/tool-annotations.test.ts +1 -0
- package/src/tests/user-token-rest-auth.test.ts +140 -1
- package/src/tests/workflow-swarm-script.test.ts +44 -0
- package/src/tests/workflow-triggers-v2.test.ts +300 -1
- package/src/tools/credential-bindings/tool.ts +277 -18
- package/src/tools/delete-page.ts +145 -0
- package/src/tools/mcp-servers/mcp-server-delete.ts +7 -4
- package/src/tools/request-human-input.ts +2 -0
- package/src/tools/resolve-user.ts +77 -27
- package/src/tools/script-apis.ts +62 -3
- package/src/tools/script-connections/tool.ts +275 -31
- package/src/tools/send-task.ts +15 -1
- package/src/tools/task-action.ts +34 -2
- package/src/tools/templates.ts +53 -1
- package/src/tools/tool-config.ts +2 -1
- package/src/tools/utils.ts +2 -0
- package/src/tools/workflows/create-workflow.ts +8 -1
- package/src/tools/workflows/update-workflow.ts +11 -2
- package/src/types.ts +90 -11
- package/src/utils/scoped-resource.ts +25 -0
- package/src/workflows/executors/human-in-the-loop.ts +1 -0
- package/src/workflows/executors/swarm-script.ts +7 -1
- package/src/workflows/triggers.ts +146 -18
- package/templates/skills/swarm-scripts/content.md +33 -8
- package/dist/cli-bgef578c.js +0 -771
- package/dist/cli-c9mtm09b.js +0 -43
- package/dist/cli-ceewqajw.js +0 -1698
- package/dist/{anthropic-messages-8nc6r2dw.js → anthropic-messages-kq3pjhbp.js} +6 -6
- package/dist/{azure-openai-responses-6yfzw3qw.js → azure-openai-responses-gm1ejtmn.js} +7 -7
- package/dist/{cli-vbraamxr.js → cli-6b4wwmm8.js} +9 -9
- package/dist/{cli-2r7s8jhp.js → cli-sznberje.js} +3 -3
- package/dist/{google-generative-ai-vfq6ymz9.js → google-generative-ai-hyrra2jm.js} +3 -3
- package/dist/{google-vertex-mj5y5rfj.js → google-vertex-8bs2pzgn.js} +3 -3
- package/dist/{openai-codex-responses-8h6kvfv8.js → openai-codex-responses-3nkvje79.js} +4 -4
- package/dist/{openai-completions-x6kjnqjd.js → openai-completions-0asftkwg.js} +11 -11
- package/dist/{openai-responses-7jwyz3ds.js → openai-responses-pmatek45.js} +10 -10
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
|
|
18
18
|
describe("REASONING_EFFORT_LEVELS", () => {
|
|
19
19
|
test("is the closed normalized enum", () => {
|
|
20
|
-
expect(REASONING_EFFORT_LEVELS).toEqual(["off", "low", "medium", "high", "xhigh"]);
|
|
20
|
+
expect(REASONING_EFFORT_LEVELS).toEqual(["off", "low", "medium", "high", "xhigh", "max"]);
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
@@ -25,10 +25,16 @@ describe("reasoningCapability — cache-sourced levels", () => {
|
|
|
25
25
|
test("claude claude-opus-4-8: levels come from reasoning_options.effort, not the fallback", () => {
|
|
26
26
|
const cap = reasoningCapability("claude", "claude-opus-4-8");
|
|
27
27
|
expect(cap.supported).toBe(true);
|
|
28
|
-
// Cache lists [low, medium, high, xhigh, max]; "max" is
|
|
28
|
+
// Cache lists [low, medium, high, xhigh, max]; "max" is not a Claude CLI effort.
|
|
29
29
|
expect(cap.levels).toEqual(["low", "medium", "high", "xhigh"]);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
+
test("codex gpt-5.6-sol supports the new max effort", () => {
|
|
33
|
+
const cap = reasoningCapability("codex", "gpt-5.6-sol");
|
|
34
|
+
expect(cap.supported).toBe(true);
|
|
35
|
+
expect(cap.levels).toEqual(["off", "low", "medium", "high", "xhigh", "max"]);
|
|
36
|
+
});
|
|
37
|
+
|
|
32
38
|
test("codex gpt-5.1-codex-max: cache already includes xhigh", () => {
|
|
33
39
|
const cap = reasoningCapability("codex", "gpt-5.1-codex-max");
|
|
34
40
|
expect(cap.supported).toBe(true);
|
|
@@ -156,6 +162,13 @@ describe("applyReasoningEffort — codex-config shape", () => {
|
|
|
156
162
|
config: { model_reasoning_effort: "xhigh" },
|
|
157
163
|
});
|
|
158
164
|
});
|
|
165
|
+
|
|
166
|
+
test("max on gpt-5.6-sol is applied", () => {
|
|
167
|
+
expect(applyReasoningEffort("codex", "gpt-5.6-sol", "max")).toEqual({
|
|
168
|
+
kind: "codex-config",
|
|
169
|
+
config: { model_reasoning_effort: "max" },
|
|
170
|
+
});
|
|
171
|
+
});
|
|
159
172
|
});
|
|
160
173
|
|
|
161
174
|
describe("applyReasoningEffort — pi-session shape", () => {
|
|
@@ -288,6 +288,56 @@ describe("dispatchScheduleTarget — script target", () => {
|
|
|
288
288
|
expect(result.task).toBeUndefined();
|
|
289
289
|
}, 15_000);
|
|
290
290
|
|
|
291
|
+
test("scheduled script runs receive ctx.api and ctx.mcp connections", async () => {
|
|
292
|
+
const { upsertScriptConnection } = await import("../be/script-connections");
|
|
293
|
+
await upsertScriptConnection({
|
|
294
|
+
slug: "schedgql",
|
|
295
|
+
kind: "graphql",
|
|
296
|
+
scope: "global",
|
|
297
|
+
baseUrl: "https://gql.vendor.test/graphql",
|
|
298
|
+
allowedHosts: ["gql.vendor.test"],
|
|
299
|
+
agentId,
|
|
300
|
+
});
|
|
301
|
+
const mcpRow = {
|
|
302
|
+
id: crypto.randomUUID(),
|
|
303
|
+
serverId: crypto.randomUUID(),
|
|
304
|
+
runtime: { slug: "schedmcp", kind: "mcp", connectionId: "", tools: [{ name: "ping" }] },
|
|
305
|
+
};
|
|
306
|
+
mcpRow.runtime.connectionId = mcpRow.id;
|
|
307
|
+
getDb()
|
|
308
|
+
.prepare(
|
|
309
|
+
`INSERT INTO mcp_servers (id, name, transport, scope, url, createdAt, lastUpdatedAt)
|
|
310
|
+
VALUES (?, ?, 'http', 'global', 'http://mcp.invalid.test/mcp', datetime('now'), datetime('now'))`,
|
|
311
|
+
)
|
|
312
|
+
.run(mcpRow.serverId, `sched-mcp-${mcpRow.serverId.slice(0, 8)}`);
|
|
313
|
+
getDb()
|
|
314
|
+
.prepare(
|
|
315
|
+
`INSERT INTO script_connections
|
|
316
|
+
(id, slug, kind, scope, allowed_hosts_json, mcp_server_id, generated_runtime_json)
|
|
317
|
+
VALUES (?, 'schedmcp', 'mcp', 'global', '[]', ?, ?)`,
|
|
318
|
+
)
|
|
319
|
+
.run(mcpRow.id, mcpRow.serverId, JSON.stringify(mcpRow.runtime));
|
|
320
|
+
|
|
321
|
+
await saveGlobalScript(
|
|
322
|
+
"schedule-target-type-ctx-connections",
|
|
323
|
+
`export default async (args, ctx) => {
|
|
324
|
+
if (!ctx.api || !("schedgql" in ctx.api)) throw new Error("ctx.api missing schedgql");
|
|
325
|
+
if (!ctx.mcp || !("schedmcp" in ctx.mcp)) throw new Error("ctx.mcp missing schedmcp");
|
|
326
|
+
return { ok: true };
|
|
327
|
+
};`,
|
|
328
|
+
);
|
|
329
|
+
const schedule = createScheduledTask({
|
|
330
|
+
name: `dispatch-script-ctx-${crypto.randomUUID()}`,
|
|
331
|
+
intervalMs: 60_000,
|
|
332
|
+
targetType: "script",
|
|
333
|
+
scriptName: "schedule-target-type-ctx-connections",
|
|
334
|
+
createdByAgentId: agentId,
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
const result = await dispatchScheduleTarget(schedule);
|
|
338
|
+
expect(result.triggeredWorkflows).toBe(false);
|
|
339
|
+
}, 15_000);
|
|
340
|
+
|
|
291
341
|
test("throws a clear error when the script does not exist", async () => {
|
|
292
342
|
const schedule = createScheduledTask({
|
|
293
343
|
name: `dispatch-script-missing-${crypto.randomUUID()}`,
|
|
@@ -4,11 +4,13 @@ import {
|
|
|
4
4
|
closeDb,
|
|
5
5
|
createAgent,
|
|
6
6
|
createScheduledTask,
|
|
7
|
+
createUser,
|
|
7
8
|
deleteScheduledTask,
|
|
8
9
|
getDb,
|
|
9
10
|
getScheduledTaskById,
|
|
10
11
|
getScheduledTaskByName,
|
|
11
12
|
getScheduledTasks,
|
|
13
|
+
getTaskById,
|
|
12
14
|
initDb,
|
|
13
15
|
updateScheduledTask,
|
|
14
16
|
} from "../be/db";
|
|
@@ -315,6 +317,44 @@ describe("Scheduled Tasks Integration", () => {
|
|
|
315
317
|
expect(afterRun?.lastRunAt).toBeDefined();
|
|
316
318
|
});
|
|
317
319
|
|
|
320
|
+
test("fired task inherits the schedule's createdBy as requestedByUserId", async () => {
|
|
321
|
+
const requester = createUser({ name: "Schedule Requester", email: "sched-req@example.com" });
|
|
322
|
+
const schedule = createScheduledTask({
|
|
323
|
+
name: "test-manual-run-createdby",
|
|
324
|
+
cronExpression: "0 9 * * *",
|
|
325
|
+
taskTemplate: "Task carrying schedule provenance",
|
|
326
|
+
createdByAgentId: testAgent.id,
|
|
327
|
+
createdBy: requester.id,
|
|
328
|
+
enabled: true,
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
await runScheduleNow(schedule.id);
|
|
332
|
+
|
|
333
|
+
const createdTask = getDb()
|
|
334
|
+
.query("SELECT id FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1")
|
|
335
|
+
.get(schedule.taskTemplate) as { id: string };
|
|
336
|
+
const task = getTaskById(createdTask.id);
|
|
337
|
+
expect(task?.requestedByUserId).toBe(requester.id);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
test("fired task has no requestedByUserId when the schedule's createdBy is unset (first-ever schedules)", async () => {
|
|
341
|
+
const schedule = createScheduledTask({
|
|
342
|
+
name: "test-manual-run-no-createdby",
|
|
343
|
+
cronExpression: "0 9 * * *",
|
|
344
|
+
taskTemplate: "Task with no schedule provenance",
|
|
345
|
+
createdByAgentId: testAgent.id,
|
|
346
|
+
enabled: true,
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
await runScheduleNow(schedule.id);
|
|
350
|
+
|
|
351
|
+
const createdTask = getDb()
|
|
352
|
+
.query("SELECT id FROM agent_tasks WHERE task = ? ORDER BY createdAt DESC LIMIT 1")
|
|
353
|
+
.get(schedule.taskTemplate) as { id: string };
|
|
354
|
+
const task = getTaskById(createdTask.id);
|
|
355
|
+
expect(task?.requestedByUserId ?? null).toBeNull();
|
|
356
|
+
});
|
|
357
|
+
|
|
318
358
|
test("should throw error for non-existent schedule", async () => {
|
|
319
359
|
await expect(runScheduleNow("non-existent-schedule-id")).rejects.toThrow(
|
|
320
360
|
"Schedule not found",
|
|
@@ -114,6 +114,7 @@ async function dispatchScriptsApi(url: string, init: RequestInit = {}): Promise<
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
let workerId: string;
|
|
117
|
+
let leadId: string;
|
|
117
118
|
let scriptId: string;
|
|
118
119
|
let savedEnv: NodeJS.ProcessEnv;
|
|
119
120
|
let savedFetch: typeof globalThis.fetch;
|
|
@@ -136,6 +137,7 @@ beforeAll(async () => {
|
|
|
136
137
|
refreshSecretScrubberCache();
|
|
137
138
|
setScriptEmbeddingProviderForTests(noOpEmbeddingProvider);
|
|
138
139
|
workerId = createAgent({ name: "script-apis-mcp-worker", isLead: false, status: "idle" }).id;
|
|
140
|
+
leadId = createAgent({ name: "script-apis-mcp-lead", isLead: true, status: "idle" }).id;
|
|
139
141
|
process.env.MCP_BASE_URL = "http://script-apis-mcp.test";
|
|
140
142
|
globalThis.fetch = (async (input, init) => {
|
|
141
143
|
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
@@ -185,18 +187,43 @@ describe("script-apis MCP tool", () => {
|
|
|
185
187
|
const tools = buildToolServer();
|
|
186
188
|
const result = (await tools.scriptApis.handler(
|
|
187
189
|
{ action: "create", scriptId, authMode: "bearer", label: "demo" },
|
|
188
|
-
meta(
|
|
190
|
+
meta(leadId),
|
|
189
191
|
)) as StructuredResult<{ id: string; token: string; authMode: string }>;
|
|
190
192
|
expect(result.structuredContent.success).toBe(true);
|
|
191
193
|
expect(result.structuredContent.data?.token).toMatch(/^xsk_/);
|
|
192
194
|
expect(result.structuredContent.data?.authMode).toBe("bearer");
|
|
193
195
|
});
|
|
194
196
|
|
|
195
|
-
test("
|
|
197
|
+
test("non-lead agents cannot mint or reveal bearer tokens", async () => {
|
|
196
198
|
const tools = buildToolServer();
|
|
199
|
+
const createDenied = (await tools.scriptApis.handler(
|
|
200
|
+
{ action: "create", scriptId, authMode: "bearer", label: "demo" },
|
|
201
|
+
meta(workerId),
|
|
202
|
+
)) as StructuredResult<unknown>;
|
|
203
|
+
expect(createDenied.structuredContent.success).toBe(false);
|
|
204
|
+
expect(createDenied.structuredContent.status).toBe(403);
|
|
205
|
+
expect(createDenied.structuredContent.error).toContain("Only lead agents can create");
|
|
206
|
+
|
|
197
207
|
const created = (await tools.scriptApis.handler(
|
|
198
208
|
{ action: "create", scriptId, authMode: "bearer" },
|
|
209
|
+
meta(leadId),
|
|
210
|
+
)) as StructuredResult<{ id: string; token: string }>;
|
|
211
|
+
expect(created.structuredContent.success).toBe(true);
|
|
212
|
+
|
|
213
|
+
const revealDenied = (await tools.scriptApis.handler(
|
|
214
|
+
{ action: "list", scriptId, includeSecrets: true },
|
|
199
215
|
meta(workerId),
|
|
216
|
+
)) as StructuredResult<unknown>;
|
|
217
|
+
expect(revealDenied.structuredContent.success).toBe(false);
|
|
218
|
+
expect(revealDenied.structuredContent.status).toBe(403);
|
|
219
|
+
expect(revealDenied.structuredContent.error).toContain("Only lead agents can reveal");
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("list masks bearer tokens by default and reveals with includeSecrets", async () => {
|
|
223
|
+
const tools = buildToolServer();
|
|
224
|
+
const created = (await tools.scriptApis.handler(
|
|
225
|
+
{ action: "create", scriptId, authMode: "bearer" },
|
|
226
|
+
meta(leadId),
|
|
200
227
|
)) as StructuredResult<{ id: string; token: string }>;
|
|
201
228
|
const realToken = created.structuredContent.data?.token;
|
|
202
229
|
expect(realToken).toBeTruthy();
|
|
@@ -209,17 +236,14 @@ describe("script-apis MCP tool", () => {
|
|
|
209
236
|
|
|
210
237
|
const revealed = (await tools.scriptApis.handler(
|
|
211
238
|
{ action: "list", scriptId, includeSecrets: true },
|
|
212
|
-
meta(
|
|
239
|
+
meta(leadId),
|
|
213
240
|
)) as StructuredResult<{ apis: Array<{ id: string; token: string | null }> }>;
|
|
214
241
|
expect(revealed.structuredContent.data?.apis[0]?.token).toBe(realToken);
|
|
215
242
|
});
|
|
216
243
|
|
|
217
244
|
test("list returns a null token for authMode 'none'", async () => {
|
|
218
245
|
const tools = buildToolServer();
|
|
219
|
-
await tools.scriptApis.handler(
|
|
220
|
-
{ action: "create", scriptId, authMode: "none" },
|
|
221
|
-
meta(workerId),
|
|
222
|
-
);
|
|
246
|
+
await tools.scriptApis.handler({ action: "create", scriptId, authMode: "none" }, meta(leadId));
|
|
223
247
|
const listed = (await tools.scriptApis.handler(
|
|
224
248
|
{ action: "list", scriptId },
|
|
225
249
|
meta(workerId),
|
|
@@ -231,14 +255,14 @@ describe("script-apis MCP tool", () => {
|
|
|
231
255
|
const tools = buildToolServer();
|
|
232
256
|
const created = (await tools.scriptApis.handler(
|
|
233
257
|
{ action: "create", scriptId, authMode: "bearer" },
|
|
234
|
-
meta(
|
|
258
|
+
meta(leadId),
|
|
235
259
|
)) as StructuredResult<{ id: string; token: string }>;
|
|
236
260
|
const endpointId = created.structuredContent.data?.id as string;
|
|
237
261
|
const oldToken = created.structuredContent.data?.token;
|
|
238
262
|
|
|
239
263
|
const rotated = (await tools.scriptApis.handler(
|
|
240
264
|
{ action: "rotate", scriptId, endpointId },
|
|
241
|
-
meta(
|
|
265
|
+
meta(leadId),
|
|
242
266
|
)) as StructuredResult<{ token: string }>;
|
|
243
267
|
expect(rotated.structuredContent.success).toBe(true);
|
|
244
268
|
expect(rotated.structuredContent.data?.token).toBeTruthy();
|
|
@@ -249,13 +273,13 @@ describe("script-apis MCP tool", () => {
|
|
|
249
273
|
const tools = buildToolServer();
|
|
250
274
|
const created = (await tools.scriptApis.handler(
|
|
251
275
|
{ action: "create", scriptId, authMode: "none" },
|
|
252
|
-
meta(
|
|
276
|
+
meta(leadId),
|
|
253
277
|
)) as StructuredResult<{ id: string }>;
|
|
254
278
|
const endpointId = created.structuredContent.data?.id as string;
|
|
255
279
|
|
|
256
280
|
const updated = (await tools.scriptApis.handler(
|
|
257
281
|
{ action: "update", scriptId, endpointId, enabled: false, label: "renamed" },
|
|
258
|
-
meta(
|
|
282
|
+
meta(leadId),
|
|
259
283
|
)) as StructuredResult<{ enabled: boolean; label: string | null }>;
|
|
260
284
|
expect(updated.structuredContent.success).toBe(true);
|
|
261
285
|
expect(updated.structuredContent.data?.enabled).toBe(false);
|
|
@@ -266,13 +290,13 @@ describe("script-apis MCP tool", () => {
|
|
|
266
290
|
const tools = buildToolServer();
|
|
267
291
|
const created = (await tools.scriptApis.handler(
|
|
268
292
|
{ action: "create", scriptId, authMode: "none" },
|
|
269
|
-
meta(
|
|
293
|
+
meta(leadId),
|
|
270
294
|
)) as StructuredResult<{ id: string }>;
|
|
271
295
|
const endpointId = created.structuredContent.data?.id as string;
|
|
272
296
|
|
|
273
297
|
const deleted = (await tools.scriptApis.handler(
|
|
274
298
|
{ action: "delete", scriptId, endpointId },
|
|
275
|
-
meta(
|
|
299
|
+
meta(leadId),
|
|
276
300
|
)) as StructuredResult<{ deleted: boolean }>;
|
|
277
301
|
expect(deleted.structuredContent.success).toBe(true);
|
|
278
302
|
expect(deleted.structuredContent.data?.deleted).toBe(true);
|