@desplega.ai/agent-swarm 1.123.0 → 1.124.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 -1
- package/dist/{actions-e4c9f0xy.js → actions-z3d0fk7z.js} +6 -6
- package/dist/{app-vmvmj2v3.js → app-q2rc9tdr.js} +4 -4
- package/dist/{assistant-yn7a792a.js → assistant-3stjq7fz.js} +9 -9
- package/dist/{boot-reembed-xg1r86h2.js → boot-reembed-5867whnb.js} +3 -3
- package/dist/{boot-reembed-chxty50a.js → boot-reembed-v6r1df32.js} +4 -4
- package/dist/{boot-scrub-logs-exwddvp5.js → boot-scrub-logs-8b8jegk3.js} +2 -2
- package/dist/{cli-1592nfd6.js → cli-0925phzv.js} +1 -1
- package/dist/{cli-hbbxmhec.js → cli-2yr6edr7.js} +4 -4
- package/dist/{cli-8cq4z4x7.js → cli-3z4q09tn.js} +182 -19
- package/dist/{cli-vz9drmce.js → cli-5jn6wnd9.js} +17 -8
- package/dist/{cli-5arfywtm.js → cli-5ncdb7ff.js} +19 -9
- package/dist/{cli-3tv9z4wx.js → cli-92bqgbgy.js} +1 -1
- package/dist/{cli-fjf04hpa.js → cli-dq2ssyf0.js} +48 -56
- package/dist/{cli-mngsj9fx.js → cli-gkvf8d83.js} +1 -1
- package/dist/{cli-mepk1j0t.js → cli-gzjsamwc.js} +2 -2
- package/dist/{cli-c9m59f83.js → cli-h89g0qrd.js} +1 -1
- package/dist/{cli-n8mf7x4b.js → cli-jp4mdj9d.js} +2 -2
- package/dist/{cli-822d4bjk.js → cli-kk58tg33.js} +7 -7
- package/dist/{cli-9hj1adgp.js → cli-mcez7z4p.js} +1 -1
- package/dist/{cli-byv3720g.js → cli-mmk5vagg.js} +2 -2
- package/dist/{cli-zdp11t8m.js → cli-p0ec4vv6.js} +1 -1
- package/dist/{cli-h2say6xk.js → cli-p0zgv8pj.js} +3 -1
- package/dist/{cli-8ef5ky75.js → cli-perb20ma.js} +1 -1
- package/dist/{cli-zkj6f2sk.js → cli-qf7acvyr.js} +90 -4
- package/dist/{cli-kmm1rwmp.js → cli-qwsagsmg.js} +1 -1
- package/dist/{cli-we91ywvy.js → cli-sqv6c9b8.js} +6 -6
- package/dist/{cli-np0yhmmk.js → cli-vm20sh8d.js} +3 -3
- package/dist/{cli-p11rf59d.js → cli-wn3m6q54.js} +3 -3
- package/dist/{cli-mkpf4ndf.js → cli-x268say8.js} +2976 -5621
- package/dist/{cli-ngbsk4yx.js → cli-y43n987v.js} +1 -1
- package/dist/{cli-4509mwm5.js → cli-ykthjw29.js} +8 -8
- package/dist/{cli-9eka6jwv.js → cli-zxb72ctk.js} +2 -2
- package/dist/cli.js +12 -10
- package/dist/{commands-sjk3zfyr.js → commands-sda76yn8.js} +2 -2
- package/dist/{db-2je5agjb.js → db-vn9e4rqj.js} +6 -2
- package/dist/{e2b-2s4psnbf.js → e2b-q345y8s4.js} +0 -4
- package/dist/{handlers-yzv369hf.js → handlers-xfja18ac.js} +9 -9
- package/dist/{hook-rfsj2r8x.js → hook-2medrp47.js} +1 -40
- package/dist/{http-v9rr144m.js → http-937pyjfc.js} +99 -44
- package/dist/{index-nr2199m6.js → index-2bqd2q9v.js} +11 -11
- package/dist/{index-3xtk777g.js → index-gw4en7jg.js} +9 -9
- package/dist/{index-c3tan44f.js → index-knqczmnm.js} +10 -10
- package/dist/{index-smjdc3h9.js → index-vah60vxp.js} +8 -8
- package/dist/{keepalive-5ds53bjd.js → keepalive-20rd6hxh.js} +5 -5
- package/dist/{lead-5xhez25b.js → lead-7w2k3a49.js} +21 -21
- package/dist/{maintenance-b43d24q6.js → maintenance-p3x918yw.js} +4 -4
- package/dist/{oauth-refresh-sweep-qe286vn2.js → oauth-refresh-sweep-shm0nzm4.js} +4 -4
- package/dist/{onboard-c4r3ds3z.js → onboard-py9dnf54.js} +6 -2
- package/dist/{otel-impl-nv3rjw61.js → otel-impl-7yjkfg68.js} +1 -1
- package/dist/{pi-mono-adapter-2syx1x4d.js → pi-mono-adapter-z6h98fva.js} +4 -38
- package/dist/{pricing-refresh-5ct2wp4k.js → pricing-refresh-3snb6370.js} +4 -4
- package/dist/{rbac-roles-m502w0qv.js → rbac-roles-5e72bbpk.js} +3 -3
- package/dist/{rbac-roles-b82cxpxn.js → rbac-roles-gqxdp8st.js} +4 -4
- package/dist/{seed-pricing-jhjphbf0.js → seed-pricing-bg42d7h2.js} +3 -3
- package/dist/{setup-zbaspydq.js → setup-nzk3kbbq.js} +2 -2
- package/dist/{worker-snvhpax5.js → worker-0p1jdzkm.js} +21 -21
- package/openapi.json +146 -1
- package/package.json +3 -1
- package/src/be/db.ts +81 -4
- package/src/be/models-catalog.ts +156 -0
- package/src/be/modelsdev-cache.ts +14 -1
- package/src/be/pricing-refresh.ts +2 -0
- package/src/be/scripts/typecheck.ts +17 -4
- package/src/be/seed-scripts/catalog/task-context-gathering.ts +1 -1
- package/src/commands/onboard/env-generator.ts +12 -0
- package/src/e2b/env.ts +0 -4
- package/src/hooks/hook.ts +0 -67
- package/src/http/all-routes.ts +1 -0
- package/src/http/index.ts +2 -0
- package/src/http/models-catalog.ts +65 -0
- package/src/http/workflows.ts +16 -4
- package/src/prompts/base-prompt.ts +8 -7
- package/src/prompts/session-templates.ts +106 -12
- package/src/providers/pi-mono-adapter.ts +12 -2
- package/src/providers/pi-mono-extension.ts +0 -64
- package/src/providers/pricing-sources.md +16 -1
- package/src/scripts-runtime/eval-harness.ts +18 -1
- package/src/scripts-runtime/swarm-sdk.ts +10 -0
- package/src/scripts-runtime/types/stdlib.d.ts +13 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +13 -0
- package/src/server-user.ts +4 -7
- package/src/slack/blocks.ts +21 -8
- package/src/slack/responses.ts +27 -51
- package/src/slack/watcher.ts +22 -5
- package/src/telemetry.ts +169 -3
- package/src/tests/base-prompt.test.ts +79 -0
- package/src/tests/mcp-tools-user.test.ts +62 -16
- package/src/tests/mcp-tools.test.ts +6 -3
- package/src/tests/memory-edit.test.ts +21 -4
- package/src/tests/model-groups-live-catalog.test.ts +65 -0
- package/src/tests/models-catalog.test.ts +119 -0
- package/src/tests/oauth-access-token-tool.test.ts +71 -1
- package/src/tests/pricing-refresh.test.ts +25 -0
- package/src/tests/prompt-template-session.test.ts +142 -5
- package/src/tests/rbac-charact-skills.test.ts +81 -14
- package/src/tests/script-apis-mcp.test.ts +56 -8
- package/src/tests/scripts-mcp-e2e.test.ts +157 -8
- package/src/tests/scripts-typecheck.test.ts +17 -0
- package/src/tests/sdk-allowlist.test.ts +34 -1
- package/src/tests/seed-scripts.test.ts +43 -0
- package/src/tests/slack-blocks.test.ts +2 -1
- package/src/tests/slack-inline-output.test.ts +24 -30
- package/src/tests/slack-watcher.test.ts +42 -0
- package/src/tests/steer-task-tool.test.ts +37 -8
- package/src/tests/steering-transport.test.ts +18 -3
- package/src/tests/swarm-tool-result-gate.test.ts +399 -0
- package/src/tests/task-tools-ctx.test.ts +49 -17
- package/src/tests/task-tools-ownership.test.ts +41 -13
- package/src/tests/telemetry-init.test.ts +376 -2
- package/src/tests/tool-output-agent-id.test.ts +14 -2
- package/src/tests/workflow-http-v2.test.ts +116 -0
- package/src/tools/accept-steer.ts +45 -53
- package/src/tools/cancel-task.ts +31 -41
- package/src/tools/context-diff.ts +19 -63
- package/src/tools/context-history.ts +22 -51
- package/src/tools/create-channel.ts +24 -39
- package/src/tools/create-metric.ts +19 -82
- package/src/tools/create-page.ts +20 -81
- package/src/tools/credential-bindings/tool.ts +125 -246
- package/src/tools/db-query.ts +13 -24
- package/src/tools/delete-channel.ts +25 -71
- package/src/tools/delete-page.ts +27 -75
- package/src/tools/get-metrics.ts +29 -22
- package/src/tools/get-swarm.ts +44 -15
- package/src/tools/get-task-details.ts +150 -32
- package/src/tools/get-tasks.ts +63 -29
- package/src/tools/inject-learning.ts +8 -38
- package/src/tools/join-swarm.ts +45 -47
- package/src/tools/kv/kv-delete.ts +13 -37
- package/src/tools/kv/kv-get.ts +38 -29
- package/src/tools/kv/kv-incr.ts +28 -56
- package/src/tools/kv/kv-list.ts +40 -31
- package/src/tools/kv/kv-set.ts +34 -76
- package/src/tools/list-channels.ts +24 -17
- package/src/tools/list-services.ts +37 -45
- package/src/tools/manage-user.ts +53 -66
- package/src/tools/mcp-servers/mcp-server-create.ts +19 -55
- package/src/tools/mcp-servers/mcp-server-delete.ts +9 -39
- package/src/tools/mcp-servers/mcp-server-get.ts +9 -35
- package/src/tools/mcp-servers/mcp-server-install.ts +13 -60
- package/src/tools/mcp-servers/mcp-server-list.ts +28 -26
- package/src/tools/mcp-servers/mcp-server-uninstall.ts +10 -36
- package/src/tools/mcp-servers/mcp-server-update.ts +13 -57
- package/src/tools/memory-delete.ts +16 -46
- package/src/tools/memory-edit.ts +48 -49
- package/src/tools/memory-get.ts +40 -36
- package/src/tools/memory-rate.ts +14 -44
- package/src/tools/memory-search.ts +46 -52
- package/src/tools/my-agent-info.ts +39 -33
- package/src/tools/oauth-access-token.ts +9 -24
- package/src/tools/poll-task.ts +50 -77
- package/src/tools/post-message.ts +24 -38
- package/src/tools/prompt-templates/delete.ts +16 -48
- package/src/tools/prompt-templates/get.ts +45 -42
- package/src/tools/prompt-templates/list.ts +29 -44
- package/src/tools/prompt-templates/preview.ts +14 -40
- package/src/tools/prompt-templates/set.ts +30 -52
- package/src/tools/read-messages.ts +45 -54
- package/src/tools/register-agentmail-inbox.ts +28 -84
- package/src/tools/register-kapso-number.ts +20 -50
- package/src/tools/register-service.ts +36 -44
- package/src/tools/repos/get-repos.ts +29 -21
- package/src/tools/repos/update-repo.ts +30 -27
- package/src/tools/request-human-input.ts +10 -33
- package/src/tools/resolve-user.ts +59 -16
- package/src/tools/schedules/create-schedule.ts +58 -173
- package/src/tools/schedules/delete-schedule.ts +16 -56
- package/src/tools/schedules/list-schedules.ts +41 -67
- package/src/tools/schedules/patch-schedule.ts +57 -153
- package/src/tools/schedules/run-schedule-now.ts +18 -59
- package/src/tools/schedules/update-schedule.ts +57 -153
- package/src/tools/script-apis.ts +46 -28
- package/src/tools/script-common.ts +129 -34
- package/src/tools/script-connections/tool.ts +59 -154
- package/src/tools/script-query-types.ts +43 -3
- package/src/tools/script-run.ts +41 -2
- package/src/tools/script-runs.ts +69 -1
- package/src/tools/script-search.ts +24 -1
- package/src/tools/script-upsert.ts +18 -3
- package/src/tools/send-task.ts +32 -81
- package/src/tools/skills/skill-create.ts +14 -39
- package/src/tools/skills/skill-delete.ts +14 -42
- package/src/tools/skills/skill-get-file.ts +10 -43
- package/src/tools/skills/skill-get.ts +9 -32
- package/src/tools/skills/skill-install-remote.ts +16 -52
- package/src/tools/skills/skill-install.ts +14 -52
- package/src/tools/skills/skill-list.ts +24 -26
- package/src/tools/skills/skill-publish.ts +18 -54
- package/src/tools/skills/skill-search.ts +21 -18
- package/src/tools/skills/skill-sync-remote.ts +12 -24
- package/src/tools/skills/skill-uninstall.ts +10 -26
- package/src/tools/skills/skill-update.ts +24 -81
- package/src/tools/slack-delete.ts +8 -32
- package/src/tools/slack-download-file.ts +17 -57
- package/src/tools/slack-list-channels.ts +16 -43
- package/src/tools/slack-post.ts +11 -40
- package/src/tools/slack-read.ts +33 -103
- package/src/tools/slack-reply.ts +16 -53
- package/src/tools/slack-start-thread.ts +14 -55
- package/src/tools/slack-update.ts +8 -35
- package/src/tools/slack-upload-file.ts +22 -122
- package/src/tools/steer-task.ts +22 -35
- package/src/tools/store-progress.ts +11 -26
- package/src/tools/swarm-config/delete-config.ts +19 -57
- package/src/tools/swarm-config/get-config.ts +36 -44
- package/src/tools/swarm-config/list-config.ts +36 -44
- package/src/tools/swarm-config/set-config.ts +35 -73
- package/src/tools/swarm-x.ts +20 -26
- package/src/tools/task-action.ts +26 -46
- package/src/tools/task-tool-ctx.ts +5 -13
- package/src/tools/tracker/tracker-link-task.ts +8 -22
- package/src/tools/tracker/tracker-map-agent.ts +8 -22
- package/src/tools/tracker/tracker-status.ts +27 -19
- package/src/tools/tracker/tracker-sync-status.ts +8 -18
- package/src/tools/tracker/tracker-unlink.ts +4 -16
- package/src/tools/unregister-service.ts +19 -59
- package/src/tools/update-profile.ts +60 -100
- package/src/tools/update-service-status.ts +42 -67
- package/src/tools/utils.ts +189 -8
- package/src/tools/whatsapp-message.ts +19 -32
- package/src/tools/workflows/cancel-workflow-run.ts +4 -16
- package/src/tools/workflows/create-workflow.ts +9 -38
- package/src/tools/workflows/delete-workflow.ts +5 -17
- package/src/tools/workflows/get-workflow-run.ts +41 -31
- package/src/tools/workflows/get-workflow.ts +10 -21
- package/src/tools/workflows/list-workflow-runs.ts +107 -34
- package/src/tools/workflows/list-workflows.ts +5 -17
- package/src/tools/workflows/patch-workflow-node.ts +11 -39
- package/src/tools/workflows/patch-workflow.ts +11 -36
- package/src/tools/workflows/retry-workflow-run.ts +4 -16
- package/src/tools/workflows/trigger-workflow.ts +22 -58
- package/src/tools/workflows/update-workflow.ts +10 -42
- package/templates/skills/swarm-scripts/SKILL.md +1 -1
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
upsertScriptConnection,
|
|
12
12
|
} from "@/be/script-connections";
|
|
13
13
|
import { can } from "@/rbac";
|
|
14
|
-
import { createToolRegistrar } from "@/tools/utils";
|
|
14
|
+
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
15
15
|
import { resolveScopedResourceId, scopedResourceScopeIdSchema } from "@/utils/scoped-resource";
|
|
16
16
|
|
|
17
17
|
const scriptConnectionsInputSchema = z.object({
|
|
@@ -92,11 +92,9 @@ const scriptConnectionsInputSchema = z.object({
|
|
|
92
92
|
enabled: z.boolean().optional().describe("Whether the connection is enabled."),
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
-
const scriptConnectionsOutputSchema =
|
|
95
|
+
const scriptConnectionsOutputSchema = swarmToolOutputSchema({
|
|
96
96
|
yourAgentId: z.string().optional(),
|
|
97
|
-
|
|
98
|
-
message: z.string(),
|
|
99
|
-
connections: z.array(z.unknown()),
|
|
97
|
+
connections: z.array(z.unknown()).optional(),
|
|
100
98
|
});
|
|
101
99
|
|
|
102
100
|
type ScriptConnectionsArgs = z.infer<typeof scriptConnectionsInputSchema>;
|
|
@@ -148,14 +146,7 @@ export const registerScriptConnectionsTool = (server: McpServer) => {
|
|
|
148
146
|
},
|
|
149
147
|
async (args, requestInfo) => {
|
|
150
148
|
if (!requestInfo.agentId) {
|
|
151
|
-
return
|
|
152
|
-
content: [{ type: "text", text: 'Agent ID not found. Set the "X-Agent-ID" header.' }],
|
|
153
|
-
structuredContent: {
|
|
154
|
-
success: false,
|
|
155
|
-
message: 'Agent ID not found. Set the "X-Agent-ID" header.',
|
|
156
|
-
connections: [],
|
|
157
|
-
},
|
|
158
|
-
};
|
|
149
|
+
return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
|
|
159
150
|
}
|
|
160
151
|
|
|
161
152
|
const agent = getAgentById(requestInfo.agentId);
|
|
@@ -170,15 +161,9 @@ export const registerScriptConnectionsTool = (server: McpServer) => {
|
|
|
170
161
|
source: "mcp",
|
|
171
162
|
});
|
|
172
163
|
if (!decision.allow) {
|
|
173
|
-
return {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
yourAgentId: requestInfo.agentId,
|
|
177
|
-
success: false,
|
|
178
|
-
message: "Only the lead can manage script connections.",
|
|
179
|
-
connections: [],
|
|
180
|
-
},
|
|
181
|
-
};
|
|
164
|
+
return toolErr("Only the lead can manage script connections.", {
|
|
165
|
+
data: { yourAgentId: requestInfo.agentId },
|
|
166
|
+
});
|
|
182
167
|
}
|
|
183
168
|
|
|
184
169
|
if (args.action === "list") {
|
|
@@ -186,101 +171,61 @@ export const registerScriptConnectionsTool = (server: McpServer) => {
|
|
|
186
171
|
const provenanceLines = connections
|
|
187
172
|
.filter((connection) => connection.kind === "openapi" || connection.baseUrl !== null)
|
|
188
173
|
.map(baseUrlProvenanceText);
|
|
189
|
-
return {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
text: `Found ${connections.length} script connection(s).${provenanceLines.length ? `\n${provenanceLines.join("\n")}` : ""}`,
|
|
194
|
-
},
|
|
195
|
-
],
|
|
196
|
-
structuredContent: {
|
|
197
|
-
yourAgentId: requestInfo.agentId,
|
|
198
|
-
success: true,
|
|
199
|
-
message: `Found ${connections.length} script connection(s).`,
|
|
200
|
-
connections,
|
|
201
|
-
},
|
|
202
|
-
};
|
|
174
|
+
return toolOk(`Found ${connections.length} script connection(s).`, {
|
|
175
|
+
details: provenanceLines.length > 0 ? provenanceLines.join("\n") : undefined,
|
|
176
|
+
data: { yourAgentId: requestInfo.agentId, connections },
|
|
177
|
+
});
|
|
203
178
|
}
|
|
204
179
|
|
|
205
180
|
if (args.action === "disable") {
|
|
206
181
|
if (!args.id) {
|
|
207
|
-
return {
|
|
208
|
-
|
|
209
|
-
structuredContent: {
|
|
182
|
+
return toolErr("id is required for disable.", {
|
|
183
|
+
data: {
|
|
210
184
|
yourAgentId: requestInfo.agentId,
|
|
211
|
-
success: false,
|
|
212
|
-
message: "id is required for disable.",
|
|
213
185
|
connections: listScriptConnections({ includeDisabled: true, allScopes: true }),
|
|
214
186
|
},
|
|
215
|
-
};
|
|
187
|
+
});
|
|
216
188
|
}
|
|
217
189
|
setScriptConnectionEnabled(args.id, false);
|
|
218
190
|
const connections = listScriptConnections({ includeDisabled: true, allScopes: true });
|
|
219
|
-
return {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
yourAgentId: requestInfo.agentId,
|
|
223
|
-
success: true,
|
|
224
|
-
message: "Script connection disabled.",
|
|
225
|
-
connections,
|
|
226
|
-
},
|
|
227
|
-
};
|
|
191
|
+
return toolOk("Script connection disabled.", {
|
|
192
|
+
data: { yourAgentId: requestInfo.agentId, connections },
|
|
193
|
+
});
|
|
228
194
|
}
|
|
229
195
|
|
|
230
196
|
if (args.action === "refresh") {
|
|
231
197
|
if (!args.id) {
|
|
232
|
-
return {
|
|
233
|
-
|
|
234
|
-
structuredContent: {
|
|
198
|
+
return toolErr("id is required for refresh.", {
|
|
199
|
+
data: {
|
|
235
200
|
yourAgentId: requestInfo.agentId,
|
|
236
|
-
success: false,
|
|
237
|
-
message: "id is required for refresh.",
|
|
238
201
|
connections: listScriptConnections({ includeDisabled: true, allScopes: true }),
|
|
239
202
|
},
|
|
240
|
-
};
|
|
203
|
+
});
|
|
241
204
|
}
|
|
242
205
|
const refreshed = await refreshScriptConnection(args.id, null, requestInfo.agentId);
|
|
243
206
|
const connections = listScriptConnections({ includeDisabled: true, allScopes: true });
|
|
244
207
|
if (!refreshed) {
|
|
245
|
-
return {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
yourAgentId: requestInfo.agentId,
|
|
249
|
-
success: false,
|
|
250
|
-
message: "Script connection not found.",
|
|
251
|
-
connections,
|
|
252
|
-
},
|
|
253
|
-
};
|
|
208
|
+
return toolErr("Script connection not found.", {
|
|
209
|
+
data: { yourAgentId: requestInfo.agentId, connections },
|
|
210
|
+
});
|
|
254
211
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
type: "text",
|
|
259
|
-
text: `Script connection ${refreshed.slug} refreshed (${baseUrlProvenanceText(refreshed)}).`,
|
|
260
|
-
},
|
|
261
|
-
],
|
|
262
|
-
structuredContent: {
|
|
263
|
-
yourAgentId: requestInfo.agentId,
|
|
264
|
-
success: !refreshed.generationError,
|
|
265
|
-
message: refreshed.generationError
|
|
266
|
-
? `Refreshed but generation failed: ${refreshed.generationError}`
|
|
267
|
-
: `Script connection ${refreshed.slug} refreshed.`,
|
|
268
|
-
connections,
|
|
269
|
-
},
|
|
212
|
+
const extras = {
|
|
213
|
+
details: baseUrlProvenanceText(refreshed),
|
|
214
|
+
data: { yourAgentId: requestInfo.agentId, connections },
|
|
270
215
|
};
|
|
216
|
+
return refreshed.generationError
|
|
217
|
+
? toolErr(`Refreshed but generation failed: ${refreshed.generationError}`, extras)
|
|
218
|
+
: toolOk(`Script connection ${refreshed.slug} refreshed.`, extras);
|
|
271
219
|
}
|
|
272
220
|
|
|
273
221
|
if (args.action === "upsert-mcp") {
|
|
274
222
|
if (!args.slug || !args.mcpServerId) {
|
|
275
|
-
return {
|
|
276
|
-
|
|
277
|
-
structuredContent: {
|
|
223
|
+
return toolErr("slug and mcpServerId are required.", {
|
|
224
|
+
data: {
|
|
278
225
|
yourAgentId: requestInfo.agentId,
|
|
279
|
-
success: false,
|
|
280
|
-
message: "slug and mcpServerId are required.",
|
|
281
226
|
connections: listScriptConnections({ includeDisabled: true, allScopes: true }),
|
|
282
227
|
},
|
|
283
|
-
};
|
|
228
|
+
});
|
|
284
229
|
}
|
|
285
230
|
|
|
286
231
|
const existing = args.id ? getScriptConnectionById(args.id) : null;
|
|
@@ -298,30 +243,20 @@ export const registerScriptConnectionsTool = (server: McpServer) => {
|
|
|
298
243
|
});
|
|
299
244
|
|
|
300
245
|
const connections = listScriptConnections({ includeDisabled: true, allScopes: true });
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
success: !connection.generationError,
|
|
306
|
-
message: connection.generationError
|
|
307
|
-
? `Saved but generation failed: ${connection.generationError}`
|
|
308
|
-
: `Script MCP connection ${connection.slug} saved.`,
|
|
309
|
-
connections,
|
|
310
|
-
},
|
|
311
|
-
};
|
|
246
|
+
const extras = { data: { yourAgentId: requestInfo.agentId, connections } };
|
|
247
|
+
return connection.generationError
|
|
248
|
+
? toolErr(`Saved but generation failed: ${connection.generationError}`, extras)
|
|
249
|
+
: toolOk(`Script MCP connection ${connection.slug} saved.`, extras);
|
|
312
250
|
}
|
|
313
251
|
|
|
314
252
|
if (args.action === "upsert-graphql") {
|
|
315
253
|
if (!args.slug || !args.baseUrl || !args.allowedHosts?.length) {
|
|
316
|
-
return {
|
|
317
|
-
|
|
318
|
-
structuredContent: {
|
|
254
|
+
return toolErr("slug, baseUrl, and allowedHosts are required.", {
|
|
255
|
+
data: {
|
|
319
256
|
yourAgentId: requestInfo.agentId,
|
|
320
|
-
success: false,
|
|
321
|
-
message: "slug, baseUrl, and allowedHosts are required.",
|
|
322
257
|
connections: listScriptConnections({ includeDisabled: true, allScopes: true }),
|
|
323
258
|
},
|
|
324
|
-
};
|
|
259
|
+
});
|
|
325
260
|
}
|
|
326
261
|
|
|
327
262
|
const existing = args.id ? getScriptConnectionById(args.id) : null;
|
|
@@ -347,51 +282,30 @@ export const registerScriptConnectionsTool = (server: McpServer) => {
|
|
|
347
282
|
});
|
|
348
283
|
|
|
349
284
|
const connections = listScriptConnections({ includeDisabled: true, allScopes: true });
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
success: !connection.generationError,
|
|
355
|
-
message: connection.generationError
|
|
356
|
-
? `Saved but generation failed: ${connection.generationError}`
|
|
357
|
-
: `Script GraphQL connection ${connection.slug} saved.`,
|
|
358
|
-
connections,
|
|
359
|
-
},
|
|
360
|
-
};
|
|
285
|
+
const extras = { data: { yourAgentId: requestInfo.agentId, connections } };
|
|
286
|
+
return connection.generationError
|
|
287
|
+
? toolErr(`Saved but generation failed: ${connection.generationError}`, extras)
|
|
288
|
+
: toolOk(`Script GraphQL connection ${connection.slug} saved.`, extras);
|
|
361
289
|
}
|
|
362
290
|
|
|
363
291
|
if (!args.slug || (!args.openapiSpecJson && !args.openapiSpecUrl && !args.specSource)) {
|
|
364
|
-
return
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
292
|
+
return toolErr(
|
|
293
|
+
"slug and exactly one OpenAPI spec source (openapiSpecJson, openapiSpecUrl, or specSource) are required.",
|
|
294
|
+
{
|
|
295
|
+
data: {
|
|
296
|
+
yourAgentId: requestInfo.agentId,
|
|
297
|
+
connections: listScriptConnections({ includeDisabled: true, allScopes: true }),
|
|
369
298
|
},
|
|
370
|
-
],
|
|
371
|
-
structuredContent: {
|
|
372
|
-
yourAgentId: requestInfo.agentId,
|
|
373
|
-
success: false,
|
|
374
|
-
message:
|
|
375
|
-
"slug and exactly one OpenAPI spec source (openapiSpecJson, openapiSpecUrl, or specSource) are required.",
|
|
376
|
-
connections: listScriptConnections({ includeDisabled: true, allScopes: true }),
|
|
377
299
|
},
|
|
378
|
-
|
|
300
|
+
);
|
|
379
301
|
}
|
|
380
302
|
if ([args.openapiSpecJson, args.openapiSpecUrl, args.specSource].filter(Boolean).length > 1) {
|
|
381
|
-
return {
|
|
382
|
-
|
|
383
|
-
{
|
|
384
|
-
type: "text",
|
|
385
|
-
text: "Provide exactly one OpenAPI spec source.",
|
|
386
|
-
},
|
|
387
|
-
],
|
|
388
|
-
structuredContent: {
|
|
303
|
+
return toolErr("Provide exactly one OpenAPI spec source.", {
|
|
304
|
+
data: {
|
|
389
305
|
yourAgentId: requestInfo.agentId,
|
|
390
|
-
success: false,
|
|
391
|
-
message: "Provide exactly one OpenAPI spec source.",
|
|
392
306
|
connections: listScriptConnections({ includeDisabled: true, allScopes: true }),
|
|
393
307
|
},
|
|
394
|
-
};
|
|
308
|
+
});
|
|
395
309
|
}
|
|
396
310
|
|
|
397
311
|
const existing = args.id ? getScriptConnectionById(args.id) : null;
|
|
@@ -421,22 +335,13 @@ export const registerScriptConnectionsTool = (server: McpServer) => {
|
|
|
421
335
|
});
|
|
422
336
|
|
|
423
337
|
const connections = listScriptConnections({ includeDisabled: true, allScopes: true });
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
type: "text",
|
|
428
|
-
text: `Script connection ${connection.slug} saved (${baseUrlProvenanceText(connection)}).`,
|
|
429
|
-
},
|
|
430
|
-
],
|
|
431
|
-
structuredContent: {
|
|
432
|
-
yourAgentId: requestInfo.agentId,
|
|
433
|
-
success: !connection.generationError,
|
|
434
|
-
message: connection.generationError
|
|
435
|
-
? `Saved but generation failed: ${connection.generationError}`
|
|
436
|
-
: `Script connection ${connection.slug} saved.`,
|
|
437
|
-
connections,
|
|
438
|
-
},
|
|
338
|
+
const extras = {
|
|
339
|
+
details: baseUrlProvenanceText(connection),
|
|
340
|
+
data: { yourAgentId: requestInfo.agentId, connections },
|
|
439
341
|
};
|
|
342
|
+
return connection.generationError
|
|
343
|
+
? toolErr(`Saved but generation failed: ${connection.generationError}`, extras)
|
|
344
|
+
: toolOk(`Script connection ${connection.slug} saved.`, extras);
|
|
440
345
|
},
|
|
441
346
|
);
|
|
442
347
|
};
|
|
@@ -9,7 +9,31 @@ import {
|
|
|
9
9
|
} from "./script-common";
|
|
10
10
|
|
|
11
11
|
export const SCRIPT_QUERY_TYPES_DESCRIPTION =
|
|
12
|
-
"Fetch the
|
|
12
|
+
"Fetch the auto-generated `swarm-sdk.d.ts` (derived from the live MCP tool registry) + the `stdlib.d.ts` blobs — for IDE-style introspection before authoring or running a script. Pass `name` to also get that script's signature; omit it for the swarm-wide type surface. The same types are used by `script-upsert`'s typecheck pass, so they are authoritative.";
|
|
13
|
+
|
|
14
|
+
function renderTypeBlobs(data: unknown): string | undefined {
|
|
15
|
+
if (typeof data !== "object" || data === null) return undefined;
|
|
16
|
+
const body = data as {
|
|
17
|
+
signature?: unknown;
|
|
18
|
+
argsJsonSchema?: unknown;
|
|
19
|
+
sdkTypes?: unknown;
|
|
20
|
+
stdlibTypes?: unknown;
|
|
21
|
+
};
|
|
22
|
+
const parts: string[] = [];
|
|
23
|
+
if (body.signature !== undefined && body.signature !== null) {
|
|
24
|
+
parts.push(`signature:\n${JSON.stringify(body.signature, null, 2)}`);
|
|
25
|
+
}
|
|
26
|
+
if (body.argsJsonSchema !== undefined && body.argsJsonSchema !== null) {
|
|
27
|
+
parts.push(`argsJsonSchema:\n${JSON.stringify(body.argsJsonSchema, null, 2)}`);
|
|
28
|
+
}
|
|
29
|
+
if (typeof body.sdkTypes === "string" && body.sdkTypes) {
|
|
30
|
+
parts.push(`swarm-sdk.d.ts:\n${body.sdkTypes}`);
|
|
31
|
+
}
|
|
32
|
+
if (typeof body.stdlibTypes === "string" && body.stdlibTypes) {
|
|
33
|
+
parts.push(`stdlib.d.ts:\n${body.stdlibTypes}`);
|
|
34
|
+
}
|
|
35
|
+
return parts.length > 0 ? parts.join("\n\n") : undefined;
|
|
36
|
+
}
|
|
13
37
|
|
|
14
38
|
export const registerScriptQueryTypesTool = (server: McpServer) => {
|
|
15
39
|
createToolRegistrar(server)(
|
|
@@ -19,18 +43,34 @@ export const registerScriptQueryTypesTool = (server: McpServer) => {
|
|
|
19
43
|
description: SCRIPT_QUERY_TYPES_DESCRIPTION,
|
|
20
44
|
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
21
45
|
inputSchema: z.object({
|
|
22
|
-
name: scriptNameSchema
|
|
46
|
+
name: scriptNameSchema
|
|
47
|
+
.optional()
|
|
48
|
+
.describe(
|
|
49
|
+
"Optional script name whose signature should be fetched. Omit to get the swarm-wide sdk/stdlib type surface.",
|
|
50
|
+
),
|
|
23
51
|
scope: scriptScopeSchema.optional().describe("Optional scope for script resolution."),
|
|
24
52
|
}),
|
|
25
53
|
outputSchema: scriptToolOutputSchema,
|
|
26
54
|
},
|
|
27
55
|
async ({ name, scope }, requestInfo) => {
|
|
56
|
+
if (!name) {
|
|
57
|
+
return proxyScriptsApi({
|
|
58
|
+
method: "GET",
|
|
59
|
+
path: "/api/scripts/type-defs",
|
|
60
|
+
requestInfo,
|
|
61
|
+
successMessage: () => "Swarm script SDK + stdlib type definitions fetched.",
|
|
62
|
+
successDetails: renderTypeBlobs,
|
|
63
|
+
uncappedDetails: true,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
28
66
|
const query = scope ? `?scope=${encodeURIComponent(scope)}` : "";
|
|
29
67
|
return proxyScriptsApi({
|
|
30
68
|
method: "GET",
|
|
31
69
|
path: `/api/scripts/${encodeURIComponent(name)}/types${query}`,
|
|
32
70
|
requestInfo,
|
|
33
|
-
successMessage: () =>
|
|
71
|
+
successMessage: () => `Type definitions for script \`${name}\` fetched.`,
|
|
72
|
+
successDetails: renderTypeBlobs,
|
|
73
|
+
uncappedDetails: true,
|
|
34
74
|
});
|
|
35
75
|
},
|
|
36
76
|
);
|
package/src/tools/script-run.ts
CHANGED
|
@@ -10,7 +10,39 @@ import {
|
|
|
10
10
|
} from "./script-common";
|
|
11
11
|
|
|
12
12
|
export const SCRIPT_RUN_DESCRIPTION =
|
|
13
|
-
"Run a named swarm-shared script (callable across agents and from workflow `swarm-script` nodes), OR inline source (auto-saved as scratch to the catalog). Use for swarm-visible, durable scripts. For local-only throwaway TS, use code-mode `run`.";
|
|
13
|
+
"Run a named swarm-shared script (callable across agents and from workflow `swarm-script` nodes), OR inline source (auto-saved as scratch to the catalog). Inline source executes without the `script-upsert` compile-time typecheck. Use for swarm-visible, durable scripts. For local-only throwaway TS, use code-mode `run`.";
|
|
14
|
+
|
|
15
|
+
function renderRunOutput(data: unknown): string | undefined {
|
|
16
|
+
if (typeof data !== "object" || data === null) return undefined;
|
|
17
|
+
const body = data as {
|
|
18
|
+
result?: unknown;
|
|
19
|
+
stdout?: string;
|
|
20
|
+
durationMs?: number;
|
|
21
|
+
truncated?: { stdout?: boolean; stderr?: boolean };
|
|
22
|
+
autoSaved?: { slug?: string };
|
|
23
|
+
kvSaved?: { namespace?: string; key?: string };
|
|
24
|
+
};
|
|
25
|
+
const parts: string[] = [];
|
|
26
|
+
if (body.result !== undefined) {
|
|
27
|
+
parts.push(
|
|
28
|
+
`result:\n${typeof body.result === "string" ? body.result : JSON.stringify(body.result, null, 2)}`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
if (typeof body.stdout === "string" && body.stdout.trim()) {
|
|
32
|
+
parts.push(`stdout:\n${body.stdout.trim()}`);
|
|
33
|
+
}
|
|
34
|
+
const notes: string[] = [];
|
|
35
|
+
if (typeof body.durationMs === "number") notes.push(`${body.durationMs}ms`);
|
|
36
|
+
if (body.truncated?.stdout || body.truncated?.stderr) {
|
|
37
|
+
notes.push("output truncated by the runtime");
|
|
38
|
+
}
|
|
39
|
+
if (body.autoSaved?.slug) notes.push(`auto-saved as scratch script \`${body.autoSaved.slug}\``);
|
|
40
|
+
if (body.kvSaved?.key) {
|
|
41
|
+
notes.push(`output persisted to kv ${body.kvSaved.namespace}/${body.kvSaved.key}`);
|
|
42
|
+
}
|
|
43
|
+
if (notes.length > 0) parts.push(`(${notes.join("; ")})`);
|
|
44
|
+
return parts.length > 0 ? parts.join("\n\n") : undefined;
|
|
45
|
+
}
|
|
14
46
|
|
|
15
47
|
export const registerScriptRunTool = (server: McpServer) => {
|
|
16
48
|
createToolRegistrar(server)(
|
|
@@ -21,7 +53,13 @@ export const registerScriptRunTool = (server: McpServer) => {
|
|
|
21
53
|
annotations: { openWorldHint: true },
|
|
22
54
|
inputSchema: z.object({
|
|
23
55
|
name: scriptNameSchema.optional().describe("Name of a reusable script to run."),
|
|
24
|
-
source: z
|
|
56
|
+
source: z
|
|
57
|
+
.string()
|
|
58
|
+
.min(1)
|
|
59
|
+
.optional()
|
|
60
|
+
.describe(
|
|
61
|
+
'Inline TypeScript source to run without a compile-time typecheck. Must `export default async function (args, ctx)` — args FIRST, ctx second. Import `ScriptContext` from "swarm-sdk" for promotion-safe typing.',
|
|
62
|
+
),
|
|
25
63
|
args: z.unknown().optional().describe("JSON-serializable script arguments."),
|
|
26
64
|
intent: z.string().default("").describe("Why this script is being run."),
|
|
27
65
|
scope: scriptScopeSchema.optional().describe("Optional scope for named script resolution."),
|
|
@@ -45,6 +83,7 @@ export const registerScriptRunTool = (server: McpServer) => {
|
|
|
45
83
|
body: args,
|
|
46
84
|
requestInfo,
|
|
47
85
|
successMessage: () => "Script run completed.",
|
|
86
|
+
successDetails: renderRunOutput,
|
|
48
87
|
}),
|
|
49
88
|
);
|
|
50
89
|
};
|
package/src/tools/script-runs.ts
CHANGED
|
@@ -13,6 +13,66 @@ export const GET_SCRIPT_RUN_DESCRIPTION =
|
|
|
13
13
|
export const LIST_SCRIPT_RUNS_DESCRIPTION =
|
|
14
14
|
"List durable script workflow runs, optionally filtered by status or agent ID.";
|
|
15
15
|
|
|
16
|
+
const JOURNAL_RENDER_LIMIT = 20;
|
|
17
|
+
const JOURNAL_VALUE_CAP = 400;
|
|
18
|
+
|
|
19
|
+
function journalValuePreview(value: unknown): string | undefined {
|
|
20
|
+
if (value === undefined || value === null) return undefined;
|
|
21
|
+
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
22
|
+
if (!serialized) return undefined;
|
|
23
|
+
return serialized.length > JOURNAL_VALUE_CAP
|
|
24
|
+
? `${serialized.slice(0, JOURNAL_VALUE_CAP)}…`
|
|
25
|
+
: serialized;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function renderRunDetail(data: unknown): string | undefined {
|
|
29
|
+
if (typeof data !== "object" || data === null) return undefined;
|
|
30
|
+
const run = (data as { run?: Record<string, unknown> }).run;
|
|
31
|
+
if (!run) return undefined;
|
|
32
|
+
const lines: string[] = [];
|
|
33
|
+
if (typeof run.status === "string") lines.push(`status: ${run.status}`);
|
|
34
|
+
if (typeof run.error === "string" && run.error) lines.push(`error: ${run.error}`);
|
|
35
|
+
if (run.output !== undefined && run.output !== null) {
|
|
36
|
+
lines.push(`output: ${JSON.stringify(run.output)}`);
|
|
37
|
+
}
|
|
38
|
+
// Journal entries must reach the text channel — most harnesses never show
|
|
39
|
+
// the model structuredContent, and a bare count hides step outcomes.
|
|
40
|
+
const journal = (data as { journal?: unknown[] }).journal;
|
|
41
|
+
if (Array.isArray(journal) && journal.length > 0) {
|
|
42
|
+
lines.push(`journal (${journal.length} entr${journal.length === 1 ? "y" : "ies"}):`);
|
|
43
|
+
for (const raw of journal.slice(0, JOURNAL_RENDER_LIMIT)) {
|
|
44
|
+
const entry = (raw ?? {}) as Record<string, unknown>;
|
|
45
|
+
const key = String(entry.stepKey ?? entry.label ?? entry.id ?? "?");
|
|
46
|
+
const kind = typeof entry.stepType === "string" ? ` [${entry.stepType}]` : "";
|
|
47
|
+
const status = typeof entry.status === "string" ? ` ${entry.status}` : "";
|
|
48
|
+
const error =
|
|
49
|
+
typeof entry.error === "string" && entry.error ? ` — error: ${entry.error}` : "";
|
|
50
|
+
const output = error ? undefined : journalValuePreview(entry.output ?? entry.result);
|
|
51
|
+
lines.push(`- ${key}${kind}:${status}${error}${output ? ` — ${output}` : ""}`);
|
|
52
|
+
}
|
|
53
|
+
if (journal.length > JOURNAL_RENDER_LIMIT) {
|
|
54
|
+
lines.push(
|
|
55
|
+
`… +${journal.length - JOURNAL_RENDER_LIMIT} more entries (see structuredContent.data.journal)`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return lines.length > 0 ? lines.join("\n") : undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function renderRunsList(data: unknown): string | undefined {
|
|
63
|
+
if (typeof data !== "object" || data === null) return undefined;
|
|
64
|
+
const runs = (data as { runs?: unknown[] }).runs;
|
|
65
|
+
if (!Array.isArray(runs) || runs.length === 0) return undefined;
|
|
66
|
+
return runs
|
|
67
|
+
.map((entry) => {
|
|
68
|
+
const run = entry as Record<string, unknown>;
|
|
69
|
+
const name = typeof run.scriptName === "string" && run.scriptName ? ` ${run.scriptName}` : "";
|
|
70
|
+
const error = typeof run.error === "string" && run.error ? ` — ${run.error}` : "";
|
|
71
|
+
return `- ${String(run.id ?? "?")}${name}: ${String(run.status ?? "unknown")}${error}`;
|
|
72
|
+
})
|
|
73
|
+
.join("\n");
|
|
74
|
+
}
|
|
75
|
+
|
|
16
76
|
export const registerScriptRunsTools = (server: McpServer) => {
|
|
17
77
|
const register = createToolRegistrar(server);
|
|
18
78
|
|
|
@@ -23,7 +83,12 @@ export const registerScriptRunsTools = (server: McpServer) => {
|
|
|
23
83
|
description: LAUNCH_SCRIPT_RUN_DESCRIPTION,
|
|
24
84
|
annotations: { openWorldHint: true },
|
|
25
85
|
inputSchema: z.object({
|
|
26
|
-
source: z
|
|
86
|
+
source: z
|
|
87
|
+
.string()
|
|
88
|
+
.min(1)
|
|
89
|
+
.describe(
|
|
90
|
+
"TypeScript script workflow source. Must `export default async function (args, ctx)` — args FIRST, ctx second.",
|
|
91
|
+
),
|
|
27
92
|
args: z.unknown().optional().describe("JSON-serializable workflow arguments."),
|
|
28
93
|
idempotencyKey: z
|
|
29
94
|
.string()
|
|
@@ -83,6 +148,8 @@ export const registerScriptRunsTools = (server: McpServer) => {
|
|
|
83
148
|
: "unknown";
|
|
84
149
|
return `Script run ${id} status: ${status}.`;
|
|
85
150
|
},
|
|
151
|
+
successDetails: renderRunDetail,
|
|
152
|
+
failureDetails: renderRunDetail,
|
|
86
153
|
}),
|
|
87
154
|
);
|
|
88
155
|
|
|
@@ -117,6 +184,7 @@ export const registerScriptRunsTools = (server: McpServer) => {
|
|
|
117
184
|
: 0;
|
|
118
185
|
return `Found ${Number.isFinite(total) ? total : 0} script run(s).`;
|
|
119
186
|
},
|
|
187
|
+
successDetails: renderRunsList,
|
|
120
188
|
});
|
|
121
189
|
},
|
|
122
190
|
);
|
|
@@ -6,6 +6,20 @@ import { proxyScriptsApi, scriptScopeSchema, scriptToolOutputSchema } from "./sc
|
|
|
6
6
|
export const SCRIPT_SEARCH_DESCRIPTION =
|
|
7
7
|
"Semantic search over swarm-shared TypeScript scripts (catalog persisted in the agent-swarm DB; callable from agents and workflows). For ephemeral throwaway TS on your local machine, use code-mode instead.";
|
|
8
8
|
|
|
9
|
+
function renderSearchResults(data: unknown): string | undefined {
|
|
10
|
+
if (typeof data !== "object" || data === null) return undefined;
|
|
11
|
+
const results = (data as { results?: unknown[] }).results;
|
|
12
|
+
if (!Array.isArray(results) || results.length === 0) return undefined;
|
|
13
|
+
return results
|
|
14
|
+
.map((entry) => {
|
|
15
|
+
const item = entry as { name?: unknown; description?: unknown; score?: unknown };
|
|
16
|
+
const description =
|
|
17
|
+
typeof item.description === "string" && item.description ? ` — ${item.description}` : "";
|
|
18
|
+
return `- ${String(item.name ?? "?")}${description}`;
|
|
19
|
+
})
|
|
20
|
+
.join("\n");
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
export const registerScriptSearchTool = (server: McpServer) => {
|
|
10
24
|
createToolRegistrar(server)(
|
|
11
25
|
"script-search",
|
|
@@ -26,7 +40,16 @@ export const registerScriptSearchTool = (server: McpServer) => {
|
|
|
26
40
|
path: "/api/scripts/search",
|
|
27
41
|
body: args,
|
|
28
42
|
requestInfo,
|
|
29
|
-
successMessage: () =>
|
|
43
|
+
successMessage: (data) => {
|
|
44
|
+
const results =
|
|
45
|
+
typeof data === "object" &&
|
|
46
|
+
data !== null &&
|
|
47
|
+
Array.isArray((data as { results?: unknown[] }).results)
|
|
48
|
+
? (data as { results: unknown[] }).results
|
|
49
|
+
: [];
|
|
50
|
+
return `Found ${results.length} script(s).`;
|
|
51
|
+
},
|
|
52
|
+
successDetails: renderSearchResults,
|
|
30
53
|
}),
|
|
31
54
|
);
|
|
32
55
|
};
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./script-common";
|
|
11
11
|
|
|
12
12
|
export const SCRIPT_UPSERT_DESCRIPTION =
|
|
13
|
-
|
|
13
|
+
'Typecheck and persist a TypeScript script to the swarm catalog under your agent scope (or global if you\'re a lead). Import `ScriptContext` from "swarm-sdk" for a real context type. Other agents and workflow nodes will be able to find and run it. For local-only scripts, use code-mode `save`.';
|
|
14
14
|
|
|
15
15
|
export const registerScriptUpsertTool = (server: McpServer) => {
|
|
16
16
|
createToolRegistrar(server)(
|
|
@@ -21,7 +21,12 @@ export const registerScriptUpsertTool = (server: McpServer) => {
|
|
|
21
21
|
annotations: { openWorldHint: false },
|
|
22
22
|
inputSchema: z.object({
|
|
23
23
|
name: scriptNameSchema.describe("Stable script name within the selected scope."),
|
|
24
|
-
source: z
|
|
24
|
+
source: z
|
|
25
|
+
.string()
|
|
26
|
+
.min(1)
|
|
27
|
+
.describe(
|
|
28
|
+
'TypeScript source, typechecked before saving. Must `export default async function (args, ctx)` — args FIRST, ctx second. Import `ScriptContext` from "swarm-sdk" to type `ctx`.',
|
|
29
|
+
),
|
|
25
30
|
description: z.string().default("").describe("Human-readable script description."),
|
|
26
31
|
intent: z.string().default("").describe("Why this script exists."),
|
|
27
32
|
scope: scriptScopeSchema.default("agent").describe("Persist under agent or global scope."),
|
|
@@ -37,7 +42,17 @@ export const registerScriptUpsertTool = (server: McpServer) => {
|
|
|
37
42
|
path: "/api/scripts/upsert",
|
|
38
43
|
body: args,
|
|
39
44
|
requestInfo,
|
|
40
|
-
successMessage: () =>
|
|
45
|
+
successMessage: (data) => {
|
|
46
|
+
const body = (data ?? {}) as {
|
|
47
|
+
name?: unknown;
|
|
48
|
+
version?: unknown;
|
|
49
|
+
contentDeduped?: unknown;
|
|
50
|
+
};
|
|
51
|
+
const name = typeof body.name === "string" ? body.name : args.name;
|
|
52
|
+
const version = typeof body.version === "number" ? ` v${body.version}` : "";
|
|
53
|
+
const deduped = body.contentDeduped ? " (content unchanged — deduped)" : "";
|
|
54
|
+
return `Script \`${name}\`${version} saved.${deduped}`;
|
|
55
|
+
},
|
|
41
56
|
}),
|
|
42
57
|
);
|
|
43
58
|
};
|