pilotswarm-sdk 0.5.37 → 0.5.39

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 (52) hide show
  1. package/api/src/http-api-transport.js +26 -7
  2. package/api/src/protocol.js +16 -7
  3. package/dist/agent-manager-tools.d.ts.map +1 -1
  4. package/dist/agent-manager-tools.js +12 -2
  5. package/dist/agent-manager-tools.js.map +1 -1
  6. package/dist/agent-package-installer.d.ts +2 -0
  7. package/dist/agent-package-installer.d.ts.map +1 -1
  8. package/dist/agent-package-installer.js +1 -0
  9. package/dist/agent-package-installer.js.map +1 -1
  10. package/dist/agent-package-service.d.ts +1 -1
  11. package/dist/agent-package-service.d.ts.map +1 -1
  12. package/dist/agent-package-service.js +79 -11
  13. package/dist/agent-package-service.js.map +1 -1
  14. package/dist/cms-migrations.d.ts.map +1 -1
  15. package/dist/cms-migrations.js +117 -0
  16. package/dist/cms-migrations.js.map +1 -1
  17. package/dist/cms.d.ts +50 -0
  18. package/dist/cms.d.ts.map +1 -1
  19. package/dist/cms.js +65 -0
  20. package/dist/cms.js.map +1 -1
  21. package/dist/index.d.ts +2 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +4 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/managed-session.d.ts +4 -7
  26. package/dist/managed-session.d.ts.map +1 -1
  27. package/dist/managed-session.js +99 -18
  28. package/dist/managed-session.js.map +1 -1
  29. package/dist/management-client.d.ts.map +1 -1
  30. package/dist/management-client.js +8 -1
  31. package/dist/management-client.js.map +1 -1
  32. package/dist/model-providers.d.ts +142 -6
  33. package/dist/model-providers.d.ts.map +1 -1
  34. package/dist/model-providers.js +117 -1
  35. package/dist/model-providers.js.map +1 -1
  36. package/dist/session-manager.d.ts +97 -7
  37. package/dist/session-manager.d.ts.map +1 -1
  38. package/dist/session-manager.js +292 -31
  39. package/dist/session-manager.js.map +1 -1
  40. package/dist/session-proxy.d.ts +43 -0
  41. package/dist/session-proxy.d.ts.map +1 -1
  42. package/dist/session-proxy.js +296 -184
  43. package/dist/session-proxy.js.map +1 -1
  44. package/dist/web/generated-op-methods.d.ts +34 -5
  45. package/dist/web/generated-op-methods.d.ts.map +1 -1
  46. package/dist/web/generated-op-methods.js +2 -0
  47. package/dist/web/generated-op-methods.js.map +1 -1
  48. package/dist/worker.d.ts +23 -0
  49. package/dist/worker.d.ts.map +1 -1
  50. package/dist/worker.js +189 -17
  51. package/dist/worker.js.map +1 -1
  52. package/package.json +3 -3
@@ -59,13 +59,10 @@ const SHOW_ARTIFACT_TOOL_SPEC = {
59
59
  * The canvas tools — declaration AND per-turn handler both build from these
60
60
  * specs, the same drift-proofing SHOW_ARTIFACT_TOOL_SPEC uses.
61
61
  *
62
- * Root sessions only. The gate is the control bridge itself: session-proxy
63
- * puts drawCanvas/readCanvas on the bridge only when the session has no
64
- * parent, and the per-turn tool list includes these tools only when the
65
- * bridge carries them. The static declarations below exist so the schemas
66
- * reach the CLI server at session create; a child's every turn re-registers
67
- * its tool list without them (registerTools is authoritative per turn), and
68
- * a child that hallucinates the call anyway hits the handler's bridge guard.
62
+ * Every session has them, root and sub-agent alike, and every session draws
63
+ * only its OWN canvases — up to five slots (canvas.html, canvas2..canvas5),
64
+ * each with a rev and an agent-chosen name. The parent's canvases and a
65
+ * child's are fully independent surfaces.
69
66
  */
70
67
  /**
71
68
  * The canvas response contract, normalized to its canonical shape or refused.
@@ -83,8 +80,9 @@ const SHOW_ARTIFACT_TOOL_SPEC = {
83
80
  // existing importers (tests included) keep their path.
84
81
  export { normalizeCanvasResponseContract } from "./canvas-app-manifest.js";
85
82
  const DRAW_CANVAS_TOOL_SPEC = {
86
- description: "Replace this session's canvas — the persistent visual surface rendered live in the user's portal — "
87
- + "with a complete HTML document. Root sessions only. "
83
+ description: "Replace one of this session's canvases — persistent visual surfaces rendered live in the user's portal — "
84
+ + "with a complete HTML document. Up to five canvases per session (slot 1-5, default 1), each with its own "
85
+ + "revision history and a friendly name you set. "
88
86
  + "Draw when the user asks for something visual (draw, visualize, chart this, keep a dashboard), or when an "
89
87
  + "outcome you are delivering would be GREATLY clarified by a quick graphic. Most replies need no drawing. "
90
88
  + "Drawing switches the user's view to the canvas, so draw only when that interruption is earned — and never "
@@ -107,6 +105,14 @@ const DRAW_CANVAS_TOOL_SPEC = {
107
105
  type: "string",
108
106
  description: "Optional one-line caption for this revision (shown in the canvas header and activity feed).",
109
107
  },
108
+ slot: {
109
+ type: "number",
110
+ description: "Which canvas to draw, 1-5. Default 1. Slots are independent surfaces with their own revisions.",
111
+ },
112
+ name: {
113
+ type: "string",
114
+ description: "Friendly name for this canvas, shown beside its revision (e.g. 'Poker table', 'Metrics'). Max 60 chars; omitting it keeps the current name.",
115
+ },
110
116
  fromArtifact: {
111
117
  type: "object",
112
118
  description: "Render a stored HTML artifact onto the canvas SERVER-SIDE — the bytes never enter your "
@@ -142,7 +148,7 @@ const DRAW_CANVAS_TOOL_SPEC = {
142
148
  handler: async () => "stub",
143
149
  };
144
150
  const UPDATE_CANVAS_TOOL_SPEC = {
145
- description: "Send a JSON data tick to the canvas page WITHOUT replacing the document. Root sessions only. "
151
+ description: "Send a JSON data tick to a canvas page WITHOUT replacing the document (slot 1-5, default 1). "
146
152
  + "Use when the canvas's CONTENT changes but its layout does not — dashboards, tickers, watchers: "
147
153
  + "draw the shell once with draw_canvas (declare data.example in the contract and register a message "
148
154
  + "listener calling one idempotent applyData(data)), then tick with update_canvas. The payload arrives "
@@ -162,13 +168,33 @@ const UPDATE_CANVAS_TOOL_SPEC = {
162
168
  type: "string",
163
169
  description: "Optional one-line caption for the activity feed.",
164
170
  },
171
+ slot: {
172
+ type: "number",
173
+ description: "Which canvas to tick, 1-5. Default 1.",
174
+ },
165
175
  },
166
176
  required: ["data"],
167
177
  },
168
178
  handler: async () => "stub",
169
179
  };
180
+ const SHOW_CANVAS_TOOL_SPEC = {
181
+ description: "Bring one of this session's ALREADY-DRAWN canvases to the user's screen without redrawing it "
182
+ + "(slot 1-5, default 1). No bytes, no new revision, and nothing is marked unseen — it only turns the "
183
+ + "user's view to a canvas that already exists: opening the canvas if it is closed, or switching slots "
184
+ + "if a different one is showing. Use it when the conversation returns to something you drew earlier. "
185
+ + "It respects the user's choices the same way draws do: if they dismissed that canvas this session, "
186
+ + "the view stays put. To change content, use draw_canvas or update_canvas instead.",
187
+ parameters: {
188
+ type: "object",
189
+ properties: {
190
+ slot: { type: "number", description: "Which canvas to present, 1-5. Default 1." },
191
+ },
192
+ required: [],
193
+ },
194
+ handler: async () => "stub",
195
+ };
170
196
  const READ_CANVAS_TOOL_SPEC = {
171
- description: "Read this session's current canvas HTML back, paged. Root sessions only. "
197
+ description: "Read one of this session's canvases back as HTML, paged (slot 1-5, default 1). "
172
198
  + "Use it before iterating on an existing drawing, and after context regeneration — the canvas survives even "
173
199
  + "when your memory of drawing it does not. "
174
200
  + "Read selectively: page with offset/maxBytes rather than round-tripping a large document every turn.",
@@ -176,6 +202,7 @@ const READ_CANVAS_TOOL_SPEC = {
176
202
  type: "object",
177
203
  properties: {
178
204
  offset: { type: "number", description: "Character offset to start reading from (default 0)." },
205
+ slot: { type: "number", description: "Which canvas to read, 1-5. Default 1." },
179
206
  maxBytes: { type: "number", description: "Maximum characters to return (default 65536, cap 262144)." },
180
207
  manifestOnly: {
181
208
  type: "boolean",
@@ -274,6 +301,35 @@ function sanitizeMessageContent(message) {
274
301
  message.content = parts;
275
302
  return normalized;
276
303
  }
304
+ /**
305
+ * Response-only message fields that carry no information when null.
306
+ *
307
+ * OpenAI and Azure emit these and accept them coming back. Strict
308
+ * OpenAI-compatible endpoints do not — they validate the request schema and
309
+ * reject unknown keys outright instead of ignoring them. Fireworks answers
310
+ * `400 Extra inputs are not permitted, field: 'messages[N].refusal', value:
311
+ * None`, and only once the conversation is long enough for a message carrying
312
+ * one to re-enter the replayed history. So the provider looks healthy for
313
+ * several turns and then fails, which makes it easy to misread as flakiness.
314
+ *
315
+ * The same class of bug is well documented against other clients for
316
+ * `stream_options`, `promptCacheKey`, `service_tier`, and replayed
317
+ * `tool_calls[].call_id`. Stripping is safe precisely because it is limited to
318
+ * null values: a null `refusal` says nothing that omitting it does not.
319
+ */
320
+ const NULL_ONLY_RESPONSE_FIELDS = ["refusal", "annotations", "audio", "function_call"];
321
+ function stripNullResponseOnlyFields(message) {
322
+ if (!message || typeof message !== "object")
323
+ return 0;
324
+ let stripped = 0;
325
+ for (const field of NULL_ONLY_RESPONSE_FIELDS) {
326
+ if (Object.prototype.hasOwnProperty.call(message, field) && message[field] == null) {
327
+ delete message[field];
328
+ stripped += 1;
329
+ }
330
+ }
331
+ return stripped;
332
+ }
277
333
  function sanitizeCopilotMessagesForReplay(messages) {
278
334
  if (!Array.isArray(messages))
279
335
  return 0;
@@ -292,6 +348,7 @@ function sanitizeCopilotMessagesForReplay(messages) {
292
348
  // that shape, so coerce them to the semantically-equivalent empty
293
349
  // string before sending the next turn.
294
350
  normalized += sanitizeMessageContent(message);
351
+ normalized += stripNullResponseOnlyFields(message);
295
352
  }
296
353
  return normalized;
297
354
  }
@@ -716,7 +773,8 @@ export class ManagedSession {
716
773
  const drawCanvasTool = defineTool("draw_canvas", DRAW_CANVAS_TOOL_SPEC);
717
774
  const updateCanvasTool = defineTool("update_canvas", UPDATE_CANVAS_TOOL_SPEC);
718
775
  const readCanvasTool = defineTool("read_canvas", READ_CANVAS_TOOL_SPEC);
719
- return [waitTool, waitOnWorkerTool, cronTool, cronAtTool, askUserTool, reportCycleTool, listModelsTool, setSessionModelTool, regenerateContextTool, regenerateAgentTool, sendSessionMessageTool, replySessionMessageTool, showArtifactTool, drawCanvasTool, updateCanvasTool, readCanvasTool];
776
+ const showCanvasTool = defineTool("show_canvas", SHOW_CANVAS_TOOL_SPEC);
777
+ return [waitTool, waitOnWorkerTool, cronTool, cronAtTool, askUserTool, reportCycleTool, listModelsTool, setSessionModelTool, regenerateContextTool, regenerateAgentTool, sendSessionMessageTool, replySessionMessageTool, showArtifactTool, drawCanvasTool, updateCanvasTool, readCanvasTool, showCanvasTool];
720
778
  }
721
779
  /**
722
780
  * Sub-agent tool definitions.
@@ -1364,7 +1422,7 @@ export class ManagedSession {
1364
1422
  if (hasTerminalTurnBoundary(turnState))
1365
1423
  return blockedAfterTurnBoundary("draw_canvas");
1366
1424
  if (typeof controlBridge?.drawCanvas !== "function") {
1367
- return "Error: draw_canvas is only available on root sessions.";
1425
+ return "Error: the canvas bridge is unavailable on this session.";
1368
1426
  }
1369
1427
  if (args?.html !== undefined && typeof args.html !== "string") {
1370
1428
  return "Error: html must be a string (the complete document; empty string clears).";
@@ -1396,6 +1454,8 @@ export class ManagedSession {
1396
1454
  if (contractResult.error)
1397
1455
  return `Error: invalid responseContract: ${contractResult.error}`;
1398
1456
  const result = await controlBridge.drawCanvas({
1457
+ ...(args?.slot !== undefined ? { slot: args.slot } : {}),
1458
+ ...(args?.name !== undefined ? { name: String(args.name) } : {}),
1399
1459
  ...(html !== undefined ? { html } : {}),
1400
1460
  ...(fromArtifact ? { fromArtifact: {
1401
1461
  ...(fromArtifact.sessionId ? { sessionId: String(fromArtifact.sessionId) } : {}),
@@ -1418,6 +1478,8 @@ export class ManagedSession {
1418
1478
  return JSON.stringify({
1419
1479
  drawn: true,
1420
1480
  rev: result.rev,
1481
+ ...(result.slot ? { slot: result.slot } : {}),
1482
+ ...(result.name !== undefined ? { name: result.name } : {}),
1421
1483
  sizeBytes: result.sizeBytes,
1422
1484
  // The interface card: manifest summary + the EFFECTIVE
1423
1485
  // contract (post-precedence, post-normalization — what the
@@ -1446,7 +1508,7 @@ export class ManagedSession {
1446
1508
  return "Error: data must be a JSON object (the page's whole-state payload), not an array — wrap it: { items: [...] }.";
1447
1509
  }
1448
1510
  if (typeof controlBridge?.updateCanvas !== "function") {
1449
- return "Error: update_canvas is only available on root sessions.";
1511
+ return "Error: the canvas bridge is unavailable on this session.";
1450
1512
  }
1451
1513
  if (!args?.data || typeof args.data !== "object") {
1452
1514
  return "Error: data must be a JSON object (the whole-state payload for the page's applyData).";
@@ -1457,7 +1519,7 @@ export class ManagedSession {
1457
1519
  return `Error: data tick is ${sizeBytes} bytes serialized; the cap is 32768. Aggregate before sending, or redraw if the shape truly grew.`;
1458
1520
  }
1459
1521
  const note = args?.note ? String(args.note) : undefined;
1460
- const result = await controlBridge.updateCanvas({ data: args.data, note });
1522
+ const result = await controlBridge.updateCanvas({ data: args.data, note, ...(args?.slot !== undefined ? { slot: args.slot } : {}) });
1461
1523
  if (result?.error)
1462
1524
  return `Error: could not update the canvas: ${result.error}`;
1463
1525
  return JSON.stringify({
@@ -1468,18 +1530,36 @@ export class ManagedSession {
1468
1530
  });
1469
1531
  },
1470
1532
  });
1533
+ const showCanvasTool = defineTool("show_canvas", {
1534
+ ...SHOW_CANVAS_TOOL_SPEC,
1535
+ handler: async (args) => {
1536
+ if (hasTerminalTurnBoundary(turnState))
1537
+ return blockedAfterTurnBoundary("show_canvas");
1538
+ if (typeof controlBridge?.showCanvas !== "function") {
1539
+ return "Error: the canvas bridge is unavailable on this session.";
1540
+ }
1541
+ const result = await controlBridge.showCanvas({
1542
+ ...(args?.slot !== undefined ? { slot: args.slot } : {}),
1543
+ });
1544
+ if (result?.error)
1545
+ return `Error: could not present the canvas: ${result.error}`;
1546
+ return JSON.stringify({ presented: true, slot: result.slot, rev: result.rev,
1547
+ reminder: "The user's view turns to that canvas (unless they dismissed it). Nothing was redrawn." });
1548
+ },
1549
+ });
1471
1550
  const readCanvasTool = defineTool("read_canvas", {
1472
1551
  ...READ_CANVAS_TOOL_SPEC,
1473
1552
  handler: async (args) => {
1474
1553
  if (hasTerminalTurnBoundary(turnState))
1475
1554
  return blockedAfterTurnBoundary("read_canvas");
1476
1555
  if (typeof controlBridge?.readCanvas !== "function") {
1477
- return "Error: read_canvas is only available on root sessions.";
1556
+ return "Error: the canvas bridge is unavailable on this session.";
1478
1557
  }
1479
1558
  const result = await controlBridge.readCanvas({
1480
1559
  offset: args?.offset,
1481
1560
  maxBytes: args?.maxBytes,
1482
1561
  manifestOnly: Boolean(args?.manifestOnly),
1562
+ ...(args?.slot !== undefined ? { slot: args.slot } : {}),
1483
1563
  });
1484
1564
  if (result?.error)
1485
1565
  return `Error: could not read the canvas: ${result.error}`;
@@ -1960,7 +2040,7 @@ export class ManagedSession {
1960
2040
  },
1961
2041
  });
1962
2042
  const SYSTEM_TOOL_NAMES = new Set([
1963
- "update_canvas", "wait", "wait_on_worker", "cron", "cron_at", "ask_user", "report_cycle", "list_available_models", "set_session_model", "send_session_message", "reply_session_message", "show_artifact", "draw_canvas", "read_canvas", "spawn_agent", "message_agent", "check_agents", "wait_for_agents", "list_sessions", "complete_agent", "cancel_agent", "delete_agent"
2043
+ "update_canvas", "wait", "wait_on_worker", "cron", "cron_at", "ask_user", "report_cycle", "list_available_models", "set_session_model", "send_session_message", "reply_session_message", "show_artifact", "draw_canvas", "read_canvas", "show_canvas", "spawn_agent", "message_agent", "check_agents", "wait_for_agents", "list_sessions", "complete_agent", "cancel_agent", "delete_agent"
1964
2044
  ]);
1965
2045
  // Merge user tools with system tools
1966
2046
  const userTools = this.config.tools ?? [];
@@ -2003,7 +2083,7 @@ export class ManagedSession {
2003
2083
  // the schema. Gate both halves on the same list so there is no tool
2004
2084
  // that exists-but-is-hidden in an ordinary session.
2005
2085
  const isManagerSession = holdsManagerBundle(this.config.agentIdentity);
2006
- const mutatingSystemToolNames = new Set(["send_session_message", "reply_session_message", "draw_canvas",
2086
+ const mutatingSystemToolNames = new Set(["send_session_message", "reply_session_message", "draw_canvas", "show_canvas",
2007
2087
  "update_canvas"]);
2008
2088
  const systemToolsForTurn = isServiceSession ? [] : [
2009
2089
  waitTool,
@@ -2031,6 +2111,7 @@ export class ManagedSession {
2031
2111
  drawCanvasTool,
2032
2112
  updateCanvasTool,
2033
2113
  readCanvasTool,
2114
+ showCanvasTool,
2034
2115
  ].filter((tool) => !isReadOnlyTuner || !mutatingSystemToolNames.has(tool.name));
2035
2116
  const subAgentToolsForTurn = isServiceSession
2036
2117
  ? []