@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
|
@@ -8,8 +8,22 @@ import {
|
|
|
8
8
|
} from "@/be/swarm-config-guard";
|
|
9
9
|
import { scheduleIntegrationsReload } from "@/http/core";
|
|
10
10
|
import { can } from "@/rbac";
|
|
11
|
-
import { createToolRegistrar } from "@/tools/utils";
|
|
12
|
-
import {
|
|
11
|
+
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
12
|
+
import { SwarmConfigScopeSchema } from "@/types";
|
|
13
|
+
|
|
14
|
+
const configEntryShape = z.looseObject({
|
|
15
|
+
id: z.string().optional(),
|
|
16
|
+
scope: SwarmConfigScopeSchema.optional(),
|
|
17
|
+
scopeId: z.string().nullable().optional(),
|
|
18
|
+
key: z.string().optional(),
|
|
19
|
+
value: z.string().optional(),
|
|
20
|
+
isSecret: z.boolean().optional(),
|
|
21
|
+
envPath: z.string().nullable().optional(),
|
|
22
|
+
description: z.string().nullable().optional(),
|
|
23
|
+
createdAt: z.string().optional(),
|
|
24
|
+
lastUpdatedAt: z.string().optional(),
|
|
25
|
+
encrypted: z.boolean().optional(),
|
|
26
|
+
});
|
|
13
27
|
|
|
14
28
|
export const registerSetConfigTool = (server: McpServer) => {
|
|
15
29
|
createToolRegistrar(server)(
|
|
@@ -47,51 +61,27 @@ export const registerSetConfigTool = (server: McpServer) => {
|
|
|
47
61
|
.optional()
|
|
48
62
|
.describe("Optional human-readable description of this config entry."),
|
|
49
63
|
}),
|
|
50
|
-
outputSchema:
|
|
64
|
+
outputSchema: swarmToolOutputSchema({
|
|
51
65
|
yourAgentId: z.string().optional(),
|
|
52
|
-
|
|
53
|
-
message: z.string(),
|
|
54
|
-
config: SwarmConfigSchema.optional(),
|
|
66
|
+
config: configEntryShape.optional(),
|
|
55
67
|
}),
|
|
56
68
|
},
|
|
57
69
|
async ({ scope, scopeId, key, value, isSecret, envPath, description }, requestInfo) => {
|
|
58
70
|
if (!requestInfo.agentId) {
|
|
59
|
-
return
|
|
60
|
-
content: [{ type: "text", text: 'Agent ID not found. Set the "X-Agent-ID" header.' }],
|
|
61
|
-
structuredContent: {
|
|
62
|
-
success: false,
|
|
63
|
-
message: 'Agent ID not found. Set the "X-Agent-ID" header.',
|
|
64
|
-
},
|
|
65
|
-
};
|
|
71
|
+
return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
|
|
66
72
|
}
|
|
67
73
|
|
|
68
74
|
try {
|
|
69
75
|
if (scope !== "global" && !scopeId) {
|
|
70
|
-
return {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
text: `scopeId is required for scope '${scope}'. Provide an agent ID or repo ID.`,
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
structuredContent: {
|
|
78
|
-
yourAgentId: requestInfo.agentId,
|
|
79
|
-
success: false,
|
|
80
|
-
message: `scopeId is required for scope '${scope}'.`,
|
|
81
|
-
},
|
|
82
|
-
};
|
|
76
|
+
return toolErr(`scopeId is required for scope '${scope}'.`, {
|
|
77
|
+
details: `scopeId is required for scope '${scope}'. Provide an agent ID or repo ID.`,
|
|
78
|
+
data: { yourAgentId: requestInfo.agentId },
|
|
79
|
+
});
|
|
83
80
|
}
|
|
84
81
|
|
|
85
82
|
if (isReservedConfigKey(key)) {
|
|
86
83
|
const message = reservedKeyError(key).message;
|
|
87
|
-
return {
|
|
88
|
-
content: [{ type: "text", text: message }],
|
|
89
|
-
structuredContent: {
|
|
90
|
-
yourAgentId: requestInfo.agentId,
|
|
91
|
-
success: false,
|
|
92
|
-
message,
|
|
93
|
-
},
|
|
94
|
-
};
|
|
84
|
+
return toolErr(message, { data: { yourAgentId: requestInfo.agentId } });
|
|
95
85
|
}
|
|
96
86
|
|
|
97
87
|
// Every swarm-config write is lead-gated (DES-445 follow-up): previously
|
|
@@ -110,27 +100,14 @@ export const registerSetConfigTool = (server: McpServer) => {
|
|
|
110
100
|
source: "mcp",
|
|
111
101
|
});
|
|
112
102
|
if (!decision.allow) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
structuredContent: {
|
|
117
|
-
yourAgentId: requestInfo.agentId,
|
|
118
|
-
success: false,
|
|
119
|
-
message,
|
|
120
|
-
},
|
|
121
|
-
};
|
|
103
|
+
return toolErr("Writing swarm config requires the lead agent.", {
|
|
104
|
+
data: { yourAgentId: requestInfo.agentId },
|
|
105
|
+
});
|
|
122
106
|
}
|
|
123
107
|
|
|
124
108
|
const validationError = validateConfigValue(key, value);
|
|
125
109
|
if (validationError) {
|
|
126
|
-
return {
|
|
127
|
-
content: [{ type: "text", text: validationError }],
|
|
128
|
-
structuredContent: {
|
|
129
|
-
yourAgentId: requestInfo.agentId,
|
|
130
|
-
success: false,
|
|
131
|
-
message: validationError,
|
|
132
|
-
},
|
|
133
|
-
};
|
|
110
|
+
return toolErr(validationError, { data: { yourAgentId: requestInfo.agentId } });
|
|
134
111
|
}
|
|
135
112
|
|
|
136
113
|
const config = upsertSwarmConfig({
|
|
@@ -149,30 +126,15 @@ export const registerSetConfigTool = (server: McpServer) => {
|
|
|
149
126
|
|
|
150
127
|
const [masked] = maskSecrets([config]);
|
|
151
128
|
|
|
152
|
-
return {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
text: `Config "${key}" set successfully (scope: ${scope}${scopeId ? `, scopeId: ${scopeId}` : ""}).`,
|
|
157
|
-
},
|
|
158
|
-
],
|
|
159
|
-
structuredContent: {
|
|
160
|
-
yourAgentId: requestInfo.agentId,
|
|
161
|
-
success: true,
|
|
162
|
-
message: `Config "${key}" set successfully.`,
|
|
163
|
-
config: masked,
|
|
164
|
-
},
|
|
165
|
-
};
|
|
129
|
+
return toolOk(`Config "${key}" set successfully.`, {
|
|
130
|
+
details: `Config "${key}" set successfully (scope: ${scope}${scopeId ? `, scopeId: ${scopeId}` : ""}).`,
|
|
131
|
+
data: { yourAgentId: requestInfo.agentId, config: masked },
|
|
132
|
+
});
|
|
166
133
|
} catch (error) {
|
|
167
134
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
168
|
-
return {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
yourAgentId: requestInfo.agentId,
|
|
172
|
-
success: false,
|
|
173
|
-
message: `Failed to set config: ${message}`,
|
|
174
|
-
},
|
|
175
|
-
};
|
|
135
|
+
return toolErr(`Failed to set config: ${message}`, {
|
|
136
|
+
data: { yourAgentId: requestInfo.agentId },
|
|
137
|
+
});
|
|
176
138
|
}
|
|
177
139
|
},
|
|
178
140
|
);
|
package/src/tools/swarm-x.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { COMPOSIO_HTTP_METHODS, composioArgsFromParts, executeComposioRequest } from "@/x/composio";
|
|
4
|
-
import { createToolRegistrar } from "./utils";
|
|
4
|
+
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "./utils";
|
|
5
5
|
|
|
6
6
|
const primitiveQueryValueSchema = z.union([z.string(), z.number(), z.boolean()]);
|
|
7
7
|
|
|
@@ -46,16 +46,15 @@ export const registerSwarmXTool = (server: McpServer) => {
|
|
|
46
46
|
.default(false)
|
|
47
47
|
.describe("Return raw text instead of JSON-pretty output text."),
|
|
48
48
|
}),
|
|
49
|
-
outputSchema:
|
|
50
|
-
target: z.literal("composio"),
|
|
51
|
-
ok: z.boolean(),
|
|
52
|
-
status: z.number(),
|
|
53
|
-
statusText: z.string(),
|
|
54
|
-
method: z.string(),
|
|
55
|
-
url: z.string(),
|
|
56
|
-
response: z.unknown(),
|
|
57
|
-
responseText: z.string(),
|
|
58
|
-
message: z.string(),
|
|
49
|
+
outputSchema: swarmToolOutputSchema({
|
|
50
|
+
target: z.literal("composio").optional(),
|
|
51
|
+
ok: z.boolean().optional(),
|
|
52
|
+
status: z.number().optional(),
|
|
53
|
+
statusText: z.string().optional(),
|
|
54
|
+
method: z.string().optional(),
|
|
55
|
+
url: z.string().optional(),
|
|
56
|
+
response: z.unknown().optional(),
|
|
57
|
+
responseText: z.string().optional(),
|
|
59
58
|
}),
|
|
60
59
|
},
|
|
61
60
|
async (input) => {
|
|
@@ -75,9 +74,8 @@ export const registerSwarmXTool = (server: McpServer) => {
|
|
|
75
74
|
);
|
|
76
75
|
} catch (err) {
|
|
77
76
|
const message = err instanceof Error ? err.message : String(err);
|
|
78
|
-
return {
|
|
79
|
-
|
|
80
|
-
structuredContent: {
|
|
77
|
+
return toolErr(`swarm_x composio: ${message}`, {
|
|
78
|
+
data: {
|
|
81
79
|
target: "composio",
|
|
82
80
|
ok: false,
|
|
83
81
|
status: 0,
|
|
@@ -86,15 +84,14 @@ export const registerSwarmXTool = (server: McpServer) => {
|
|
|
86
84
|
url: "",
|
|
87
85
|
response: null,
|
|
88
86
|
responseText: "",
|
|
89
|
-
message,
|
|
90
87
|
},
|
|
91
|
-
|
|
92
|
-
};
|
|
88
|
+
});
|
|
93
89
|
}
|
|
94
90
|
|
|
95
|
-
const
|
|
96
|
-
result.
|
|
97
|
-
const
|
|
91
|
+
const summary =
|
|
92
|
+
`Composio ${result.method} ${result.url} → HTTP ${result.status} ${result.statusText}`.trim();
|
|
93
|
+
const details = result.error || result.formattedBody || undefined;
|
|
94
|
+
const data = {
|
|
98
95
|
target: "composio" as const,
|
|
99
96
|
ok: result.ok,
|
|
100
97
|
status: result.status,
|
|
@@ -103,14 +100,11 @@ export const registerSwarmXTool = (server: McpServer) => {
|
|
|
103
100
|
url: result.url,
|
|
104
101
|
response: result.body,
|
|
105
102
|
responseText: result.text,
|
|
106
|
-
message,
|
|
107
103
|
};
|
|
108
104
|
|
|
109
|
-
return
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
isError: !result.ok,
|
|
113
|
-
};
|
|
105
|
+
return result.ok
|
|
106
|
+
? toolOk(summary, { details, data })
|
|
107
|
+
: toolErr(result.error || summary, { details, data });
|
|
114
108
|
},
|
|
115
109
|
);
|
|
116
110
|
};
|
package/src/tools/task-action.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
2
|
import * as z from "zod";
|
|
4
3
|
import { AssetKeyAuthorizationError, authorizeAssetKeyWrite } from "@/be/asset-key-auth";
|
|
5
4
|
import { resolveTaskAuditUserId } from "@/be/audit-user";
|
|
@@ -29,15 +28,21 @@ import {
|
|
|
29
28
|
updateTaskClaudeSessionId,
|
|
30
29
|
} from "@/be/db";
|
|
31
30
|
import { assertOwnsTask, ownerCtx, type ToolCtx } from "@/tools/task-tool-ctx";
|
|
32
|
-
import { createToolRegistrar } from "@/tools/utils";
|
|
33
31
|
import {
|
|
34
|
-
|
|
32
|
+
createToolRegistrar,
|
|
33
|
+
type SwarmToolResult,
|
|
34
|
+
swarmToolOutputSchema,
|
|
35
|
+
toolErr,
|
|
36
|
+
toolOk,
|
|
37
|
+
} from "@/tools/utils";
|
|
38
|
+
import {
|
|
35
39
|
AssetKeySchema,
|
|
36
40
|
BudgetRefusalCauseSchema,
|
|
37
41
|
ModelTierSchema,
|
|
38
42
|
ReasoningEffortSchema,
|
|
39
43
|
splitLegacyModelAlias,
|
|
40
44
|
} from "@/types";
|
|
45
|
+
import { looseAgentTaskOutputSchema } from "./get-task-details";
|
|
41
46
|
|
|
42
47
|
export const TaskActionSchema = z.enum([
|
|
43
48
|
"create",
|
|
@@ -100,11 +105,9 @@ export const taskActionInputSchema = z.object({
|
|
|
100
105
|
),
|
|
101
106
|
});
|
|
102
107
|
|
|
103
|
-
export const taskActionOutputSchema =
|
|
108
|
+
export const taskActionOutputSchema = swarmToolOutputSchema({
|
|
104
109
|
yourAgentId: z.string().optional(),
|
|
105
|
-
|
|
106
|
-
message: z.string(),
|
|
107
|
-
task: AgentTaskSchema.optional(),
|
|
110
|
+
task: looseAgentTaskOutputSchema.optional(),
|
|
108
111
|
// Phase 3: budget-admission refusal fields. Populated only on
|
|
109
112
|
// `accept` action when the per-agent or global daily budget is blown.
|
|
110
113
|
refusalCause: BudgetRefusalCauseSchema.optional(),
|
|
@@ -133,43 +136,26 @@ type TaskActionResult = {
|
|
|
133
136
|
refusalSideEffects?: unknown;
|
|
134
137
|
};
|
|
135
138
|
|
|
136
|
-
function agentOnlyActionResult():
|
|
137
|
-
|
|
138
|
-
const structuredContent = {
|
|
139
|
-
success: false,
|
|
140
|
-
message,
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
isError: true,
|
|
145
|
-
content: [
|
|
146
|
-
{ type: "text", text: message },
|
|
147
|
-
{ type: "text", text: JSON.stringify(structuredContent) },
|
|
148
|
-
],
|
|
149
|
-
structuredContent,
|
|
150
|
-
};
|
|
139
|
+
function agentOnlyActionResult(): SwarmToolResult {
|
|
140
|
+
return toolErr("This action is only available to worker agents.");
|
|
151
141
|
}
|
|
152
142
|
|
|
153
|
-
function
|
|
154
|
-
const { refusalSideEffects: _omit, ...
|
|
155
|
-
const
|
|
143
|
+
function taskActionResult(result: TaskActionResult, agentId?: string): SwarmToolResult {
|
|
144
|
+
const { refusalSideEffects: _omit, success, message, ...rest } = result;
|
|
145
|
+
const data = {
|
|
156
146
|
yourAgentId: agentId,
|
|
157
|
-
...
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
content: [
|
|
162
|
-
{ type: "text", text: result.message },
|
|
163
|
-
{ type: "text", text: JSON.stringify(structuredContent) },
|
|
164
|
-
],
|
|
165
|
-
structuredContent,
|
|
147
|
+
...rest,
|
|
166
148
|
};
|
|
149
|
+
// Most harnesses only show the model the text channel — render the payload
|
|
150
|
+
// (task object, refusalCause, ...) there too, not just in structuredContent.
|
|
151
|
+
const details = Object.keys(rest).length > 0 ? JSON.stringify(rest, null, 2) : undefined;
|
|
152
|
+
return success ? toolOk(message, { data, details }) : toolErr(message, { data, details });
|
|
167
153
|
}
|
|
168
154
|
|
|
169
155
|
export async function taskActionHandler(
|
|
170
156
|
ctx: ToolCtx,
|
|
171
157
|
input: TaskActionArgs,
|
|
172
|
-
): Promise<
|
|
158
|
+
): Promise<SwarmToolResult> {
|
|
173
159
|
const {
|
|
174
160
|
action,
|
|
175
161
|
task,
|
|
@@ -191,7 +177,7 @@ export async function taskActionHandler(
|
|
|
191
177
|
return agentOnlyActionResult();
|
|
192
178
|
}
|
|
193
179
|
|
|
194
|
-
const result = getDb().transaction((): TaskActionResult |
|
|
180
|
+
const result = getDb().transaction((): TaskActionResult | SwarmToolResult => {
|
|
195
181
|
if (!taskId) {
|
|
196
182
|
return { success: false, message: `Task ID is required for '${action}' action.` };
|
|
197
183
|
}
|
|
@@ -239,17 +225,11 @@ export async function taskActionHandler(
|
|
|
239
225
|
};
|
|
240
226
|
})();
|
|
241
227
|
|
|
242
|
-
return "
|
|
228
|
+
return "ok" in result ? result : taskActionResult(result);
|
|
243
229
|
}
|
|
244
230
|
|
|
245
231
|
if (!ctx.agentId) {
|
|
246
|
-
return
|
|
247
|
-
content: [{ type: "text", text: 'Agent ID not found. Set the "X-Agent-ID" header.' }],
|
|
248
|
-
structuredContent: {
|
|
249
|
-
success: false,
|
|
250
|
-
message: 'Agent ID not found. Set the "X-Agent-ID" header.',
|
|
251
|
-
},
|
|
252
|
-
};
|
|
232
|
+
return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
|
|
253
233
|
}
|
|
254
234
|
|
|
255
235
|
const agentId = ctx.agentId;
|
|
@@ -266,7 +246,7 @@ export async function taskActionHandler(
|
|
|
266
246
|
: error instanceof Error
|
|
267
247
|
? error.message
|
|
268
248
|
: String(error);
|
|
269
|
-
return
|
|
249
|
+
return taskActionResult({ success: false, message }, agentId);
|
|
270
250
|
}
|
|
271
251
|
}
|
|
272
252
|
|
|
@@ -597,7 +577,7 @@ export async function taskActionHandler(
|
|
|
597
577
|
emitBudgetRefusalSideEffects(sideEffects.context, sideEffects.inserted);
|
|
598
578
|
}
|
|
599
579
|
|
|
600
|
-
return
|
|
580
|
+
return taskActionResult(result, agentId);
|
|
601
581
|
}
|
|
602
582
|
|
|
603
583
|
export const registerTaskActionTool = (server: McpServer) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
1
|
import { can, type PermissionVerb } from "@/rbac";
|
|
3
2
|
import type { AgentTask, User } from "@/types";
|
|
4
|
-
import type
|
|
3
|
+
import { type RequestInfo, type SwarmToolResult, toolErr } from "./utils";
|
|
5
4
|
|
|
6
5
|
export type ToolCtx =
|
|
7
6
|
| { kind: "owner"; agentId?: string; sourceTaskId?: string; sessionId?: string }
|
|
@@ -29,7 +28,7 @@ export function assertOwnsTask(
|
|
|
29
28
|
ctx: ToolCtx,
|
|
30
29
|
task: AgentTask,
|
|
31
30
|
verb: PermissionVerb = "task.read.own",
|
|
32
|
-
):
|
|
31
|
+
): SwarmToolResult | null {
|
|
33
32
|
// RBAC chokepoint — a future admin/role tier widens visibility here, in this one function.
|
|
34
33
|
const decision = can({
|
|
35
34
|
principal:
|
|
@@ -46,14 +45,7 @@ export function assertOwnsTask(
|
|
|
46
45
|
return null;
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
content: [{ type: "text", text: message }],
|
|
53
|
-
structuredContent: {
|
|
54
|
-
success: false,
|
|
55
|
-
code: "forbidden",
|
|
56
|
-
message,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
48
|
+
return toolErr(`Forbidden: this task is not yours (task ${task.id}).`, {
|
|
49
|
+
data: { code: "forbidden" },
|
|
50
|
+
});
|
|
59
51
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { createTrackerSync } from "@/be/db-queries/tracker";
|
|
4
|
-
import { createToolRegistrar } from "@/tools/utils";
|
|
4
|
+
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
5
5
|
|
|
6
6
|
export const registerTrackerLinkTaskTool = (server: McpServer) => {
|
|
7
7
|
createToolRegistrar(server)(
|
|
@@ -21,10 +21,8 @@ export const registerTrackerLinkTaskTool = (server: McpServer) => {
|
|
|
21
21
|
.describe("Human-readable identifier (e.g. 'ENG-42')"),
|
|
22
22
|
externalUrl: z.string().optional().describe("URL to the external issue"),
|
|
23
23
|
}),
|
|
24
|
-
outputSchema:
|
|
25
|
-
|
|
26
|
-
message: z.string(),
|
|
27
|
-
sync: z.any().optional(),
|
|
24
|
+
outputSchema: swarmToolOutputSchema({
|
|
25
|
+
sync: z.unknown().optional(),
|
|
28
26
|
}),
|
|
29
27
|
},
|
|
30
28
|
async (args, _requestInfo, _meta) => {
|
|
@@ -39,25 +37,13 @@ export const registerTrackerLinkTaskTool = (server: McpServer) => {
|
|
|
39
37
|
syncDirection: "bidirectional",
|
|
40
38
|
});
|
|
41
39
|
|
|
42
|
-
return
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
text: `Linked task ${args.swarmTaskId} to ${args.provider} issue ${args.externalIdentifier ?? args.externalId}`,
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
structuredContent: {
|
|
50
|
-
success: true,
|
|
51
|
-
message: `Linked task ${args.swarmTaskId} to ${args.provider} issue ${args.externalIdentifier ?? args.externalId}.`,
|
|
52
|
-
sync,
|
|
53
|
-
},
|
|
54
|
-
};
|
|
40
|
+
return toolOk(
|
|
41
|
+
`Linked task ${args.swarmTaskId} to ${args.provider} issue ${args.externalIdentifier ?? args.externalId}.`,
|
|
42
|
+
{ data: { sync } },
|
|
43
|
+
);
|
|
55
44
|
} catch (error) {
|
|
56
45
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
57
|
-
return {
|
|
58
|
-
content: [{ type: "text", text: `Failed to link task: ${message}` }],
|
|
59
|
-
structuredContent: { success: false, message: `Failed: ${message}` },
|
|
60
|
-
};
|
|
46
|
+
return toolErr(`Failed to link task: ${message}`);
|
|
61
47
|
}
|
|
62
48
|
},
|
|
63
49
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { createTrackerAgentMapping } from "@/be/db-queries/tracker";
|
|
4
|
-
import { createToolRegistrar } from "@/tools/utils";
|
|
4
|
+
import { createToolRegistrar, swarmToolOutputSchema, toolErr, toolOk } from "@/tools/utils";
|
|
5
5
|
|
|
6
6
|
export const registerTrackerMapAgentTool = (server: McpServer) => {
|
|
7
7
|
createToolRegistrar(server)(
|
|
@@ -17,10 +17,8 @@ export const registerTrackerMapAgentTool = (server: McpServer) => {
|
|
|
17
17
|
externalUserId: z.string().describe("The external user ID in the tracker"),
|
|
18
18
|
agentName: z.string().describe("Display name for the agent mapping"),
|
|
19
19
|
}),
|
|
20
|
-
outputSchema:
|
|
21
|
-
|
|
22
|
-
message: z.string(),
|
|
23
|
-
mapping: z.any().optional(),
|
|
20
|
+
outputSchema: swarmToolOutputSchema({
|
|
21
|
+
mapping: z.unknown().optional(),
|
|
24
22
|
}),
|
|
25
23
|
},
|
|
26
24
|
async (args, _requestInfo, _meta) => {
|
|
@@ -32,25 +30,13 @@ export const registerTrackerMapAgentTool = (server: McpServer) => {
|
|
|
32
30
|
agentName: args.agentName,
|
|
33
31
|
});
|
|
34
32
|
|
|
35
|
-
return
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
text: `Mapped agent ${args.agentName} to ${args.provider} user ${args.externalUserId}`,
|
|
40
|
-
},
|
|
41
|
-
],
|
|
42
|
-
structuredContent: {
|
|
43
|
-
success: true,
|
|
44
|
-
message: `Mapped agent ${args.agentName} to ${args.provider} user ${args.externalUserId}.`,
|
|
45
|
-
mapping,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
33
|
+
return toolOk(
|
|
34
|
+
`Mapped agent ${args.agentName} to ${args.provider} user ${args.externalUserId}.`,
|
|
35
|
+
{ data: { mapping } },
|
|
36
|
+
);
|
|
48
37
|
} catch (error) {
|
|
49
38
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
50
|
-
return {
|
|
51
|
-
content: [{ type: "text", text: `Failed to map agent: ${message}` }],
|
|
52
|
-
structuredContent: { success: false, message: `Failed: ${message}` },
|
|
53
|
-
};
|
|
39
|
+
return toolErr(`Failed to map agent: ${message}`);
|
|
54
40
|
}
|
|
55
41
|
},
|
|
56
42
|
);
|
|
@@ -2,7 +2,7 @@ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { getOAuthApp, getOAuthTokens } from "@/be/db-queries/oauth";
|
|
4
4
|
import { ensureToken } from "@/oauth/ensure-token";
|
|
5
|
-
import { createToolRegistrar } from "@/tools/utils";
|
|
5
|
+
import { createToolRegistrar, swarmToolOutputSchema, toolOk } from "@/tools/utils";
|
|
6
6
|
|
|
7
7
|
export const registerTrackerStatusTool = (server: McpServer) => {
|
|
8
8
|
createToolRegistrar(server)(
|
|
@@ -13,17 +13,18 @@ export const registerTrackerStatusTool = (server: McpServer) => {
|
|
|
13
13
|
"Show all connected trackers and their OAuth status (token expiry, workspace info). Proactively refreshes near-expiry tokens before reporting, so the returned `tokenExpiresAt` reflects the row that subsequent API calls (and direct DB reads) will see.",
|
|
14
14
|
annotations: { readOnlyHint: true },
|
|
15
15
|
|
|
16
|
-
outputSchema:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
outputSchema: swarmToolOutputSchema({
|
|
17
|
+
trackers: z
|
|
18
|
+
.array(
|
|
19
|
+
z.looseObject({
|
|
20
|
+
provider: z.string().optional(),
|
|
21
|
+
connected: z.boolean().optional(),
|
|
22
|
+
tokenExpiresAt: z.string().nullable().optional(),
|
|
23
|
+
scopes: z.string().nullable().optional(),
|
|
24
|
+
redirectUri: z.string().nullable().optional(),
|
|
25
|
+
}),
|
|
26
|
+
)
|
|
27
|
+
.optional(),
|
|
27
28
|
}),
|
|
28
29
|
},
|
|
29
30
|
async (_requestInfo, _meta) => {
|
|
@@ -50,13 +51,20 @@ export const registerTrackerStatusTool = (server: McpServer) => {
|
|
|
50
51
|
.map((t) => `${t.provider}: ${t.connected ? "connected" : "not connected"}`)
|
|
51
52
|
.join(", ");
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const details = trackers
|
|
55
|
+
.map((t) => {
|
|
56
|
+
const bits = [
|
|
57
|
+
`provider: ${t.provider}`,
|
|
58
|
+
`connected: ${t.connected}`,
|
|
59
|
+
`tokenExpiresAt: ${t.tokenExpiresAt ?? "n/a"}`,
|
|
60
|
+
`scopes: ${t.scopes ?? "n/a"}`,
|
|
61
|
+
`redirectUri: ${t.redirectUri ?? "n/a"}`,
|
|
62
|
+
];
|
|
63
|
+
return `- ${bits.join(", ")}`;
|
|
64
|
+
})
|
|
65
|
+
.join("\n");
|
|
66
|
+
|
|
67
|
+
return toolOk(`Tracker status: ${summary}`, { details, data: { trackers } });
|
|
60
68
|
},
|
|
61
69
|
);
|
|
62
70
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { getAllTrackerSyncs } from "@/be/db-queries/tracker";
|
|
4
|
-
import { createToolRegistrar } from "@/tools/utils";
|
|
4
|
+
import { createToolRegistrar, swarmToolOutputSchema, toolOk } from "@/tools/utils";
|
|
5
5
|
|
|
6
6
|
export const registerTrackerSyncStatusTool = (server: McpServer) => {
|
|
7
7
|
createToolRegistrar(server)(
|
|
@@ -15,28 +15,18 @@ export const registerTrackerSyncStatusTool = (server: McpServer) => {
|
|
|
15
15
|
provider: z.string().optional().describe("Filter by provider (e.g. 'linear', 'jira')"),
|
|
16
16
|
entityType: z.enum(["task"]).optional().describe("Filter by entity type"),
|
|
17
17
|
}),
|
|
18
|
-
outputSchema:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
syncs: z.array(z.any()),
|
|
18
|
+
outputSchema: swarmToolOutputSchema({
|
|
19
|
+
count: z.number().optional(),
|
|
20
|
+
syncs: z.array(z.unknown()).optional(),
|
|
22
21
|
}),
|
|
23
22
|
},
|
|
24
23
|
async (args, _requestInfo, _meta) => {
|
|
25
24
|
const syncs = getAllTrackerSyncs(args.provider, args.entityType);
|
|
26
25
|
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
text: `Found ${syncs.length} tracker sync mapping(s)${args.provider ? ` for ${args.provider}` : ""}${args.entityType ? ` (${args.entityType})` : ""}.`,
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
structuredContent: {
|
|
35
|
-
success: true,
|
|
36
|
-
count: syncs.length,
|
|
37
|
-
syncs,
|
|
38
|
-
},
|
|
39
|
-
};
|
|
26
|
+
return toolOk(
|
|
27
|
+
`Found ${syncs.length} tracker sync mapping(s)${args.provider ? ` for ${args.provider}` : ""}${args.entityType ? ` (${args.entityType})` : ""}.`,
|
|
28
|
+
{ data: { count: syncs.length, syncs } },
|
|
29
|
+
);
|
|
40
30
|
},
|
|
41
31
|
);
|
|
42
32
|
};
|