@desplega.ai/agent-swarm 1.147.0 → 1.148.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.
Files changed (73) hide show
  1. package/README.md +11 -0
  2. package/dist/{acp-adapter-9n319wqc.js → acp-adapter-grez7xhd.js} +1 -1
  3. package/dist/{actions-2vxqvpr9.js → actions-kweznh5a.js} +6 -6
  4. package/dist/{app-w066xfy0.js → app-5fvvjv9m.js} +3 -3
  5. package/dist/{assistant-kt31dj2h.js → assistant-40m4w50s.js} +8 -8
  6. package/dist/{boot-reembed-j3mm3rfz.js → boot-reembed-9rxmb26n.js} +4 -4
  7. package/dist/{boot-reembed-az5rassp.js → boot-reembed-cn357y5n.js} +3 -3
  8. package/dist/{boot-scrub-logs-b6h54817.js → boot-scrub-logs-5tpp0x3y.js} +2 -2
  9. package/dist/{claude-adapter-w1z04ann.js → claude-adapter-9pz5q2pb.js} +3 -3
  10. package/dist/{claude-sdk-session-f0cc1kec.js → claude-sdk-session-v8w0s7qm.js} +3 -3
  11. package/dist/{cli-rw51bq3j.js → cli-0amc6myn.js} +1 -1
  12. package/dist/{cli-3tgwnf43.js → cli-0er5m69z.js} +3 -3
  13. package/dist/{cli-f7dsy61y.js → cli-3n7cbfjn.js} +1 -1
  14. package/dist/{cli-smby5m17.js → cli-56y3hch2.js} +5 -5
  15. package/dist/{cli-1th1728g.js → cli-5khqvvnq.js} +1 -1
  16. package/dist/{cli-ftht3zzj.js → cli-6s2y152y.js} +1 -1
  17. package/dist/{cli-53s590z8.js → cli-7gn7c2af.js} +1 -1
  18. package/dist/{cli-tzvk9haz.js → cli-9216xm24.js} +9 -9
  19. package/dist/{cli-w9kb3bk1.js → cli-anedxf1w.js} +3 -1
  20. package/dist/{cli-89xfd7f9.js → cli-brxyat7h.js} +1 -1
  21. package/dist/{cli-12fz972k.js → cli-cdjezzc7.js} +3 -3
  22. package/dist/{cli-zhjmqxzh.js → cli-dcem3pr1.js} +1 -1
  23. package/dist/{cli-b5bq9crk.js → cli-dk3me3qs.js} +7 -7
  24. package/dist/{cli-yz3djrm0.js → cli-f8j56xv2.js} +7 -7
  25. package/dist/{cli-m8yrsg97.js → cli-hp2est46.js} +2 -2
  26. package/dist/{cli-mmemxxdc.js → cli-hz8xhefy.js} +2 -2
  27. package/dist/{cli-8v0g1yc8.js → cli-hzhhrt7b.js} +1 -1
  28. package/dist/{cli-hbv0kq6w.js → cli-kzvhgvk3.js} +2 -2
  29. package/dist/{cli-719k9j2c.js → cli-m1p5cysp.js} +2 -2
  30. package/dist/{cli-dttph1bw.js → cli-n2cwscdd.js} +2 -2
  31. package/dist/{cli-54wwve05.js → cli-n9grk3yd.js} +3 -3
  32. package/dist/{cli-atcve9y8.js → cli-p73drk6p.js} +78 -37
  33. package/dist/{cli-f146mn5s.js → cli-qy6h009w.js} +5 -5
  34. package/dist/{cli-de14znh8.js → cli-tebsjpk7.js} +2 -2
  35. package/dist/{cli-4nr988h6.js → cli-v3e51x7w.js} +1 -1
  36. package/dist/{cli-p1d5b073.js → cli-xqcpg1st.js} +1 -1
  37. package/dist/{cli-n8508nre.js → cli-ztn0ga15.js} +1 -1
  38. package/dist/cli.js +13 -11
  39. package/dist/{codex-adapter-zw4dwsx7.js → codex-adapter-ehhj2qwc.js} +2 -2
  40. package/dist/{codex-session-runner-k981s65v.js → codex-session-runner-5hne566k.js} +2 -2
  41. package/dist/{commands-sykrxx7e.js → commands-xnvh951h.js} +2 -2
  42. package/dist/{db-sfbsc8wt.js → db-ycr5zfr4.js} +2 -2
  43. package/dist/{handlers-0aspcejm.js → handlers-1vt77kgq.js} +8 -8
  44. package/dist/{hook-hxccs7m5.js → hook-91ntpmff.js} +1 -1
  45. package/dist/{hook-4nvqj2sb.js → hook-qfwjydvn.js} +2 -2
  46. package/dist/{http-y06z517d.js → http-h6g7bv5b.js} +34 -34
  47. package/dist/{index-hssww7kj.js → index-0ez2aack.js} +11 -11
  48. package/dist/{index-tce1rss4.js → index-47ghesbn.js} +8 -8
  49. package/dist/{index-x5j894zf.js → index-antf9t4p.js} +10 -10
  50. package/dist/{index-k8znfx0z.js → index-d2mytx95.js} +9 -9
  51. package/dist/{keepalive-w733ax66.js → keepalive-c4sp7yvd.js} +4 -4
  52. package/dist/{lead-75bjqa9d.js → lead-4r7z9e8v.js} +22 -22
  53. package/dist/{maintenance-w4f1zjck.js → maintenance-yqjfdjas.js} +4 -4
  54. package/dist/{oauth-refresh-sweep-wdetky26.js → oauth-refresh-sweep-wtqgnh3c.js} +3 -3
  55. package/dist/{onboard-bb5net8s.js → onboard-a4krmh46.js} +2 -2
  56. package/dist/{otel-impl-0w7c14ap.js → otel-impl-725kq0vp.js} +1 -1
  57. package/dist/{pricing-refresh-9nzsrgcq.js → pricing-refresh-kqxd7w9h.js} +4 -4
  58. package/dist/{rbac-roles-z1jrffbt.js → rbac-roles-gws5xej6.js} +2 -2
  59. package/dist/{rbac-roles-r3hqjp09.js → rbac-roles-t3wygpth.js} +3 -3
  60. package/dist/{render-v2-vbr89fnb.js → render-v2-x1wxvn51.js} +3 -3
  61. package/dist/{seed-pricing-g62hy1pk.js → seed-pricing-t6y8d0vf.js} +3 -3
  62. package/dist/{setup-gnfqnptp.js → setup-x50py6xg.js} +2 -2
  63. package/dist/{worker-kznxp4qm.js → worker-zsz0qfxk.js} +22 -22
  64. package/openapi.json +1 -1
  65. package/package.json +3 -1
  66. package/src/tests/mcp-input-ergonomics.test.ts +386 -0
  67. package/src/tools/accept-steer.ts +0 -1
  68. package/src/tools/memory-get.ts +10 -3
  69. package/src/tools/memory-rate.ts +19 -7
  70. package/src/tools/memory-search.ts +2 -1
  71. package/src/tools/memory-store.ts +25 -5
  72. package/src/tools/send-task.ts +9 -2
  73. package/src/tools/store-progress.ts +35 -4
@@ -16,7 +16,6 @@ export const acceptSteerInputSchema = z.object({
16
16
  steeringMessageId: z.uuid().describe("The steering message ID to acknowledge."),
17
17
  note: z
18
18
  .string()
19
- .max(500)
20
19
  .optional()
21
20
  .describe("Optional short note describing how the steering was incorporated."),
22
21
  });
@@ -80,12 +80,14 @@ export const registerMemoryGetTool = (server: McpServer) => {
80
80
  annotations: { readOnlyHint: true },
81
81
 
82
82
  inputSchema: z.object({
83
- memoryId: z.uuid().describe("The ID of the memory to retrieve."),
83
+ memoryId: z.uuid().optional().describe("The ID of the memory to retrieve (or use id)."),
84
+ id: z.uuid().optional().describe("Alias for memoryId, matching memory-search results."),
84
85
  intent: z
85
86
  .string()
86
87
  .min(1)
88
+ .optional()
87
89
  .describe(
88
- "Why you are retrieving this memory. Required. E.g. 'need full details of the auth fix pattern'.",
90
+ "Optional reason for retrieving this memory. E.g. 'need full details of the auth fix pattern'.",
89
91
  ),
90
92
  }),
91
93
  outputSchema: swarmToolOutputSchema({
@@ -102,7 +104,12 @@ export const registerMemoryGetTool = (server: McpServer) => {
102
104
  rateHint: z.string().optional(),
103
105
  }),
104
106
  },
105
- async ({ memoryId, intent }, requestInfo, _meta) => {
107
+ async ({ memoryId: requestedMemoryId, id, intent }, requestInfo, _meta) => {
108
+ if (requestedMemoryId && id && requestedMemoryId !== id) {
109
+ return toolErr("memoryId and id must identify the same memory; supply only one.");
110
+ }
111
+ const memoryId = requestedMemoryId ?? id;
112
+ if (!memoryId) return toolErr("Supply memoryId (or its alias id) from memory-search.");
106
113
  const store = getMemoryStore();
107
114
  const memoryForAuth = await store.peek(memoryId);
108
115
 
@@ -42,15 +42,21 @@ export const registerMemoryRateTool = (server: McpServer) => {
42
42
  "the swarm learns to surface better memories next time.",
43
43
  annotations: { destructiveHint: false },
44
44
  inputSchema: z.object({
45
- id: z.string().describe("Memory ID returned by memory_search."),
45
+ id: z
46
+ .string()
47
+ .min(1)
48
+ .optional()
49
+ .describe("Memory ID returned by memory-search (or use memoryId)."),
50
+ memoryId: z.string().min(1).optional().describe("Alias for id, matching memory-get."),
46
51
  useful: z
47
52
  .boolean()
48
53
  .describe("true = this memory helped solve the task; false = misled or wasted time."),
49
54
  note: z
50
55
  .string()
51
- .max(280)
52
56
  .optional()
53
- .describe("Short reason. Captured for telemetry; not surfaced to other agents."),
57
+ .describe(
58
+ "Reason, stored up to 500 characters for telemetry; not surfaced to other agents.",
59
+ ),
54
60
  referencesSource: z
55
61
  .string()
56
62
  .min(1)
@@ -60,7 +66,13 @@ export const registerMemoryRateTool = (server: McpServer) => {
60
66
  }),
61
67
  outputSchema: swarmToolOutputSchema(),
62
68
  },
63
- async ({ id, useful, note, referencesSource }, requestInfo, _meta) => {
69
+ async ({ id, memoryId, useful, note, referencesSource }, requestInfo, _meta) => {
70
+ if (id && memoryId && id !== memoryId) {
71
+ return toolErr("id and memoryId must identify the same memory; supply only one.");
72
+ }
73
+ const resolvedMemoryId = id ?? memoryId;
74
+ if (!resolvedMemoryId)
75
+ return toolErr("Supply id (or its alias memoryId) from memory-search.");
64
76
  if (!requestInfo.agentId) {
65
77
  return toolErr("Agent ID required. Are you registered in the swarm?");
66
78
  }
@@ -85,11 +97,11 @@ export const registerMemoryRateTool = (server: McpServer) => {
85
97
  const apiKey = getApiKey();
86
98
 
87
99
  const event = {
88
- memoryId: id,
100
+ memoryId: resolvedMemoryId,
89
101
  signal: useful ? 1 : -1,
90
102
  weight: 1.0,
91
103
  source: "explicit-self" as const,
92
- reasoning: note ?? "",
104
+ reasoning: (note ?? "").slice(0, 500),
93
105
  taskId: requestInfo.sourceTaskId,
94
106
  ...(cleanedReferencesSource !== undefined
95
107
  ? { referencesSource: cleanedReferencesSource }
@@ -129,7 +141,7 @@ export const registerMemoryRateTool = (server: McpServer) => {
129
141
  return toolErr(`Memory rating failed (HTTP ${response.status}).`);
130
142
  }
131
143
 
132
- return toolOk(`Memory ${id} rated as ${useful ? "useful" : "not useful"}.`);
144
+ return toolOk(`Memory ${resolvedMemoryId} rated as ${useful ? "useful" : "not useful"}.`);
133
145
  } catch (err) {
134
146
  return toolErr(`Memory rating failed: ${(err as Error).message}`);
135
147
  }
@@ -84,8 +84,9 @@ export const registerMemorySearchTool = (server: McpServer) => {
84
84
  intent: z
85
85
  .string()
86
86
  .min(1)
87
+ .optional()
87
88
  .describe(
88
- "Why you are searching for this memory. Required. E.g. 'looking for auth pattern to fix login bug'.",
89
+ "Optional reason for searching for this memory. E.g. 'looking for auth pattern to fix login bug'.",
89
90
  ),
90
91
  scope: z
91
92
  .enum(["all", "agent", "swarm"])
@@ -24,14 +24,19 @@ export const registerMemoryStoreTool = (server: McpServer) => {
24
24
  .string()
25
25
  .min(1)
26
26
  .max(200)
27
- .describe("Short title, one line, used in search results and the UI."),
27
+ .optional()
28
+ .describe(
29
+ "Short title used in search results and the UI. Defaults to the first non-empty content line (up to 200 characters).",
30
+ ),
28
31
  scope: AgentMemoryScopeSchema.default("agent").describe(
29
32
  "'agent' (default): only you can recall it. 'swarm': every agent can recall it.",
30
33
  ),
31
34
  tags: z
32
- .array(z.string())
35
+ .union([z.array(z.string()), z.string()])
33
36
  .optional()
34
- .describe("Free-form tags, for example a repo name or a topic."),
37
+ .describe(
38
+ "Free-form tags as an array or a comma-separated string, for example a repo name or a topic.",
39
+ ),
35
40
  taskId: z
36
41
  .uuid()
37
42
  .optional()
@@ -49,7 +54,22 @@ export const registerMemoryStoreTool = (server: McpServer) => {
49
54
  queued: z.boolean().optional(),
50
55
  }),
51
56
  },
52
- async ({ content, name, scope, tags, taskId, intent }, requestInfo, _meta) => {
57
+ async ({ content, name: requestedName, scope, tags, taskId, intent }, requestInfo, _meta) => {
58
+ const name =
59
+ requestedName ??
60
+ content
61
+ .split(/\r?\n/)
62
+ .find((line) => line.trim())
63
+ ?.trim()
64
+ .slice(0, 200) ??
65
+ "Untitled memory";
66
+ const normalizedTags =
67
+ typeof tags === "string"
68
+ ? tags
69
+ .split(",")
70
+ .map((tag) => tag.trim())
71
+ .filter(Boolean)
72
+ : tags;
53
73
  if (!requestInfo.agentId) {
54
74
  return toolErr("Agent ID required. Are you registered in the swarm?");
55
75
  }
@@ -64,7 +84,7 @@ export const registerMemoryStoreTool = (server: McpServer) => {
64
84
  scope,
65
85
  source: "manual",
66
86
  sourceTaskId: taskId ?? null,
67
- tags,
87
+ tags: normalizedTags,
68
88
  intent,
69
89
  });
70
90
 
@@ -11,6 +11,7 @@ import {
11
11
  getAgentById,
12
12
  getDbClient,
13
13
  getTaskById,
14
+ getUserById,
14
15
  hasCapacity,
15
16
  } from "@/be/db";
16
17
  import { repointTrackerSyncBySwarmId } from "@/be/db-queries/tracker";
@@ -148,10 +149,10 @@ export const sendTaskInputSchema = z
148
149
  ),
149
150
  requestedByUserId: z
150
151
  .string()
151
- .uuid()
152
+ .regex(/^[a-f0-9]{32}$/, "Expected a registry user ID (32 lowercase hexadecimal characters).")
152
153
  .optional()
153
154
  .describe(
154
- "ID of the human user who originally requested this task chain. When omitted, inherited from the caller's current task so the attribution flows through multi-hop delegation automatically.",
155
+ "Registered requester ID (32 lowercase hexadecimal characters). When omitted, inherited from the caller's current task so the attribution flows through multi-hop delegation automatically.",
155
156
  ),
156
157
  followUpConfig: FollowUpConfigSchema.optional().describe(
157
158
  "Control the lead follow-up created when this task finishes. When to use `followUpConfig`: set `disabled: true` when you'll wait for this task to complete inline and no follow-up is needed; set `onCompleted` / `onFailed` with specific instructions when you need to follow up effectively on a particular outcome of a long-running flow; for normal one-shot tasks, leave it unset because defaults are fine. It is most valuable for long-running / complex flows.",
@@ -257,6 +258,12 @@ export async function sendTaskHandler(
257
258
  const requestedByUserId =
258
259
  ctx.kind === "user" ? ctx.userId : (inputRequestedByUserId ?? undefined);
259
260
 
261
+ if (ctx.kind === "owner" && requestedByUserId && !(await getUserById(requestedByUserId))) {
262
+ return toolErr("requestedByUserId must identify an existing registered user.", {
263
+ data: { yourAgentId: creatorAgentId },
264
+ });
265
+ }
266
+
260
267
  if (ctx.kind === "owner" && agentId === ctx.agentId) {
261
268
  return toolErr("Cannot send a task to yourself, are you drunk?", {
262
269
  data: { yourAgentId: ctx.agentId },
@@ -68,12 +68,19 @@ export const registerStoreProgressTool = (server: McpServer) => {
68
68
  annotations: { idempotentHint: true },
69
69
 
70
70
  inputSchema: z.object({
71
- taskId: z.uuid().describe("The ID of the task to update progress for."),
71
+ taskId: z
72
+ .uuid()
73
+ .optional()
74
+ .describe(
75
+ "Full task UUID. Defaults to the caller-owned task in X-Source-Task-Id; required outside task context.",
76
+ ),
72
77
  progress: z.string().optional().describe("The progress update to store."),
73
78
  status: z
74
- .enum(["completed", "failed"])
79
+ .enum(["completed", "failed", "in_progress", "pending"])
75
80
  .optional()
76
- .describe("Set to 'completed' or 'failed' to finish the task."),
81
+ .describe(
82
+ "Set to 'completed' or 'failed' to finish the task. 'in_progress' and 'pending' store progress only and do not change task status.",
83
+ ),
77
84
  output: z
78
85
  .string()
79
86
  .optional()
@@ -111,7 +118,16 @@ export const registerStoreProgressTool = (server: McpServer) => {
111
118
  outputSchema: storeProgressOutputSchema,
112
119
  },
113
120
  async (
114
- { taskId, progress, status, output, failureReason, attachments, persistMemory, force },
121
+ {
122
+ taskId: requestedTaskId,
123
+ progress,
124
+ status: requestedStatus,
125
+ output,
126
+ failureReason,
127
+ attachments,
128
+ persistMemory,
129
+ force,
130
+ },
115
131
  requestInfo,
116
132
  _meta,
117
133
  ) => {
@@ -119,6 +135,21 @@ export const registerStoreProgressTool = (server: McpServer) => {
119
135
  return toolErr('Agent ID not found. The MCP client should define the "X-Agent-ID" header.');
120
136
  }
121
137
 
138
+ const taskId = requestedTaskId ?? requestInfo.sourceTaskId;
139
+ if (!taskId || !z.uuid().safeParse(taskId).success) {
140
+ return toolErr("Supply taskId as the full task UUID; no valid task context is available.");
141
+ }
142
+ if (!requestedTaskId) {
143
+ const contextTask = await getTaskById(taskId);
144
+ if (!contextTask || contextTask.agentId !== requestInfo.agentId) {
145
+ return toolErr("Omitted taskId requires a source task assigned to the calling agent.");
146
+ }
147
+ }
148
+ const status =
149
+ requestedStatus === "completed" || requestedStatus === "failed"
150
+ ? requestedStatus
151
+ : undefined;
152
+
122
153
  // Verify agent-fs pointers before opening the write transaction. The
123
154
  // registering agent's resolved config selects both credentials and the
124
155
  // exact org/drive; never let the provider fall back to a personal drive.