@yanlinglabs/winter-runtime-sdk 0.0.1 → 0.0.2
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 +68 -15
- package/dist/door.d.ts +62 -1
- package/dist/errors.d.ts +8 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.js +376 -298
- package/dist/messaging/index.d.ts +1 -3
- package/dist/messaging/router.d.ts +1 -12
- package/dist/official/aliases.d.ts +6 -2
- package/dist/official/index.d.ts +2 -2
- package/dist/official/mcp-descriptors.d.ts +59 -47
- package/dist/sdk.d.ts +90 -5
- package/dist/version-matrix.d.ts +44 -4
- package/package.json +5 -5
- package/dist/messaging/handlers.d.ts +0 -56
- package/dist/native-args.d.ts +0 -76
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ class RuntimeHandoffRequiredError extends RuntimeSdkError {
|
|
|
27
27
|
class RuntimeLaunchInputError extends RuntimeSdkError {
|
|
28
28
|
field;
|
|
29
29
|
constructor(args) {
|
|
30
|
-
super(`winter-runtime-sdk: the
|
|
30
|
+
super(`winter-runtime-sdk: ${args.leg === undefined ? "" : `the ${args.leg} leg: `}\`${args.field}\` — ${args.reason}`);
|
|
31
31
|
this.field = args.field;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -68,6 +68,7 @@ class RuntimeSdkDisposedError extends RuntimeSdkError {
|
|
|
68
68
|
|
|
69
69
|
// src/door.ts
|
|
70
70
|
import { buildChildAddress, buildSessionAddress, serializeRuntimeAddress } from "@yanlinglabs/winter-agent-sdk/messaging";
|
|
71
|
+
import { transcriptSourceForSessionKey } from "@yanlinglabs/winter-agent-sdk/tools";
|
|
71
72
|
|
|
72
73
|
// src/official/branding.ts
|
|
73
74
|
function officialBranchLabel(brand) {
|
|
@@ -76,95 +77,11 @@ function officialBranchLabel(brand) {
|
|
|
76
77
|
|
|
77
78
|
// src/official/aliases.ts
|
|
78
79
|
import { mcpToolName } from "@yanlinglabs/winter-agent-sdk";
|
|
79
|
-
|
|
80
|
-
// src/native-args.ts
|
|
81
|
-
import { validateToField } from "@yanlinglabs/winter-agent-sdk/messaging";
|
|
82
|
-
var SEND_MESSAGE_TO_MAX = 300;
|
|
83
|
-
var SEND_MESSAGE_SUMMARY_MAX = 200;
|
|
84
|
-
var LIST_AGENTS_FIELD_MAX = 256;
|
|
85
|
-
var NATIVE_SEND_MESSAGE_SCHEMA = {
|
|
86
|
-
type: "object",
|
|
87
|
-
properties: {
|
|
88
|
-
to: { type: "string", maxLength: SEND_MESSAGE_TO_MAX, description: 'no newline, no "*" broadcast' },
|
|
89
|
-
message: { type: "string", description: 'required; defaults "" for pure idle subscription' },
|
|
90
|
-
summary: { type: "string", maxLength: SEND_MESSAGE_SUMMARY_MAX },
|
|
91
|
-
notify_when_idle: { type: "boolean", description: "one-shot; main conversation -> same-machine session only" }
|
|
92
|
-
},
|
|
93
|
-
required: ["to", "message"]
|
|
94
|
-
};
|
|
95
|
-
var NATIVE_LIST_AGENTS_SCHEMA = {
|
|
96
|
-
type: "object",
|
|
97
|
-
properties: {
|
|
98
|
-
channel: { type: "string", maxLength: LIST_AGENTS_FIELD_MAX, description: "reserved" },
|
|
99
|
-
q: { type: "string", maxLength: LIST_AGENTS_FIELD_MAX, description: "reserved" }
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
var NATIVE_LIST_AGENTS_OUTPUT_SCHEMA = {
|
|
103
|
-
type: "object",
|
|
104
|
-
properties: { listing: { type: "string" } },
|
|
105
|
-
required: ["listing"]
|
|
106
|
-
};
|
|
107
|
-
var SEND_MESSAGE_FIELDS = new Set(Object.keys(NATIVE_SEND_MESSAGE_SCHEMA.properties));
|
|
108
|
-
var LIST_AGENTS_FIELDS = new Set(Object.keys(NATIVE_LIST_AGENTS_SCHEMA.properties));
|
|
109
|
-
function acceptNativeSendMessageArgs(input) {
|
|
110
|
-
if (typeof input !== "object" || input === null)
|
|
111
|
-
return { ok: false, reason: "expected an object of SendMessage arguments" };
|
|
112
|
-
const record = input;
|
|
113
|
-
const extra = Object.keys(record).filter((key) => !SEND_MESSAGE_FIELDS.has(key));
|
|
114
|
-
if (extra.length > 0)
|
|
115
|
-
return { ok: false, reason: `unknown argument(s): ${extra.join(", ")}` };
|
|
116
|
-
const to = record["to"];
|
|
117
|
-
const validated = validateToField(to);
|
|
118
|
-
if (!validated.ok)
|
|
119
|
-
return { ok: false, reason: validated.message };
|
|
120
|
-
const message = record["message"];
|
|
121
|
-
if (typeof message !== "string")
|
|
122
|
-
return { ok: false, reason: "`message` is required and must be a string (an empty string is a pure idle subscription)" };
|
|
123
|
-
const summary = record["summary"];
|
|
124
|
-
if (summary !== undefined && (typeof summary !== "string" || summary.length > SEND_MESSAGE_SUMMARY_MAX)) {
|
|
125
|
-
return { ok: false, reason: `\`summary\` must be a string of at most ${SEND_MESSAGE_SUMMARY_MAX} characters` };
|
|
126
|
-
}
|
|
127
|
-
const notify = record["notify_when_idle"];
|
|
128
|
-
if (notify !== undefined && typeof notify !== "boolean")
|
|
129
|
-
return { ok: false, reason: "`notify_when_idle` must be a boolean" };
|
|
130
|
-
return {
|
|
131
|
-
ok: true,
|
|
132
|
-
args: {
|
|
133
|
-
to,
|
|
134
|
-
message,
|
|
135
|
-
...summary === undefined ? {} : { summary },
|
|
136
|
-
...notify === undefined ? {} : { notify_when_idle: notify }
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
function acceptNativeListAgentsArgs(input) {
|
|
141
|
-
if (input === undefined || input === null)
|
|
142
|
-
return { ok: true, args: {} };
|
|
143
|
-
if (typeof input !== "object")
|
|
144
|
-
return { ok: false, reason: "expected an object of ListAgents arguments" };
|
|
145
|
-
const record = input;
|
|
146
|
-
const extra = Object.keys(record).filter((key) => !LIST_AGENTS_FIELDS.has(key));
|
|
147
|
-
if (extra.length > 0)
|
|
148
|
-
return { ok: false, reason: `unknown argument(s): ${extra.join(", ")}` };
|
|
149
|
-
for (const field of ["channel", "q"]) {
|
|
150
|
-
const value = record[field];
|
|
151
|
-
if (value !== undefined && (typeof value !== "string" || value.length > LIST_AGENTS_FIELD_MAX)) {
|
|
152
|
-
return { ok: false, reason: `\`${field}\` must be a string of at most ${LIST_AGENTS_FIELD_MAX} characters` };
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return {
|
|
156
|
-
ok: true,
|
|
157
|
-
args: {
|
|
158
|
-
...typeof record["channel"] === "string" ? { channel: record["channel"] } : {},
|
|
159
|
-
...typeof record["q"] === "string" ? { q: record["q"] } : {}
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// src/official/aliases.ts
|
|
165
80
|
var ALIASED_BUILTINS = [
|
|
166
81
|
{ builtin: "SendMessage", tool: "send_message" },
|
|
167
|
-
{ builtin: "ListAgents", tool: "list_agents" }
|
|
82
|
+
{ builtin: "ListAgents", tool: "list_agents" },
|
|
83
|
+
{ builtin: "ReadNotifications", tool: "read_notifications" },
|
|
84
|
+
{ builtin: "advisor", tool: "advisor" }
|
|
168
85
|
];
|
|
169
86
|
function officialToolAliases(brand) {
|
|
170
87
|
return Object.fromEntries(ALIASED_BUILTINS.map(({ builtin, tool }) => [builtin, mcpToolName(brand, tool)]));
|
|
@@ -270,6 +187,15 @@ class OfficialStdoutUnterminatedError extends OfficialBranchError {
|
|
|
270
187
|
this.graceMs = args.graceMs;
|
|
271
188
|
}
|
|
272
189
|
}
|
|
190
|
+
class OfficialMcpError extends OfficialBranchError {
|
|
191
|
+
code = "official_mcp_failure";
|
|
192
|
+
winterClass = "WinterSDKError";
|
|
193
|
+
server;
|
|
194
|
+
constructor(args) {
|
|
195
|
+
super(`${args.branchLabel}: the MCP server ${args.server} failed — ${args.reason}`, args.branchLabel);
|
|
196
|
+
this.server = args.server;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
273
199
|
class OfficialInvalidResumeError extends OfficialBranchError {
|
|
274
200
|
code = "official_invalid_resume";
|
|
275
201
|
winterClass = "WinterSDKError";
|
|
@@ -426,14 +352,14 @@ function createApprovalBridge(options) {
|
|
|
426
352
|
const request = { toolName, input, ...rest };
|
|
427
353
|
const containment = containmentDecisionFor(toolName, input, containmentPolicy);
|
|
428
354
|
if (!containment.allow) {
|
|
429
|
-
const
|
|
430
|
-
options.onDecision?.({ request, result, source: "containment-floor" });
|
|
431
|
-
return
|
|
355
|
+
const result2 = { behavior: "deny", message: containment.reason, toolUseID: request.toolUseID };
|
|
356
|
+
options.onDecision?.({ request, result: result2, source: "containment-floor" });
|
|
357
|
+
return result2;
|
|
432
358
|
}
|
|
433
359
|
if (options.mode === "dontAsk") {
|
|
434
|
-
const
|
|
435
|
-
options.onDecision?.({ request, result, source: "dont-ask" });
|
|
436
|
-
return
|
|
360
|
+
const result2 = { behavior: "allow", updatedInput: input, toolUseID: request.toolUseID };
|
|
361
|
+
options.onDecision?.({ request, result: result2, source: "dont-ask" });
|
|
362
|
+
return result2;
|
|
437
363
|
}
|
|
438
364
|
const result = await options.broker(request);
|
|
439
365
|
if (savedApprovals === "disable" && result.behavior === "allow" && result.updatedPermissions !== undefined) {
|
|
@@ -1578,6 +1504,123 @@ function assertOptionsInvariants(options, branchLabel) {
|
|
|
1578
1504
|
}
|
|
1579
1505
|
}
|
|
1580
1506
|
|
|
1507
|
+
// src/official/mcp-descriptors.ts
|
|
1508
|
+
import { isWinterMcpServerInstance, mcpToolName as mcpToolName3 } from "@yanlinglabs/winter-agent-sdk";
|
|
1509
|
+
import {
|
|
1510
|
+
WINTER_DEFAULT_TOOL_DEFINITIONS,
|
|
1511
|
+
createAdvisorToolHandler,
|
|
1512
|
+
createMessagingToolHandlers
|
|
1513
|
+
} from "@yanlinglabs/winter-agent-sdk/tools";
|
|
1514
|
+
function mcpResult(handler) {
|
|
1515
|
+
return async (args, extra) => {
|
|
1516
|
+
const result = await handler(args, extra);
|
|
1517
|
+
return { content: [{ type: "text", text: result.text }], ...result.isError === undefined ? {} : { isError: result.isError } };
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
function descriptorFor(definition, handler) {
|
|
1521
|
+
return {
|
|
1522
|
+
tool: definition.toolName,
|
|
1523
|
+
description: definition.description,
|
|
1524
|
+
inputSchema: definition.inputSchema,
|
|
1525
|
+
...definition.outputSchema === undefined ? {} : { outputSchema: definition.outputSchema },
|
|
1526
|
+
...definition.annotations === undefined ? {} : { annotations: definition.annotations },
|
|
1527
|
+
exposure: "deferred",
|
|
1528
|
+
permissionClass: definition.permissionClass,
|
|
1529
|
+
handler: mcpResult(handler)
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
function winterMcpServerDescriptor(args) {
|
|
1533
|
+
const messaging = createMessagingToolHandlers(args.port, args.caller);
|
|
1534
|
+
const advisor = createAdvisorToolHandler({
|
|
1535
|
+
transcriptSource: args.advisor.transcriptSource,
|
|
1536
|
+
resolveReviewer: args.advisor.resolveReviewer ?? (() => {
|
|
1537
|
+
return;
|
|
1538
|
+
}),
|
|
1539
|
+
...args.advisor.maxChars === undefined ? {} : { maxChars: args.advisor.maxChars }
|
|
1540
|
+
});
|
|
1541
|
+
const handlers = {
|
|
1542
|
+
send_message: messaging.sendMessage,
|
|
1543
|
+
list_agents: messaging.listAgents,
|
|
1544
|
+
read_notifications: messaging.readNotifications,
|
|
1545
|
+
advisor
|
|
1546
|
+
};
|
|
1547
|
+
const tools = WINTER_DEFAULT_TOOL_DEFINITIONS.map((definition) => {
|
|
1548
|
+
const handler = handlers[definition.toolName];
|
|
1549
|
+
if (handler === undefined)
|
|
1550
|
+
throw new OfficialMcpError({ server: args.brand.mcpServerName, reason: `the SDK declares a default tool this branch has no handler for: \`${definition.toolName}\``, branchLabel: "winter-claude-agent" });
|
|
1551
|
+
return descriptorFor(definition, handler);
|
|
1552
|
+
});
|
|
1553
|
+
return { name: args.brand.mcpServerName, version: args.version ?? "1.0.0", tools: [...tools, ...args.capabilities ?? []] };
|
|
1554
|
+
}
|
|
1555
|
+
function capabilityServerDescriptor(server, version = "1.0.0") {
|
|
1556
|
+
if (!isWinterMcpServerInstance(server.instance)) {
|
|
1557
|
+
throw new RuntimeLaunchInputError({
|
|
1558
|
+
field: "capabilities",
|
|
1559
|
+
reason: `the capability server \`${server.name}\` carries no in-process instance the router can call (\`listTools\`/\`callTool\`), so its tools could be forwarded to the Winter leg and never registered on the official one`
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
const instance = server.instance;
|
|
1563
|
+
const declared = server.tools ?? instance.listTools();
|
|
1564
|
+
const tools = declared.map((tool) => {
|
|
1565
|
+
const meta = tool._meta;
|
|
1566
|
+
const permissionClass = typeof meta?.["permissionClass"] === "string" ? meta["permissionClass"] : server.name;
|
|
1567
|
+
return {
|
|
1568
|
+
tool: tool.name,
|
|
1569
|
+
description: tool.description ?? "",
|
|
1570
|
+
inputSchema: capabilityInputSchema(tool.inputSchema, server.name, tool.name),
|
|
1571
|
+
...tool.annotations === undefined ? {} : { annotations: tool.annotations },
|
|
1572
|
+
exposure: "eager",
|
|
1573
|
+
permissionClass,
|
|
1574
|
+
handler: async (rawArgs) => {
|
|
1575
|
+
const result = await instance.callTool(tool.name, rawArgs ?? {});
|
|
1576
|
+
return { content: result.content, ...result.isError === undefined ? {} : { isError: result.isError } };
|
|
1577
|
+
}
|
|
1578
|
+
};
|
|
1579
|
+
});
|
|
1580
|
+
return { name: server.name, version, tools };
|
|
1581
|
+
}
|
|
1582
|
+
function capabilityNameCollisionError(args) {
|
|
1583
|
+
return new RuntimeLaunchInputError({
|
|
1584
|
+
field: args.field,
|
|
1585
|
+
reason: `\`${args.name}\` is the name of a capability server this handle forwards, and the caller's own \`mcpServers\` already carries it — one of the two would silently not be registered, and the other leg would still have the capability, so the door refuses rather than choose for you`
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
function capabilityServerDescriptors(servers) {
|
|
1589
|
+
return servers.map((server) => capabilityServerDescriptor(server));
|
|
1590
|
+
}
|
|
1591
|
+
function capabilityInputSchema(raw, server, tool) {
|
|
1592
|
+
const properties = raw["properties"];
|
|
1593
|
+
if (raw["type"] !== "object" || properties !== undefined && (typeof properties !== "object" || properties === null)) {
|
|
1594
|
+
throw new RuntimeLaunchInputError({
|
|
1595
|
+
field: "capabilities",
|
|
1596
|
+
reason: `the capability tool \`${tool}\` on \`${server}\` declares an input schema that is not a JSON-Schema object, and the official branch's in-process registration has no conversion for anything else`
|
|
1597
|
+
});
|
|
1598
|
+
}
|
|
1599
|
+
const required = raw["required"];
|
|
1600
|
+
const additionalProperties = raw["additionalProperties"];
|
|
1601
|
+
return {
|
|
1602
|
+
type: "object",
|
|
1603
|
+
...properties === undefined ? {} : { properties },
|
|
1604
|
+
...Array.isArray(required) ? { required: required.map(String) } : {},
|
|
1605
|
+
...typeof additionalProperties === "boolean" ? { additionalProperties } : {}
|
|
1606
|
+
};
|
|
1607
|
+
}
|
|
1608
|
+
function materializeOfficialMcpServer(args) {
|
|
1609
|
+
const { createSdkMcpServer, tool } = args.module;
|
|
1610
|
+
if (typeof createSdkMcpServer !== "function" || typeof tool !== "function") {
|
|
1611
|
+
throw new OfficialMcpError({
|
|
1612
|
+
server: args.descriptor.name,
|
|
1613
|
+
reason: "the injected official SDK module exposes no in-process MCP server constructor, so the standing server cannot be registered and every aliased built-in would resolve to a missing tool",
|
|
1614
|
+
branchLabel: args.branchLabel
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
const tools = args.descriptor.tools.map((descriptor) => tool(descriptor.tool, descriptor.description, args.toInputShape(descriptor.inputSchema), async (rawArgs, extra) => descriptor.handler(rawArgs, extra), descriptor.annotations === undefined ? undefined : { annotations: descriptor.annotations }));
|
|
1618
|
+
return createSdkMcpServer({ name: args.descriptor.name, version: args.descriptor.version, tools });
|
|
1619
|
+
}
|
|
1620
|
+
function officialMcpServers(args) {
|
|
1621
|
+
return { [args.descriptor.name]: materializeOfficialMcpServer(args) };
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1581
1624
|
// src/vendor-paths.ts
|
|
1582
1625
|
import { tmpdir } from "node:os";
|
|
1583
1626
|
import { join } from "node:path";
|
|
@@ -1722,10 +1765,60 @@ function officialConnectionEnv(args) {
|
|
|
1722
1765
|
explicit["ANTHROPIC_BASE_URL"] = baseUrl;
|
|
1723
1766
|
return explicit;
|
|
1724
1767
|
}
|
|
1768
|
+
function officialCapabilityServers(deps, args) {
|
|
1769
|
+
if (deps.toInputShape === undefined) {
|
|
1770
|
+
if (deps.capabilities === undefined)
|
|
1771
|
+
return;
|
|
1772
|
+
throw new RuntimeLaunchInputError({
|
|
1773
|
+
leg: "official",
|
|
1774
|
+
field: "toInputShape",
|
|
1775
|
+
reason: "this handle was constructed with `capabilities` but no JSON-Schema → validator-shape bridge, and the official runtime registers in-process servers only through its own validator's shape — so those tools would exist on the Winter leg and silently not on this one (WS-14 §11)"
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
for (const name of Object.keys(args.hostOwned ?? {})) {
|
|
1779
|
+
if ((deps.capabilities ?? []).some((descriptor) => descriptor.name === name))
|
|
1780
|
+
throw capabilityNameCollisionError({ field: "runtime.official.mcpServers", name });
|
|
1781
|
+
}
|
|
1782
|
+
const toInputShape = deps.toInputShape;
|
|
1783
|
+
const module = deps.mcpModule;
|
|
1784
|
+
if (module === undefined) {
|
|
1785
|
+
throw new RuntimeLaunchInputError({
|
|
1786
|
+
leg: "official",
|
|
1787
|
+
field: "peers.claude",
|
|
1788
|
+
reason: "the official leg cannot register the standing server without the official SDK module the servers are registered into"
|
|
1789
|
+
});
|
|
1790
|
+
}
|
|
1791
|
+
const standing = winterMcpServerDescriptor({
|
|
1792
|
+
brand: deps.brand,
|
|
1793
|
+
port: deps.messaging,
|
|
1794
|
+
caller: args.caller,
|
|
1795
|
+
advisor: { transcriptSource: args.transcriptSource, ...deps.advisor?.resolveReviewer === undefined ? {} : { resolveReviewer: deps.advisor.resolveReviewer }, ...deps.advisor?.maxChars === undefined ? {} : { maxChars: deps.advisor.maxChars } }
|
|
1796
|
+
});
|
|
1797
|
+
const servers = {};
|
|
1798
|
+
for (const descriptor of [standing, ...deps.capabilities ?? []]) {
|
|
1799
|
+
Object.assign(servers, officialMcpServers({ descriptor, module, toInputShape, branchLabel: args.branchLabel }));
|
|
1800
|
+
}
|
|
1801
|
+
return servers;
|
|
1802
|
+
}
|
|
1725
1803
|
function openOfficialLeg(deps, request) {
|
|
1726
1804
|
const branchLabel = officialBranchLabel(deps.brand);
|
|
1727
|
-
const parsed = request.input.parentSessionId === undefined ? buildSessionAddress(request.input.sessionId) : buildChildAddress(request.input.parentSessionId, request.input.sessionId);
|
|
1728
1805
|
const address = officialLegAddress(request.input);
|
|
1806
|
+
const advisorTranscriptSource = () => ({
|
|
1807
|
+
async getEntries() {
|
|
1808
|
+
const cwd = request.options.cwd;
|
|
1809
|
+
const projectKey = request.input.projectKey ?? (cwd === undefined || cwd.length === 0 ? undefined : deps.transcriptProjectKey(cwd));
|
|
1810
|
+
if (projectKey === undefined)
|
|
1811
|
+
return [];
|
|
1812
|
+
const row = await deps.directory.get(address);
|
|
1813
|
+
const sessionId = row?.backendSessionId ?? request.options.sessionId;
|
|
1814
|
+
if (sessionId === undefined || sessionId.length === 0)
|
|
1815
|
+
return [];
|
|
1816
|
+
return transcriptSourceForSessionKey({ projectKey, sessionId }, { store: deps.shared().store }).getEntries();
|
|
1817
|
+
}
|
|
1818
|
+
});
|
|
1819
|
+
const messagingCaller = request.input.parentSessionId === undefined ? { sessionId: request.input.sessionId } : { sessionId: request.input.parentSessionId, agentId: request.input.sessionId };
|
|
1820
|
+
const routerBuiltMcpServers = officialCapabilityServers(deps, { caller: messagingCaller, transcriptSource: advisorTranscriptSource(), branchLabel, hostOwned: request.input.mcpServers });
|
|
1821
|
+
const parsed = request.input.parentSessionId === undefined ? buildSessionAddress(request.input.sessionId) : buildChildAddress(request.input.parentSessionId, request.input.sessionId);
|
|
1729
1822
|
const stream = typeof request.prompt === "string" ? undefined : createOfficialInputStream();
|
|
1730
1823
|
let detach;
|
|
1731
1824
|
let sawInit = false;
|
|
@@ -1821,7 +1914,7 @@ function openOfficialLeg(deps, request) {
|
|
|
1821
1914
|
...request.input.options ?? {},
|
|
1822
1915
|
advertisesHandoff: request.input.advertisesHandoff ?? true,
|
|
1823
1916
|
env,
|
|
1824
|
-
...request.input.mcpServers === undefined ? {} : { mcpServers: request.input.mcpServers },
|
|
1917
|
+
...routerBuiltMcpServers === undefined && request.input.mcpServers === undefined ? {} : { mcpServers: { ...routerBuiltMcpServers, ...request.input.mcpServers } },
|
|
1825
1918
|
...bridge === undefined ? {} : { canUseTool: bridge },
|
|
1826
1919
|
...request.options.permissionMode === undefined ? {} : { permissionMode: request.options.permissionMode },
|
|
1827
1920
|
...request.options.sessionId === undefined ? {} : { sessionId: request.options.sessionId },
|
|
@@ -2123,7 +2216,7 @@ function createInMemoryRuntimeDirectoryStore() {
|
|
|
2123
2216
|
}
|
|
2124
2217
|
|
|
2125
2218
|
// src/directory/directory.ts
|
|
2126
|
-
import { parseRuntimeAddress, resolveTarget, serializeRuntimeAddress as serializeRuntimeAddress3, validateToField
|
|
2219
|
+
import { parseRuntimeAddress, resolveTarget, serializeRuntimeAddress as serializeRuntimeAddress3, validateToField } from "@yanlinglabs/winter-agent-sdk/messaging";
|
|
2127
2220
|
|
|
2128
2221
|
// src/directory/entries.ts
|
|
2129
2222
|
import { buildSessionAddress as buildSessionAddress2, serializeRuntimeAddress as serializeRuntimeAddress2 } from "@yanlinglabs/winter-agent-sdk/messaging";
|
|
@@ -2369,7 +2462,7 @@ function createRuntimeDirectory(context, options = {}) {
|
|
|
2369
2462
|
return (await store.load()).find((entry) => entry.address === address);
|
|
2370
2463
|
}
|
|
2371
2464
|
async function resolveIn(snap, to, ctx) {
|
|
2372
|
-
const valid =
|
|
2465
|
+
const valid = validateToField(to);
|
|
2373
2466
|
if (!valid.ok)
|
|
2374
2467
|
return { kind: "not-found", reason: valid.message };
|
|
2375
2468
|
const callerOwner = owningSessionIdOf(ctx.from);
|
|
@@ -2452,7 +2545,6 @@ function createRuntimeDirectory(context, options = {}) {
|
|
|
2452
2545
|
}
|
|
2453
2546
|
// src/messaging/router.ts
|
|
2454
2547
|
import {
|
|
2455
|
-
callerAddress,
|
|
2456
2548
|
createLoopGuard,
|
|
2457
2549
|
createMessagingRouter,
|
|
2458
2550
|
createNotificationQueue,
|
|
@@ -3199,32 +3291,32 @@ function selectChildRuntimePairing(parent, child) {
|
|
|
3199
3291
|
};
|
|
3200
3292
|
}
|
|
3201
3293
|
var CHILD_PROVIDER_UNAVAILABLE = "child-provider-unavailable";
|
|
3202
|
-
function resumeChildSelection(
|
|
3203
|
-
const input = childInput({ ...context, model:
|
|
3204
|
-
const rows = resolveCandidateRows({ ...input, requested: { ...input.requested, model:
|
|
3294
|
+
function resumeChildSelection(record2, context) {
|
|
3295
|
+
const input = childInput({ ...context, model: record2.modelRef, provider: record2.providerId });
|
|
3296
|
+
const rows = resolveCandidateRows({ ...input, requested: { ...input.requested, model: record2.modelRef } });
|
|
3205
3297
|
if (isRefusal2(rows)) {
|
|
3206
3298
|
return {
|
|
3207
3299
|
kind: "unavailable",
|
|
3208
3300
|
retryable: false,
|
|
3209
|
-
reason: `${CHILD_PROVIDER_UNAVAILABLE}: ${
|
|
3301
|
+
reason: `${CHILD_PROVIDER_UNAVAILABLE}: ${record2.modelRef} on provider ${record2.providerId} — ${rows.detail}`
|
|
3210
3302
|
};
|
|
3211
3303
|
}
|
|
3212
|
-
const recorded = rows.find((candidate) => candidate.row.key ===
|
|
3304
|
+
const recorded = rows.find((candidate) => candidate.row.key === record2.modelRef);
|
|
3213
3305
|
if (recorded === undefined) {
|
|
3214
3306
|
return {
|
|
3215
3307
|
kind: "unavailable",
|
|
3216
3308
|
retryable: false,
|
|
3217
|
-
reason: `${CHILD_PROVIDER_UNAVAILABLE}: this child is recorded on the row ${
|
|
3309
|
+
reason: `${CHILD_PROVIDER_UNAVAILABLE}: this child is recorded on the row ${record2.modelRef} (provider ${record2.providerId}), which is no longer among the servable rows for that provider (now: ${rows.map((candidate) => candidate.row.key).join(", ")}); a resumed child re-resolves under its OWN recorded model and provider (WS-10, Phase 6.6 amendment)`
|
|
3218
3310
|
};
|
|
3219
3311
|
}
|
|
3220
|
-
if (recorded.family !==
|
|
3312
|
+
if (recorded.family !== record2.family) {
|
|
3221
3313
|
return {
|
|
3222
3314
|
kind: "unavailable",
|
|
3223
3315
|
retryable: false,
|
|
3224
|
-
reason: `${CHILD_PROVIDER_UNAVAILABLE}: this child is recorded in the ${
|
|
3316
|
+
reason: `${CHILD_PROVIDER_UNAVAILABLE}: this child is recorded in the ${record2.family} family and its recorded row ${record2.modelRef} now resolves into ${recorded.family}; never a substitution, never a different family (WS-13c §4)`
|
|
3225
3317
|
};
|
|
3226
3318
|
}
|
|
3227
|
-
return { kind: "resumed", selection:
|
|
3319
|
+
return { kind: "resumed", selection: record2 };
|
|
3228
3320
|
}
|
|
3229
3321
|
|
|
3230
3322
|
// src/messaging/winter-adapter.ts
|
|
@@ -3509,8 +3601,8 @@ function createGlobalMessaging(context, options = {}) {
|
|
|
3509
3601
|
} catch {
|
|
3510
3602
|
return;
|
|
3511
3603
|
}
|
|
3512
|
-
for (const
|
|
3513
|
-
await handle.noteIdle(address, { notificationId:
|
|
3604
|
+
for (const record2 of drained.notifications) {
|
|
3605
|
+
await handle.noteIdle(address, { notificationId: record2.notification_id, content: record2.content });
|
|
3514
3606
|
}
|
|
3515
3607
|
if (drained.remaining === 0 || drained.notifications.length === 0)
|
|
3516
3608
|
return;
|
|
@@ -3735,58 +3827,6 @@ function createGlobalMessaging(context, options = {}) {
|
|
|
3735
3827
|
};
|
|
3736
3828
|
return handle;
|
|
3737
3829
|
}
|
|
3738
|
-
function callerAddressOf(caller) {
|
|
3739
|
-
return callerAddress(caller);
|
|
3740
|
-
}
|
|
3741
|
-
// src/messaging/handlers.ts
|
|
3742
|
-
var VENDOR_TOOL_USE_ID_META_KEY = "claudecode/toolUseId";
|
|
3743
|
-
function toolUseIdFromExtra(extra) {
|
|
3744
|
-
if (typeof extra !== "object" || extra === null)
|
|
3745
|
-
return;
|
|
3746
|
-
const meta = extra._meta;
|
|
3747
|
-
if (typeof meta !== "object" || meta === null)
|
|
3748
|
-
return;
|
|
3749
|
-
const id = meta[VENDOR_TOOL_USE_ID_META_KEY];
|
|
3750
|
-
return typeof id === "string" && id.length > 0 ? id : undefined;
|
|
3751
|
-
}
|
|
3752
|
-
var MODEL_FACING_FAILURES = new Set(["refused", "ambiguous", "not_found", "unavailable"]);
|
|
3753
|
-
function text(body, isError = false) {
|
|
3754
|
-
return { content: [{ type: "text", text: body }], ...isError ? { isError: true } : {} };
|
|
3755
|
-
}
|
|
3756
|
-
function createMessagingToolHandlers(messaging, caller) {
|
|
3757
|
-
const identity = () => typeof caller === "function" ? caller() : caller;
|
|
3758
|
-
return {
|
|
3759
|
-
async sendMessage(rawArgs, extra) {
|
|
3760
|
-
const accepted = acceptNativeSendMessageArgs(rawArgs);
|
|
3761
|
-
if (!accepted.ok)
|
|
3762
|
-
return text(accepted.reason, true);
|
|
3763
|
-
const bound = identity();
|
|
3764
|
-
const perCall = toolUseIdFromExtra(extra);
|
|
3765
|
-
const who = perCall === undefined ? bound : { ...bound, toolUseId: perCall };
|
|
3766
|
-
const from = callerAddressOf(who);
|
|
3767
|
-
const result = await messaging.sendDetailed({
|
|
3768
|
-
from,
|
|
3769
|
-
to: accepted.args.to,
|
|
3770
|
-
body: accepted.args.message,
|
|
3771
|
-
...accepted.args.summary === undefined ? {} : { summary: accepted.args.summary },
|
|
3772
|
-
...accepted.args.notify_when_idle === undefined ? {} : { notifyWhenIdle: accepted.args.notify_when_idle },
|
|
3773
|
-
...who.toolUseId === undefined ? {} : { originToolCallId: who.toolUseId }
|
|
3774
|
-
});
|
|
3775
|
-
const payload = result.notify === undefined ? result.outcome : { ...result.outcome, notify: result.notify };
|
|
3776
|
-
return text(JSON.stringify(payload), MODEL_FACING_FAILURES.has(result.outcome.status));
|
|
3777
|
-
},
|
|
3778
|
-
async listAgents(rawArgs) {
|
|
3779
|
-
const accepted = acceptNativeListAgentsArgs(rawArgs);
|
|
3780
|
-
if (!accepted.ok)
|
|
3781
|
-
return text(accepted.reason, true);
|
|
3782
|
-
const from = callerAddressOf(identity());
|
|
3783
|
-
const rows = await messaging.listReachable({ from });
|
|
3784
|
-
const listing = rows.length === 0 ? "No agents or sessions are currently reachable." : rows.map((row) => `- ${row.name === undefined ? row.address : `${row.name} (${row.address})`} [${row.objectKind}/${row.runtimeKind}] status=${row.status} mode=${row.mode}`).join(`
|
|
3785
|
-
`);
|
|
3786
|
-
return text(JSON.stringify({ listing }));
|
|
3787
|
-
}
|
|
3788
|
-
};
|
|
3789
|
-
}
|
|
3790
3830
|
// src/messaging/index.ts
|
|
3791
3831
|
function createRuntimeMessaging(context, options = {}) {
|
|
3792
3832
|
let messaging;
|
|
@@ -3928,14 +3968,14 @@ function createSharedSessionStore(input) {
|
|
|
3928
3968
|
}
|
|
3929
3969
|
return state;
|
|
3930
3970
|
};
|
|
3931
|
-
const recordMirrorError = (key,
|
|
3971
|
+
const recordMirrorError = (key, record2) => {
|
|
3932
3972
|
const state = stateFor(key);
|
|
3933
3973
|
state.health = "repair-required";
|
|
3934
3974
|
state.errors.push({
|
|
3935
3975
|
projectKey: key.projectKey,
|
|
3936
3976
|
sessionId: key.sessionId,
|
|
3937
3977
|
...key.subpath === undefined ? {} : { subpath: key.subpath },
|
|
3938
|
-
...
|
|
3978
|
+
...record2,
|
|
3939
3979
|
at: now().toISOString()
|
|
3940
3980
|
});
|
|
3941
3981
|
};
|
|
@@ -4018,12 +4058,12 @@ function createSharedSessionStore(input) {
|
|
|
4018
4058
|
for (const batch of [...batches.values()])
|
|
4019
4059
|
await flush(batch.key);
|
|
4020
4060
|
await tail;
|
|
4021
|
-
const errors = [...sessions.values()].flatMap((
|
|
4061
|
+
const errors = [...sessions.values()].flatMap((state2) => state2.errors);
|
|
4022
4062
|
return {
|
|
4023
4063
|
settled: batches.size === 0,
|
|
4024
|
-
batchesCommitted: [...sessions.values()].reduce((sum,
|
|
4064
|
+
batchesCommitted: [...sessions.values()].reduce((sum, state2) => sum + state2.batchesCommitted, 0),
|
|
4025
4065
|
errors,
|
|
4026
|
-
transcriptHealth: [...sessions.values()].some((
|
|
4066
|
+
transcriptHealth: [...sessions.values()].some((state2) => state2.health === "repair-required") ? "repair-required" : "ok"
|
|
4027
4067
|
};
|
|
4028
4068
|
}
|
|
4029
4069
|
const session = sessionOf(key);
|
|
@@ -4639,7 +4679,7 @@ function sidecarPath(home, key) {
|
|
|
4639
4679
|
}
|
|
4640
4680
|
function writeSidecar(path, records) {
|
|
4641
4681
|
mkdirSync2(dirname(path), { recursive: true, mode: 448 });
|
|
4642
|
-
const lines = records.map((
|
|
4682
|
+
const lines = records.map((record2) => JSON.stringify({ sessionId: PROBE_KEY.sessionId, anchorUuid: record2.anchorUuid, provider: "probe", model: "probe", itemIndex: 0, kind: record2.kind, payload: "opaque" }));
|
|
4643
4683
|
writeFile(path, Buffer.from(`${lines.join(`
|
|
4644
4684
|
`)}
|
|
4645
4685
|
`, "utf8"));
|
|
@@ -4734,12 +4774,12 @@ async function probeNoWashBack(context, deps) {
|
|
|
4734
4774
|
});
|
|
4735
4775
|
legs.push(await pinnedLeg("mirror from a decorated copy", deps, async (bed) => {
|
|
4736
4776
|
const canonicalBeforeResume = readFileSync2(canonicalPath);
|
|
4737
|
-
const
|
|
4777
|
+
const before2 = await entryCount(shared, PROBE_KEY);
|
|
4738
4778
|
await bed.freshProcessResume({ home, stagingRoot, key: PROBE_KEY, shared });
|
|
4739
4779
|
await shared.settle(PROBE_KEY);
|
|
4740
|
-
const
|
|
4741
|
-
if (
|
|
4742
|
-
return { passed: false, evidence: `unexercised: the resume from the decorated copy produced no entries (${
|
|
4780
|
+
const after2 = await entryCount(shared, PROBE_KEY);
|
|
4781
|
+
if (after2 <= before2) {
|
|
4782
|
+
return { passed: false, evidence: `unexercised: the resume from the decorated copy produced no entries (${before2} before, ${after2} after), so no mirror write was observed` };
|
|
4743
4783
|
}
|
|
4744
4784
|
const canonicalAfterResume = readFileSync2(canonicalPath);
|
|
4745
4785
|
const prefixIntact = canonicalAfterResume.subarray(0, canonicalBeforeResume.length).equals(canonicalBeforeResume);
|
|
@@ -4748,7 +4788,7 @@ async function probeNoWashBack(context, deps) {
|
|
|
4748
4788
|
const duplicateUuids = uuids.length - new Set(uuids).size;
|
|
4749
4789
|
return {
|
|
4750
4790
|
passed: prefixIntact && stillNoDecoration && duplicateUuids === 0,
|
|
4751
|
-
evidence: `after a resume from the decorated copy that mirrored ${
|
|
4791
|
+
evidence: `after a resume from the decorated copy that mirrored ${after2 - before2} entr(y|ies): canonical prefix intact=${prefixIntact}; decoration still absent=${stillNoDecoration}; duplicate uuids=${duplicateUuids}`
|
|
4752
4792
|
};
|
|
4753
4793
|
}));
|
|
4754
4794
|
return legs;
|
|
@@ -4799,8 +4839,8 @@ async function probeSidecarRoundTrip(context, deps) {
|
|
|
4799
4839
|
const seenUuids = new Set;
|
|
4800
4840
|
let orderIntact = lines.length > 0;
|
|
4801
4841
|
for (const line of lines) {
|
|
4802
|
-
const
|
|
4803
|
-
if (typeof
|
|
4842
|
+
const parent2 = parentOf(line);
|
|
4843
|
+
if (typeof parent2 === "string" && !seenUuids.has(parent2)) {
|
|
4804
4844
|
orderIntact = false;
|
|
4805
4845
|
break;
|
|
4806
4846
|
}
|
|
@@ -5072,11 +5112,11 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5072
5112
|
};
|
|
5073
5113
|
const reviewSelectionFor = async (args) => {
|
|
5074
5114
|
const { persisted, to } = args;
|
|
5075
|
-
const
|
|
5115
|
+
const stamped2 = { ...persisted, runtimeKind: to };
|
|
5076
5116
|
if (deps.selectionInputFor === undefined) {
|
|
5077
5117
|
return {
|
|
5078
5118
|
kind: "unreviewed",
|
|
5079
|
-
selection:
|
|
5119
|
+
selection: stamped2,
|
|
5080
5120
|
detail: `no selection input was supplied, so nothing checked whether ${to} can serve ${persisted.providerId}/${persisted.modelRef}; the destination's own init is the first thing that will (supply \`selectionInputFor\` to review it here instead)`
|
|
5081
5121
|
};
|
|
5082
5122
|
}
|
|
@@ -5112,7 +5152,7 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5112
5152
|
detail: `the official runtime does not serve ${persisted.providerId}/${persisted.modelRef}`
|
|
5113
5153
|
};
|
|
5114
5154
|
}
|
|
5115
|
-
return { kind: "servable", selection:
|
|
5155
|
+
return { kind: "servable", selection: stamped2, review };
|
|
5116
5156
|
};
|
|
5117
5157
|
const plan = async (session, to) => {
|
|
5118
5158
|
const entry = await loadEntry(session);
|
|
@@ -5138,30 +5178,30 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5138
5178
|
selection
|
|
5139
5179
|
};
|
|
5140
5180
|
};
|
|
5141
|
-
const execute = async (
|
|
5181
|
+
const execute = async (plan2) => {
|
|
5142
5182
|
const trail = [];
|
|
5143
|
-
const
|
|
5183
|
+
const record2 = (step, ok, detail) => {
|
|
5144
5184
|
trail.push({ step, name: HANDOFF_STEPS[step - 1].name, ok, detail });
|
|
5145
5185
|
};
|
|
5146
5186
|
const lossy = (step, reason) => {
|
|
5147
|
-
|
|
5187
|
+
record2(step, false, reason);
|
|
5148
5188
|
return { kind: "lossy-fork-offered", reason, step, detail: reason, steps: trail };
|
|
5149
5189
|
};
|
|
5150
5190
|
const blocked = (step, reason, detail) => {
|
|
5151
|
-
|
|
5191
|
+
record2(step, false, detail);
|
|
5152
5192
|
return { kind: "blocked", reason, step, detail, steps: trail };
|
|
5153
5193
|
};
|
|
5154
|
-
const session =
|
|
5194
|
+
const session = plan2.session;
|
|
5155
5195
|
let shared;
|
|
5156
|
-
let
|
|
5196
|
+
let winterHome2;
|
|
5157
5197
|
try {
|
|
5158
5198
|
shared = sharedOf();
|
|
5159
|
-
|
|
5199
|
+
winterHome2 = homeOf();
|
|
5160
5200
|
} catch (error) {
|
|
5161
5201
|
return lossy(1, `the shared session store could not be resolved, so nothing about this session can be read or written: ${error instanceof Error ? error.message : String(error)}`);
|
|
5162
5202
|
}
|
|
5163
|
-
if (
|
|
5164
|
-
return lossy(8,
|
|
5203
|
+
if (plan2.selection.kind === "refused") {
|
|
5204
|
+
return lossy(8, plan2.selection.refusal.detail);
|
|
5165
5205
|
}
|
|
5166
5206
|
let lease;
|
|
5167
5207
|
let stagedRoot;
|
|
@@ -5187,13 +5227,13 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5187
5227
|
try {
|
|
5188
5228
|
entry = await loadEntry(session);
|
|
5189
5229
|
assertOneDecoratorStore();
|
|
5190
|
-
if (entry.runtimeKind !==
|
|
5191
|
-
return lossy(1, `this plan was built when ${
|
|
5230
|
+
if (entry.runtimeKind !== plan2.from) {
|
|
5231
|
+
return lossy(1, `this plan was built when ${plan2.from} owned the session and ${entry.runtimeKind} owns it now; re-plan against the current owner`);
|
|
5192
5232
|
}
|
|
5193
|
-
const owner = await deps.participants?.source?.(session,
|
|
5233
|
+
const owner = await deps.participants?.source?.(session, plan2.from) ?? undefined;
|
|
5194
5234
|
const healthNow = owner?.health === undefined ? undefined : await owner.health();
|
|
5195
|
-
const markers = new Map([...markersFor({ entry, to:
|
|
5196
|
-
for (const step of
|
|
5235
|
+
const markers = new Map([...markersFor({ entry, to: plan2.to, session, ...healthNow === undefined ? {} : { health: healthNow } })]);
|
|
5236
|
+
for (const step of plan2.steps) {
|
|
5197
5237
|
if (step.knownUnprovable !== undefined)
|
|
5198
5238
|
markers.set(step.step, step.knownUnprovable);
|
|
5199
5239
|
}
|
|
@@ -5208,12 +5248,12 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5208
5248
|
return blocked(1, "lease-held", error instanceof Error ? error.message : String(error));
|
|
5209
5249
|
}
|
|
5210
5250
|
await owner?.stopNewTurns?.();
|
|
5211
|
-
|
|
5251
|
+
record2(1, true, "the handoff lease is held by this process and the source is not taking new turns");
|
|
5212
5252
|
at = 2;
|
|
5213
5253
|
const drained = owner === undefined ? { ok: true, detail: "there is no live owner to drain" } : await owner.drainToIdleBoundary();
|
|
5214
5254
|
if (!drained.ok)
|
|
5215
5255
|
return lossy(2, drained.reason);
|
|
5216
|
-
|
|
5256
|
+
record2(2, true, drained.detail ?? "the active turn reached an idle terminal boundary");
|
|
5217
5257
|
at = 3;
|
|
5218
5258
|
const streamed = owner === undefined ? { ok: true, detail: "there is no live stream to drain" } : await owner.drainStream();
|
|
5219
5259
|
if (!streamed.ok)
|
|
@@ -5221,7 +5261,7 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5221
5261
|
const settled = await shared.settle(session);
|
|
5222
5262
|
if (!settled.settled)
|
|
5223
5263
|
return lossy(3, "the pending append barrier did not settle, so the canonical tail is still moving");
|
|
5224
|
-
|
|
5264
|
+
record2(3, true, `${streamed.detail ?? "the stream reached its terminal result"}; ${settled.batchesCommitted} canonical append batch(es) settled`);
|
|
5225
5265
|
at = 4;
|
|
5226
5266
|
const eligibility = owner?.eligibility === undefined ? undefined : await owner.eligibility();
|
|
5227
5267
|
if (eligibility !== undefined && !eligibility.eligible) {
|
|
@@ -5235,11 +5275,11 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5235
5275
|
if (report.status === "diverged" || report.appended !== comparison.missing) {
|
|
5236
5276
|
return blocked(4, "repair-required", `the canonical store could not be reconciled against ${localRoot}: ${comparison.missing} entr(y|ies) were missing and ${report.appended} landed (${report.status})`);
|
|
5237
5277
|
}
|
|
5238
|
-
|
|
5278
|
+
record2(4, true, `the canonical tail was ${comparison.missing} entr(y|ies) behind the recorded local-write root and has been reconciled`);
|
|
5239
5279
|
} else if (comparison.kind === "diverged" || comparison.kind === "canonical-ahead") {
|
|
5240
5280
|
return blocked(4, "repair-required", comparison.reason);
|
|
5241
5281
|
} else {
|
|
5242
|
-
|
|
5282
|
+
record2(4, true, comparison.reason);
|
|
5243
5283
|
}
|
|
5244
5284
|
const storeHealth = shared.health(session);
|
|
5245
5285
|
if (storeHealth.transcriptHealth !== "ok") {
|
|
@@ -5247,10 +5287,10 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5247
5287
|
return blocked(4, "mirror-error", `the mirror recorded ${storeHealth.errors.length} failure(s) for this session${cause === undefined ? "" : ` (last: ${cause.cause})`}, and it is not reconciled`);
|
|
5248
5288
|
}
|
|
5249
5289
|
at = 5;
|
|
5250
|
-
const validation = await validateSessionTranscript(shared, session,
|
|
5290
|
+
const validation = await validateSessionTranscript(shared, session, winterHome2);
|
|
5251
5291
|
if (!validation.ok)
|
|
5252
5292
|
return lossy(5, validation.reason);
|
|
5253
|
-
|
|
5293
|
+
record2(5, true, validation.detail);
|
|
5254
5294
|
at = 6;
|
|
5255
5295
|
const closed = await owner?.close() ?? undefined;
|
|
5256
5296
|
if (closed !== undefined && closed.ok === false)
|
|
@@ -5266,18 +5306,18 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5266
5306
|
let staged;
|
|
5267
5307
|
pendingWritten = true;
|
|
5268
5308
|
try {
|
|
5269
|
-
staged = await markHandoffPending({ shared, session, entry, plan, level, now: now() });
|
|
5309
|
+
staged = await markHandoffPending({ shared, session, entry, plan: plan2, level, now: now() });
|
|
5270
5310
|
} catch (error) {
|
|
5271
5311
|
await unwind();
|
|
5272
5312
|
return lossy(6, `the handoff could not be staged: ${error instanceof Error ? error.message : String(error)}`);
|
|
5273
5313
|
}
|
|
5274
|
-
|
|
5314
|
+
record2(6, true, `the owner is closed, the writer lease was granted to this process, and a pending handoff to ${plan2.to} at level ${level} is recorded — ownership has NOT moved`);
|
|
5275
5315
|
at = 7;
|
|
5276
5316
|
let continuity;
|
|
5277
5317
|
try {
|
|
5278
5318
|
const layout = (deps.tempLayoutFor ?? defaultTempLayout(context))(entry, session);
|
|
5279
5319
|
continuity = materializeTempContinuity({
|
|
5280
|
-
to:
|
|
5320
|
+
to: plan2.to,
|
|
5281
5321
|
layout,
|
|
5282
5322
|
...owner?.effectiveTempDir === undefined ? {} : { recordedTempDir: owner.effectiveTempDir }
|
|
5283
5323
|
});
|
|
@@ -5285,25 +5325,25 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5285
5325
|
await unwind();
|
|
5286
5326
|
return lossy(7, `temp continuity could not be materialized: ${error instanceof Error ? error.message : String(error)}`);
|
|
5287
5327
|
}
|
|
5288
|
-
|
|
5328
|
+
record2(7, true, `${continuity.mode}: the session's scratch is at ${continuity.effectiveTempDir}${continuity.supersededDir === undefined ? "" : `, superseding ${continuity.supersededDir} (retained)`}`);
|
|
5289
5329
|
at = 8;
|
|
5290
|
-
const stagingRoot =
|
|
5330
|
+
const stagingRoot = plan2.to === "claude-agent" ? stagingRootFor(staged.stagingUuid) : undefined;
|
|
5291
5331
|
if (stagingRoot !== undefined)
|
|
5292
5332
|
stagedRoot = stagingRoot;
|
|
5293
5333
|
const decorated = await decoratorOf().decorate({
|
|
5294
5334
|
session,
|
|
5295
|
-
to:
|
|
5296
|
-
materializedPath: stagingRoot === undefined ? canonicalTranscriptPath(
|
|
5335
|
+
to: plan2.to,
|
|
5336
|
+
materializedPath: stagingRoot === undefined ? canonicalTranscriptPath(winterHome2, session) : materializedTranscriptPath(stagingRoot, session),
|
|
5297
5337
|
decoration: {
|
|
5298
5338
|
kind: "handoff",
|
|
5299
|
-
from:
|
|
5339
|
+
from: plan2.from,
|
|
5300
5340
|
at: now().toISOString(),
|
|
5301
|
-
text: (deps.noteText ?? defaultNoteText)({ from:
|
|
5341
|
+
text: (deps.noteText ?? defaultNoteText)({ from: plan2.from, to: plan2.to, session })
|
|
5302
5342
|
}
|
|
5303
5343
|
});
|
|
5304
5344
|
target = {
|
|
5305
5345
|
address: entry.address,
|
|
5306
|
-
runtimeKind:
|
|
5346
|
+
runtimeKind: plan2.to,
|
|
5307
5347
|
backendSessionId: session.sessionId,
|
|
5308
5348
|
projectKey: session.projectKey,
|
|
5309
5349
|
compatibilityLevel: level,
|
|
@@ -5311,9 +5351,9 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5311
5351
|
...stagingRoot === undefined ? {} : { stagingRoot, profile: "store-backed-resume" },
|
|
5312
5352
|
effectiveTempDir: continuity.effectiveTempDir,
|
|
5313
5353
|
door: decorated.door,
|
|
5314
|
-
selection:
|
|
5354
|
+
selection: plan2.selection.selection
|
|
5315
5355
|
};
|
|
5316
|
-
const destination = await deps.participants?.destination?.(session,
|
|
5356
|
+
const destination = await deps.participants?.destination?.(session, plan2.to) ?? undefined;
|
|
5317
5357
|
if (destination === undefined) {
|
|
5318
5358
|
await unwind();
|
|
5319
5359
|
return lossy(8, "no destination runtime confirmed the resumed session and level, and the next user message must not be delivered until one does");
|
|
@@ -5334,7 +5374,7 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5334
5374
|
await unwind();
|
|
5335
5375
|
const reason = `the destination confirmed init but the producer record could not be written: ${error instanceof Error ? error.message : String(error)}`;
|
|
5336
5376
|
const enriched = target?.stagingRoot === undefined ? reason : `${reason}. The destination is reading ${target.stagingRoot}; that staging copy is retained deliberately and belongs to the host's retention pass.`;
|
|
5337
|
-
|
|
5377
|
+
record2(8, false, enriched);
|
|
5338
5378
|
return {
|
|
5339
5379
|
kind: "lossy-fork-offered",
|
|
5340
5380
|
reason,
|
|
@@ -5346,7 +5386,7 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5346
5386
|
}
|
|
5347
5387
|
const notes = [];
|
|
5348
5388
|
try {
|
|
5349
|
-
await syncDirectoryEntry({ context, entry, plan, staged, now: now() });
|
|
5389
|
+
await syncDirectoryEntry({ context, entry, plan: plan2, staged, now: now() });
|
|
5350
5390
|
} catch (error) {
|
|
5351
5391
|
notes.push(`the host directory's derived copy is behind and will be repaired on the next plan(): ${error instanceof Error ? error.message : String(error)}`);
|
|
5352
5392
|
}
|
|
@@ -5358,12 +5398,12 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5358
5398
|
notes.push(`the labelled handoff note could not be appended: ${error instanceof Error ? error.message : String(error)}`);
|
|
5359
5399
|
}
|
|
5360
5400
|
}
|
|
5361
|
-
|
|
5401
|
+
record2(8, true, confirmed.detail ?? `the destination confirmed ${session.sessionId} at level ${level}, and ownership moved`);
|
|
5362
5402
|
return {
|
|
5363
5403
|
kind: "resumed",
|
|
5364
|
-
selection:
|
|
5404
|
+
selection: plan2.selection.selection,
|
|
5365
5405
|
step: 8,
|
|
5366
|
-
detail: `the session resumed on ${
|
|
5406
|
+
detail: `the session resumed on ${plan2.to} at level ${level} through the ${decorated.door} decoration door${notes.length === 0 ? "" : ` — ${notes.join("; ")}`}`,
|
|
5367
5407
|
target,
|
|
5368
5408
|
steps: trail
|
|
5369
5409
|
};
|
|
@@ -5372,9 +5412,9 @@ function createHandoffBarrier(context, deps = {}) {
|
|
|
5372
5412
|
if (committed && entry !== undefined) {
|
|
5373
5413
|
return {
|
|
5374
5414
|
kind: "resumed",
|
|
5375
|
-
selection:
|
|
5415
|
+
selection: plan2.selection.selection,
|
|
5376
5416
|
step: 8,
|
|
5377
|
-
detail: `the session resumed on ${
|
|
5417
|
+
detail: `the session resumed on ${plan2.to}, but the barrier failed afterwards: ${detail}`,
|
|
5378
5418
|
...target === undefined ? {} : { target },
|
|
5379
5419
|
steps: trail
|
|
5380
5420
|
};
|
|
@@ -5423,8 +5463,8 @@ async function compareAgainstLocalRoot(args) {
|
|
|
5423
5463
|
continue;
|
|
5424
5464
|
compared += 1;
|
|
5425
5465
|
const entries = await args.shared.store.load(key) ?? [];
|
|
5426
|
-
const
|
|
5427
|
-
const comparison = compareTranscriptTail({ localPath, canonicalLines, isDecoration: (uuid) => args.shared.decorations.has(args.session, uuid) });
|
|
5466
|
+
const canonicalLines2 = entries.filter((entry) => entry["type"] !== "agent_metadata").map((entry) => JSON.stringify(entry));
|
|
5467
|
+
const comparison = compareTranscriptTail({ localPath, canonicalLines: canonicalLines2, isDecoration: (uuid) => args.shared.decorations.has(args.session, uuid) });
|
|
5428
5468
|
const what = key.subpath === undefined ? "the session's transcript" : `subkey ${key.subpath}`;
|
|
5429
5469
|
switch (comparison.kind) {
|
|
5430
5470
|
case "match":
|
|
@@ -5605,7 +5645,7 @@ async function markHandoffPending(args) {
|
|
|
5605
5645
|
const chainable = entries.filter((entry) => typeof entry["uuid"] === "string");
|
|
5606
5646
|
const cursor = chainable[chainable.length - 1]?.["uuid"] ?? "";
|
|
5607
5647
|
const health = args.shared.health(args.session);
|
|
5608
|
-
const
|
|
5648
|
+
const record2 = {
|
|
5609
5649
|
type: DIALECT_RECORD_ENTRY_TYPE,
|
|
5610
5650
|
backendSessionId: args.session.sessionId,
|
|
5611
5651
|
transcriptProjectKey: args.session.projectKey,
|
|
@@ -5625,18 +5665,18 @@ async function markHandoffPending(args) {
|
|
|
5625
5665
|
}
|
|
5626
5666
|
]);
|
|
5627
5667
|
await args.shared.settle(args.session);
|
|
5628
|
-
return { cursor, stagingUuid: cryptoRandomUuid(), record };
|
|
5668
|
+
return { cursor, stagingUuid: cryptoRandomUuid(), record: record2 };
|
|
5629
5669
|
}
|
|
5630
5670
|
async function commitProducerRecord(args) {
|
|
5631
|
-
const
|
|
5671
|
+
const record2 = {
|
|
5632
5672
|
...args.staged.record,
|
|
5633
5673
|
...args.producer?.sdkVersion === undefined ? {} : { producerSdkVersion: args.producer.sdkVersion },
|
|
5634
5674
|
...args.producer?.engineVersion === undefined ? {} : { producerEngineVersion: args.producer.engineVersion }
|
|
5635
5675
|
};
|
|
5636
|
-
await args.shared.store.append(args.session, [
|
|
5676
|
+
await args.shared.store.append(args.session, [record2]);
|
|
5637
5677
|
await args.shared.settle(args.session);
|
|
5638
5678
|
const summary = await args.shared.canonical.readSessionSummary({ projectKey: args.session.projectKey, sessionId: args.session.sessionId });
|
|
5639
|
-
if (summary?.["producerRuntime"] !==
|
|
5679
|
+
if (summary?.["producerRuntime"] !== record2["producerRuntime"]) {
|
|
5640
5680
|
throw new HandoffCommitError(`the producer record did not land: the summary still names ${String(summary?.["producerRuntime"] ?? "no producer")}`);
|
|
5641
5681
|
}
|
|
5642
5682
|
}
|
|
@@ -6337,7 +6377,7 @@ class SelectionRefusedError extends RuntimeSdkError {
|
|
|
6337
6377
|
import { createRequire as createRequire2 } from "node:module";
|
|
6338
6378
|
import { dirname as dirname2, join as join7 } from "node:path";
|
|
6339
6379
|
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
|
|
6340
|
-
var SUPPORTED = { winterAgentSdk: ">=0.0.
|
|
6380
|
+
var SUPPORTED = { winterAgentSdk: ">=0.0.3 <0.1.0", claudeAgentSdk: "0.3.250" };
|
|
6341
6381
|
var SUPPORTED_PROTOCOL_VERSIONS = ["1.0"];
|
|
6342
6382
|
function parseVersion(raw) {
|
|
6343
6383
|
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(raw.trim());
|
|
@@ -6400,18 +6440,17 @@ var VERSION_EXPORT_NAMES = ["SDK_VERSION", "VERSION", "PACKAGE_VERSION", "versio
|
|
|
6400
6440
|
function readExportedVersion(namespace) {
|
|
6401
6441
|
if (typeof namespace !== "object" || namespace === null)
|
|
6402
6442
|
return;
|
|
6403
|
-
const
|
|
6443
|
+
const record2 = namespace;
|
|
6404
6444
|
for (const name of VERSION_EXPORT_NAMES) {
|
|
6405
|
-
const value =
|
|
6445
|
+
const value = record2[name];
|
|
6406
6446
|
if (typeof value === "string" && parseVersion(value) !== undefined)
|
|
6407
6447
|
return value;
|
|
6408
6448
|
}
|
|
6409
6449
|
return;
|
|
6410
6450
|
}
|
|
6411
|
-
function readResolvedManifestVersion(packageName) {
|
|
6451
|
+
function readResolvedManifestVersion(packageName, resolveEntry = (name) => createRequire2(import.meta.url).resolve(name)) {
|
|
6412
6452
|
try {
|
|
6413
|
-
|
|
6414
|
-
let dir = dirname2(require2.resolve(packageName));
|
|
6453
|
+
let dir = dirname2(resolveEntry(packageName));
|
|
6415
6454
|
for (let depth = 0;depth < 10; depth++) {
|
|
6416
6455
|
const manifest = join7(dir, "package.json");
|
|
6417
6456
|
if (existsSync4(manifest)) {
|
|
@@ -6429,19 +6468,25 @@ function readResolvedManifestVersion(packageName) {
|
|
|
6429
6468
|
return;
|
|
6430
6469
|
}
|
|
6431
6470
|
}
|
|
6432
|
-
function identityFor(packageName, namespace, supported) {
|
|
6471
|
+
function identityFor(packageName, namespace, supported, declared, seams) {
|
|
6472
|
+
if (declared !== undefined && parseVersion(declared) !== undefined) {
|
|
6473
|
+
return { packageName, packageVersion: declared, source: "host-declared", supported };
|
|
6474
|
+
}
|
|
6433
6475
|
const exported = readExportedVersion(namespace);
|
|
6434
6476
|
if (exported !== undefined)
|
|
6435
6477
|
return { packageName, packageVersion: exported, source: "peer-export", supported };
|
|
6436
|
-
const resolved = readResolvedManifestVersion(packageName);
|
|
6478
|
+
const resolved = readResolvedManifestVersion(packageName, seams.resolveEntry);
|
|
6437
6479
|
if (resolved !== undefined)
|
|
6438
6480
|
return { packageName, packageVersion: resolved, source: "resolved-manifest", supported };
|
|
6439
6481
|
return;
|
|
6440
6482
|
}
|
|
6441
6483
|
var UNKNOWN_ACTUAL = "unknown (the injected module exports no version identity and no installed copy could be resolved)";
|
|
6442
|
-
function assertVersionMatrix(peers) {
|
|
6484
|
+
function assertVersionMatrix(peers, declared) {
|
|
6485
|
+
return resolveVersionMatrix(peers, declared);
|
|
6486
|
+
}
|
|
6487
|
+
function resolveVersionMatrix(peers, declared, seams = {}) {
|
|
6443
6488
|
const winterName = "@yanlinglabs/winter-agent-sdk";
|
|
6444
|
-
const winterIdentity = identityFor(winterName, peers.winter, SUPPORTED.winterAgentSdk);
|
|
6489
|
+
const winterIdentity = identityFor(winterName, peers.winter, SUPPORTED.winterAgentSdk, declared?.winterAgentSdk, seams);
|
|
6445
6490
|
if (winterIdentity === undefined) {
|
|
6446
6491
|
throw new RuntimeSdkVersionError({ expected: `${winterName} ${SUPPORTED.winterAgentSdk}`, actual: UNKNOWN_ACTUAL });
|
|
6447
6492
|
}
|
|
@@ -6470,7 +6515,7 @@ function assertVersionMatrix(peers) {
|
|
|
6470
6515
|
if (peers.claude === undefined)
|
|
6471
6516
|
return report;
|
|
6472
6517
|
const claudeName = "@anthropic-ai/claude-agent-sdk";
|
|
6473
|
-
const claudeIdentity = identityFor(claudeName, peers.claude, SUPPORTED.claudeAgentSdk);
|
|
6518
|
+
const claudeIdentity = identityFor(claudeName, peers.claude, SUPPORTED.claudeAgentSdk, declared?.claudeAgentSdk, seams);
|
|
6474
6519
|
if (claudeIdentity === undefined) {
|
|
6475
6520
|
throw new RuntimeSdkVersionError({ expected: `${claudeName} ${SUPPORTED.claudeAgentSdk}`, actual: UNKNOWN_ACTUAL });
|
|
6476
6521
|
}
|
|
@@ -6486,10 +6531,10 @@ function runtimeSdkInternals(sdk) {
|
|
|
6486
6531
|
return sdk[INTERNALS];
|
|
6487
6532
|
}
|
|
6488
6533
|
var INTERNALS = Symbol.for("winter-runtime-sdk.internals");
|
|
6489
|
-
function forwardableOptions(options, brand) {
|
|
6534
|
+
function forwardableOptions(options, brand, capabilityServers) {
|
|
6490
6535
|
const stripKeys = ROUTER_ONLY_OPTION_KEYS.filter((key) => (key in options));
|
|
6491
6536
|
const injectBrand = brand !== undefined && options.brand === undefined;
|
|
6492
|
-
if (stripKeys.length === 0 && !injectBrand)
|
|
6537
|
+
if (stripKeys.length === 0 && !injectBrand && capabilityServers === undefined)
|
|
6493
6538
|
return options;
|
|
6494
6539
|
const forwarded = {};
|
|
6495
6540
|
for (const key of Object.keys(options)) {
|
|
@@ -6499,15 +6544,51 @@ function forwardableOptions(options, brand) {
|
|
|
6499
6544
|
}
|
|
6500
6545
|
if (injectBrand)
|
|
6501
6546
|
forwarded["brand"] = brand;
|
|
6547
|
+
if (capabilityServers !== undefined)
|
|
6548
|
+
forwarded["mcpServers"] = mergedMcpServers(options.mcpServers, capabilityServers);
|
|
6502
6549
|
return forwarded;
|
|
6503
6550
|
}
|
|
6551
|
+
function mergedMcpServers(callerOwned, capabilityServers) {
|
|
6552
|
+
if (callerOwned === undefined)
|
|
6553
|
+
return capabilityServers;
|
|
6554
|
+
assertNoCapabilityCollision(callerOwned, capabilityServers);
|
|
6555
|
+
return { ...callerOwned, ...capabilityServers };
|
|
6556
|
+
}
|
|
6557
|
+
function assertNoCapabilityCollision(callerOwned, capabilityServers) {
|
|
6558
|
+
if (callerOwned === undefined)
|
|
6559
|
+
return;
|
|
6560
|
+
for (const name of Object.keys(capabilityServers)) {
|
|
6561
|
+
if (name in callerOwned)
|
|
6562
|
+
throw capabilityNameCollisionError({ field: "mcpServers", name });
|
|
6563
|
+
}
|
|
6564
|
+
}
|
|
6565
|
+
function capabilityServerRecord(capabilities, brand) {
|
|
6566
|
+
if (capabilities === undefined || capabilities.length === 0)
|
|
6567
|
+
return;
|
|
6568
|
+
const record2 = {};
|
|
6569
|
+
for (const server of capabilities) {
|
|
6570
|
+
if (server.name === brand.mcpServerName) {
|
|
6571
|
+
throw new RuntimeLaunchInputError({
|
|
6572
|
+
field: "capabilities",
|
|
6573
|
+
reason: `\`${server.name}\` is the brand's own standing-server name, which the router registers the messaging tools under on the official branch — a capability server may not claim it (WS-09 §1.3)`
|
|
6574
|
+
});
|
|
6575
|
+
}
|
|
6576
|
+
if (server.name in record2) {
|
|
6577
|
+
throw new RuntimeLaunchInputError({ field: "capabilities", reason: `two capability servers are named \`${server.name}\`, so one of them would never be registered` });
|
|
6578
|
+
}
|
|
6579
|
+
record2[server.name] = server;
|
|
6580
|
+
}
|
|
6581
|
+
return record2;
|
|
6582
|
+
}
|
|
6504
6583
|
function createRuntimeSdk(opts) {
|
|
6505
|
-
const versions = assertVersionMatrix(opts.peers);
|
|
6584
|
+
const versions = assertVersionMatrix(opts.peers, opts.peerVersions);
|
|
6506
6585
|
const resolved = opts.peers.winter.resolveBrand(opts.brand);
|
|
6507
6586
|
if (!resolved.ok)
|
|
6508
6587
|
throw new opts.peers.winter.InvalidBrandError(resolved.reason);
|
|
6509
6588
|
const brand = resolved.brand;
|
|
6510
6589
|
const directoryStore = opts.directoryStore ?? createInMemoryRuntimeDirectoryStore();
|
|
6590
|
+
const capabilityServers = capabilityServerRecord(opts.capabilities, brand);
|
|
6591
|
+
const capabilityDescriptors = opts.capabilities === undefined || opts.capabilities.length === 0 ? undefined : capabilityServerDescriptors(opts.capabilities);
|
|
6511
6592
|
const base = {
|
|
6512
6593
|
peers: opts.peers,
|
|
6513
6594
|
keychain: opts.keychain,
|
|
@@ -6554,6 +6635,8 @@ function createRuntimeSdk(opts) {
|
|
|
6554
6635
|
const queryImpl = (args) => {
|
|
6555
6636
|
assertLive("query");
|
|
6556
6637
|
const options = args.options ?? {};
|
|
6638
|
+
if (capabilityServers !== undefined)
|
|
6639
|
+
assertNoCapabilityCollision(options.mcpServers, capabilityServers);
|
|
6557
6640
|
const runtime = options.runtime;
|
|
6558
6641
|
const decided = runtime === undefined ? undefined : runtime.selection ?? (runtime.select === undefined ? undefined : decide(runtime.select));
|
|
6559
6642
|
const ledgerKey = runtime?.official !== undefined ? officialLegAddress(runtime.official) : runtime?.sessionId === undefined ? undefined : sessionLedgerKey(runtime.sessionId);
|
|
@@ -6584,10 +6667,14 @@ function createRuntimeSdk(opts) {
|
|
|
6584
6667
|
transcriptProjectKey,
|
|
6585
6668
|
...opts.vendoredOfficialRuntime === undefined ? {} : { vendoredOfficialRuntime: opts.vendoredOfficialRuntime },
|
|
6586
6669
|
...opts.official === undefined ? {} : { policy: opts.official },
|
|
6670
|
+
...capabilityDescriptors === undefined ? {} : { capabilities: capabilityDescriptors },
|
|
6671
|
+
...opts.toInputShape === undefined ? {} : { toInputShape: opts.toInputShape },
|
|
6672
|
+
...opts.peers.claude === undefined ? {} : { mcpModule: opts.peers.claude },
|
|
6673
|
+
...opts.advisor === undefined ? {} : { advisor: opts.advisor },
|
|
6587
6674
|
onOpened: noteOpened
|
|
6588
6675
|
}, { prompt: args.prompt, options: forwardableOptions(options, opts.brand === undefined ? undefined : brand), input: official, selection: decided });
|
|
6589
6676
|
}
|
|
6590
|
-
const winterQuery = opts.peers.winter.query({ prompt: args.prompt, options: forwardableOptions(options, opts.brand === undefined ? undefined : brand) });
|
|
6677
|
+
const winterQuery = opts.peers.winter.query({ prompt: args.prompt, options: forwardableOptions(options, opts.brand === undefined ? undefined : brand, capabilityServers) });
|
|
6591
6678
|
noteOpened("winter-agent");
|
|
6592
6679
|
return winterQuery;
|
|
6593
6680
|
};
|
|
@@ -6617,63 +6704,54 @@ function createRuntimeSdk(opts) {
|
|
|
6617
6704
|
return sdk;
|
|
6618
6705
|
}
|
|
6619
6706
|
export {
|
|
6620
|
-
|
|
6621
|
-
D14_CLAUDE_OAUTH_APPROVED_DEFAULT,
|
|
6622
|
-
EXECUTION_INDIRECTION_ENV_NAMES,
|
|
6623
|
-
EXECUTION_INDIRECTION_ENV_PREFIXES,
|
|
6624
|
-
LIST_AGENTS_FIELD_MAX,
|
|
6625
|
-
MATERIALIZED_RESUME_PROBE_REPORTS,
|
|
6626
|
-
NATIVE_LIST_AGENTS_OUTPUT_SCHEMA,
|
|
6627
|
-
NATIVE_LIST_AGENTS_SCHEMA,
|
|
6628
|
-
NATIVE_SEND_MESSAGE_SCHEMA,
|
|
6629
|
-
NotImplementedYet,
|
|
6630
|
-
RESUME_STAGING_PREFIX,
|
|
6631
|
-
ROUTER_ONLY_OPTION_KEYS,
|
|
6632
|
-
RuntimeHandoffRequiredError,
|
|
6633
|
-
RuntimeLaunchInputError,
|
|
6634
|
-
RuntimeSdkDisposedError,
|
|
6635
|
-
RuntimeSdkError,
|
|
6636
|
-
RuntimeSdkVersionError,
|
|
6637
|
-
SELECTION_RULES,
|
|
6638
|
-
SEND_MESSAGE_SUMMARY_MAX,
|
|
6639
|
-
SEND_MESSAGE_TO_MAX,
|
|
6640
|
-
SUPPORTED,
|
|
6641
|
-
SUPPORTED_PROTOCOL_VERSIONS,
|
|
6642
|
-
SelectionRefusedError,
|
|
6643
|
-
TRAFFIC_OPT_OUT_VARIABLES,
|
|
6644
|
-
TRAFFIC_OPT_OUT_VARIABLE_NAMES,
|
|
6645
|
-
UNKNOWN_VERSION,
|
|
6646
|
-
UnaddressableEntryError,
|
|
6647
|
-
VERSION_EXPORT_NAMES,
|
|
6648
|
-
acceptNativeListAgentsArgs,
|
|
6649
|
-
acceptNativeSendMessageArgs,
|
|
6650
|
-
assertVersionMatrix,
|
|
6651
|
-
createAttachedSessionRegistry,
|
|
6652
|
-
createInMemoryRuntimeDirectoryStore,
|
|
6653
|
-
createMessagingToolHandlers,
|
|
6654
|
-
createOfficialInputStream,
|
|
6655
|
-
createRuntimeMessaging,
|
|
6656
|
-
createRuntimeSdk,
|
|
6657
|
-
forwardableOptions,
|
|
6658
|
-
isExecutionIndirectionVariable,
|
|
6659
|
-
isOfficialQuery,
|
|
6660
|
-
isResumeStagingRoot,
|
|
6661
|
-
isSelectionRefusal,
|
|
6662
|
-
materializedResumeReportForPin,
|
|
6663
|
-
officialConnectionEnv,
|
|
6664
|
-
officialCredentialPlan,
|
|
6665
|
-
officialUserTurn,
|
|
6666
|
-
parseVersion,
|
|
6667
|
-
readExportedVersion,
|
|
6668
|
-
readResolvedManifestVersion,
|
|
6669
|
-
resumeChildSelection,
|
|
6670
|
-
resumeStagingRoot,
|
|
6671
|
-
reviewPersistedSelection,
|
|
6672
|
-
ruleIdOf,
|
|
6673
|
-
runtimeSdkInternals,
|
|
6674
|
-
satisfiesRange,
|
|
6675
|
-
selectChildRuntime,
|
|
6676
|
-
selectChildRuntimePairing,
|
|
6707
|
+
selectionVersionsFrom,
|
|
6677
6708
|
selectRuntime,
|
|
6678
|
-
|
|
6709
|
+
selectChildRuntimePairing,
|
|
6710
|
+
selectChildRuntime,
|
|
6711
|
+
satisfiesRange,
|
|
6712
|
+
runtimeSdkInternals,
|
|
6713
|
+
ruleIdOf,
|
|
6714
|
+
reviewPersistedSelection,
|
|
6715
|
+
resumeStagingRoot,
|
|
6716
|
+
resumeChildSelection,
|
|
6717
|
+
readResolvedManifestVersion,
|
|
6718
|
+
readExportedVersion,
|
|
6719
|
+
parseVersion,
|
|
6720
|
+
officialUserTurn,
|
|
6721
|
+
officialCredentialPlan,
|
|
6722
|
+
officialConnectionEnv,
|
|
6723
|
+
materializedResumeReportForPin,
|
|
6724
|
+
isSelectionRefusal,
|
|
6725
|
+
isResumeStagingRoot,
|
|
6726
|
+
isOfficialQuery,
|
|
6727
|
+
isExecutionIndirectionVariable,
|
|
6728
|
+
forwardableOptions,
|
|
6729
|
+
createRuntimeSdk,
|
|
6730
|
+
createRuntimeMessaging,
|
|
6731
|
+
createOfficialInputStream,
|
|
6732
|
+
createInMemoryRuntimeDirectoryStore,
|
|
6733
|
+
createAttachedSessionRegistry,
|
|
6734
|
+
assertVersionMatrix,
|
|
6735
|
+
VERSION_EXPORT_NAMES,
|
|
6736
|
+
UnaddressableEntryError,
|
|
6737
|
+
UNKNOWN_VERSION,
|
|
6738
|
+
TRAFFIC_OPT_OUT_VARIABLE_NAMES,
|
|
6739
|
+
TRAFFIC_OPT_OUT_VARIABLES,
|
|
6740
|
+
SelectionRefusedError,
|
|
6741
|
+
SUPPORTED_PROTOCOL_VERSIONS,
|
|
6742
|
+
SUPPORTED,
|
|
6743
|
+
SELECTION_RULES,
|
|
6744
|
+
RuntimeSdkVersionError,
|
|
6745
|
+
RuntimeSdkError,
|
|
6746
|
+
RuntimeSdkDisposedError,
|
|
6747
|
+
RuntimeLaunchInputError,
|
|
6748
|
+
RuntimeHandoffRequiredError,
|
|
6749
|
+
ROUTER_ONLY_OPTION_KEYS,
|
|
6750
|
+
RESUME_STAGING_PREFIX,
|
|
6751
|
+
NotImplementedYet,
|
|
6752
|
+
MATERIALIZED_RESUME_PROBE_REPORTS,
|
|
6753
|
+
EXECUTION_INDIRECTION_ENV_PREFIXES,
|
|
6754
|
+
EXECUTION_INDIRECTION_ENV_NAMES,
|
|
6755
|
+
D14_CLAUDE_OAUTH_APPROVED_DEFAULT,
|
|
6756
|
+
CHILD_PROVIDER_UNAVAILABLE
|
|
6679
6757
|
};
|