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.
- package/api/src/http-api-transport.js +26 -7
- package/api/src/protocol.js +16 -7
- package/dist/agent-manager-tools.d.ts.map +1 -1
- package/dist/agent-manager-tools.js +12 -2
- package/dist/agent-manager-tools.js.map +1 -1
- package/dist/agent-package-installer.d.ts +2 -0
- package/dist/agent-package-installer.d.ts.map +1 -1
- package/dist/agent-package-installer.js +1 -0
- package/dist/agent-package-installer.js.map +1 -1
- package/dist/agent-package-service.d.ts +1 -1
- package/dist/agent-package-service.d.ts.map +1 -1
- package/dist/agent-package-service.js +79 -11
- package/dist/agent-package-service.js.map +1 -1
- package/dist/cms-migrations.d.ts.map +1 -1
- package/dist/cms-migrations.js +117 -0
- package/dist/cms-migrations.js.map +1 -1
- package/dist/cms.d.ts +50 -0
- package/dist/cms.d.ts.map +1 -1
- package/dist/cms.js +65 -0
- package/dist/cms.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/managed-session.d.ts +4 -7
- package/dist/managed-session.d.ts.map +1 -1
- package/dist/managed-session.js +99 -18
- package/dist/managed-session.js.map +1 -1
- package/dist/management-client.d.ts.map +1 -1
- package/dist/management-client.js +8 -1
- package/dist/management-client.js.map +1 -1
- package/dist/model-providers.d.ts +142 -6
- package/dist/model-providers.d.ts.map +1 -1
- package/dist/model-providers.js +117 -1
- package/dist/model-providers.js.map +1 -1
- package/dist/session-manager.d.ts +97 -7
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +292 -31
- package/dist/session-manager.js.map +1 -1
- package/dist/session-proxy.d.ts +43 -0
- package/dist/session-proxy.d.ts.map +1 -1
- package/dist/session-proxy.js +296 -184
- package/dist/session-proxy.js.map +1 -1
- package/dist/web/generated-op-methods.d.ts +34 -5
- package/dist/web/generated-op-methods.d.ts.map +1 -1
- package/dist/web/generated-op-methods.js +2 -0
- package/dist/web/generated-op-methods.js.map +1 -1
- package/dist/worker.d.ts +23 -0
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +189 -17
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
package/dist/managed-session.js
CHANGED
|
@@ -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
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
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
|
|
87
|
-
+ "with a complete HTML document.
|
|
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
|
|
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
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
? []
|