@opengeni/runtime 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,292 @@
1
+ // src/mcp-network.ts
2
+ import {
3
+ isNonPublicAddress,
4
+ pinnedFetch,
5
+ resolvePinnedDestination
6
+ } from "@opengeni/network";
7
+ import { undiciFetch } from "@opengeni/network";
8
+ var MCP_MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
9
+ var MCP_MAX_INBOUND_REQUEST_BYTES = 1024 * 1024;
10
+ var MCP_MAX_TOOL_DEFINITION_BYTES = 128 * 1024;
11
+ var MCP_MAX_TOOL_LIST_BYTES = 4 * 1024 * 1024;
12
+ var MCP_MAX_TOOL_LIST_ENTRIES = 1e3;
13
+ var MCP_MAX_TOOL_RESULT_BYTES = 1024 * 1024;
14
+ var MCP_MAX_TOOL_SEARCH_DISCLOSURE_BYTES = 256 * 1024;
15
+ var MCP_MAX_SELECTED_SERVERS = 64;
16
+ var MCP_MAX_CONCURRENT_SERVER_OPERATIONS = 8;
17
+ var MCP_MAX_AGGREGATE_TOOL_LIST_ENTRIES = 4096;
18
+ var MCP_MAX_AGGREGATE_TOOL_LIST_BYTES = 16 * 1024 * 1024;
19
+ var MCP_MAX_TOOL_SEARCH_SOURCES = 64;
20
+ var MCP_MAX_TOOL_SEARCH_SOURCE_LABEL_LENGTH = 120;
21
+ var MCP_MAX_TOOL_SEARCH_DESCRIPTION_BYTES = 16 * 1024;
22
+ var McpPayloadTooLargeError = class extends Error {
23
+ constructor(label, actualBytes, maxBytes) {
24
+ super(`${label} exceeds the ${maxBytes}-byte safety limit`);
25
+ this.label = label;
26
+ this.actualBytes = actualBytes;
27
+ this.maxBytes = maxBytes;
28
+ this.name = "McpPayloadTooLargeError";
29
+ }
30
+ };
31
+ function mcpSerializedSizeBytes(value) {
32
+ let serialized;
33
+ try {
34
+ serialized = JSON.stringify(value) ?? "null";
35
+ } catch {
36
+ throw new Error("MCP payload is not JSON serializable");
37
+ }
38
+ return Buffer.byteLength(serialized);
39
+ }
40
+ function assertMcpPayloadWithinBytes(value, maxBytes, label) {
41
+ const actualBytes = mcpSerializedSizeBytes(value);
42
+ if (actualBytes > maxBytes) {
43
+ throw new McpPayloadTooLargeError(label, actualBytes, maxBytes);
44
+ }
45
+ }
46
+ function assertMcpToolListWithinBounds(tools) {
47
+ if (tools.length > MCP_MAX_TOOL_LIST_ENTRIES) {
48
+ throw new McpPayloadTooLargeError("MCP tool list", tools.length, MCP_MAX_TOOL_LIST_ENTRIES);
49
+ }
50
+ for (const tool of tools) {
51
+ const toolBytes = mcpSerializedSizeBytes(tool);
52
+ if (toolBytes > MCP_MAX_TOOL_DEFINITION_BYTES) {
53
+ throw new McpPayloadTooLargeError(
54
+ "MCP tool definition",
55
+ toolBytes,
56
+ MCP_MAX_TOOL_DEFINITION_BYTES
57
+ );
58
+ }
59
+ }
60
+ const totalBytes = mcpSerializedSizeBytes(tools);
61
+ if (totalBytes > MCP_MAX_TOOL_LIST_BYTES) {
62
+ throw new McpPayloadTooLargeError("MCP tool list", totalBytes, MCP_MAX_TOOL_LIST_BYTES);
63
+ }
64
+ return tools;
65
+ }
66
+ function assertMcpServerSelectionWithinBounds(servers) {
67
+ if (servers.length > MCP_MAX_SELECTED_SERVERS) {
68
+ throw new McpPayloadTooLargeError(
69
+ "selected MCP server count",
70
+ servers.length,
71
+ MCP_MAX_SELECTED_SERVERS
72
+ );
73
+ }
74
+ return servers;
75
+ }
76
+ var McpAggregateToolListBudget = class {
77
+ constructor(label = "aggregate MCP tool list", maxEntries = MCP_MAX_AGGREGATE_TOOL_LIST_ENTRIES, maxBytes = MCP_MAX_AGGREGATE_TOOL_LIST_BYTES) {
78
+ this.label = label;
79
+ this.maxEntries = maxEntries;
80
+ this.maxBytes = maxBytes;
81
+ }
82
+ contributions = /* @__PURE__ */ new Map();
83
+ totalEntries = 0;
84
+ totalBytes = 0;
85
+ replace(sourceId, tools) {
86
+ assertMcpToolListWithinBounds(tools);
87
+ const contribution = {
88
+ entries: tools.length,
89
+ // Conservatively account each server as its complete serialized array.
90
+ // Summing these arrays slightly over-counts the brackets relative to one
91
+ // flattened array, which is intentional for a fail-closed hard ceiling.
92
+ bytes: mcpSerializedSizeBytes(tools)
93
+ };
94
+ const previous = this.contributions.get(sourceId) ?? { entries: 0, bytes: 0 };
95
+ const nextEntries = this.totalEntries - previous.entries + contribution.entries;
96
+ if (nextEntries > this.maxEntries) {
97
+ throw new McpPayloadTooLargeError(this.label, nextEntries, this.maxEntries);
98
+ }
99
+ const nextBytes = this.totalBytes - previous.bytes + contribution.bytes;
100
+ if (nextBytes > this.maxBytes) {
101
+ throw new McpPayloadTooLargeError(this.label, nextBytes, this.maxBytes);
102
+ }
103
+ this.contributions.set(sourceId, contribution);
104
+ this.totalEntries = nextEntries;
105
+ this.totalBytes = nextBytes;
106
+ return tools;
107
+ }
108
+ remove(sourceId) {
109
+ const previous = this.contributions.get(sourceId);
110
+ if (!previous) return;
111
+ this.contributions.delete(sourceId);
112
+ this.totalEntries -= previous.entries;
113
+ this.totalBytes -= previous.bytes;
114
+ }
115
+ snapshot() {
116
+ return { entries: this.totalEntries, bytes: this.totalBytes };
117
+ }
118
+ };
119
+ async function boundedParallelMap(values, concurrency, mapper) {
120
+ if (!Number.isInteger(concurrency) || concurrency < 1) {
121
+ throw new Error("bounded parallel map concurrency must be a positive integer");
122
+ }
123
+ if (values.length === 0) return [];
124
+ const results = new Array(values.length);
125
+ const errors = [];
126
+ let nextIndex = 0;
127
+ let stopped = false;
128
+ const worker = async () => {
129
+ while (!stopped) {
130
+ const index = nextIndex;
131
+ if (index >= values.length) return;
132
+ nextIndex += 1;
133
+ try {
134
+ results[index] = await mapper(values[index], index);
135
+ } catch (error) {
136
+ errors.push({ index, error });
137
+ stopped = true;
138
+ }
139
+ }
140
+ };
141
+ await Promise.all(Array.from({ length: Math.min(concurrency, values.length) }, () => worker()));
142
+ if (errors.length > 0) {
143
+ errors.sort((left, right) => left.index - right.index);
144
+ throw errors[0].error;
145
+ }
146
+ return results;
147
+ }
148
+ function guardedMcpFetch(settings, fetchImpl, options = {}) {
149
+ return async (input, init) => {
150
+ const response = await pinnedFetch(input, init, settings, {
151
+ fetchImpl,
152
+ ...options.dnsLookup ? { dnsLookup: options.dnsLookup } : {},
153
+ label: "MCP endpoint",
154
+ requireHttpsOutsideLocalTest: options.requireHttpsOutsideLocalTest ?? true
155
+ });
156
+ return boundMcpResponseBody(response, options.maxResponseBytes ?? MCP_MAX_RESPONSE_BYTES);
157
+ };
158
+ }
159
+ function boundMcpResponseBody(response, maxBytes) {
160
+ const declaredLength = Number(response.headers.get("content-length"));
161
+ if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
162
+ void response.body?.cancel().catch(() => void 0);
163
+ throw new McpPayloadTooLargeError("MCP response", declaredLength, maxBytes);
164
+ }
165
+ if (!response.body) {
166
+ return response;
167
+ }
168
+ const reader = response.body.getReader();
169
+ let receivedBytes = 0;
170
+ const body = new ReadableStream({
171
+ async pull(controller) {
172
+ try {
173
+ const chunk = await reader.read();
174
+ if (chunk.done) {
175
+ controller.close();
176
+ return;
177
+ }
178
+ receivedBytes += chunk.value.byteLength;
179
+ if (receivedBytes > maxBytes) {
180
+ await reader.cancel().catch(() => void 0);
181
+ controller.error(new McpPayloadTooLargeError("MCP response", receivedBytes, maxBytes));
182
+ return;
183
+ }
184
+ controller.enqueue(chunk.value);
185
+ } catch (error) {
186
+ controller.error(error);
187
+ }
188
+ },
189
+ async cancel(reason) {
190
+ await reader.cancel(reason).catch(() => void 0);
191
+ }
192
+ });
193
+ const bounded = new Response(body, {
194
+ status: response.status,
195
+ statusText: response.statusText,
196
+ headers: response.headers
197
+ });
198
+ Object.defineProperties(bounded, {
199
+ redirected: { value: response.redirected },
200
+ type: { value: response.type },
201
+ url: { value: response.url }
202
+ });
203
+ return bounded;
204
+ }
205
+ async function cancelMcpResponseBody(response) {
206
+ await response.body?.cancel().catch(() => void 0);
207
+ }
208
+ async function boundedMcpRequest(request, maxBytes = MCP_MAX_INBOUND_REQUEST_BYTES) {
209
+ const declared = request.headers.get("content-length");
210
+ if (declared !== null) {
211
+ const normalized = declared.trim();
212
+ if (!/^\d+$/.test(normalized)) {
213
+ await request.body?.cancel().catch(() => void 0);
214
+ throw new McpPayloadTooLargeError("MCP request", 0, maxBytes);
215
+ }
216
+ const declaredBytes = Number(normalized);
217
+ if (!Number.isSafeInteger(declaredBytes) || declaredBytes > maxBytes) {
218
+ await request.body?.cancel().catch(() => void 0);
219
+ throw new McpPayloadTooLargeError("MCP request", declaredBytes, maxBytes);
220
+ }
221
+ }
222
+ if (!request.body) {
223
+ return request;
224
+ }
225
+ const reader = request.body.getReader();
226
+ const chunks = [];
227
+ let receivedBytes = 0;
228
+ try {
229
+ for (; ; ) {
230
+ const result = await reader.read();
231
+ if (result.done) break;
232
+ receivedBytes += result.value.byteLength;
233
+ if (receivedBytes > maxBytes) {
234
+ await reader.cancel().catch(() => void 0);
235
+ throw new McpPayloadTooLargeError("MCP request", receivedBytes, maxBytes);
236
+ }
237
+ chunks.push(result.value);
238
+ }
239
+ } catch (error) {
240
+ await reader.cancel().catch(() => void 0);
241
+ throw error;
242
+ } finally {
243
+ reader.releaseLock();
244
+ }
245
+ const body = new Uint8Array(receivedBytes);
246
+ let offset = 0;
247
+ for (const chunk of chunks) {
248
+ body.set(chunk, offset);
249
+ offset += chunk.byteLength;
250
+ }
251
+ return new Request(request, { body, headers: request.headers });
252
+ }
253
+ async function assertMcpDestinationAllowed(rawUrl, settings, options = {}) {
254
+ await resolvePinnedDestination(rawUrl, settings, {
255
+ ...options.dnsLookup ? { dnsLookup: options.dnsLookup } : {},
256
+ label: "MCP endpoint",
257
+ requireHttpsOutsideLocalTest: true
258
+ });
259
+ }
260
+ var isNonPublicMcpAddress = isNonPublicAddress;
261
+
262
+ export {
263
+ MCP_MAX_RESPONSE_BYTES,
264
+ MCP_MAX_INBOUND_REQUEST_BYTES,
265
+ MCP_MAX_TOOL_DEFINITION_BYTES,
266
+ MCP_MAX_TOOL_LIST_BYTES,
267
+ MCP_MAX_TOOL_LIST_ENTRIES,
268
+ MCP_MAX_TOOL_RESULT_BYTES,
269
+ MCP_MAX_TOOL_SEARCH_DISCLOSURE_BYTES,
270
+ MCP_MAX_SELECTED_SERVERS,
271
+ MCP_MAX_CONCURRENT_SERVER_OPERATIONS,
272
+ MCP_MAX_AGGREGATE_TOOL_LIST_ENTRIES,
273
+ MCP_MAX_AGGREGATE_TOOL_LIST_BYTES,
274
+ MCP_MAX_TOOL_SEARCH_SOURCES,
275
+ MCP_MAX_TOOL_SEARCH_SOURCE_LABEL_LENGTH,
276
+ MCP_MAX_TOOL_SEARCH_DESCRIPTION_BYTES,
277
+ McpPayloadTooLargeError,
278
+ mcpSerializedSizeBytes,
279
+ assertMcpPayloadWithinBytes,
280
+ assertMcpToolListWithinBounds,
281
+ assertMcpServerSelectionWithinBounds,
282
+ McpAggregateToolListBudget,
283
+ boundedParallelMap,
284
+ guardedMcpFetch,
285
+ boundMcpResponseBody,
286
+ cancelMcpResponseBody,
287
+ boundedMcpRequest,
288
+ assertMcpDestinationAllowed,
289
+ isNonPublicMcpAddress,
290
+ undiciFetch
291
+ };
292
+ //# sourceMappingURL=chunk-HAN5D27J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp-network.ts"],"sourcesContent":["import type { Settings } from \"@opengeni/config\";\nimport {\n isNonPublicAddress,\n pinnedFetch,\n resolvePinnedDestination,\n type DnsLookup,\n type FetchLike,\n} from \"@opengeni/network\";\n\nexport { undiciFetch } from \"@opengeni/network\";\n\nexport const MCP_MAX_RESPONSE_BYTES = 8 * 1024 * 1024;\nexport const MCP_MAX_INBOUND_REQUEST_BYTES = 1024 * 1024;\nexport const MCP_MAX_TOOL_DEFINITION_BYTES = 128 * 1024;\nexport const MCP_MAX_TOOL_LIST_BYTES = 4 * 1024 * 1024;\nexport const MCP_MAX_TOOL_LIST_ENTRIES = 1_000;\nexport const MCP_MAX_TOOL_RESULT_BYTES = 1024 * 1024;\nexport const MCP_MAX_TOOL_SEARCH_DISCLOSURE_BYTES = 256 * 1024;\nexport const MCP_MAX_SELECTED_SERVERS = 64;\nexport const MCP_MAX_CONCURRENT_SERVER_OPERATIONS = 8;\nexport const MCP_MAX_AGGREGATE_TOOL_LIST_ENTRIES = 4_096;\nexport const MCP_MAX_AGGREGATE_TOOL_LIST_BYTES = 16 * 1024 * 1024;\nexport const MCP_MAX_TOOL_SEARCH_SOURCES = 64;\nexport const MCP_MAX_TOOL_SEARCH_SOURCE_LABEL_LENGTH = 120;\nexport const MCP_MAX_TOOL_SEARCH_DESCRIPTION_BYTES = 16 * 1024;\n\nexport class McpPayloadTooLargeError extends Error {\n constructor(\n readonly label: string,\n readonly actualBytes: number,\n readonly maxBytes: number,\n ) {\n super(`${label} exceeds the ${maxBytes}-byte safety limit`);\n this.name = \"McpPayloadTooLargeError\";\n }\n}\n\nexport function mcpSerializedSizeBytes(value: unknown): number {\n let serialized: string;\n try {\n serialized = JSON.stringify(value) ?? \"null\";\n } catch {\n throw new Error(\"MCP payload is not JSON serializable\");\n }\n return Buffer.byteLength(serialized);\n}\n\nexport function assertMcpPayloadWithinBytes(value: unknown, maxBytes: number, label: string): void {\n const actualBytes = mcpSerializedSizeBytes(value);\n if (actualBytes > maxBytes) {\n throw new McpPayloadTooLargeError(label, actualBytes, maxBytes);\n }\n}\n\nexport function assertMcpToolListWithinBounds<T>(tools: readonly T[]): readonly T[] {\n if (tools.length > MCP_MAX_TOOL_LIST_ENTRIES) {\n throw new McpPayloadTooLargeError(\"MCP tool list\", tools.length, MCP_MAX_TOOL_LIST_ENTRIES);\n }\n for (const tool of tools) {\n const toolBytes = mcpSerializedSizeBytes(tool);\n if (toolBytes > MCP_MAX_TOOL_DEFINITION_BYTES) {\n throw new McpPayloadTooLargeError(\n \"MCP tool definition\",\n toolBytes,\n MCP_MAX_TOOL_DEFINITION_BYTES,\n );\n }\n }\n // Measure the complete JSON array, including brackets and separators. Summing\n // definitions alone under-counts by one byte per separator plus the array\n // delimiters and makes the advertised serialized-byte ceiling porous.\n const totalBytes = mcpSerializedSizeBytes(tools);\n if (totalBytes > MCP_MAX_TOOL_LIST_BYTES) {\n throw new McpPayloadTooLargeError(\"MCP tool list\", totalBytes, MCP_MAX_TOOL_LIST_BYTES);\n }\n return tools;\n}\n\nexport function assertMcpServerSelectionWithinBounds<T>(servers: readonly T[]): readonly T[] {\n if (servers.length > MCP_MAX_SELECTED_SERVERS) {\n throw new McpPayloadTooLargeError(\n \"selected MCP server count\",\n servers.length,\n MCP_MAX_SELECTED_SERVERS,\n );\n }\n return servers;\n}\n\ntype McpToolListContribution = {\n entries: number;\n bytes: number;\n};\n\n/**\n * Atomic aggregate accounting shared by every exposed tools/list in one run.\n * A repeated list for the same source REPLACES its prior contribution, so\n * cache invalidation/relisting cannot ratchet the budget upward. Failed\n * replacements leave the previous accounting intact.\n */\nexport class McpAggregateToolListBudget {\n private readonly contributions = new Map<string, McpToolListContribution>();\n private totalEntries = 0;\n private totalBytes = 0;\n\n constructor(\n private readonly label = \"aggregate MCP tool list\",\n private readonly maxEntries = MCP_MAX_AGGREGATE_TOOL_LIST_ENTRIES,\n private readonly maxBytes = MCP_MAX_AGGREGATE_TOOL_LIST_BYTES,\n ) {}\n\n replace<T>(sourceId: string, tools: readonly T[]): readonly T[] {\n assertMcpToolListWithinBounds(tools);\n const contribution = {\n entries: tools.length,\n // Conservatively account each server as its complete serialized array.\n // Summing these arrays slightly over-counts the brackets relative to one\n // flattened array, which is intentional for a fail-closed hard ceiling.\n bytes: mcpSerializedSizeBytes(tools),\n };\n const previous = this.contributions.get(sourceId) ?? { entries: 0, bytes: 0 };\n const nextEntries = this.totalEntries - previous.entries + contribution.entries;\n if (nextEntries > this.maxEntries) {\n throw new McpPayloadTooLargeError(this.label, nextEntries, this.maxEntries);\n }\n const nextBytes = this.totalBytes - previous.bytes + contribution.bytes;\n if (nextBytes > this.maxBytes) {\n throw new McpPayloadTooLargeError(this.label, nextBytes, this.maxBytes);\n }\n this.contributions.set(sourceId, contribution);\n this.totalEntries = nextEntries;\n this.totalBytes = nextBytes;\n return tools;\n }\n\n remove(sourceId: string): void {\n const previous = this.contributions.get(sourceId);\n if (!previous) return;\n this.contributions.delete(sourceId);\n this.totalEntries -= previous.entries;\n this.totalBytes -= previous.bytes;\n }\n\n snapshot(): Readonly<McpToolListContribution> {\n return { entries: this.totalEntries, bytes: this.totalBytes };\n }\n}\n\n/** Stable-order parallel map with a hard in-flight ceiling and fail-stop drain. */\nexport async function boundedParallelMap<T, R>(\n values: readonly T[],\n concurrency: number,\n mapper: (value: T, index: number) => Promise<R>,\n): Promise<R[]> {\n if (!Number.isInteger(concurrency) || concurrency < 1) {\n throw new Error(\"bounded parallel map concurrency must be a positive integer\");\n }\n if (values.length === 0) return [];\n\n const results = new Array<R>(values.length);\n const errors: Array<{ index: number; error: unknown }> = [];\n let nextIndex = 0;\n let stopped = false;\n const worker = async () => {\n while (!stopped) {\n const index = nextIndex;\n if (index >= values.length) return;\n nextIndex += 1;\n try {\n results[index] = await mapper(values[index]!, index);\n } catch (error) {\n errors.push({ index, error });\n stopped = true;\n }\n }\n };\n await Promise.all(Array.from({ length: Math.min(concurrency, values.length) }, () => worker()));\n if (errors.length > 0) {\n errors.sort((left, right) => left.index - right.index);\n throw errors[0]!.error;\n }\n return results;\n}\n\n/**\n * Guard normal MCP traffic with the same deployment policy as OAuth traffic.\n * The pinned transport resolves and policy-checks the destination after the\n * caller has composed any credential headers, then performs the final network\n * call through the vetted Agent. It forces manual redirects, so an\n * Authorization-bearing request never follows a provider-controlled Location\n * to an unvalidated host.\n *\n * This module is deliberately agent-loop-free. API code imports the explicit\n * `@opengeni/runtime/mcp-network` leaf rather than the runtime root barrel.\n */\nexport function guardedMcpFetch<TInput extends string | URL | Request>(\n settings: Pick<Settings, \"environment\" | \"integrationsAllowPrivateNetworkTargets\">,\n fetchImpl: (input: TInput, init?: RequestInit) => Promise<Response>,\n options: {\n maxResponseBytes?: number;\n dnsLookup?: DnsLookup;\n requireHttpsOutsideLocalTest?: boolean;\n } = {},\n): (input: TInput, init?: RequestInit) => Promise<Response> {\n return async (input: TInput, init?: RequestInit) => {\n const response = await pinnedFetch(input, init, settings, {\n fetchImpl: fetchImpl as FetchLike,\n ...(options.dnsLookup ? { dnsLookup: options.dnsLookup } : {}),\n label: \"MCP endpoint\",\n requireHttpsOutsideLocalTest: options.requireHttpsOutsideLocalTest ?? true,\n });\n return boundMcpResponseBody(response, options.maxResponseBytes ?? MCP_MAX_RESPONSE_BYTES);\n };\n}\n\nexport function boundMcpResponseBody(response: Response, maxBytes: number): Response {\n const declaredLength = Number(response.headers.get(\"content-length\"));\n if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {\n void response.body?.cancel().catch(() => undefined);\n throw new McpPayloadTooLargeError(\"MCP response\", declaredLength, maxBytes);\n }\n if (!response.body) {\n return response;\n }\n\n const reader = response.body.getReader();\n let receivedBytes = 0;\n const body = new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const chunk = await reader.read();\n if (chunk.done) {\n controller.close();\n return;\n }\n receivedBytes += chunk.value.byteLength;\n if (receivedBytes > maxBytes) {\n await reader.cancel().catch(() => undefined);\n controller.error(new McpPayloadTooLargeError(\"MCP response\", receivedBytes, maxBytes));\n return;\n }\n controller.enqueue(chunk.value);\n } catch (error) {\n controller.error(error);\n }\n },\n async cancel(reason) {\n await reader.cancel(reason).catch(() => undefined);\n },\n });\n const bounded = new Response(body, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n Object.defineProperties(bounded, {\n redirected: { value: response.redirected },\n type: { value: response.type },\n url: { value: response.url },\n });\n return bounded;\n}\n\nexport async function cancelMcpResponseBody(response: Response): Promise<void> {\n await response.body?.cancel().catch(() => undefined);\n}\n\n/** Read and rebuild an inbound MCP request before the SDK parses it. */\nexport async function boundedMcpRequest(\n request: Request,\n maxBytes = MCP_MAX_INBOUND_REQUEST_BYTES,\n): Promise<Request> {\n const declared = request.headers.get(\"content-length\");\n if (declared !== null) {\n const normalized = declared.trim();\n if (!/^\\d+$/.test(normalized)) {\n await request.body?.cancel().catch(() => undefined);\n throw new McpPayloadTooLargeError(\"MCP request\", 0, maxBytes);\n }\n const declaredBytes = Number(normalized);\n if (!Number.isSafeInteger(declaredBytes) || declaredBytes > maxBytes) {\n await request.body?.cancel().catch(() => undefined);\n throw new McpPayloadTooLargeError(\"MCP request\", declaredBytes, maxBytes);\n }\n }\n if (!request.body) {\n return request;\n }\n const reader = request.body.getReader();\n const chunks: Uint8Array[] = [];\n let receivedBytes = 0;\n try {\n for (;;) {\n const result = await reader.read();\n if (result.done) break;\n receivedBytes += result.value.byteLength;\n if (receivedBytes > maxBytes) {\n await reader.cancel().catch(() => undefined);\n throw new McpPayloadTooLargeError(\"MCP request\", receivedBytes, maxBytes);\n }\n chunks.push(result.value);\n }\n } catch (error) {\n await reader.cancel().catch(() => undefined);\n throw error;\n } finally {\n reader.releaseLock();\n }\n const body = new Uint8Array(receivedBytes);\n let offset = 0;\n for (const chunk of chunks) {\n body.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new Request(request, { body, headers: request.headers });\n}\n\nexport async function assertMcpDestinationAllowed(\n rawUrl: string,\n settings: Pick<Settings, \"environment\" | \"integrationsAllowPrivateNetworkTargets\">,\n options: { dnsLookup?: DnsLookup } = {},\n): Promise<void> {\n await resolvePinnedDestination(rawUrl, settings, {\n ...(options.dnsLookup ? { dnsLookup: options.dnsLookup } : {}),\n label: \"MCP endpoint\",\n requireHttpsOutsideLocalTest: true,\n });\n}\n\nexport const isNonPublicMcpAddress = isNonPublicAddress;\n"],"mappings":";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAEP,SAAS,mBAAmB;AAErB,IAAM,yBAAyB,IAAI,OAAO;AAC1C,IAAM,gCAAgC,OAAO;AAC7C,IAAM,gCAAgC,MAAM;AAC5C,IAAM,0BAA0B,IAAI,OAAO;AAC3C,IAAM,4BAA4B;AAClC,IAAM,4BAA4B,OAAO;AACzC,IAAM,uCAAuC,MAAM;AACnD,IAAM,2BAA2B;AACjC,IAAM,uCAAuC;AAC7C,IAAM,sCAAsC;AAC5C,IAAM,oCAAoC,KAAK,OAAO;AACtD,IAAM,8BAA8B;AACpC,IAAM,0CAA0C;AAChD,IAAM,wCAAwC,KAAK;AAEnD,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACjD,YACW,OACA,aACA,UACT;AACA,UAAM,GAAG,KAAK,gBAAgB,QAAQ,oBAAoB;AAJjD;AACA;AACA;AAGT,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,uBAAuB,OAAwB;AAC7D,MAAI;AACJ,MAAI;AACF,iBAAa,KAAK,UAAU,KAAK,KAAK;AAAA,EACxC,QAAQ;AACN,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACA,SAAO,OAAO,WAAW,UAAU;AACrC;AAEO,SAAS,4BAA4B,OAAgB,UAAkB,OAAqB;AACjG,QAAM,cAAc,uBAAuB,KAAK;AAChD,MAAI,cAAc,UAAU;AAC1B,UAAM,IAAI,wBAAwB,OAAO,aAAa,QAAQ;AAAA,EAChE;AACF;AAEO,SAAS,8BAAiC,OAAmC;AAClF,MAAI,MAAM,SAAS,2BAA2B;AAC5C,UAAM,IAAI,wBAAwB,iBAAiB,MAAM,QAAQ,yBAAyB;AAAA,EAC5F;AACA,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,uBAAuB,IAAI;AAC7C,QAAI,YAAY,+BAA+B;AAC7C,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAIA,QAAM,aAAa,uBAAuB,KAAK;AAC/C,MAAI,aAAa,yBAAyB;AACxC,UAAM,IAAI,wBAAwB,iBAAiB,YAAY,uBAAuB;AAAA,EACxF;AACA,SAAO;AACT;AAEO,SAAS,qCAAwC,SAAqC;AAC3F,MAAI,QAAQ,SAAS,0BAA0B;AAC7C,UAAM,IAAI;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAaO,IAAM,6BAAN,MAAiC;AAAA,EAKtC,YACmB,QAAQ,2BACR,aAAa,qCACb,WAAW,mCAC5B;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EARc,gBAAgB,oBAAI,IAAqC;AAAA,EAClE,eAAe;AAAA,EACf,aAAa;AAAA,EAQrB,QAAW,UAAkB,OAAmC;AAC9D,kCAA8B,KAAK;AACnC,UAAM,eAAe;AAAA,MACnB,SAAS,MAAM;AAAA;AAAA;AAAA;AAAA,MAIf,OAAO,uBAAuB,KAAK;AAAA,IACrC;AACA,UAAM,WAAW,KAAK,cAAc,IAAI,QAAQ,KAAK,EAAE,SAAS,GAAG,OAAO,EAAE;AAC5E,UAAM,cAAc,KAAK,eAAe,SAAS,UAAU,aAAa;AACxE,QAAI,cAAc,KAAK,YAAY;AACjC,YAAM,IAAI,wBAAwB,KAAK,OAAO,aAAa,KAAK,UAAU;AAAA,IAC5E;AACA,UAAM,YAAY,KAAK,aAAa,SAAS,QAAQ,aAAa;AAClE,QAAI,YAAY,KAAK,UAAU;AAC7B,YAAM,IAAI,wBAAwB,KAAK,OAAO,WAAW,KAAK,QAAQ;AAAA,IACxE;AACA,SAAK,cAAc,IAAI,UAAU,YAAY;AAC7C,SAAK,eAAe;AACpB,SAAK,aAAa;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,UAAwB;AAC7B,UAAM,WAAW,KAAK,cAAc,IAAI,QAAQ;AAChD,QAAI,CAAC,SAAU;AACf,SAAK,cAAc,OAAO,QAAQ;AAClC,SAAK,gBAAgB,SAAS;AAC9B,SAAK,cAAc,SAAS;AAAA,EAC9B;AAAA,EAEA,WAA8C;AAC5C,WAAO,EAAE,SAAS,KAAK,cAAc,OAAO,KAAK,WAAW;AAAA,EAC9D;AACF;AAGA,eAAsB,mBACpB,QACA,aACA,QACc;AACd,MAAI,CAAC,OAAO,UAAU,WAAW,KAAK,cAAc,GAAG;AACrD,UAAM,IAAI,MAAM,6DAA6D;AAAA,EAC/E;AACA,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AAEjC,QAAM,UAAU,IAAI,MAAS,OAAO,MAAM;AAC1C,QAAM,SAAmD,CAAC;AAC1D,MAAI,YAAY;AAChB,MAAI,UAAU;AACd,QAAM,SAAS,YAAY;AACzB,WAAO,CAAC,SAAS;AACf,YAAM,QAAQ;AACd,UAAI,SAAS,OAAO,OAAQ;AAC5B,mBAAa;AACb,UAAI;AACF,gBAAQ,KAAK,IAAI,MAAM,OAAO,OAAO,KAAK,GAAI,KAAK;AAAA,MACrD,SAAS,OAAO;AACd,eAAO,KAAK,EAAE,OAAO,MAAM,CAAC;AAC5B,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,OAAO,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;AAC9F,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,KAAK,CAAC,MAAM,UAAU,KAAK,QAAQ,MAAM,KAAK;AACrD,UAAM,OAAO,CAAC,EAAG;AAAA,EACnB;AACA,SAAO;AACT;AAaO,SAAS,gBACd,UACA,WACA,UAII,CAAC,GACqD;AAC1D,SAAO,OAAO,OAAe,SAAuB;AAClD,UAAM,WAAW,MAAM,YAAY,OAAO,MAAM,UAAU;AAAA,MACxD;AAAA,MACA,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,MAC5D,OAAO;AAAA,MACP,8BAA8B,QAAQ,gCAAgC;AAAA,IACxE,CAAC;AACD,WAAO,qBAAqB,UAAU,QAAQ,oBAAoB,sBAAsB;AAAA,EAC1F;AACF;AAEO,SAAS,qBAAqB,UAAoB,UAA4B;AACnF,QAAM,iBAAiB,OAAO,SAAS,QAAQ,IAAI,gBAAgB,CAAC;AACpE,MAAI,OAAO,SAAS,cAAc,KAAK,iBAAiB,UAAU;AAChE,SAAK,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAClD,UAAM,IAAI,wBAAwB,gBAAgB,gBAAgB,QAAQ;AAAA,EAC5E;AACA,MAAI,CAAC,SAAS,MAAM;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,MAAI,gBAAgB;AACpB,QAAM,OAAO,IAAI,eAA2B;AAAA,IAC1C,MAAM,KAAK,YAAY;AACrB,UAAI;AACF,cAAM,QAAQ,MAAM,OAAO,KAAK;AAChC,YAAI,MAAM,MAAM;AACd,qBAAW,MAAM;AACjB;AAAA,QACF;AACA,yBAAiB,MAAM,MAAM;AAC7B,YAAI,gBAAgB,UAAU;AAC5B,gBAAM,OAAO,OAAO,EAAE,MAAM,MAAM,MAAS;AAC3C,qBAAW,MAAM,IAAI,wBAAwB,gBAAgB,eAAe,QAAQ,CAAC;AACrF;AAAA,QACF;AACA,mBAAW,QAAQ,MAAM,KAAK;AAAA,MAChC,SAAS,OAAO;AACd,mBAAW,MAAM,KAAK;AAAA,MACxB;AAAA,IACF;AAAA,IACA,MAAM,OAAO,QAAQ;AACnB,YAAM,OAAO,OAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,IACnD;AAAA,EACF,CAAC;AACD,QAAM,UAAU,IAAI,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB,SAAS,SAAS;AAAA,EACpB,CAAC;AACD,SAAO,iBAAiB,SAAS;AAAA,IAC/B,YAAY,EAAE,OAAO,SAAS,WAAW;AAAA,IACzC,MAAM,EAAE,OAAO,SAAS,KAAK;AAAA,IAC7B,KAAK,EAAE,OAAO,SAAS,IAAI;AAAA,EAC7B,CAAC;AACD,SAAO;AACT;AAEA,eAAsB,sBAAsB,UAAmC;AAC7E,QAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AACrD;AAGA,eAAsB,kBACpB,SACA,WAAW,+BACO;AAClB,QAAM,WAAW,QAAQ,QAAQ,IAAI,gBAAgB;AACrD,MAAI,aAAa,MAAM;AACrB,UAAM,aAAa,SAAS,KAAK;AACjC,QAAI,CAAC,QAAQ,KAAK,UAAU,GAAG;AAC7B,YAAM,QAAQ,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAClD,YAAM,IAAI,wBAAwB,eAAe,GAAG,QAAQ;AAAA,IAC9D;AACA,UAAM,gBAAgB,OAAO,UAAU;AACvC,QAAI,CAAC,OAAO,cAAc,aAAa,KAAK,gBAAgB,UAAU;AACpE,YAAM,QAAQ,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAClD,YAAM,IAAI,wBAAwB,eAAe,eAAe,QAAQ;AAAA,IAC1E;AAAA,EACF;AACA,MAAI,CAAC,QAAQ,MAAM;AACjB,WAAO;AAAA,EACT;AACA,QAAM,SAAS,QAAQ,KAAK,UAAU;AACtC,QAAM,SAAuB,CAAC;AAC9B,MAAI,gBAAgB;AACpB,MAAI;AACF,eAAS;AACP,YAAM,SAAS,MAAM,OAAO,KAAK;AACjC,UAAI,OAAO,KAAM;AACjB,uBAAiB,OAAO,MAAM;AAC9B,UAAI,gBAAgB,UAAU;AAC5B,cAAM,OAAO,OAAO,EAAE,MAAM,MAAM,MAAS;AAC3C,cAAM,IAAI,wBAAwB,eAAe,eAAe,QAAQ;AAAA,MAC1E;AACA,aAAO,KAAK,OAAO,KAAK;AAAA,IAC1B;AAAA,EACF,SAAS,OAAO;AACd,UAAM,OAAO,OAAO,EAAE,MAAM,MAAM,MAAS;AAC3C,UAAM;AAAA,EACR,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACA,QAAM,OAAO,IAAI,WAAW,aAAa;AACzC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,SAAK,IAAI,OAAO,MAAM;AACtB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO,IAAI,QAAQ,SAAS,EAAE,MAAM,SAAS,QAAQ,QAAQ,CAAC;AAChE;AAEA,eAAsB,4BACpB,QACA,UACA,UAAqC,CAAC,GACvB;AACf,QAAM,yBAAyB,QAAQ,UAAU;AAAA,IAC/C,GAAI,QAAQ,YAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,IAC5D,OAAO;AAAA,IACP,8BAA8B;AAAA,EAChC,CAAC;AACH;AAEO,IAAM,wBAAwB;","names":[]}
@@ -120,6 +120,7 @@ type ModalOrphanSweepResult = {
120
120
  terminated: ModalOrphanSweepTermination[];
121
121
  skipped: number;
122
122
  };
123
+ type RevalidateModalOrphanTermination = (candidate: ModalOrphanSweepTermination) => Promise<boolean>;
123
124
  declare function modalSandboxAttributionEnvironment(input: ModalSandboxAttribution): Record<string, string>;
124
125
  declare function modalSandboxAttributionTags(input: ModalSandboxAttribution): Record<string, string>;
125
126
  type ModalModule = typeof modal;
@@ -142,6 +143,9 @@ declare function sweepModalOrphanSandboxes(settings: Settings, liveLeases: LiveM
142
143
  maxTerminations?: number;
143
144
  unattributedGraceMs?: number;
144
145
  client?: ModalClientLike;
146
+ /** Re-read durable ownership immediately before provider termination. A
147
+ * false result or callback failure skips the destructive action. */
148
+ revalidateTermination?: RevalidateModalOrphanTermination;
145
149
  }): Promise<ModalOrphanSweepResult>;
146
150
 
147
151
  interface NegotiationContext {
@@ -319,7 +323,7 @@ declare const DEFAULT_DESKTOP_GEOMETRY: DesktopGeometry;
319
323
  * value to viewers by the caller; this error is for diagnostics. */
320
324
  declare class DisplayStackError extends Error {
321
325
  readonly exitCode: number;
322
- readonly stage: "xvfb" | "x11vnc" | "websockify" | "paint" | "unknown";
326
+ readonly stage: "xvfb" | "x11vnc" | "websockify" | "paint" | "lock" | "timeout" | "unknown";
323
327
  constructor(exitCode: number, output: string);
324
328
  }
325
329
  /** Thrown when the provider session cannot run commands (a headless-only
@@ -328,12 +332,39 @@ declare class DisplayStackError extends Error {
328
332
  declare class DisplayStackUnsupportedError extends Error {
329
333
  constructor(message: string);
330
334
  }
335
+ type DisplayStackCallerKind = "viewer" | "computer" | "unknown";
336
+ type DisplayStackClassification = "cold" | "already_ready" | "contention" | "unknown";
337
+ type DisplayStackTelemetryStatus = "started" | "waiting" | "completed" | "failed";
338
+ /** Secret-free, bounded-cardinality stage observation. Provider/sandbox IDs are
339
+ * log correlation fields, never metric labels. */
340
+ type DisplayStackTelemetryEvent = {
341
+ type: "display_stack.stage";
342
+ requestId: string;
343
+ stage: string;
344
+ status: DisplayStackTelemetryStatus;
345
+ elapsedMs: number;
346
+ source: "host" | "sandbox";
347
+ classification: DisplayStackClassification;
348
+ callerKind: DisplayStackCallerKind;
349
+ sandboxId?: string;
350
+ leaseEpoch?: number;
351
+ providerSessionId?: number;
352
+ };
353
+ type DisplayStackTelemetryContext = {
354
+ callerKind: DisplayStackCallerKind;
355
+ sandboxId?: string;
356
+ leaseEpoch?: number;
357
+ };
331
358
  type EnsureDisplayStackOptions = {
332
359
  geometry?: DesktopGeometry;
333
360
  /** The exposed stream port; defaults to 6080. */
334
361
  port?: number;
335
- /** Per-exec timeout; defaults to DISPLAY_STACK_TIMEOUT_MS. */
362
+ /** Whole-operation wall-clock timeout; defaults to DISPLAY_STACK_TIMEOUT_MS. */
336
363
  timeoutMs?: number;
364
+ /** Caller correlation. Supplying it enables the default structured log sink. */
365
+ telemetryContext?: DisplayStackTelemetryContext;
366
+ /** Optional non-blocking telemetry sink (tests/embedders may replace logging). */
367
+ onTelemetry?: (event: DisplayStackTelemetryEvent) => void | Promise<void>;
337
368
  };
338
369
  type EnsureDisplayStackResult = {
339
370
  /** The exposed port the stack listens on (websockify/noVNC). */
@@ -685,6 +716,9 @@ declare function deleteRecordingArtifacts(session: unknown, proc: RecordingProce
685
716
  /** The storage object key for a recording artifact (parallels the file-asset layout). */
686
717
  declare function recordingStorageKey(workspaceId: string, sessionId: string, recordingId: string, codec: RecordingCodec): string;
687
718
 
719
+ declare function parseExecBannerSessionId(raw: string): number | null;
720
+ declare function parseExecBannerExitCode(raw: string): number | null;
721
+
688
722
  type ChannelAExecResult = {
689
723
  output?: string;
690
724
  stdout?: string;
@@ -863,10 +897,6 @@ declare class SandboxChannelAService {
863
897
  }
864
898
  declare function stripExecBanner(raw: string): string;
865
899
  declare function isExecSessionLostBanner(out: string, execSessionId: number): boolean;
866
- declare function parseExecBannerSessionId(raw: string): number | null;
867
- /** Recover a completed execCommand fallback's exit status from its banner.
868
- * Only the banner region is inspected, so command output cannot spoof success. */
869
- declare function parseExecBannerExitCode(raw: string): number | null;
870
900
  declare function assertSafeRelPath(p: string): string;
871
901
  declare function parsePorcelainV2(z: string): Omit<GitStatusResponse, "revision">;
872
902
  type NumstatEntry = {
@@ -2571,4 +2601,4 @@ declare function establishSandboxSessionFromEnvelope(settings: Settings, envelop
2571
2601
  */
2572
2602
  declare function serializeEstablishedSandboxEnvelope(established: EstablishedSandboxSession): Promise<Record<string, unknown> | null>;
2573
2603
 
2574
- export { OP_STREAM_SILENCE_TIMEOUT_MS as $, type ActiveBackendResolverDeps as A, type BackendUnresolvableCode as B, ChannelAConflictError as C, DEFAULT_DESKTOP_GEOMETRY as D, type EnsureDisplayStackOptions as E, FAULT_FIELD_WHAT_HAPPENED as F, type MintStreamTokenInput as G, MockAgentResponder as H, type MockAgentResponderOptions as I, type MockExecHandler as J, type ModalModuleLoader as K, type LiveModalSandboxLeaseAttribution as L, type MaterializeRunCredentialsOptions as M, type ModalOrphanSweepResult as N, type ModalSandboxAttribution as O, NEVER_SENT_DETAIL_KEY as P, NatsControlRpc as Q, type RunCredentialSessionReady as R, type NatsOpStreamConnection as S, NatsOpStreamTransport as T, type NatsRequestConnection as U, type NegotiationContext as V, type NormalizedRunCredentialMaterial as W, type NumstatEntry as X, OP_STREAM_ACK_INTERVAL_MS as Y, OP_STREAM_DEFAULT_WINDOW_BYTES as Z, OP_STREAM_RECONNECT_HOLD_MS as _, type RuntimeMetricsHooks as a, SelfhostedSandboxClient as a$, type OpStreamExecOutcome as a0, type OpStreamJournal as a1, type OpStreamSubscription as a2, type OpStreamTransport as a3, OpStreamUnavailableError as a4, PROVIDER_REGISTRY as a5, type ProviderConstructionContext as a6, type ProviderRegistration as a7, REPOSITORY_DISCOVERY_LIMIT as a8, type RecordingArtifactMetadata as a9, SELFHOSTED_RETRY_BACKOFF_BASE_MS as aA, SELFHOSTED_RETRY_BACKOFF_CAP_MS as aB, SELFHOSTED_RETRY_BACKOFF_FACTOR as aC, SELFHOSTED_TIMEOUT_MAX_RETRIES as aD, STREAM_PORT as aE, STREAM_TOKEN_DEFAULT_TTL_SECONDS as aF, SandboxChannelAService as aG, type SandboxChannelAServiceOptions as aH, SandboxConfigError as aI, type SandboxCreatedCallback as aJ, SandboxProviderUnavailableError as aK, SandboxResumeStateUnavailableError as aL, type SelfhostedApplyDiff as aM, SelfhostedControlError as aN, type SelfhostedEditor as aO, type SelfhostedEnrollment as aP, type SelfhostedExecArgs as aQ, type SelfhostedExecResult as aR, type SelfhostedImageOutput as aS, type SelfhostedLivenessState as aT, type SelfhostedNegotiationInput as aU, type SelfhostedOpObservation as aV, type SelfhostedOpObserver as aW, type SelfhostedOpStreamDeps as aX, type SelfhostedRelayConfig as aY, type SelfhostedRetryClock as aZ, type SelfhostedRetryDecision as a_, type RecordingCodec as aa, type RecordingContentType as ab, RecordingError as ac, type RecordingProcess as ad, RecordingUnavailableError as ae, type RepositoryDiscoveryDegradedReason as af, type RepositoryDiscoveryResult as ag, type ResolvedActiveBackend as ah, type RoutableBackendSession as ai, type RoutableSandbox as aj, RoutingSandboxSession as ak, type RoutingSandboxSessionDeps as al, type RoutingTransitionEvent as am, RoutingUnsupportedError as an, type RunCredentialCommandRunner as ao, type RunCredentialCommandSession as ap, type RunCredentialExpectedScope as aq, RunCredentialValidationError as ar, SELFHOSTED_DEFAULT_TIMEOUT_MS as as, SELFHOSTED_DRAINING_MAX_RETRIES as at, SELFHOSTED_EXEC_DRAINING_MAX_RETRIES as au, SELFHOSTED_IDEMPOTENT_READONLY_OPS as av, SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES as aw, SELFHOSTED_NEVER_SENT_MAX_RETRIES as ax, SELFHOSTED_RECONNECT_WINDOW_MS as ay, SELFHOSTED_RELAY_STREAM_PATH as az, ActiveBackendUnresolvableError as b, parseUnifiedPatch as b$, SelfhostedSession as b0, type SelfhostedSessionBuild as b1, type SelfhostedSessionDeps as b2, type SelfhostedSessionState as b3, type SelfhostedUnavailableReason as b4, type StartRecordingInput as b5, StreamPortUnavailableError as b6, type SwapTargetEstablishability as b7, TERMINAL_SERVER_TIMEOUT_MS as b8, TerminalServerError as b9, ensureModalRegistryImage as bA, ensureTerminalServer as bB, establishSandboxSessionFromEnvelope as bC, execDeadlineHint as bD, exposeStreamPort as bE, extForCodec as bF, inspectRecordingArtifact as bG, isExecSessionLostBanner as bH, isProviderSandboxNotFoundError as bI, isSelfhostedProviderNotFoundError as bJ, makeActiveBackendResolver as bK, materializeRunCredentials as bL, mintStreamToken as bM, modalSandboxAttributionEnvironment as bN, modalSandboxAttributionTags as bO, negotiateCapabilities as bP, negotiateSelfhostedCapabilities as bQ, nextDurableOpId as bR, normalizeRunCredentialsResolution as bS, offlineAgentError as bT, offlineControlResponse as bU, opAckSubject as bV, opFrameSubject as bW, parseExecBannerExitCode as bX, parseExecBannerSessionId as bY, parseNumstatZ as bZ, parsePorcelainV2 as b_, TerminalServerUnsupportedError as ba, ToolspaceTokenPathError as bb, agentErrorToControlError as bc, assertDescriptorRegistryInvariants as bd, assertProviderRegistryInvariants as be, assertSafeRelPath as bf, backendSupportsOs as bg, buildDisplayStackScript as bh, buildSelfhostedBackendSession as bi, buildStreamUrl as bj, buildTerminalServerScript as bk, clearRunCredentials as bl, clearRunCredentialsForAttempt as bm, contentTypeForCodec as bn, createSandboxClient as bo, createSandboxClientForBackend as bp, decideSelfhostedRetry as bq, decodeModalSnapshotId as br, defaultSelfhostedRetryClock as bs, deletePriorPersistedSnapshot as bt, deleteRecordingArtifacts as bu, deserializeSandboxSessionStateEnvelope as bv, desktopCapableBackend as bw, drainingExhaustedError as bx, drainingMessage as by, ensureDisplayStack as bz, type ActivePointer as c, payloadTooLargeMessage as c0, readWorkspaceArchiveFromEnvelopeSessionState as c1, recordingStorageKey as c2, renderSelfhostedFault as c3, restoredSandboxSessionStateFromEntry as c4, runCredentialPointerFile as c5, runCredentialRoot as c6, runWithToolCallCorrelation as c7, sandboxStateEntryFromRunState as c8, sanitizeOpIdToken as c9, withToolspaceTokenEnvironment as cA, withToolspaceTokenSession as cB, selectBackend as ca, selfhostedFaultClass as cb, selfhostedLiveness as cc, selfhostedRetryBackoffMs as cd, serializeEstablishedSandboxEnvelope as ce, setSelfhostedApplyDiff as cf, startRecording as cg, stopRecording as ch, stripExecBanner as ci, subjectFor as cj, swapTargetEstablishability as ck, sweepModalOrphanSandboxes as cl, tagModalSandbox as cm, tearDownDisplayStack as cn, tearDownTerminalServer as co, terminateModalSandboxById as cp, timeoutAgentError as cq, timeoutControlResponse as cr, toolspaceTokenFileForSession as cs, toolspaceTokenFileFromEnvironment as ct, uploadRecordingArtifact as cu, verifyStreamToken as cv, withRunCredentialEnvironment as cw, withRunCredentialsClient as cx, withRunCredentialsSession as cy, withToolspaceTokenClient as cz, type ChannelAEmitter as d, type ChannelAExecArgs as e, type ChannelAExecResult as f, ChannelANotFoundError as g, type ChannelASession as h, ChannelAUnavailableError as i, ChannelAUnsupportedError as j, ChannelAValidationError as k, type ControlRpc as l, DISPLAY_STACK_TIMEOUT_MS as m, type DesktopGeometry as n, DisplayStackError as o, DisplayStackUnsupportedError as p, type EnsureDisplayStackResult as q, type EnsureTerminalServerOptions as r, type EnsureTerminalServerResult as s, type EstablishedSandboxSession as t, type ExposeStreamPortInput as u, type ExposeStreamPortResult as v, type ExposedPortEndpoint as w, FAULT_FIELD_WHAT_PRESERVED as x, FAULT_FIELD_WHAT_TO_TRY as y, FAULT_FIELD_WHICH_LAYER as z };
2604
+ export { type NegotiationContext as $, type ActiveBackendResolverDeps as A, type BackendUnresolvableCode as B, ChannelAConflictError as C, DEFAULT_DESKTOP_GEOMETRY as D, type EnsureDisplayStackOptions as E, type ExposeStreamPortResult as F, type ExposedPortEndpoint as G, FAULT_FIELD_WHAT_HAPPENED as H, FAULT_FIELD_WHAT_PRESERVED as I, FAULT_FIELD_WHAT_TO_TRY as J, FAULT_FIELD_WHICH_LAYER as K, type LiveModalSandboxLeaseAttribution as L, type MaterializeRunCredentialsOptions as M, type MintStreamTokenInput as N, MockAgentResponder as O, type MockAgentResponderOptions as P, type MockExecHandler as Q, type RunCredentialSessionReady as R, type ModalModuleLoader as S, type ModalOrphanSweepResult as T, type ModalOrphanSweepTermination as U, type ModalSandboxAttribution as V, NEVER_SENT_DETAIL_KEY as W, NatsControlRpc as X, type NatsOpStreamConnection as Y, NatsOpStreamTransport as Z, type NatsRequestConnection as _, type RuntimeMetricsHooks as a, type SelfhostedNegotiationInput as a$, type NormalizedRunCredentialMaterial as a0, type NumstatEntry as a1, OP_STREAM_ACK_INTERVAL_MS as a2, OP_STREAM_DEFAULT_WINDOW_BYTES as a3, OP_STREAM_RECONNECT_HOLD_MS as a4, OP_STREAM_SILENCE_TIMEOUT_MS as a5, type OpStreamExecOutcome as a6, type OpStreamJournal as a7, type OpStreamSubscription as a8, type OpStreamTransport as a9, SELFHOSTED_DRAINING_MAX_RETRIES as aA, SELFHOSTED_EXEC_DRAINING_MAX_RETRIES as aB, SELFHOSTED_IDEMPOTENT_READONLY_OPS as aC, SELFHOSTED_INFRASTRUCTURE_FAULT_CLASSES as aD, SELFHOSTED_NEVER_SENT_MAX_RETRIES as aE, SELFHOSTED_RECONNECT_WINDOW_MS as aF, SELFHOSTED_RELAY_STREAM_PATH as aG, SELFHOSTED_RETRY_BACKOFF_BASE_MS as aH, SELFHOSTED_RETRY_BACKOFF_CAP_MS as aI, SELFHOSTED_RETRY_BACKOFF_FACTOR as aJ, SELFHOSTED_TIMEOUT_MAX_RETRIES as aK, STREAM_PORT as aL, STREAM_TOKEN_DEFAULT_TTL_SECONDS as aM, SandboxChannelAService as aN, type SandboxChannelAServiceOptions as aO, SandboxConfigError as aP, type SandboxCreatedCallback as aQ, SandboxProviderUnavailableError as aR, SandboxResumeStateUnavailableError as aS, type SelfhostedApplyDiff as aT, SelfhostedControlError as aU, type SelfhostedEditor as aV, type SelfhostedEnrollment as aW, type SelfhostedExecArgs as aX, type SelfhostedExecResult as aY, type SelfhostedImageOutput as aZ, type SelfhostedLivenessState as a_, OpStreamUnavailableError as aa, PROVIDER_REGISTRY as ab, type ProviderConstructionContext as ac, type ProviderRegistration as ad, REPOSITORY_DISCOVERY_LIMIT as ae, type RecordingArtifactMetadata as af, type RecordingCodec as ag, type RecordingContentType as ah, RecordingError as ai, type RecordingProcess as aj, RecordingUnavailableError as ak, type RepositoryDiscoveryDegradedReason as al, type RepositoryDiscoveryResult as am, type ResolvedActiveBackend as an, type RevalidateModalOrphanTermination as ao, type RoutableBackendSession as ap, type RoutableSandbox as aq, RoutingSandboxSession as ar, type RoutingSandboxSessionDeps as as, type RoutingTransitionEvent as at, RoutingUnsupportedError as au, type RunCredentialCommandRunner as av, type RunCredentialCommandSession as aw, type RunCredentialExpectedScope as ax, RunCredentialValidationError as ay, SELFHOSTED_DEFAULT_TIMEOUT_MS as az, ActiveBackendUnresolvableError as b, offlineControlResponse as b$, type SelfhostedOpObservation as b0, type SelfhostedOpObserver as b1, type SelfhostedOpStreamDeps as b2, type SelfhostedRelayConfig as b3, type SelfhostedRetryClock as b4, type SelfhostedRetryDecision as b5, SelfhostedSandboxClient as b6, SelfhostedSession as b7, type SelfhostedSessionBuild as b8, type SelfhostedSessionDeps as b9, deletePriorPersistedSnapshot as bA, deleteRecordingArtifacts as bB, deserializeSandboxSessionStateEnvelope as bC, desktopCapableBackend as bD, drainingExhaustedError as bE, drainingMessage as bF, ensureDisplayStack as bG, ensureModalRegistryImage as bH, ensureTerminalServer as bI, establishSandboxSessionFromEnvelope as bJ, execDeadlineHint as bK, exposeStreamPort as bL, extForCodec as bM, inspectRecordingArtifact as bN, isExecSessionLostBanner as bO, isProviderSandboxNotFoundError as bP, isSelfhostedProviderNotFoundError as bQ, makeActiveBackendResolver as bR, materializeRunCredentials as bS, mintStreamToken as bT, modalSandboxAttributionEnvironment as bU, modalSandboxAttributionTags as bV, negotiateCapabilities as bW, negotiateSelfhostedCapabilities as bX, nextDurableOpId as bY, normalizeRunCredentialsResolution as bZ, offlineAgentError as b_, type SelfhostedSessionState as ba, type SelfhostedUnavailableReason as bb, type StartRecordingInput as bc, StreamPortUnavailableError as bd, type SwapTargetEstablishability as be, TERMINAL_SERVER_TIMEOUT_MS as bf, TerminalServerError as bg, TerminalServerUnsupportedError as bh, ToolspaceTokenPathError as bi, agentErrorToControlError as bj, assertDescriptorRegistryInvariants as bk, assertProviderRegistryInvariants as bl, assertSafeRelPath as bm, backendSupportsOs as bn, buildDisplayStackScript as bo, buildSelfhostedBackendSession as bp, buildStreamUrl as bq, buildTerminalServerScript as br, clearRunCredentials as bs, clearRunCredentialsForAttempt as bt, contentTypeForCodec as bu, createSandboxClient as bv, createSandboxClientForBackend as bw, decideSelfhostedRetry as bx, decodeModalSnapshotId as by, defaultSelfhostedRetryClock as bz, type ActivePointer as c, opAckSubject as c0, opFrameSubject as c1, parseExecBannerExitCode as c2, parseExecBannerSessionId as c3, parseNumstatZ as c4, parsePorcelainV2 as c5, parseUnifiedPatch as c6, payloadTooLargeMessage as c7, readWorkspaceArchiveFromEnvelopeSessionState as c8, recordingStorageKey as c9, toolspaceTokenFileFromEnvironment as cA, uploadRecordingArtifact as cB, verifyStreamToken as cC, withRunCredentialEnvironment as cD, withRunCredentialsClient as cE, withRunCredentialsSession as cF, withToolspaceTokenClient as cG, withToolspaceTokenEnvironment as cH, withToolspaceTokenSession as cI, renderSelfhostedFault as ca, restoredSandboxSessionStateFromEntry as cb, runCredentialPointerFile as cc, runCredentialRoot as cd, runWithToolCallCorrelation as ce, sandboxStateEntryFromRunState as cf, sanitizeOpIdToken as cg, selectBackend as ch, selfhostedFaultClass as ci, selfhostedLiveness as cj, selfhostedRetryBackoffMs as ck, serializeEstablishedSandboxEnvelope as cl, setSelfhostedApplyDiff as cm, startRecording as cn, stopRecording as co, stripExecBanner as cp, subjectFor as cq, swapTargetEstablishability as cr, sweepModalOrphanSandboxes as cs, tagModalSandbox as ct, tearDownDisplayStack as cu, tearDownTerminalServer as cv, terminateModalSandboxById as cw, timeoutAgentError as cx, timeoutControlResponse as cy, toolspaceTokenFileForSession as cz, type ChannelAEmitter as d, type ChannelAExecArgs as e, type ChannelAExecResult as f, ChannelANotFoundError as g, type ChannelASession as h, ChannelAUnavailableError as i, ChannelAUnsupportedError as j, ChannelAValidationError as k, type ControlRpc as l, DISPLAY_STACK_TIMEOUT_MS as m, type DesktopGeometry as n, type DisplayStackCallerKind as o, type DisplayStackClassification as p, DisplayStackError as q, type DisplayStackTelemetryContext as r, type DisplayStackTelemetryEvent as s, type DisplayStackTelemetryStatus as t, DisplayStackUnsupportedError as u, type EnsureDisplayStackResult as v, type EnsureTerminalServerOptions as w, type EnsureTerminalServerResult as x, type EstablishedSandboxSession as y, type ExposeStreamPortInput as z };