@finalai/agent-provider 0.1.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.
Potentially problematic release.
This version of @finalai/agent-provider might be problematic. Click here for more details.
- package/README.md +12 -0
- package/dist/modules/channel-context.d.mts +102 -0
- package/dist/modules/channel-context.mjs +52 -0
- package/dist/modules/channel-context.mjs.map +7 -0
- package/dist/modules/channel-socket.d.mts +65 -0
- package/dist/modules/channel-socket.mjs +188 -0
- package/dist/modules/channel-socket.mjs.map +7 -0
- package/dist/modules/channel.d.mts +382 -0
- package/dist/modules/channel.mjs +146 -0
- package/dist/modules/channel.mjs.map +7 -0
- package/dist/modules/conformance/agent.d.mts +20 -0
- package/dist/modules/conformance/agent.mjs +623 -0
- package/dist/modules/conformance/agent.mjs.map +7 -0
- package/dist/modules/conformance/fixtures.d.mts +41 -0
- package/dist/modules/conformance/fixtures.mjs +190 -0
- package/dist/modules/conformance/fixtures.mjs.map +7 -0
- package/dist/modules/conformance/harness-kit.d.mts +82 -0
- package/dist/modules/conformance/harness-kit.mjs +1303 -0
- package/dist/modules/conformance/harness-kit.mjs.map +7 -0
- package/dist/modules/conformance/image.d.mts +2 -0
- package/dist/modules/conformance/image.mjs +79 -0
- package/dist/modules/conformance/image.mjs.map +7 -0
- package/dist/modules/conformance/index.d.mts +8 -0
- package/dist/modules/conformance/index.mjs +12 -0
- package/dist/modules/conformance/index.mjs.map +7 -0
- package/dist/modules/conformance/local-harness.d.mts +25 -0
- package/dist/modules/conformance/local-harness.mjs +108 -0
- package/dist/modules/conformance/local-harness.mjs.map +7 -0
- package/dist/modules/conformance/protocol.d.mts +30 -0
- package/dist/modules/conformance/protocol.mjs +56 -0
- package/dist/modules/conformance/protocol.mjs.map +7 -0
- package/dist/modules/conformance/sandbox-kit.d.mts +19 -0
- package/dist/modules/conformance/sandbox-kit.mjs +320 -0
- package/dist/modules/conformance/sandbox-kit.mjs.map +7 -0
- package/dist/modules/conformance/scripted-model/chat-completions.d.mts +30 -0
- package/dist/modules/conformance/scripted-model/chat-completions.mjs +125 -0
- package/dist/modules/conformance/scripted-model/chat-completions.mjs.map +7 -0
- package/dist/modules/conformance/scripted-model/directives.d.mts +84 -0
- package/dist/modules/conformance/scripted-model/directives.mjs +304 -0
- package/dist/modules/conformance/scripted-model/directives.mjs.map +7 -0
- package/dist/modules/conformance/scripted-model/handler.d.mts +14 -0
- package/dist/modules/conformance/scripted-model/handler.mjs +133 -0
- package/dist/modules/conformance/scripted-model/handler.mjs.map +7 -0
- package/dist/modules/conformance/scripted-model/index.d.mts +6 -0
- package/dist/modules/conformance/scripted-model/index.mjs +7 -0
- package/dist/modules/conformance/scripted-model/index.mjs.map +7 -0
- package/dist/modules/conformance/scripted-model/messages.d.mts +39 -0
- package/dist/modules/conformance/scripted-model/messages.mjs +139 -0
- package/dist/modules/conformance/scripted-model/messages.mjs.map +7 -0
- package/dist/modules/conformance/scripted-model/responses.d.mts +62 -0
- package/dist/modules/conformance/scripted-model/responses.mjs +273 -0
- package/dist/modules/conformance/scripted-model/responses.mjs.map +7 -0
- package/dist/modules/conformance/scripted-model/sse.d.mts +15 -0
- package/dist/modules/conformance/scripted-model/sse.mjs +75 -0
- package/dist/modules/conformance/scripted-model/sse.mjs.map +7 -0
- package/dist/modules/conformance/v1-agent.d.mts +24 -0
- package/dist/modules/conformance/v1-agent.mjs +40 -0
- package/dist/modules/conformance/v1-agent.mjs.map +7 -0
- package/dist/modules/credential-routes.d.mts +24 -0
- package/dist/modules/credential-routes.mjs +25 -0
- package/dist/modules/credential-routes.mjs.map +7 -0
- package/dist/modules/credentials.d.mts +206 -0
- package/dist/modules/credentials.mjs +207 -0
- package/dist/modules/credentials.mjs.map +7 -0
- package/dist/modules/dynamic.d.mts +32 -0
- package/dist/modules/dynamic.mjs +77 -0
- package/dist/modules/dynamic.mjs.map +7 -0
- package/dist/modules/harness.d.mts +397 -0
- package/dist/modules/harness.mjs +213 -0
- package/dist/modules/harness.mjs.map +7 -0
- package/dist/modules/index.d.mts +15 -0
- package/dist/modules/index.mjs +40 -0
- package/dist/modules/index.mjs.map +7 -0
- package/dist/modules/json.d.mts +12 -0
- package/dist/modules/json.mjs +19 -0
- package/dist/modules/json.mjs.map +7 -0
- package/dist/modules/local-channel-socket.d.mts +23 -0
- package/dist/modules/local-channel-socket.mjs +141 -0
- package/dist/modules/local-channel-socket.mjs.map +7 -0
- package/dist/modules/manifest.d.mts +558 -0
- package/dist/modules/manifest.mjs +266 -0
- package/dist/modules/manifest.mjs.map +7 -0
- package/dist/modules/mcp-content.d.mts +21 -0
- package/dist/modules/mcp-content.mjs +86 -0
- package/dist/modules/mcp-content.mjs.map +7 -0
- package/dist/modules/provider-ref.d.mts +29 -0
- package/dist/modules/provider-ref.mjs +55 -0
- package/dist/modules/provider-ref.mjs.map +7 -0
- package/dist/modules/sandbox/bytes.d.mts +9 -0
- package/dist/modules/sandbox/bytes.mjs +154 -0
- package/dist/modules/sandbox/bytes.mjs.map +7 -0
- package/dist/modules/sandbox/client.d.mts +51 -0
- package/dist/modules/sandbox/client.mjs +500 -0
- package/dist/modules/sandbox/client.mjs.map +7 -0
- package/dist/modules/sandbox/confined-files.d.mts +22 -0
- package/dist/modules/sandbox/confined-files.mjs +142 -0
- package/dist/modules/sandbox/confined-files.mjs.map +7 -0
- package/dist/modules/sandbox/convenience.d.mts +10 -0
- package/dist/modules/sandbox/convenience.mjs +116 -0
- package/dist/modules/sandbox/convenience.mjs.map +7 -0
- package/dist/modules/sandbox/editor.d.mts +49 -0
- package/dist/modules/sandbox/editor.mjs +43 -0
- package/dist/modules/sandbox/editor.mjs.map +7 -0
- package/dist/modules/sandbox/frame-channel.d.mts +47 -0
- package/dist/modules/sandbox/frame-channel.mjs +153 -0
- package/dist/modules/sandbox/frame-channel.mjs.map +7 -0
- package/dist/modules/sandbox/index.d.mts +18 -0
- package/dist/modules/sandbox/index.mjs +70 -0
- package/dist/modules/sandbox/index.mjs.map +7 -0
- package/dist/modules/sandbox/mcp-channel.d.mts +9 -0
- package/dist/modules/sandbox/mcp-channel.mjs +77 -0
- package/dist/modules/sandbox/mcp-channel.mjs.map +7 -0
- package/dist/modules/sandbox/mcp-hosted.d.mts +46 -0
- package/dist/modules/sandbox/mcp-hosted.mjs +221 -0
- package/dist/modules/sandbox/mcp-hosted.mjs.map +7 -0
- package/dist/modules/sandbox/mcp-search.d.mts +51 -0
- package/dist/modules/sandbox/mcp-search.mjs +129 -0
- package/dist/modules/sandbox/mcp-search.mjs.map +7 -0
- package/dist/modules/sandbox/mcp-shell.d.mts +21 -0
- package/dist/modules/sandbox/mcp-shell.mjs +205 -0
- package/dist/modules/sandbox/mcp-shell.mjs.map +7 -0
- package/dist/modules/sandbox/mcp-testing.d.mts +11 -0
- package/dist/modules/sandbox/mcp-testing.mjs +33 -0
- package/dist/modules/sandbox/mcp-testing.mjs.map +7 -0
- package/dist/modules/sandbox/mcp.d.mts +83 -0
- package/dist/modules/sandbox/mcp.mjs +971 -0
- package/dist/modules/sandbox/mcp.mjs.map +7 -0
- package/dist/modules/sandbox/memory-sandbox.d.mts +32 -0
- package/dist/modules/sandbox/memory-sandbox.mjs +416 -0
- package/dist/modules/sandbox/memory-sandbox.mjs.map +7 -0
- package/dist/modules/sandbox/memory-shell.d.mts +29 -0
- package/dist/modules/sandbox/memory-shell.mjs +278 -0
- package/dist/modules/sandbox/memory-shell.mjs.map +7 -0
- package/dist/modules/sandbox/open-scope-node.d.mts +4 -0
- package/dist/modules/sandbox/open-scope-node.mjs +19 -0
- package/dist/modules/sandbox/open-scope-node.mjs.map +7 -0
- package/dist/modules/sandbox/open-scope.d.mts +16 -0
- package/dist/modules/sandbox/open-scope.mjs +66 -0
- package/dist/modules/sandbox/open-scope.mjs.map +7 -0
- package/dist/modules/sandbox/paths.d.mts +7 -0
- package/dist/modules/sandbox/paths.mjs +50 -0
- package/dist/modules/sandbox/paths.mjs.map +7 -0
- package/dist/modules/sandbox/rpc-peer.d.mts +35 -0
- package/dist/modules/sandbox/rpc-peer.mjs +224 -0
- package/dist/modules/sandbox/rpc-peer.mjs.map +7 -0
- package/dist/modules/sandbox/seeds.d.mts +26 -0
- package/dist/modules/sandbox/seeds.mjs +228 -0
- package/dist/modules/sandbox/seeds.mjs.map +7 -0
- package/dist/modules/sandbox/server.d.mts +66 -0
- package/dist/modules/sandbox/server.mjs +567 -0
- package/dist/modules/sandbox/server.mjs.map +7 -0
- package/dist/modules/sandbox/snapshots.d.mts +49 -0
- package/dist/modules/sandbox/snapshots.mjs +55 -0
- package/dist/modules/sandbox/snapshots.mjs.map +7 -0
- package/dist/modules/sandbox/stream-mux.d.mts +18 -0
- package/dist/modules/sandbox/stream-mux.mjs +285 -0
- package/dist/modules/sandbox/stream-mux.mjs.map +7 -0
- package/dist/modules/sandbox/testing.d.mts +25 -0
- package/dist/modules/sandbox/testing.mjs +64 -0
- package/dist/modules/sandbox/testing.mjs.map +7 -0
- package/dist/modules/sandbox/types.d.mts +352 -0
- package/dist/modules/sandbox/types.mjs +86 -0
- package/dist/modules/sandbox/types.mjs.map +7 -0
- package/dist/modules/sandbox/wire.d.mts +671 -0
- package/dist/modules/sandbox/wire.mjs +537 -0
- package/dist/modules/sandbox/wire.mjs.map +7 -0
- package/dist/modules/sandbox/workspace-root.d.mts +8 -0
- package/dist/modules/sandbox/workspace-root.mjs +79 -0
- package/dist/modules/sandbox/workspace-root.mjs.map +7 -0
- package/dist/modules/schemas.d.mts +121 -0
- package/dist/modules/schemas.mjs +146 -0
- package/dist/modules/schemas.mjs.map +7 -0
- package/dist/modules/semantic-events.d.mts +31 -0
- package/dist/modules/semantic-events.mjs +23 -0
- package/dist/modules/semantic-events.mjs.map +7 -0
- package/package.json +199 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/sandbox/server.ts"],
|
|
4
|
+
"sourcesContent": ["import * as z from 'zod';\nimport type { JsonValue } from \"../json.mjs\";\nimport { narrowerSandboxAccess, SandboxAccess, sandboxAccessAtLeast } from \"../manifest.mjs\";\nimport { base64ToBytes, bytesToStream } from \"./bytes.mjs\";\nimport { confinedReadDir, confinedReadFile, confinedStat } from \"./confined-files.mjs\";\nimport { createRpcPeer, type RpcPeerIface, type RpcRequestContextIface } from \"./rpc-peer.mjs\";\nimport {\n isMcpChannelEndpoint,\n SandboxCapability,\n type McpChannelEndpointIface,\n type McpChannelIface,\n type NetworkSandboxSessionIface,\n type SandboxMcpEndpoint,\n type SandboxProcessIface,\n type SandboxProviderHandleIface,\n} from \"./types.mjs\";\nimport {\n createFrameChannelPair,\n frameChannelFromStream,\n frameChannelFromWebSocket,\n HANDLE_RPC_EXECUTE_METHODS,\n HANDLE_RPC_FILE_WRITE_METHODS,\n HANDLE_RPC_LIFECYCLE_METHODS,\n HANDLE_RPC_VERSION,\n HandleRpcCloseCode,\n handleRpcError,\n HandleRpcErrorCode,\n HandleRpcMethod,\n handleRpcMethodSchemas,\n parseHandleRpcMethod,\n type DescribeResultIface,\n type FrameChannelIface,\n type FrameStreamIface,\n type HandleRpcResult,\n type WebSocketLikeIface,\n type WireFrame,\n} from \"./wire.mjs\";\n\n// Serves the handle RPC (wire.ts) for a NetworkSandboxSessionIface. The session\n// service runs it for every provider at its stable per-binding endpoint, which\n// may lazily start the sandbox (through the provider) on the first call.\n\nexport interface HandleAccessPolicyIface {\n // Read bindings reject writes, removes, process execution and computer use;\n // execute bindings allow processes and computer use but not file writes.\n mode: SandboxAccess;\n // Allows sandbox/stop, sandbox/destroy and sandbox/setNetworkPolicy.\n lifecycle: boolean;\n}\n\nexport const DEFAULT_HANDLE_ACCESS: HandleAccessPolicyIface = {\n mode: SandboxAccess.Write,\n lifecycle: false,\n};\n\nexport interface HandleAuthorizationIface {\n // When the credential expires; the server closes the connection then unless\n // the client refreshed it.\n expiresAt: string | null;\n // Narrows the server's access policy for this connection.\n access?: HandleAccessPolicyIface;\n}\n\n// Returns null to reject. `token` is null when the client sent none.\nexport type HandleAuthorizeFn = (args: {\n token: string | null;\n}) => Promise<HandleAuthorizationIface | null>;\n\nexport type HandleLifecycle = Pick<\n SandboxProviderHandleIface<NetworkSandboxSessionIface>,\n 'onSandboxStop' | 'onSandboxDelete' | 'onRuntimeShutdown'\n>;\n\nexport interface HandleResolutionIface {\n sandbox: NetworkSandboxSessionIface;\n handle?: HandleLifecycle;\n access?: HandleAccessPolicyIface;\n}\n\nexport interface HandleRpcMessageHandlerOptionsIface {\n send: (frame: WireFrame) => void;\n close: (code: number, reason: string) => void;\n authorize: HandleAuthorizeFn;\n // Called once per connection, after `initialize` is authorized. The session\n // service's stable endpoint starts the sandbox here through its provider.\n resolve: (authorization: HandleAuthorizationIface) => Promise<HandleResolutionIface>;\n access?: HandleAccessPolicyIface;\n // Token presented in the connection request, used when `initialize` has none.\n connectionToken?: string | null;\n // Send stream chunks as binary frames (default true).\n binary?: boolean;\n // The outer host applies hosted-tool policy before exposing this transport.\n mcpChannels?: boolean;\n now?: () => number;\n // Runs for each validated operation, after binding access checks.\n authorizeOperation?: (context: RpcRequestContextIface) => Promise<void>;\n}\n\nexport interface HandleRpcMessageHandlerIface {\n onFrame(frame: WireFrame): void;\n onClose(code?: number, reason?: string): void;\n}\n\n// Computer use counts only when `sandbox/computerUse` can answer it: an MCP\n// channel endpoint does not cross this wire (its host re-addresses it, as the\n// session service does with withHostedMcpEndpoints).\nconst servesComputerUse = async (sandbox: NetworkSandboxSessionIface): Promise<boolean> => {\n if (sandbox.computerUse == null) return false;\n try {\n return !isMcpChannelEndpoint(await sandbox.computerUse());\n } catch {\n return false;\n }\n};\n\nconst capabilitiesOf = async (\n sandbox: NetworkSandboxSessionIface,\n mcpChannels = false,\n): Promise<SandboxCapability[]> => {\n const capabilities = [SandboxCapability.Files, SandboxCapability.Process];\n if (sandbox.ports.length > 0) capabilities.push(SandboxCapability.Ports);\n if (sandbox.setNetworkPolicy != null) capabilities.push(SandboxCapability.NetworkPolicy);\n if (mcpChannels ? sandbox.computerUse != null : await servesComputerUse(sandbox))\n capabilities.push(SandboxCapability.ComputerUse);\n if (sandbox.screen != null) capabilities.push(SandboxCapability.Screen);\n if (sandbox.localMcp != null) capabilities.push(SandboxCapability.LocalMcp);\n return capabilities;\n};\n\nexport const describeSandbox = async (\n sandbox: NetworkSandboxSessionIface,\n mcpChannels = false,\n): Promise<DescribeResultIface> => ({\n handleRpcVersion: HANDLE_RPC_VERSION,\n id: sandbox.id,\n defaultWorkingDirectory: sandbox.defaultWorkingDirectory,\n ports: [...sandbox.ports],\n capabilities: await capabilitiesOf(sandbox, mcpChannels),\n description: sandbox.description,\n});\n\nconst narrowAccess = (\n base: HandleAccessPolicyIface,\n narrower: HandleAccessPolicyIface | undefined,\n): HandleAccessPolicyIface =>\n narrower == null\n ? base\n : {\n mode: narrowerSandboxAccess(base.mode, narrower.mode),\n lifecycle: base.lifecycle && narrower.lifecycle,\n };\n\nconst parseParams = <S extends z.ZodType>(schema: S, params: JsonValue): z.output<S> => {\n const parsed = schema.safeParse(params);\n if (!parsed.success) {\n throw handleRpcError({\n code: HandleRpcErrorCode.InvalidParams,\n message: z.prettifyError(parsed.error),\n });\n }\n return parsed.data;\n};\n\n// The upload stream ids a request names, read before full validation.\nconst uploadStreamIdsSchema = z.object({\n streamId: z.number().int().nonnegative().optional(),\n stdinStreamId: z.number().int().nonnegative().nullable().optional(),\n});\n\nconst unsupported = (what: string) =>\n handleRpcError({ code: HandleRpcErrorCode.Unsupported, message: `this sandbox has no ${what}` });\n\n// Byte-range slice of a stream.\nconst sliceStream = (\n source: ReadableStream<Uint8Array>,\n offset: number,\n length: number | undefined,\n): ReadableStream<Uint8Array> => {\n let position = 0;\n const end = length == null ? Number.POSITIVE_INFINITY : offset + length;\n const reader = source.getReader();\n return new ReadableStream<Uint8Array>({\n pull: async (controller) => {\n for (;;) {\n if (position >= end) {\n controller.close();\n await reader.cancel().catch(() => undefined);\n return;\n }\n const { done, value } = await reader.read();\n if (done) {\n controller.close();\n return;\n }\n const chunkStart = position;\n position += value.byteLength;\n const from = Math.max(0, offset - chunkStart);\n const to = Math.min(value.byteLength, end - chunkStart);\n if (to > from) {\n controller.enqueue(value.subarray(from, to));\n return;\n }\n }\n },\n cancel: (reason) => reader.cancel(reason),\n });\n};\n\n// Low-level, transport-agnostic handler: feed it frames, it calls `send` and\n// `close`. Use it where the host owns the socket (Hono upgradeWebSocket, a\n// Durable Object's hibernation handlers, a relay).\nexport const createHandleRpcMessageHandler = (\n options: HandleRpcMessageHandlerOptionsIface,\n): HandleRpcMessageHandlerIface => {\n const now = options.now ?? Date.now;\n const [local, remote] = createFrameChannelPair();\n let ended = false;\n // `remote` is our side; frames the peer writes to it go out through `send`.\n remote.listen({\n frame: (frame) => options.send(frame),\n close: (info) => {\n if (!ended) {\n ended = true;\n options.close(info.code, info.reason);\n }\n },\n });\n const peerChannel: FrameChannelIface = local;\n const connection = createServerConnection({\n channel: peerChannel,\n authorize: options.authorize,\n resolve: options.resolve,\n access: options.access ?? DEFAULT_HANDLE_ACCESS,\n connectionToken: options.connectionToken ?? null,\n binary: options.binary ?? true,\n mcpChannels: options.mcpChannels,\n now,\n authorizeOperation: options.authorizeOperation,\n });\n return {\n onFrame: (frame) => remote.send(frame),\n onClose: (code, reason) => {\n ended = true;\n connection.close(code ?? 1000, reason ?? '');\n },\n };\n};\n\ninterface ServerConnectionIface {\n close(code: number, reason: string): void;\n}\n\ninterface ServerConnectionArgsIface {\n channel: FrameChannelIface;\n authorize: HandleAuthorizeFn;\n resolve: (authorization: HandleAuthorizationIface) => Promise<HandleResolutionIface>;\n access: HandleAccessPolicyIface;\n connectionToken: string | null;\n binary: boolean;\n mcpChannels?: boolean;\n now: () => number;\n authorizeOperation?: (context: RpcRequestContextIface) => Promise<void>;\n}\n\nconst createServerConnection = (args: ServerConnectionArgsIface): ServerConnectionIface => {\n let sandbox: NetworkSandboxSessionIface | null = null;\n let access = args.access;\n let initializing = false;\n let handle: HandleLifecycle | null = null;\n let expiryTimer: ReturnType<typeof setTimeout> | null = null;\n const processes = new Map<string, SandboxProcessIface>();\n const mcpEndpoints = new Map<string, McpChannelEndpointIface>();\n const mcpConnections = new Map<string, McpChannelIface>();\n let nextMcpChannelId = 0;\n let shutdown: Promise<void> | null = null;\n // Incoming streams registered in beforeRequest, keyed by request id.\n const incomingByRequest = new Map<\n string | number,\n { streamId: number; stream: ReadableStream<Uint8Array> }\n >();\n\n const scheduleExpiry = (expiresAt: string | null) => {\n if (expiryTimer != null) clearTimeout(expiryTimer);\n expiryTimer = null;\n if (expiresAt == null) return;\n const delay = Date.parse(expiresAt) - args.now();\n if (Number.isNaN(delay)) return;\n expiryTimer = setTimeout(\n () =>\n delay > 2_147_483_647\n ? scheduleExpiry(expiresAt)\n : peer.close(HandleRpcCloseCode.Unauthorized, 'credential expired'),\n Math.max(0, Math.min(2_147_483_647, delay)),\n );\n };\n\n const requireSandbox = (): NetworkSandboxSessionIface => {\n if (sandbox == null) {\n throw handleRpcError({\n code: HandleRpcErrorCode.NotInitialized,\n message: 'initialize first',\n });\n }\n return sandbox;\n };\n\n const checkAccess = (method: HandleRpcMethod, params: JsonValue) => {\n if (\n method === HandleRpcMethod.Screen &&\n !parseParams(handleRpcMethodSchemas[method].params, params).viewOnly &&\n !sandboxAccessAtLeast(access.mode, SandboxAccess.Execute)\n )\n throw handleRpcError({\n code: HandleRpcErrorCode.Forbidden,\n message: 'Screen input control requires execute access',\n });\n if (\n !sandboxAccessAtLeast(access.mode, SandboxAccess.Execute) &&\n HANDLE_RPC_EXECUTE_METHODS.includes(method)\n ) {\n throw handleRpcError({\n code: HandleRpcErrorCode.Forbidden,\n message: `${method} is not allowed on a read-only binding`,\n });\n }\n if (\n !sandboxAccessAtLeast(access.mode, SandboxAccess.Write) &&\n HANDLE_RPC_FILE_WRITE_METHODS.includes(method)\n ) {\n throw handleRpcError({\n code: HandleRpcErrorCode.Forbidden,\n message: `${method} is not allowed without write access`,\n });\n }\n if (!access.lifecycle && HANDLE_RPC_LIFECYCLE_METHODS.includes(method)) {\n throw handleRpcError({\n code: HandleRpcErrorCode.Forbidden,\n message: `${method} is not allowed on this binding`,\n });\n }\n };\n\n const featureFlags = (): Pick<DescribeResultIface, 'providerHooks' | 'mcpChannels'> => {\n const flags: Pick<DescribeResultIface, 'providerHooks' | 'mcpChannels'> = {};\n if (handle != null) flags.providerHooks = true;\n if (args.mcpChannels === true) flags.mcpChannels = true;\n return flags;\n };\n\n const initialize = async (\n params: JsonValue,\n ): Promise<HandleRpcResult<HandleRpcMethod.Initialize>> => {\n const parsed = parseParams(handleRpcMethodSchemas[HandleRpcMethod.Initialize].params, params);\n if (sandbox != null || initializing) {\n throw handleRpcError({\n code: HandleRpcErrorCode.InvalidRequest,\n message: 'already initialized',\n });\n }\n initializing = true;\n try {\n const token = parsed.token ?? args.connectionToken;\n const authorization = await args.authorize({ token });\n if (authorization == null) {\n setTimeout(() => peer.close(HandleRpcCloseCode.Unauthorized, 'unauthorized'), 0);\n throw handleRpcError({ code: HandleRpcErrorCode.Unauthorized, message: 'unauthorized' });\n }\n const resolution = await args.resolve(authorization);\n access = narrowAccess(narrowAccess(access, resolution.access), authorization.access);\n sandbox = resolution.sandbox;\n handle = resolution.handle ?? null;\n scheduleExpiry(authorization.expiresAt);\n return {\n ...(await describeSandbox(sandbox, args.mcpChannels)),\n confinedFiles: true,\n ...featureFlags(),\n expiresAt: authorization.expiresAt,\n };\n } finally {\n initializing = false;\n }\n };\n\n const pump = (streamId: number, source: ReadableStream<Uint8Array>) => {\n peer.streams.openOutgoing(streamId, source).catch(() => undefined);\n };\n\n const mcpDescriptor = (endpoint: SandboxMcpEndpoint, key: string) => {\n if (!isMcpChannelEndpoint(endpoint)) return endpoint;\n if (args.mcpChannels !== true) throw unsupported('MCP channels over the handle RPC');\n mcpEndpoints.set(key, endpoint);\n return { name: endpoint.name, endpointKey: key };\n };\n const mcpConnection = (id: string): McpChannelIface => {\n const channel = mcpConnections.get(id);\n if (channel == null)\n throw handleRpcError({\n code: HandleRpcErrorCode.NotFound,\n message: 'MCP channel not found on this connection',\n });\n return channel;\n };\n\n // Fails a request's upload stream when the request fails, so the client\n // stops sending.\n const dispatch = async (context: RpcRequestContextIface): Promise<object> => {\n try {\n return await dispatchMethod(context);\n } catch (error) {\n const entry = incomingByRequest.get(context.id);\n incomingByRequest.delete(context.id);\n if (entry != null) peer.streams.cancelIncoming(entry.streamId, 'request failed');\n throw error;\n }\n };\n\n const dispatchMethod = async (context: RpcRequestContextIface): Promise<object> => {\n const method = parseHandleRpcMethod(context.method);\n if (method == null) {\n throw handleRpcError({\n code: HandleRpcErrorCode.MethodNotFound,\n message: `unknown method ${context.method}`,\n });\n }\n if (method === HandleRpcMethod.Initialize) return initialize(context.params);\n const target = requireSandbox();\n if (shutdown != null && method !== HandleRpcMethod.OnRuntimeShutdown)\n throw handleRpcError({\n code: HandleRpcErrorCode.ConnectionClosed,\n message: 'Provider handle is shutting down',\n });\n checkAccess(method, context.params);\n parseParams(handleRpcMethodSchemas[method].params, context.params);\n await args.authorizeOperation?.(context);\n if (context.signal.aborted)\n throw handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: 'request cancelled' });\n const abortSignal = context.signal;\n switch (method) {\n case HandleRpcMethod.Describe:\n return {\n ...(await describeSandbox(target, args.mcpChannels)),\n confinedFiles: true,\n ...featureFlags(),\n };\n case HandleRpcMethod.AuthRefresh: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const authorization = await args.authorize({ token: params.token });\n if (authorization == null)\n throw handleRpcError({ code: HandleRpcErrorCode.Unauthorized, message: 'unauthorized' });\n access = narrowAccess(access, authorization.access);\n scheduleExpiry(authorization.expiresAt);\n return { expiresAt: authorization.expiresAt };\n }\n case HandleRpcMethod.ReadFile: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const stream =\n params.root == null\n ? await target.readFile({ path: params.path, abortSignal })\n : await (\n target.confinedFileReader?.readFile ??\n ((options) => confinedReadFile(target, options))\n )({ path: params.path, root: params.root, abortSignal });\n if (stream == null) return { found: false };\n const ranged =\n params.offset != null || params.length != null\n ? sliceStream(stream, params.offset ?? 0, params.length)\n : stream;\n // The client registered the stream before asking, so start right away.\n pump(params.streamId, ranged);\n return { found: true };\n }\n case HandleRpcMethod.ReadTextFile: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const text = await target.readTextFile({ ...params, abortSignal });\n return { text };\n }\n case HandleRpcMethod.WriteFile: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const incoming = incomingByRequest.get(context.id)?.stream ?? null;\n const content =\n incoming ??\n bytesToStream(\n params.contentBase64 == null ? new Uint8Array() : base64ToBytes(params.contentBase64),\n );\n await target.writeFile({ path: params.path, content, abortSignal });\n incomingByRequest.delete(context.id);\n return {};\n }\n case HandleRpcMethod.Spawn: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const stdin = incomingByRequest.get(context.id)?.stream ?? null;\n if (processes.has(params.processId)) {\n throw handleRpcError({\n code: HandleRpcErrorCode.InvalidParams,\n message: 'processId already in use',\n });\n }\n const child = await target.spawn({\n command: params.command,\n args: params.args,\n cwd: params.cwd,\n env: params.env,\n shell: params.shell,\n timeoutMs: params.timeoutMs,\n // A closed stdin is an empty stream.\n stdin: stdin ?? '',\n });\n incomingByRequest.delete(context.id);\n processes.set(params.processId, child);\n pump(params.stdoutStreamId, child.stdout);\n pump(params.stderrStreamId, child.stderr);\n return { pid: child.pid };\n }\n case HandleRpcMethod.ProcessWait: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const child = processes.get(params.processId);\n if (child == null)\n throw handleRpcError({ code: HandleRpcErrorCode.NotFound, message: 'no such process' });\n const result = await new Promise<{ exitCode: number }>((resolve, reject) => {\n const onAbort = () =>\n reject(handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: 'cancelled' }));\n abortSignal.addEventListener('abort', onAbort, { once: true });\n child.wait().then(\n (value) => {\n abortSignal.removeEventListener('abort', onAbort);\n resolve(value);\n },\n (cause: unknown) => {\n abortSignal.removeEventListener('abort', onAbort);\n reject(cause);\n },\n );\n });\n processes.delete(params.processId);\n return result;\n }\n case HandleRpcMethod.ProcessKill: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const child = processes.get(params.processId);\n if (child == null)\n throw handleRpcError({ code: HandleRpcErrorCode.NotFound, message: 'no such process' });\n await child.kill(params.signal);\n return {};\n }\n case HandleRpcMethod.Run: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n return target.run({ ...params, abortSignal });\n }\n case HandleRpcMethod.Stat: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n return {\n stat:\n params.root == null\n ? await target.stat({ path: params.path, abortSignal })\n : await (\n target.confinedFileReader?.stat ?? ((options) => confinedStat(target, options))\n )({\n path: params.path,\n root: params.root,\n abortSignal,\n }),\n };\n }\n case HandleRpcMethod.ReadDir: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n return {\n entries:\n params.root == null\n ? await target.readDir({ path: params.path, abortSignal })\n : await (\n target.confinedFileReader?.readDir ??\n ((options) => confinedReadDir(target, options))\n )({\n path: params.path,\n root: params.root,\n abortSignal,\n }),\n };\n }\n case HandleRpcMethod.RemovePath: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n await target.removePath({ ...params, abortSignal });\n return {};\n }\n case HandleRpcMethod.GetPortEndpoint: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n return target.getPortEndpoint(params);\n }\n case HandleRpcMethod.Stop:\n await target.stop();\n return {};\n case HandleRpcMethod.Destroy:\n await target.destroy();\n return {};\n case HandleRpcMethod.OnRuntimeShutdown: {\n if (handle == null) throw unsupported('provider lifecycle hooks');\n const shutdownHandle = handle;\n shutdown ??= (async () => {\n await Promise.allSettled([...processes.values()].map((child) => child.kill()));\n await Promise.allSettled([...mcpConnections.values()].map((channel) => channel.close()));\n processes.clear();\n mcpConnections.clear();\n mcpEndpoints.clear();\n await shutdownHandle.onRuntimeShutdown();\n })();\n await shutdown;\n return {};\n }\n case HandleRpcMethod.OnSandboxStop:\n if (handle == null) throw unsupported('provider lifecycle hooks');\n await handle.onSandboxStop();\n return {};\n case HandleRpcMethod.OnSandboxDelete: {\n if (handle == null) throw unsupported('provider lifecycle hooks');\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n await handle.onSandboxDelete(params);\n return {};\n }\n case HandleRpcMethod.SetNetworkPolicy: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n if (target.setNetworkPolicy == null) throw unsupported('network policy');\n await target.setNetworkPolicy(params);\n return {};\n }\n case HandleRpcMethod.ComputerUse: {\n if (target.computerUse == null) throw unsupported('computer use');\n const endpoint = await target.computerUse();\n return mcpDescriptor(endpoint, 'computerUse');\n }\n case HandleRpcMethod.McpOpen: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const endpoint = mcpEndpoints.get(params.endpointKey);\n if (args.mcpChannels !== true || endpoint == null)\n throw unsupported('MCP channel endpoint');\n const channel = await endpoint.connect({ abortSignal });\n if (abortSignal.aborted) {\n await channel.close();\n abortSignal.throwIfAborted();\n }\n const channelId = String(++nextMcpChannelId);\n mcpConnections.set(channelId, channel);\n return { channelId };\n }\n case HandleRpcMethod.McpSend: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n await mcpConnection(params.channelId).send(params.message, { abortSignal });\n return {};\n }\n case HandleRpcMethod.McpReceive: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n return { messages: await mcpConnection(params.channelId).receive({ abortSignal }) };\n }\n case HandleRpcMethod.McpClose: {\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n const channel = mcpConnection(params.channelId);\n await channel.close();\n mcpConnections.delete(params.channelId);\n return {};\n }\n case HandleRpcMethod.Screen: {\n if (target.screen == null) throw unsupported('screen');\n const params = parseParams(handleRpcMethodSchemas[method].params, context.params);\n return target.screen(params);\n }\n case HandleRpcMethod.LocalMcp:\n if (target.localMcp == null) throw unsupported('local MCP servers');\n return {\n endpoints: (await target.localMcp()).flatMap((endpoint, index) =>\n args.mcpChannels !== true && isMcpChannelEndpoint(endpoint)\n ? []\n : [mcpDescriptor(endpoint, `localMcp:${index}:${endpoint.name}`)],\n ),\n };\n }\n };\n\n // Registers client-to-server streams synchronously, before their chunks.\n const beforeRequest = (context: RpcRequestContextIface) => {\n if (context.method !== HandleRpcMethod.WriteFile && context.method !== HandleRpcMethod.Spawn)\n return;\n const ids = uploadStreamIdsSchema.safeParse(context.params);\n if (!ids.success) return;\n const streamId =\n context.method === HandleRpcMethod.WriteFile ? ids.data.streamId : ids.data.stdinStreamId;\n if (streamId == null) return;\n const stream = peer.streams.openIncoming(streamId);\n // Reject unauthorized or disallowed uploads before buffering their data.\n const floor =\n context.method === HandleRpcMethod.WriteFile ? SandboxAccess.Write : SandboxAccess.Execute;\n if (sandbox == null || !sandboxAccessAtLeast(access.mode, floor)) {\n peer.streams.cancelIncoming(streamId, 'rejected');\n return;\n }\n incomingByRequest.set(context.id, { streamId, stream });\n };\n\n const onClose = () => {\n if (expiryTimer != null) clearTimeout(expiryTimer);\n for (const child of processes.values()) child.kill().catch(() => undefined);\n for (const channel of mcpConnections.values()) void channel.close().catch(() => undefined);\n mcpConnections.clear();\n mcpEndpoints.clear();\n processes.clear();\n incomingByRequest.clear();\n };\n\n const peer: RpcPeerIface = createRpcPeer({\n channel: args.channel,\n binary: args.binary,\n onRequest: dispatch,\n beforeRequest,\n onClose,\n });\n\n return { close: (code, reason) => peer.close(code, reason) };\n};\n\nexport interface ServeSandboxHandleArgsIface {\n sandbox: NetworkSandboxSessionIface;\n handle?: HandleLifecycle;\n authorize: HandleAuthorizeFn;\n access?: HandleAccessPolicyIface;\n binary?: boolean;\n // The outer host applies hosted-tool policy before exposing this transport.\n mcpChannels?: boolean;\n now?: () => number;\n}\n\nexport interface SandboxHandleServerIface {\n // Attaches a connection; returns a function that closes it.\n attach(channel: FrameChannelIface, context?: { token?: string | null }): () => void;\n attachWebSocket(socket: WebSocketLikeIface, context?: { token?: string | null }): () => void;\n attachStream(stream: FrameStreamIface, context?: { token?: string | null }): () => void;\n messageHandler(args: {\n send: (frame: WireFrame) => void;\n close: (code: number, reason: string) => void;\n token?: string | null;\n }): HandleRpcMessageHandlerIface;\n}\n\nexport const serveSandboxHandle = (args: ServeSandboxHandleArgsIface): SandboxHandleServerIface => {\n const access = args.access ?? DEFAULT_HANDLE_ACCESS;\n const resolve = async (): Promise<HandleResolutionIface> => ({\n sandbox: args.sandbox,\n handle: args.handle,\n });\n const attach = (channel: FrameChannelIface, context?: { token?: string | null }) => {\n const connection = createServerConnection({\n channel,\n authorize: args.authorize,\n resolve,\n access,\n connectionToken: context?.token ?? null,\n binary: args.binary ?? true,\n mcpChannels: args.mcpChannels,\n now: args.now ?? Date.now,\n });\n return () => connection.close(HandleRpcCloseCode.Normal, 'closed');\n };\n return {\n attach,\n attachWebSocket: (socket, context) =>\n attach(frameChannelFromWebSocket(socket).channel, context),\n attachStream: (stream, context) => attach(frameChannelFromStream(stream), context),\n messageHandler: (handlerArgs) =>\n createHandleRpcMessageHandler({\n send: handlerArgs.send,\n close: handlerArgs.close,\n authorize: args.authorize,\n resolve,\n access,\n connectionToken: handlerArgs.token ?? null,\n binary: args.binary,\n mcpChannels: args.mcpChannels,\n now: args.now,\n }),\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import { SandboxEntryType } from "./types.mjs";
|
|
3
|
+
export declare enum SandboxSnapshotOperation {
|
|
4
|
+
Stat = "stat",
|
|
5
|
+
ReadDirectory = "read-directory",
|
|
6
|
+
Read = "read"
|
|
7
|
+
}
|
|
8
|
+
export declare const sandboxSnapshotRequestSchema: z.ZodObject<{
|
|
9
|
+
operation: z.ZodEnum<typeof SandboxSnapshotOperation>;
|
|
10
|
+
path: z.ZodOptional<z.ZodString>;
|
|
11
|
+
snapshotId: z.ZodOptional<z.ZodString>;
|
|
12
|
+
offset: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
length: z.ZodOptional<z.ZodNumber>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
export declare const sandboxSnapshotResponseSchema: z.ZodObject<{
|
|
16
|
+
root: z.ZodString;
|
|
17
|
+
path: z.ZodString;
|
|
18
|
+
snapshot: z.ZodObject<{
|
|
19
|
+
id: z.ZodString;
|
|
20
|
+
capturedAt: z.ZodString;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
result: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
23
|
+
operation: z.ZodLiteral<SandboxSnapshotOperation.Stat>;
|
|
24
|
+
stat: z.ZodNullable<z.ZodObject<{
|
|
25
|
+
path: z.ZodString;
|
|
26
|
+
type: z.ZodEnum<typeof SandboxEntryType>;
|
|
27
|
+
size: z.ZodNumber;
|
|
28
|
+
modifiedAt: z.ZodNullable<z.ZodString>;
|
|
29
|
+
mode: z.ZodNullable<z.ZodNumber>;
|
|
30
|
+
}, z.core.$strip>>;
|
|
31
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
32
|
+
operation: z.ZodLiteral<SandboxSnapshotOperation.ReadDirectory>;
|
|
33
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
34
|
+
name: z.ZodString;
|
|
35
|
+
path: z.ZodString;
|
|
36
|
+
type: z.ZodEnum<typeof SandboxEntryType>;
|
|
37
|
+
size: z.ZodNullable<z.ZodNumber>;
|
|
38
|
+
}, z.core.$strip>>;
|
|
39
|
+
truncated: z.ZodBoolean;
|
|
40
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
|
+
operation: z.ZodLiteral<SandboxSnapshotOperation.Read>;
|
|
42
|
+
offset: z.ZodNumber;
|
|
43
|
+
size: z.ZodNumber;
|
|
44
|
+
contentBase64: z.ZodString;
|
|
45
|
+
truncated: z.ZodBoolean;
|
|
46
|
+
}, z.core.$strip>], "operation">;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
export type SandboxSnapshotRequestIface = z.infer<typeof sandboxSnapshotRequestSchema>;
|
|
49
|
+
export type SandboxSnapshotResponseIface = z.infer<typeof sandboxSnapshotResponseSchema>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { SandboxEntryType } from "./types.mjs";
|
|
3
|
+
var SandboxSnapshotOperation = /* @__PURE__ */ ((SandboxSnapshotOperation2) => {
|
|
4
|
+
SandboxSnapshotOperation2["Stat"] = "stat";
|
|
5
|
+
SandboxSnapshotOperation2["ReadDirectory"] = "read-directory";
|
|
6
|
+
SandboxSnapshotOperation2["Read"] = "read";
|
|
7
|
+
return SandboxSnapshotOperation2;
|
|
8
|
+
})(SandboxSnapshotOperation || {});
|
|
9
|
+
const sandboxSnapshotRequestSchema = z.object({
|
|
10
|
+
operation: z.nativeEnum(SandboxSnapshotOperation),
|
|
11
|
+
// Omitted means the provider's workspace root.
|
|
12
|
+
path: z.string().max(4096).optional(),
|
|
13
|
+
snapshotId: z.string().optional(),
|
|
14
|
+
offset: z.number().int().nonnegative().optional(),
|
|
15
|
+
length: z.number().int().positive().max(1024 * 1024).optional()
|
|
16
|
+
});
|
|
17
|
+
const statSchema = z.object({
|
|
18
|
+
path: z.string(),
|
|
19
|
+
type: z.nativeEnum(SandboxEntryType),
|
|
20
|
+
size: z.number().int().nonnegative(),
|
|
21
|
+
modifiedAt: z.string().nullable(),
|
|
22
|
+
mode: z.number().nullable()
|
|
23
|
+
});
|
|
24
|
+
const entrySchema = z.object({
|
|
25
|
+
name: z.string(),
|
|
26
|
+
path: z.string(),
|
|
27
|
+
type: z.nativeEnum(SandboxEntryType),
|
|
28
|
+
size: z.number().nullable()
|
|
29
|
+
});
|
|
30
|
+
const sandboxSnapshotResponseSchema = z.object({
|
|
31
|
+
root: z.string(),
|
|
32
|
+
path: z.string(),
|
|
33
|
+
snapshot: z.object({ id: z.string(), capturedAt: z.string() }),
|
|
34
|
+
result: z.discriminatedUnion("operation", [
|
|
35
|
+
z.object({ operation: z.literal("stat" /* Stat */), stat: statSchema.nullable() }),
|
|
36
|
+
z.object({
|
|
37
|
+
operation: z.literal("read-directory" /* ReadDirectory */),
|
|
38
|
+
entries: z.array(entrySchema),
|
|
39
|
+
truncated: z.boolean()
|
|
40
|
+
}),
|
|
41
|
+
z.object({
|
|
42
|
+
operation: z.literal("read" /* Read */),
|
|
43
|
+
offset: z.number().int().nonnegative(),
|
|
44
|
+
size: z.number().int().nonnegative(),
|
|
45
|
+
contentBase64: z.string(),
|
|
46
|
+
truncated: z.boolean()
|
|
47
|
+
})
|
|
48
|
+
])
|
|
49
|
+
});
|
|
50
|
+
export {
|
|
51
|
+
SandboxSnapshotOperation,
|
|
52
|
+
sandboxSnapshotRequestSchema,
|
|
53
|
+
sandboxSnapshotResponseSchema
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=snapshots.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/sandbox/snapshots.ts"],
|
|
4
|
+
"sourcesContent": ["import * as z from 'zod';\nimport { SandboxEntryType } from \"./types.mjs\";\n\nexport enum SandboxSnapshotOperation {\n Stat = 'stat',\n ReadDirectory = 'read-directory',\n Read = 'read',\n}\n\nexport const sandboxSnapshotRequestSchema = z.object({\n operation: z.nativeEnum(SandboxSnapshotOperation),\n // Omitted means the provider's workspace root.\n path: z.string().max(4096).optional(),\n snapshotId: z.string().optional(),\n offset: z.number().int().nonnegative().optional(),\n length: z\n .number()\n .int()\n .positive()\n .max(1024 * 1024)\n .optional(),\n});\n\nconst statSchema = z.object({\n path: z.string(),\n type: z.nativeEnum(SandboxEntryType),\n size: z.number().int().nonnegative(),\n modifiedAt: z.string().nullable(),\n mode: z.number().nullable(),\n});\nconst entrySchema = z.object({\n name: z.string(),\n path: z.string(),\n type: z.nativeEnum(SandboxEntryType),\n size: z.number().nullable(),\n});\n\nexport const sandboxSnapshotResponseSchema = z.object({\n root: z.string(),\n path: z.string(),\n snapshot: z.object({ id: z.string(), capturedAt: z.string() }),\n result: z.discriminatedUnion('operation', [\n z.object({ operation: z.literal(SandboxSnapshotOperation.Stat), stat: statSchema.nullable() }),\n z.object({\n operation: z.literal(SandboxSnapshotOperation.ReadDirectory),\n entries: z.array(entrySchema),\n truncated: z.boolean(),\n }),\n z.object({\n operation: z.literal(SandboxSnapshotOperation.Read),\n offset: z.number().int().nonnegative(),\n size: z.number().int().nonnegative(),\n contentBase64: z.string(),\n truncated: z.boolean(),\n }),\n ]),\n});\n\nexport type SandboxSnapshotRequestIface = z.infer<typeof sandboxSnapshotRequestSchema>;\nexport type SandboxSnapshotResponseIface = z.infer<typeof sandboxSnapshotResponseSchema>;\n"],
|
|
5
|
+
"mappings": "AAAA,YAAY,OAAO;AACnB,SAAS,wBAAwB;AAE1B,IAAK,2BAAL,kBAAKA,8BAAL;AACL,EAAAA,0BAAA,UAAO;AACP,EAAAA,0BAAA,mBAAgB;AAChB,EAAAA,0BAAA,UAAO;AAHG,SAAAA;AAAA,GAAA;AAML,MAAM,+BAA+B,EAAE,OAAO;AAAA,EACnD,WAAW,EAAE,WAAW,wBAAwB;AAAA;AAAA,EAEhD,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,SAAS;AAAA,EACpC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EAChD,QAAQ,EACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT,IAAI,OAAO,IAAI,EACf,SAAS;AACd,CAAC;AAED,MAAM,aAAa,EAAE,OAAO;AAAA,EAC1B,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,WAAW,gBAAgB;AAAA,EACnC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACnC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,MAAM,EAAE,OAAO,EAAE,SAAS;AAC5B,CAAC;AACD,MAAM,cAAc,EAAE,OAAO;AAAA,EAC3B,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,WAAW,gBAAgB;AAAA,EACnC,MAAM,EAAE,OAAO,EAAE,SAAS;AAC5B,CAAC;AAEM,MAAM,gCAAgC,EAAE,OAAO;AAAA,EACpD,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,OAAO;AAAA,EACf,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,YAAY,EAAE,OAAO,EAAE,CAAC;AAAA,EAC7D,QAAQ,EAAE,mBAAmB,aAAa;AAAA,IACxC,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,iBAA6B,GAAG,MAAM,WAAW,SAAS,EAAE,CAAC;AAAA,IAC7F,EAAE,OAAO;AAAA,MACP,WAAW,EAAE,QAAQ,oCAAsC;AAAA,MAC3D,SAAS,EAAE,MAAM,WAAW;AAAA,MAC5B,WAAW,EAAE,QAAQ;AAAA,IACvB,CAAC;AAAA,IACD,EAAE,OAAO;AAAA,MACP,WAAW,EAAE,QAAQ,iBAA6B;AAAA,MAClD,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,MACrC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,MACnC,eAAe,EAAE,OAAO;AAAA,MACxB,WAAW,EAAE,QAAQ;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": ["SandboxSnapshotOperation"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { JsonValue } from "../json.mjs";
|
|
2
|
+
import { type WireFrame } from "./wire.mjs";
|
|
3
|
+
export interface StreamMuxIface {
|
|
4
|
+
openIncoming(streamId: number): ReadableStream<Uint8Array>;
|
|
5
|
+
discardIncoming(streamId: number): void;
|
|
6
|
+
cancelIncoming(streamId: number, reason: string): void;
|
|
7
|
+
openOutgoing(streamId: number, source: ReadableStream<Uint8Array>): Promise<void>;
|
|
8
|
+
abortOutgoing(streamId: number, reason: string): void;
|
|
9
|
+
handleNotification(method: string, params: JsonValue): boolean;
|
|
10
|
+
handleBinary(frame: Uint8Array): void;
|
|
11
|
+
failAll(error: Error): void;
|
|
12
|
+
}
|
|
13
|
+
export declare const createStreamMux: (args: {
|
|
14
|
+
send: (frame: WireFrame) => void;
|
|
15
|
+
binary: boolean;
|
|
16
|
+
windowBytes?: number;
|
|
17
|
+
chunkBytes?: number;
|
|
18
|
+
}) => StreamMuxIface;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { base64ToBytes, bytesToBase64 } from "./bytes.mjs";
|
|
2
|
+
import {
|
|
3
|
+
decodeBinaryFrame,
|
|
4
|
+
encodeChunkFrame,
|
|
5
|
+
errnoOf,
|
|
6
|
+
handleRpcError,
|
|
7
|
+
HandleRpcErrorCode,
|
|
8
|
+
HandleRpcNotification,
|
|
9
|
+
INITIAL_STREAM_WINDOW_BYTES,
|
|
10
|
+
isHandleRpcError,
|
|
11
|
+
MAX_CHUNK_BYTES,
|
|
12
|
+
streamCancelParamsSchema,
|
|
13
|
+
streamChunkParamsSchema,
|
|
14
|
+
streamCreditParamsSchema,
|
|
15
|
+
streamEndParamsSchema,
|
|
16
|
+
streamErrorParamsSchema
|
|
17
|
+
} from "./wire.mjs";
|
|
18
|
+
const createStreamMux = (args) => {
|
|
19
|
+
const windowBytes = args.windowBytes ?? INITIAL_STREAM_WINDOW_BYTES;
|
|
20
|
+
const chunkBytes = Math.min(args.chunkBytes ?? MAX_CHUNK_BYTES, windowBytes);
|
|
21
|
+
const grantThreshold = Math.max(1, Math.floor(windowBytes / 4));
|
|
22
|
+
const incoming = /* @__PURE__ */ new Map();
|
|
23
|
+
const outgoing = /* @__PURE__ */ new Map();
|
|
24
|
+
let failed = null;
|
|
25
|
+
const notify = (method, params) => {
|
|
26
|
+
args.send(JSON.stringify({ jsonrpc: "2.0", method, params }));
|
|
27
|
+
};
|
|
28
|
+
const wakeIncoming = (state) => {
|
|
29
|
+
const wake = state.wake;
|
|
30
|
+
state.wake = null;
|
|
31
|
+
wake?.();
|
|
32
|
+
};
|
|
33
|
+
const wakeOutgoing = (state) => {
|
|
34
|
+
const wake = state.wake;
|
|
35
|
+
state.wake = null;
|
|
36
|
+
wake?.();
|
|
37
|
+
};
|
|
38
|
+
const stopOutgoing = (state, error, silent) => {
|
|
39
|
+
if (state.cancelled != null) return;
|
|
40
|
+
state.cancelled = error;
|
|
41
|
+
state.silent = silent;
|
|
42
|
+
wakeOutgoing(state);
|
|
43
|
+
state.reader?.cancel(error).catch(() => void 0);
|
|
44
|
+
};
|
|
45
|
+
const grant = (streamId, state, bytes) => {
|
|
46
|
+
state.ungranted += bytes;
|
|
47
|
+
if (state.ended || state.error != null) return;
|
|
48
|
+
if (state.ungranted >= grantThreshold) {
|
|
49
|
+
const amount = state.ungranted;
|
|
50
|
+
state.ungranted = 0;
|
|
51
|
+
state.credit += amount;
|
|
52
|
+
notify(HandleRpcNotification.StreamCredit, { streamId, bytes: amount });
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const openIncoming = (streamId) => {
|
|
56
|
+
const state = {
|
|
57
|
+
queue: [],
|
|
58
|
+
ended: false,
|
|
59
|
+
error: failed,
|
|
60
|
+
wake: null,
|
|
61
|
+
ungranted: 0,
|
|
62
|
+
credit: windowBytes
|
|
63
|
+
};
|
|
64
|
+
incoming.set(streamId, state);
|
|
65
|
+
return new ReadableStream(
|
|
66
|
+
{
|
|
67
|
+
pull: async (controller) => {
|
|
68
|
+
while (state.queue.length === 0 && !state.ended && state.error == null) {
|
|
69
|
+
await new Promise((resolve) => {
|
|
70
|
+
state.wake = resolve;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const chunk = state.queue.shift();
|
|
74
|
+
if (chunk != null) {
|
|
75
|
+
controller.enqueue(chunk);
|
|
76
|
+
grant(streamId, state, chunk.byteLength);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
incoming.delete(streamId);
|
|
80
|
+
if (state.error != null) controller.error(state.error);
|
|
81
|
+
else controller.close();
|
|
82
|
+
},
|
|
83
|
+
cancel: (reason) => {
|
|
84
|
+
if (incoming.get(streamId) !== state) return;
|
|
85
|
+
incoming.delete(streamId);
|
|
86
|
+
state.error = handleRpcError({
|
|
87
|
+
code: HandleRpcErrorCode.Cancelled,
|
|
88
|
+
message: "stream cancelled"
|
|
89
|
+
});
|
|
90
|
+
notify(HandleRpcNotification.StreamCancel, {
|
|
91
|
+
streamId,
|
|
92
|
+
reason: reason instanceof Error ? reason.message : "cancelled"
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{ highWaterMark: 0 }
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
const discardIncoming = (streamId) => {
|
|
100
|
+
const state = incoming.get(streamId);
|
|
101
|
+
if (state == null) return;
|
|
102
|
+
incoming.delete(streamId);
|
|
103
|
+
state.ended = true;
|
|
104
|
+
wakeIncoming(state);
|
|
105
|
+
};
|
|
106
|
+
const cancelIncoming = (streamId, reason) => {
|
|
107
|
+
const state = incoming.get(streamId);
|
|
108
|
+
if (state == null) return;
|
|
109
|
+
incoming.delete(streamId);
|
|
110
|
+
state.error = handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: reason });
|
|
111
|
+
wakeIncoming(state);
|
|
112
|
+
notify(HandleRpcNotification.StreamCancel, { streamId, reason });
|
|
113
|
+
};
|
|
114
|
+
const sendChunk = (streamId, payload) => {
|
|
115
|
+
if (args.binary) args.send(encodeChunkFrame(streamId, payload));
|
|
116
|
+
else notify(HandleRpcNotification.StreamChunk, { streamId, data: bytesToBase64(payload) });
|
|
117
|
+
};
|
|
118
|
+
const openOutgoing = async (streamId, source) => {
|
|
119
|
+
const reader = source.getReader();
|
|
120
|
+
const state = {
|
|
121
|
+
credit: windowBytes,
|
|
122
|
+
cancelled: failed,
|
|
123
|
+
silent: failed != null,
|
|
124
|
+
wake: null,
|
|
125
|
+
reader
|
|
126
|
+
};
|
|
127
|
+
outgoing.set(streamId, state);
|
|
128
|
+
try {
|
|
129
|
+
for (; ; ) {
|
|
130
|
+
if (state.cancelled != null) throw state.cancelled;
|
|
131
|
+
const { done, value } = await reader.read();
|
|
132
|
+
if (state.cancelled != null) throw state.cancelled;
|
|
133
|
+
if (done) break;
|
|
134
|
+
let offset = 0;
|
|
135
|
+
while (offset < value.byteLength) {
|
|
136
|
+
while (state.credit <= 0 && state.cancelled == null) {
|
|
137
|
+
await new Promise((resolve) => {
|
|
138
|
+
state.wake = resolve;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (state.cancelled != null) throw state.cancelled;
|
|
142
|
+
const size = Math.min(value.byteLength - offset, state.credit, chunkBytes);
|
|
143
|
+
sendChunk(streamId, value.subarray(offset, offset + size));
|
|
144
|
+
state.credit -= size;
|
|
145
|
+
offset += size;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
outgoing.delete(streamId);
|
|
149
|
+
notify(HandleRpcNotification.StreamEnd, { streamId });
|
|
150
|
+
} catch (error) {
|
|
151
|
+
outgoing.delete(streamId);
|
|
152
|
+
reader.cancel(error).catch(() => void 0);
|
|
153
|
+
if (!state.silent && failed == null) {
|
|
154
|
+
const message = error instanceof Error ? error.message : "stream source failed";
|
|
155
|
+
notify(HandleRpcNotification.StreamError, {
|
|
156
|
+
streamId,
|
|
157
|
+
message,
|
|
158
|
+
code: isHandleRpcError(error) ? error.code : HandleRpcErrorCode.Internal,
|
|
159
|
+
errno: errnoOf(error)
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const abortOutgoing = (streamId, reason) => {
|
|
166
|
+
const state = outgoing.get(streamId);
|
|
167
|
+
if (state == null) return;
|
|
168
|
+
stopOutgoing(
|
|
169
|
+
state,
|
|
170
|
+
handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: reason }),
|
|
171
|
+
false
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
const deliverChunk = (streamId, payload) => {
|
|
175
|
+
const state = incoming.get(streamId);
|
|
176
|
+
if (state == null || state.ended || state.error != null) return;
|
|
177
|
+
if (payload.byteLength > state.credit || payload.byteLength > MAX_CHUNK_BYTES) {
|
|
178
|
+
state.queue.length = 0;
|
|
179
|
+
state.error = handleRpcError({
|
|
180
|
+
code: HandleRpcErrorCode.InvalidRequest,
|
|
181
|
+
message: "stream exceeded its credit window"
|
|
182
|
+
});
|
|
183
|
+
notify(HandleRpcNotification.StreamCancel, {
|
|
184
|
+
streamId,
|
|
185
|
+
reason: "stream exceeded its credit window"
|
|
186
|
+
});
|
|
187
|
+
wakeIncoming(state);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
state.credit -= payload.byteLength;
|
|
191
|
+
state.queue.push(payload);
|
|
192
|
+
wakeIncoming(state);
|
|
193
|
+
};
|
|
194
|
+
const handleNotification = (method, params) => {
|
|
195
|
+
switch (method) {
|
|
196
|
+
case HandleRpcNotification.StreamChunk: {
|
|
197
|
+
const parsed = streamChunkParamsSchema.safeParse(params);
|
|
198
|
+
if (parsed.success) {
|
|
199
|
+
try {
|
|
200
|
+
deliverChunk(parsed.data.streamId, base64ToBytes(parsed.data.data));
|
|
201
|
+
} catch {
|
|
202
|
+
cancelIncoming(parsed.data.streamId, "invalid base64 stream chunk");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
case HandleRpcNotification.StreamEnd: {
|
|
208
|
+
const parsed = streamEndParamsSchema.safeParse(params);
|
|
209
|
+
const state = parsed.success ? incoming.get(parsed.data.streamId) : void 0;
|
|
210
|
+
if (state != null) {
|
|
211
|
+
state.ended = true;
|
|
212
|
+
wakeIncoming(state);
|
|
213
|
+
}
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
case HandleRpcNotification.StreamError: {
|
|
217
|
+
const parsed = streamErrorParamsSchema.safeParse(params);
|
|
218
|
+
const state = parsed.success ? incoming.get(parsed.data.streamId) : void 0;
|
|
219
|
+
if (parsed.success && state != null) {
|
|
220
|
+
state.error = handleRpcError({
|
|
221
|
+
code: parsed.data.code ?? HandleRpcErrorCode.Internal,
|
|
222
|
+
message: parsed.data.message,
|
|
223
|
+
errno: parsed.data.errno ?? null
|
|
224
|
+
});
|
|
225
|
+
wakeIncoming(state);
|
|
226
|
+
}
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
case HandleRpcNotification.StreamCredit: {
|
|
230
|
+
const parsed = streamCreditParamsSchema.safeParse(params);
|
|
231
|
+
const state = parsed.success ? outgoing.get(parsed.data.streamId) : void 0;
|
|
232
|
+
if (parsed.success && state != null) {
|
|
233
|
+
state.credit += parsed.data.bytes;
|
|
234
|
+
wakeOutgoing(state);
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
case HandleRpcNotification.StreamCancel: {
|
|
239
|
+
const parsed = streamCancelParamsSchema.safeParse(params);
|
|
240
|
+
const state = parsed.success ? outgoing.get(parsed.data.streamId) : void 0;
|
|
241
|
+
if (parsed.success && state != null) {
|
|
242
|
+
stopOutgoing(
|
|
243
|
+
state,
|
|
244
|
+
handleRpcError({
|
|
245
|
+
code: HandleRpcErrorCode.Cancelled,
|
|
246
|
+
message: parsed.data.reason ?? "stream cancelled by peer"
|
|
247
|
+
}),
|
|
248
|
+
true
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
default:
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
const handleBinary = (frame) => {
|
|
258
|
+
const decoded = decodeBinaryFrame(frame);
|
|
259
|
+
if (decoded != null) deliverChunk(decoded.streamId, decoded.payload);
|
|
260
|
+
};
|
|
261
|
+
const failAll = (error) => {
|
|
262
|
+
failed = error;
|
|
263
|
+
for (const state of incoming.values()) {
|
|
264
|
+
state.error = error;
|
|
265
|
+
wakeIncoming(state);
|
|
266
|
+
}
|
|
267
|
+
incoming.clear();
|
|
268
|
+
for (const state of outgoing.values()) stopOutgoing(state, error, true);
|
|
269
|
+
outgoing.clear();
|
|
270
|
+
};
|
|
271
|
+
return {
|
|
272
|
+
openIncoming,
|
|
273
|
+
discardIncoming,
|
|
274
|
+
cancelIncoming,
|
|
275
|
+
openOutgoing,
|
|
276
|
+
abortOutgoing,
|
|
277
|
+
handleNotification,
|
|
278
|
+
handleBinary,
|
|
279
|
+
failAll
|
|
280
|
+
};
|
|
281
|
+
};
|
|
282
|
+
export {
|
|
283
|
+
createStreamMux
|
|
284
|
+
};
|
|
285
|
+
//# sourceMappingURL=stream-mux.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/sandbox/stream-mux.ts"],
|
|
4
|
+
"sourcesContent": ["import type { JsonObject, JsonValue } from \"../json.mjs\";\nimport { base64ToBytes, bytesToBase64 } from \"./bytes.mjs\";\nimport {\n decodeBinaryFrame,\n encodeChunkFrame,\n errnoOf,\n handleRpcError,\n HandleRpcErrorCode,\n HandleRpcNotification,\n INITIAL_STREAM_WINDOW_BYTES,\n isHandleRpcError,\n MAX_CHUNK_BYTES,\n streamCancelParamsSchema,\n streamChunkParamsSchema,\n streamCreditParamsSchema,\n streamEndParamsSchema,\n streamErrorParamsSchema,\n type WireFrame,\n} from \"./wire.mjs\";\n\n// Credit-based byte streams multiplexed on one handle RPC connection (see the\n// framing notes in wire.ts). Used identically by client and server.\n\nexport interface StreamMuxIface {\n // Data flowing from the peer to us. The stream must be opened before the\n // peer can send its first chunk.\n openIncoming(streamId: number): ReadableStream<Uint8Array>;\n // Drops an incoming stream the peer will never send (a file not found).\n discardIncoming(streamId: number): void;\n // Tells the peer to stop sending, and fails the local reader.\n cancelIncoming(streamId: number, reason: string): void;\n // Data flowing from us to the peer; resolves when `stream/end` was sent and\n // rejects if the peer cancels or the connection fails.\n openOutgoing(streamId: number, source: ReadableStream<Uint8Array>): Promise<void>;\n // Stops an outgoing stream locally and fails it on the peer.\n abortOutgoing(streamId: number, reason: string): void;\n // Returns true when the notification was a stream notification.\n handleNotification(method: string, params: JsonValue): boolean;\n handleBinary(frame: Uint8Array): void;\n failAll(error: Error): void;\n}\n\ninterface IncomingStateIface {\n queue: Uint8Array[];\n ended: boolean;\n error: Error | null;\n wake: (() => void) | null;\n ungranted: number;\n credit: number;\n}\n\ninterface OutgoingStateIface {\n credit: number;\n cancelled: Error | null;\n // True when the peer or the connection stopped the stream, so the peer must\n // not be told about it.\n silent: boolean;\n wake: (() => void) | null;\n reader: ReadableStreamDefaultReader<Uint8Array> | null;\n}\n\nexport const createStreamMux = (args: {\n send: (frame: WireFrame) => void;\n binary: boolean;\n windowBytes?: number;\n chunkBytes?: number;\n}): StreamMuxIface => {\n const windowBytes = args.windowBytes ?? INITIAL_STREAM_WINDOW_BYTES;\n const chunkBytes = Math.min(args.chunkBytes ?? MAX_CHUNK_BYTES, windowBytes);\n // Credit is returned in batches to keep the reverse channel quiet.\n const grantThreshold = Math.max(1, Math.floor(windowBytes / 4));\n const incoming = new Map<number, IncomingStateIface>();\n const outgoing = new Map<number, OutgoingStateIface>();\n let failed: Error | null = null;\n\n const notify = (method: HandleRpcNotification, params: JsonObject) => {\n args.send(JSON.stringify({ jsonrpc: '2.0', method, params }));\n };\n\n const wakeIncoming = (state: IncomingStateIface) => {\n const wake = state.wake;\n state.wake = null;\n wake?.();\n };\n\n const wakeOutgoing = (state: OutgoingStateIface) => {\n const wake = state.wake;\n state.wake = null;\n wake?.();\n };\n\n const stopOutgoing = (state: OutgoingStateIface, error: Error, silent: boolean) => {\n if (state.cancelled != null) return;\n state.cancelled = error;\n state.silent = silent;\n wakeOutgoing(state);\n state.reader?.cancel(error).catch(() => undefined);\n };\n\n const grant = (streamId: number, state: IncomingStateIface, bytes: number) => {\n state.ungranted += bytes;\n if (state.ended || state.error != null) return;\n if (state.ungranted >= grantThreshold) {\n const amount = state.ungranted;\n state.ungranted = 0;\n state.credit += amount;\n notify(HandleRpcNotification.StreamCredit, { streamId, bytes: amount });\n }\n };\n\n const openIncoming = (streamId: number): ReadableStream<Uint8Array> => {\n const state: IncomingStateIface = {\n queue: [],\n ended: false,\n error: failed,\n wake: null,\n ungranted: 0,\n credit: windowBytes,\n };\n incoming.set(streamId, state);\n return new ReadableStream<Uint8Array>(\n {\n pull: async (controller) => {\n while (state.queue.length === 0 && !state.ended && state.error == null) {\n await new Promise<void>((resolve) => {\n state.wake = resolve;\n });\n }\n const chunk = state.queue.shift();\n if (chunk != null) {\n controller.enqueue(chunk);\n grant(streamId, state, chunk.byteLength);\n return;\n }\n incoming.delete(streamId);\n if (state.error != null) controller.error(state.error);\n else controller.close();\n },\n cancel: (reason) => {\n if (incoming.get(streamId) !== state) return;\n incoming.delete(streamId);\n state.error = handleRpcError({\n code: HandleRpcErrorCode.Cancelled,\n message: 'stream cancelled',\n });\n notify(HandleRpcNotification.StreamCancel, {\n streamId,\n reason: reason instanceof Error ? reason.message : 'cancelled',\n });\n },\n },\n { highWaterMark: 0 },\n );\n };\n\n const discardIncoming = (streamId: number) => {\n const state = incoming.get(streamId);\n if (state == null) return;\n incoming.delete(streamId);\n state.ended = true;\n wakeIncoming(state);\n };\n\n const cancelIncoming = (streamId: number, reason: string) => {\n const state = incoming.get(streamId);\n if (state == null) return;\n incoming.delete(streamId);\n state.error = handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: reason });\n wakeIncoming(state);\n notify(HandleRpcNotification.StreamCancel, { streamId, reason });\n };\n\n const sendChunk = (streamId: number, payload: Uint8Array) => {\n if (args.binary) args.send(encodeChunkFrame(streamId, payload));\n else notify(HandleRpcNotification.StreamChunk, { streamId, data: bytesToBase64(payload) });\n };\n\n const openOutgoing = async (\n streamId: number,\n source: ReadableStream<Uint8Array>,\n ): Promise<void> => {\n const reader = source.getReader();\n const state: OutgoingStateIface = {\n credit: windowBytes,\n cancelled: failed,\n silent: failed != null,\n wake: null,\n reader,\n };\n outgoing.set(streamId, state);\n try {\n for (;;) {\n if (state.cancelled != null) throw state.cancelled;\n const { done, value } = await reader.read();\n // Stopping cancels the reader, which ends a pending read.\n if (state.cancelled != null) throw state.cancelled;\n if (done) break;\n let offset = 0;\n while (offset < value.byteLength) {\n while (state.credit <= 0 && state.cancelled == null) {\n await new Promise<void>((resolve) => {\n state.wake = resolve;\n });\n }\n if (state.cancelled != null) throw state.cancelled;\n const size = Math.min(value.byteLength - offset, state.credit, chunkBytes);\n sendChunk(streamId, value.subarray(offset, offset + size));\n state.credit -= size;\n offset += size;\n }\n }\n outgoing.delete(streamId);\n notify(HandleRpcNotification.StreamEnd, { streamId });\n } catch (error) {\n outgoing.delete(streamId);\n reader.cancel(error).catch(() => undefined);\n if (!state.silent && failed == null) {\n const message = error instanceof Error ? error.message : 'stream source failed';\n notify(HandleRpcNotification.StreamError, {\n streamId,\n message,\n code: isHandleRpcError(error) ? error.code : HandleRpcErrorCode.Internal,\n errno: errnoOf(error),\n });\n }\n throw error;\n }\n };\n\n const abortOutgoing = (streamId: number, reason: string) => {\n const state = outgoing.get(streamId);\n if (state == null) return;\n stopOutgoing(\n state,\n handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: reason }),\n false,\n );\n };\n\n const deliverChunk = (streamId: number, payload: Uint8Array) => {\n const state = incoming.get(streamId);\n if (state == null || state.ended || state.error != null) return;\n if (payload.byteLength > state.credit || payload.byteLength > MAX_CHUNK_BYTES) {\n state.queue.length = 0;\n state.error = handleRpcError({\n code: HandleRpcErrorCode.InvalidRequest,\n message: 'stream exceeded its credit window',\n });\n notify(HandleRpcNotification.StreamCancel, {\n streamId,\n reason: 'stream exceeded its credit window',\n });\n wakeIncoming(state);\n return;\n }\n state.credit -= payload.byteLength;\n state.queue.push(payload);\n wakeIncoming(state);\n };\n\n const handleNotification = (method: string, params: JsonValue): boolean => {\n switch (method) {\n case HandleRpcNotification.StreamChunk: {\n const parsed = streamChunkParamsSchema.safeParse(params);\n if (parsed.success) {\n try {\n deliverChunk(parsed.data.streamId, base64ToBytes(parsed.data.data));\n } catch {\n cancelIncoming(parsed.data.streamId, 'invalid base64 stream chunk');\n }\n }\n return true;\n }\n case HandleRpcNotification.StreamEnd: {\n const parsed = streamEndParamsSchema.safeParse(params);\n const state = parsed.success ? incoming.get(parsed.data.streamId) : undefined;\n if (state != null) {\n state.ended = true;\n wakeIncoming(state);\n }\n return true;\n }\n case HandleRpcNotification.StreamError: {\n const parsed = streamErrorParamsSchema.safeParse(params);\n const state = parsed.success ? incoming.get(parsed.data.streamId) : undefined;\n if (parsed.success && state != null) {\n state.error = handleRpcError({\n code: parsed.data.code ?? HandleRpcErrorCode.Internal,\n message: parsed.data.message,\n errno: parsed.data.errno ?? null,\n });\n wakeIncoming(state);\n }\n return true;\n }\n case HandleRpcNotification.StreamCredit: {\n const parsed = streamCreditParamsSchema.safeParse(params);\n const state = parsed.success ? outgoing.get(parsed.data.streamId) : undefined;\n if (parsed.success && state != null) {\n state.credit += parsed.data.bytes;\n wakeOutgoing(state);\n }\n return true;\n }\n case HandleRpcNotification.StreamCancel: {\n const parsed = streamCancelParamsSchema.safeParse(params);\n const state = parsed.success ? outgoing.get(parsed.data.streamId) : undefined;\n if (parsed.success && state != null) {\n stopOutgoing(\n state,\n handleRpcError({\n code: HandleRpcErrorCode.Cancelled,\n message: parsed.data.reason ?? 'stream cancelled by peer',\n }),\n true,\n );\n }\n return true;\n }\n default:\n return false;\n }\n };\n\n const handleBinary = (frame: Uint8Array) => {\n const decoded = decodeBinaryFrame(frame);\n if (decoded != null) deliverChunk(decoded.streamId, decoded.payload);\n };\n\n const failAll = (error: Error) => {\n failed = error;\n for (const state of incoming.values()) {\n state.error = error;\n wakeIncoming(state);\n }\n incoming.clear();\n for (const state of outgoing.values()) stopOutgoing(state, error, true);\n outgoing.clear();\n };\n\n return {\n openIncoming,\n discardIncoming,\n cancelIncoming,\n openOutgoing,\n abortOutgoing,\n handleNotification,\n handleBinary,\n failAll,\n };\n};\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,eAAe,qBAAqB;AAC7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AA2CA,MAAM,kBAAkB,CAAC,SAKV;AACpB,QAAM,cAAc,KAAK,eAAe;AACxC,QAAM,aAAa,KAAK,IAAI,KAAK,cAAc,iBAAiB,WAAW;AAE3E,QAAM,iBAAiB,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,CAAC,CAAC;AAC9D,QAAM,WAAW,oBAAI,IAAgC;AACrD,QAAM,WAAW,oBAAI,IAAgC;AACrD,MAAI,SAAuB;AAE3B,QAAM,SAAS,CAAC,QAA+B,WAAuB;AACpE,SAAK,KAAK,KAAK,UAAU,EAAE,SAAS,OAAO,QAAQ,OAAO,CAAC,CAAC;AAAA,EAC9D;AAEA,QAAM,eAAe,CAAC,UAA8B;AAClD,UAAM,OAAO,MAAM;AACnB,UAAM,OAAO;AACb,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,CAAC,UAA8B;AAClD,UAAM,OAAO,MAAM;AACnB,UAAM,OAAO;AACb,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,CAAC,OAA2B,OAAc,WAAoB;AACjF,QAAI,MAAM,aAAa,KAAM;AAC7B,UAAM,YAAY;AAClB,UAAM,SAAS;AACf,iBAAa,KAAK;AAClB,UAAM,QAAQ,OAAO,KAAK,EAAE,MAAM,MAAM,MAAS;AAAA,EACnD;AAEA,QAAM,QAAQ,CAAC,UAAkB,OAA2B,UAAkB;AAC5E,UAAM,aAAa;AACnB,QAAI,MAAM,SAAS,MAAM,SAAS,KAAM;AACxC,QAAI,MAAM,aAAa,gBAAgB;AACrC,YAAM,SAAS,MAAM;AACrB,YAAM,YAAY;AAClB,YAAM,UAAU;AAChB,aAAO,sBAAsB,cAAc,EAAE,UAAU,OAAO,OAAO,CAAC;AAAA,IACxE;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,aAAiD;AACrE,UAAM,QAA4B;AAAA,MAChC,OAAO,CAAC;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,MACN,WAAW;AAAA,MACX,QAAQ;AAAA,IACV;AACA,aAAS,IAAI,UAAU,KAAK;AAC5B,WAAO,IAAI;AAAA,MACT;AAAA,QACE,MAAM,OAAO,eAAe;AAC1B,iBAAO,MAAM,MAAM,WAAW,KAAK,CAAC,MAAM,SAAS,MAAM,SAAS,MAAM;AACtE,kBAAM,IAAI,QAAc,CAAC,YAAY;AACnC,oBAAM,OAAO;AAAA,YACf,CAAC;AAAA,UACH;AACA,gBAAM,QAAQ,MAAM,MAAM,MAAM;AAChC,cAAI,SAAS,MAAM;AACjB,uBAAW,QAAQ,KAAK;AACxB,kBAAM,UAAU,OAAO,MAAM,UAAU;AACvC;AAAA,UACF;AACA,mBAAS,OAAO,QAAQ;AACxB,cAAI,MAAM,SAAS,KAAM,YAAW,MAAM,MAAM,KAAK;AAAA,cAChD,YAAW,MAAM;AAAA,QACxB;AAAA,QACA,QAAQ,CAAC,WAAW;AAClB,cAAI,SAAS,IAAI,QAAQ,MAAM,MAAO;AACtC,mBAAS,OAAO,QAAQ;AACxB,gBAAM,QAAQ,eAAe;AAAA,YAC3B,MAAM,mBAAmB;AAAA,YACzB,SAAS;AAAA,UACX,CAAC;AACD,iBAAO,sBAAsB,cAAc;AAAA,YACzC;AAAA,YACA,QAAQ,kBAAkB,QAAQ,OAAO,UAAU;AAAA,UACrD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MACA,EAAE,eAAe,EAAE;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,kBAAkB,CAAC,aAAqB;AAC5C,UAAM,QAAQ,SAAS,IAAI,QAAQ;AACnC,QAAI,SAAS,KAAM;AACnB,aAAS,OAAO,QAAQ;AACxB,UAAM,QAAQ;AACd,iBAAa,KAAK;AAAA,EACpB;AAEA,QAAM,iBAAiB,CAAC,UAAkB,WAAmB;AAC3D,UAAM,QAAQ,SAAS,IAAI,QAAQ;AACnC,QAAI,SAAS,KAAM;AACnB,aAAS,OAAO,QAAQ;AACxB,UAAM,QAAQ,eAAe,EAAE,MAAM,mBAAmB,WAAW,SAAS,OAAO,CAAC;AACpF,iBAAa,KAAK;AAClB,WAAO,sBAAsB,cAAc,EAAE,UAAU,OAAO,CAAC;AAAA,EACjE;AAEA,QAAM,YAAY,CAAC,UAAkB,YAAwB;AAC3D,QAAI,KAAK,OAAQ,MAAK,KAAK,iBAAiB,UAAU,OAAO,CAAC;AAAA,QACzD,QAAO,sBAAsB,aAAa,EAAE,UAAU,MAAM,cAAc,OAAO,EAAE,CAAC;AAAA,EAC3F;AAEA,QAAM,eAAe,OACnB,UACA,WACkB;AAClB,UAAM,SAAS,OAAO,UAAU;AAChC,UAAM,QAA4B;AAAA,MAChC,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,QAAQ,UAAU;AAAA,MAClB,MAAM;AAAA,MACN;AAAA,IACF;AACA,aAAS,IAAI,UAAU,KAAK;AAC5B,QAAI;AACF,iBAAS;AACP,YAAI,MAAM,aAAa,KAAM,OAAM,MAAM;AACzC,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAE1C,YAAI,MAAM,aAAa,KAAM,OAAM,MAAM;AACzC,YAAI,KAAM;AACV,YAAI,SAAS;AACb,eAAO,SAAS,MAAM,YAAY;AAChC,iBAAO,MAAM,UAAU,KAAK,MAAM,aAAa,MAAM;AACnD,kBAAM,IAAI,QAAc,CAAC,YAAY;AACnC,oBAAM,OAAO;AAAA,YACf,CAAC;AAAA,UACH;AACA,cAAI,MAAM,aAAa,KAAM,OAAM,MAAM;AACzC,gBAAM,OAAO,KAAK,IAAI,MAAM,aAAa,QAAQ,MAAM,QAAQ,UAAU;AACzE,oBAAU,UAAU,MAAM,SAAS,QAAQ,SAAS,IAAI,CAAC;AACzD,gBAAM,UAAU;AAChB,oBAAU;AAAA,QACZ;AAAA,MACF;AACA,eAAS,OAAO,QAAQ;AACxB,aAAO,sBAAsB,WAAW,EAAE,SAAS,CAAC;AAAA,IACtD,SAAS,OAAO;AACd,eAAS,OAAO,QAAQ;AACxB,aAAO,OAAO,KAAK,EAAE,MAAM,MAAM,MAAS;AAC1C,UAAI,CAAC,MAAM,UAAU,UAAU,MAAM;AACnC,cAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,eAAO,sBAAsB,aAAa;AAAA,UACxC;AAAA,UACA;AAAA,UACA,MAAM,iBAAiB,KAAK,IAAI,MAAM,OAAO,mBAAmB;AAAA,UAChE,OAAO,QAAQ,KAAK;AAAA,QACtB,CAAC;AAAA,MACH;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,UAAkB,WAAmB;AAC1D,UAAM,QAAQ,SAAS,IAAI,QAAQ;AACnC,QAAI,SAAS,KAAM;AACnB;AAAA,MACE;AAAA,MACA,eAAe,EAAE,MAAM,mBAAmB,WAAW,SAAS,OAAO,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,UAAkB,YAAwB;AAC9D,UAAM,QAAQ,SAAS,IAAI,QAAQ;AACnC,QAAI,SAAS,QAAQ,MAAM,SAAS,MAAM,SAAS,KAAM;AACzD,QAAI,QAAQ,aAAa,MAAM,UAAU,QAAQ,aAAa,iBAAiB;AAC7E,YAAM,MAAM,SAAS;AACrB,YAAM,QAAQ,eAAe;AAAA,QAC3B,MAAM,mBAAmB;AAAA,QACzB,SAAS;AAAA,MACX,CAAC;AACD,aAAO,sBAAsB,cAAc;AAAA,QACzC;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AACD,mBAAa,KAAK;AAClB;AAAA,IACF;AACA,UAAM,UAAU,QAAQ;AACxB,UAAM,MAAM,KAAK,OAAO;AACxB,iBAAa,KAAK;AAAA,EACpB;AAEA,QAAM,qBAAqB,CAAC,QAAgB,WAA+B;AACzE,YAAQ,QAAQ;AAAA,MACd,KAAK,sBAAsB,aAAa;AACtC,cAAM,SAAS,wBAAwB,UAAU,MAAM;AACvD,YAAI,OAAO,SAAS;AAClB,cAAI;AACF,yBAAa,OAAO,KAAK,UAAU,cAAc,OAAO,KAAK,IAAI,CAAC;AAAA,UACpE,QAAQ;AACN,2BAAe,OAAO,KAAK,UAAU,6BAA6B;AAAA,UACpE;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,sBAAsB,WAAW;AACpC,cAAM,SAAS,sBAAsB,UAAU,MAAM;AACrD,cAAM,QAAQ,OAAO,UAAU,SAAS,IAAI,OAAO,KAAK,QAAQ,IAAI;AACpE,YAAI,SAAS,MAAM;AACjB,gBAAM,QAAQ;AACd,uBAAa,KAAK;AAAA,QACpB;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,sBAAsB,aAAa;AACtC,cAAM,SAAS,wBAAwB,UAAU,MAAM;AACvD,cAAM,QAAQ,OAAO,UAAU,SAAS,IAAI,OAAO,KAAK,QAAQ,IAAI;AACpE,YAAI,OAAO,WAAW,SAAS,MAAM;AACnC,gBAAM,QAAQ,eAAe;AAAA,YAC3B,MAAM,OAAO,KAAK,QAAQ,mBAAmB;AAAA,YAC7C,SAAS,OAAO,KAAK;AAAA,YACrB,OAAO,OAAO,KAAK,SAAS;AAAA,UAC9B,CAAC;AACD,uBAAa,KAAK;AAAA,QACpB;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,sBAAsB,cAAc;AACvC,cAAM,SAAS,yBAAyB,UAAU,MAAM;AACxD,cAAM,QAAQ,OAAO,UAAU,SAAS,IAAI,OAAO,KAAK,QAAQ,IAAI;AACpE,YAAI,OAAO,WAAW,SAAS,MAAM;AACnC,gBAAM,UAAU,OAAO,KAAK;AAC5B,uBAAa,KAAK;AAAA,QACpB;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,sBAAsB,cAAc;AACvC,cAAM,SAAS,yBAAyB,UAAU,MAAM;AACxD,cAAM,QAAQ,OAAO,UAAU,SAAS,IAAI,OAAO,KAAK,QAAQ,IAAI;AACpE,YAAI,OAAO,WAAW,SAAS,MAAM;AACnC;AAAA,YACE;AAAA,YACA,eAAe;AAAA,cACb,MAAM,mBAAmB;AAAA,cACzB,SAAS,OAAO,KAAK,UAAU;AAAA,YACjC,CAAC;AAAA,YACD;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,UAAsB;AAC1C,UAAM,UAAU,kBAAkB,KAAK;AACvC,QAAI,WAAW,KAAM,cAAa,QAAQ,UAAU,QAAQ,OAAO;AAAA,EACrE;AAEA,QAAM,UAAU,CAAC,UAAiB;AAChC,aAAS;AACT,eAAW,SAAS,SAAS,OAAO,GAAG;AACrC,YAAM,QAAQ;AACd,mBAAa,KAAK;AAAA,IACpB;AACA,aAAS,MAAM;AACf,eAAW,SAAS,SAAS,OAAO,EAAG,cAAa,OAAO,OAAO,IAAI;AACtE,aAAS,MAAM;AAAA,EACjB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ConnectSandboxClientArgsIface, type SandboxClientIface } from "./client.mjs";
|
|
2
|
+
import { type HandleAccessPolicyIface, type HandleAuthorizeFn, type HandleLifecycle, type HandleRpcMessageHandlerOptionsIface } from "./server.mjs";
|
|
3
|
+
import type { NetworkSandboxSessionIface } from "./types.mjs";
|
|
4
|
+
import { type FrameChannelIface } from "./wire.mjs";
|
|
5
|
+
export interface InMemoryHandleNetworkIface {
|
|
6
|
+
serve(args: {
|
|
7
|
+
url: string;
|
|
8
|
+
sandbox: NetworkSandboxSessionIface;
|
|
9
|
+
handle?: HandleLifecycle;
|
|
10
|
+
authorize?: HandleAuthorizeFn;
|
|
11
|
+
access?: HandleAccessPolicyIface;
|
|
12
|
+
binary?: boolean;
|
|
13
|
+
mcpChannels?: boolean;
|
|
14
|
+
}): void;
|
|
15
|
+
mount(url: string, options: Omit<HandleRpcMessageHandlerOptionsIface, 'send' | 'close' | 'connectionToken'>): void;
|
|
16
|
+
openChannel(target: {
|
|
17
|
+
url: string;
|
|
18
|
+
token: string;
|
|
19
|
+
}): Promise<FrameChannelIface>;
|
|
20
|
+
connect(args: Omit<ConnectSandboxClientArgsIface, 'openChannel'>): Promise<SandboxClientIface>;
|
|
21
|
+
dropAll(): void;
|
|
22
|
+
dials(): string[];
|
|
23
|
+
}
|
|
24
|
+
export declare const allowAllTokens: HandleAuthorizeFn;
|
|
25
|
+
export declare const createInMemoryHandleNetwork: () => InMemoryHandleNetworkIface;
|