@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,66 @@
|
|
|
1
|
+
import { SandboxAccess } from "../manifest.mjs";
|
|
2
|
+
import { type RpcRequestContextIface } from "./rpc-peer.mjs";
|
|
3
|
+
import { type NetworkSandboxSessionIface, type SandboxProviderHandleIface } from "./types.mjs";
|
|
4
|
+
import { type DescribeResultIface, type FrameChannelIface, type FrameStreamIface, type WebSocketLikeIface, type WireFrame } from "./wire.mjs";
|
|
5
|
+
export interface HandleAccessPolicyIface {
|
|
6
|
+
mode: SandboxAccess;
|
|
7
|
+
lifecycle: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const DEFAULT_HANDLE_ACCESS: HandleAccessPolicyIface;
|
|
10
|
+
export interface HandleAuthorizationIface {
|
|
11
|
+
expiresAt: string | null;
|
|
12
|
+
access?: HandleAccessPolicyIface;
|
|
13
|
+
}
|
|
14
|
+
export type HandleAuthorizeFn = (args: {
|
|
15
|
+
token: string | null;
|
|
16
|
+
}) => Promise<HandleAuthorizationIface | null>;
|
|
17
|
+
export type HandleLifecycle = Pick<SandboxProviderHandleIface<NetworkSandboxSessionIface>, 'onSandboxStop' | 'onSandboxDelete' | 'onRuntimeShutdown'>;
|
|
18
|
+
export interface HandleResolutionIface {
|
|
19
|
+
sandbox: NetworkSandboxSessionIface;
|
|
20
|
+
handle?: HandleLifecycle;
|
|
21
|
+
access?: HandleAccessPolicyIface;
|
|
22
|
+
}
|
|
23
|
+
export interface HandleRpcMessageHandlerOptionsIface {
|
|
24
|
+
send: (frame: WireFrame) => void;
|
|
25
|
+
close: (code: number, reason: string) => void;
|
|
26
|
+
authorize: HandleAuthorizeFn;
|
|
27
|
+
resolve: (authorization: HandleAuthorizationIface) => Promise<HandleResolutionIface>;
|
|
28
|
+
access?: HandleAccessPolicyIface;
|
|
29
|
+
connectionToken?: string | null;
|
|
30
|
+
binary?: boolean;
|
|
31
|
+
mcpChannels?: boolean;
|
|
32
|
+
now?: () => number;
|
|
33
|
+
authorizeOperation?: (context: RpcRequestContextIface) => Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export interface HandleRpcMessageHandlerIface {
|
|
36
|
+
onFrame(frame: WireFrame): void;
|
|
37
|
+
onClose(code?: number, reason?: string): void;
|
|
38
|
+
}
|
|
39
|
+
export declare const describeSandbox: (sandbox: NetworkSandboxSessionIface, mcpChannels?: boolean) => Promise<DescribeResultIface>;
|
|
40
|
+
export declare const createHandleRpcMessageHandler: (options: HandleRpcMessageHandlerOptionsIface) => HandleRpcMessageHandlerIface;
|
|
41
|
+
export interface ServeSandboxHandleArgsIface {
|
|
42
|
+
sandbox: NetworkSandboxSessionIface;
|
|
43
|
+
handle?: HandleLifecycle;
|
|
44
|
+
authorize: HandleAuthorizeFn;
|
|
45
|
+
access?: HandleAccessPolicyIface;
|
|
46
|
+
binary?: boolean;
|
|
47
|
+
mcpChannels?: boolean;
|
|
48
|
+
now?: () => number;
|
|
49
|
+
}
|
|
50
|
+
export interface SandboxHandleServerIface {
|
|
51
|
+
attach(channel: FrameChannelIface, context?: {
|
|
52
|
+
token?: string | null;
|
|
53
|
+
}): () => void;
|
|
54
|
+
attachWebSocket(socket: WebSocketLikeIface, context?: {
|
|
55
|
+
token?: string | null;
|
|
56
|
+
}): () => void;
|
|
57
|
+
attachStream(stream: FrameStreamIface, context?: {
|
|
58
|
+
token?: string | null;
|
|
59
|
+
}): () => void;
|
|
60
|
+
messageHandler(args: {
|
|
61
|
+
send: (frame: WireFrame) => void;
|
|
62
|
+
close: (code: number, reason: string) => void;
|
|
63
|
+
token?: string | null;
|
|
64
|
+
}): HandleRpcMessageHandlerIface;
|
|
65
|
+
}
|
|
66
|
+
export declare const serveSandboxHandle: (args: ServeSandboxHandleArgsIface) => SandboxHandleServerIface;
|
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { narrowerSandboxAccess, SandboxAccess, sandboxAccessAtLeast } from "../manifest.mjs";
|
|
3
|
+
import { base64ToBytes, bytesToStream } from "./bytes.mjs";
|
|
4
|
+
import { confinedReadDir, confinedReadFile, confinedStat } from "./confined-files.mjs";
|
|
5
|
+
import { createRpcPeer } from "./rpc-peer.mjs";
|
|
6
|
+
import {
|
|
7
|
+
isMcpChannelEndpoint,
|
|
8
|
+
SandboxCapability
|
|
9
|
+
} from "./types.mjs";
|
|
10
|
+
import {
|
|
11
|
+
createFrameChannelPair,
|
|
12
|
+
frameChannelFromStream,
|
|
13
|
+
frameChannelFromWebSocket,
|
|
14
|
+
HANDLE_RPC_EXECUTE_METHODS,
|
|
15
|
+
HANDLE_RPC_FILE_WRITE_METHODS,
|
|
16
|
+
HANDLE_RPC_LIFECYCLE_METHODS,
|
|
17
|
+
HANDLE_RPC_VERSION,
|
|
18
|
+
HandleRpcCloseCode,
|
|
19
|
+
handleRpcError,
|
|
20
|
+
HandleRpcErrorCode,
|
|
21
|
+
HandleRpcMethod,
|
|
22
|
+
handleRpcMethodSchemas,
|
|
23
|
+
parseHandleRpcMethod
|
|
24
|
+
} from "./wire.mjs";
|
|
25
|
+
const DEFAULT_HANDLE_ACCESS = {
|
|
26
|
+
mode: SandboxAccess.Write,
|
|
27
|
+
lifecycle: false
|
|
28
|
+
};
|
|
29
|
+
const servesComputerUse = async (sandbox) => {
|
|
30
|
+
if (sandbox.computerUse == null) return false;
|
|
31
|
+
try {
|
|
32
|
+
return !isMcpChannelEndpoint(await sandbox.computerUse());
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const capabilitiesOf = async (sandbox, mcpChannels = false) => {
|
|
38
|
+
const capabilities = [SandboxCapability.Files, SandboxCapability.Process];
|
|
39
|
+
if (sandbox.ports.length > 0) capabilities.push(SandboxCapability.Ports);
|
|
40
|
+
if (sandbox.setNetworkPolicy != null) capabilities.push(SandboxCapability.NetworkPolicy);
|
|
41
|
+
if (mcpChannels ? sandbox.computerUse != null : await servesComputerUse(sandbox))
|
|
42
|
+
capabilities.push(SandboxCapability.ComputerUse);
|
|
43
|
+
if (sandbox.screen != null) capabilities.push(SandboxCapability.Screen);
|
|
44
|
+
if (sandbox.localMcp != null) capabilities.push(SandboxCapability.LocalMcp);
|
|
45
|
+
return capabilities;
|
|
46
|
+
};
|
|
47
|
+
const describeSandbox = async (sandbox, mcpChannels = false) => ({
|
|
48
|
+
handleRpcVersion: HANDLE_RPC_VERSION,
|
|
49
|
+
id: sandbox.id,
|
|
50
|
+
defaultWorkingDirectory: sandbox.defaultWorkingDirectory,
|
|
51
|
+
ports: [...sandbox.ports],
|
|
52
|
+
capabilities: await capabilitiesOf(sandbox, mcpChannels),
|
|
53
|
+
description: sandbox.description
|
|
54
|
+
});
|
|
55
|
+
const narrowAccess = (base, narrower) => narrower == null ? base : {
|
|
56
|
+
mode: narrowerSandboxAccess(base.mode, narrower.mode),
|
|
57
|
+
lifecycle: base.lifecycle && narrower.lifecycle
|
|
58
|
+
};
|
|
59
|
+
const parseParams = (schema, params) => {
|
|
60
|
+
const parsed = schema.safeParse(params);
|
|
61
|
+
if (!parsed.success) {
|
|
62
|
+
throw handleRpcError({
|
|
63
|
+
code: HandleRpcErrorCode.InvalidParams,
|
|
64
|
+
message: z.prettifyError(parsed.error)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return parsed.data;
|
|
68
|
+
};
|
|
69
|
+
const uploadStreamIdsSchema = z.object({
|
|
70
|
+
streamId: z.number().int().nonnegative().optional(),
|
|
71
|
+
stdinStreamId: z.number().int().nonnegative().nullable().optional()
|
|
72
|
+
});
|
|
73
|
+
const unsupported = (what) => handleRpcError({ code: HandleRpcErrorCode.Unsupported, message: `this sandbox has no ${what}` });
|
|
74
|
+
const sliceStream = (source, offset, length) => {
|
|
75
|
+
let position = 0;
|
|
76
|
+
const end = length == null ? Number.POSITIVE_INFINITY : offset + length;
|
|
77
|
+
const reader = source.getReader();
|
|
78
|
+
return new ReadableStream({
|
|
79
|
+
pull: async (controller) => {
|
|
80
|
+
for (; ; ) {
|
|
81
|
+
if (position >= end) {
|
|
82
|
+
controller.close();
|
|
83
|
+
await reader.cancel().catch(() => void 0);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const { done, value } = await reader.read();
|
|
87
|
+
if (done) {
|
|
88
|
+
controller.close();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const chunkStart = position;
|
|
92
|
+
position += value.byteLength;
|
|
93
|
+
const from = Math.max(0, offset - chunkStart);
|
|
94
|
+
const to = Math.min(value.byteLength, end - chunkStart);
|
|
95
|
+
if (to > from) {
|
|
96
|
+
controller.enqueue(value.subarray(from, to));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
cancel: (reason) => reader.cancel(reason)
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
const createHandleRpcMessageHandler = (options) => {
|
|
105
|
+
const now = options.now ?? Date.now;
|
|
106
|
+
const [local, remote] = createFrameChannelPair();
|
|
107
|
+
let ended = false;
|
|
108
|
+
remote.listen({
|
|
109
|
+
frame: (frame) => options.send(frame),
|
|
110
|
+
close: (info) => {
|
|
111
|
+
if (!ended) {
|
|
112
|
+
ended = true;
|
|
113
|
+
options.close(info.code, info.reason);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
const peerChannel = local;
|
|
118
|
+
const connection = createServerConnection({
|
|
119
|
+
channel: peerChannel,
|
|
120
|
+
authorize: options.authorize,
|
|
121
|
+
resolve: options.resolve,
|
|
122
|
+
access: options.access ?? DEFAULT_HANDLE_ACCESS,
|
|
123
|
+
connectionToken: options.connectionToken ?? null,
|
|
124
|
+
binary: options.binary ?? true,
|
|
125
|
+
mcpChannels: options.mcpChannels,
|
|
126
|
+
now,
|
|
127
|
+
authorizeOperation: options.authorizeOperation
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
onFrame: (frame) => remote.send(frame),
|
|
131
|
+
onClose: (code, reason) => {
|
|
132
|
+
ended = true;
|
|
133
|
+
connection.close(code ?? 1e3, reason ?? "");
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
const createServerConnection = (args) => {
|
|
138
|
+
let sandbox = null;
|
|
139
|
+
let access = args.access;
|
|
140
|
+
let initializing = false;
|
|
141
|
+
let handle = null;
|
|
142
|
+
let expiryTimer = null;
|
|
143
|
+
const processes = /* @__PURE__ */ new Map();
|
|
144
|
+
const mcpEndpoints = /* @__PURE__ */ new Map();
|
|
145
|
+
const mcpConnections = /* @__PURE__ */ new Map();
|
|
146
|
+
let nextMcpChannelId = 0;
|
|
147
|
+
let shutdown = null;
|
|
148
|
+
const incomingByRequest = /* @__PURE__ */ new Map();
|
|
149
|
+
const scheduleExpiry = (expiresAt) => {
|
|
150
|
+
if (expiryTimer != null) clearTimeout(expiryTimer);
|
|
151
|
+
expiryTimer = null;
|
|
152
|
+
if (expiresAt == null) return;
|
|
153
|
+
const delay = Date.parse(expiresAt) - args.now();
|
|
154
|
+
if (Number.isNaN(delay)) return;
|
|
155
|
+
expiryTimer = setTimeout(
|
|
156
|
+
() => delay > 2147483647 ? scheduleExpiry(expiresAt) : peer.close(HandleRpcCloseCode.Unauthorized, "credential expired"),
|
|
157
|
+
Math.max(0, Math.min(2147483647, delay))
|
|
158
|
+
);
|
|
159
|
+
};
|
|
160
|
+
const requireSandbox = () => {
|
|
161
|
+
if (sandbox == null) {
|
|
162
|
+
throw handleRpcError({
|
|
163
|
+
code: HandleRpcErrorCode.NotInitialized,
|
|
164
|
+
message: "initialize first"
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return sandbox;
|
|
168
|
+
};
|
|
169
|
+
const checkAccess = (method, params) => {
|
|
170
|
+
if (method === HandleRpcMethod.Screen && !parseParams(handleRpcMethodSchemas[method].params, params).viewOnly && !sandboxAccessAtLeast(access.mode, SandboxAccess.Execute))
|
|
171
|
+
throw handleRpcError({
|
|
172
|
+
code: HandleRpcErrorCode.Forbidden,
|
|
173
|
+
message: "Screen input control requires execute access"
|
|
174
|
+
});
|
|
175
|
+
if (!sandboxAccessAtLeast(access.mode, SandboxAccess.Execute) && HANDLE_RPC_EXECUTE_METHODS.includes(method)) {
|
|
176
|
+
throw handleRpcError({
|
|
177
|
+
code: HandleRpcErrorCode.Forbidden,
|
|
178
|
+
message: `${method} is not allowed on a read-only binding`
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (!sandboxAccessAtLeast(access.mode, SandboxAccess.Write) && HANDLE_RPC_FILE_WRITE_METHODS.includes(method)) {
|
|
182
|
+
throw handleRpcError({
|
|
183
|
+
code: HandleRpcErrorCode.Forbidden,
|
|
184
|
+
message: `${method} is not allowed without write access`
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (!access.lifecycle && HANDLE_RPC_LIFECYCLE_METHODS.includes(method)) {
|
|
188
|
+
throw handleRpcError({
|
|
189
|
+
code: HandleRpcErrorCode.Forbidden,
|
|
190
|
+
message: `${method} is not allowed on this binding`
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const featureFlags = () => {
|
|
195
|
+
const flags = {};
|
|
196
|
+
if (handle != null) flags.providerHooks = true;
|
|
197
|
+
if (args.mcpChannels === true) flags.mcpChannels = true;
|
|
198
|
+
return flags;
|
|
199
|
+
};
|
|
200
|
+
const initialize = async (params) => {
|
|
201
|
+
const parsed = parseParams(handleRpcMethodSchemas[HandleRpcMethod.Initialize].params, params);
|
|
202
|
+
if (sandbox != null || initializing) {
|
|
203
|
+
throw handleRpcError({
|
|
204
|
+
code: HandleRpcErrorCode.InvalidRequest,
|
|
205
|
+
message: "already initialized"
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
initializing = true;
|
|
209
|
+
try {
|
|
210
|
+
const token = parsed.token ?? args.connectionToken;
|
|
211
|
+
const authorization = await args.authorize({ token });
|
|
212
|
+
if (authorization == null) {
|
|
213
|
+
setTimeout(() => peer.close(HandleRpcCloseCode.Unauthorized, "unauthorized"), 0);
|
|
214
|
+
throw handleRpcError({ code: HandleRpcErrorCode.Unauthorized, message: "unauthorized" });
|
|
215
|
+
}
|
|
216
|
+
const resolution = await args.resolve(authorization);
|
|
217
|
+
access = narrowAccess(narrowAccess(access, resolution.access), authorization.access);
|
|
218
|
+
sandbox = resolution.sandbox;
|
|
219
|
+
handle = resolution.handle ?? null;
|
|
220
|
+
scheduleExpiry(authorization.expiresAt);
|
|
221
|
+
return {
|
|
222
|
+
...await describeSandbox(sandbox, args.mcpChannels),
|
|
223
|
+
confinedFiles: true,
|
|
224
|
+
...featureFlags(),
|
|
225
|
+
expiresAt: authorization.expiresAt
|
|
226
|
+
};
|
|
227
|
+
} finally {
|
|
228
|
+
initializing = false;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const pump = (streamId, source) => {
|
|
232
|
+
peer.streams.openOutgoing(streamId, source).catch(() => void 0);
|
|
233
|
+
};
|
|
234
|
+
const mcpDescriptor = (endpoint, key) => {
|
|
235
|
+
if (!isMcpChannelEndpoint(endpoint)) return endpoint;
|
|
236
|
+
if (args.mcpChannels !== true) throw unsupported("MCP channels over the handle RPC");
|
|
237
|
+
mcpEndpoints.set(key, endpoint);
|
|
238
|
+
return { name: endpoint.name, endpointKey: key };
|
|
239
|
+
};
|
|
240
|
+
const mcpConnection = (id) => {
|
|
241
|
+
const channel = mcpConnections.get(id);
|
|
242
|
+
if (channel == null)
|
|
243
|
+
throw handleRpcError({
|
|
244
|
+
code: HandleRpcErrorCode.NotFound,
|
|
245
|
+
message: "MCP channel not found on this connection"
|
|
246
|
+
});
|
|
247
|
+
return channel;
|
|
248
|
+
};
|
|
249
|
+
const dispatch = async (context) => {
|
|
250
|
+
try {
|
|
251
|
+
return await dispatchMethod(context);
|
|
252
|
+
} catch (error) {
|
|
253
|
+
const entry = incomingByRequest.get(context.id);
|
|
254
|
+
incomingByRequest.delete(context.id);
|
|
255
|
+
if (entry != null) peer.streams.cancelIncoming(entry.streamId, "request failed");
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const dispatchMethod = async (context) => {
|
|
260
|
+
const method = parseHandleRpcMethod(context.method);
|
|
261
|
+
if (method == null) {
|
|
262
|
+
throw handleRpcError({
|
|
263
|
+
code: HandleRpcErrorCode.MethodNotFound,
|
|
264
|
+
message: `unknown method ${context.method}`
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
if (method === HandleRpcMethod.Initialize) return initialize(context.params);
|
|
268
|
+
const target = requireSandbox();
|
|
269
|
+
if (shutdown != null && method !== HandleRpcMethod.OnRuntimeShutdown)
|
|
270
|
+
throw handleRpcError({
|
|
271
|
+
code: HandleRpcErrorCode.ConnectionClosed,
|
|
272
|
+
message: "Provider handle is shutting down"
|
|
273
|
+
});
|
|
274
|
+
checkAccess(method, context.params);
|
|
275
|
+
parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
276
|
+
await args.authorizeOperation?.(context);
|
|
277
|
+
if (context.signal.aborted)
|
|
278
|
+
throw handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: "request cancelled" });
|
|
279
|
+
const abortSignal = context.signal;
|
|
280
|
+
switch (method) {
|
|
281
|
+
case HandleRpcMethod.Describe:
|
|
282
|
+
return {
|
|
283
|
+
...await describeSandbox(target, args.mcpChannels),
|
|
284
|
+
confinedFiles: true,
|
|
285
|
+
...featureFlags()
|
|
286
|
+
};
|
|
287
|
+
case HandleRpcMethod.AuthRefresh: {
|
|
288
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
289
|
+
const authorization = await args.authorize({ token: params.token });
|
|
290
|
+
if (authorization == null)
|
|
291
|
+
throw handleRpcError({ code: HandleRpcErrorCode.Unauthorized, message: "unauthorized" });
|
|
292
|
+
access = narrowAccess(access, authorization.access);
|
|
293
|
+
scheduleExpiry(authorization.expiresAt);
|
|
294
|
+
return { expiresAt: authorization.expiresAt };
|
|
295
|
+
}
|
|
296
|
+
case HandleRpcMethod.ReadFile: {
|
|
297
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
298
|
+
const stream = params.root == null ? await target.readFile({ path: params.path, abortSignal }) : await (target.confinedFileReader?.readFile ?? ((options) => confinedReadFile(target, options)))({ path: params.path, root: params.root, abortSignal });
|
|
299
|
+
if (stream == null) return { found: false };
|
|
300
|
+
const ranged = params.offset != null || params.length != null ? sliceStream(stream, params.offset ?? 0, params.length) : stream;
|
|
301
|
+
pump(params.streamId, ranged);
|
|
302
|
+
return { found: true };
|
|
303
|
+
}
|
|
304
|
+
case HandleRpcMethod.ReadTextFile: {
|
|
305
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
306
|
+
const text = await target.readTextFile({ ...params, abortSignal });
|
|
307
|
+
return { text };
|
|
308
|
+
}
|
|
309
|
+
case HandleRpcMethod.WriteFile: {
|
|
310
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
311
|
+
const incoming = incomingByRequest.get(context.id)?.stream ?? null;
|
|
312
|
+
const content = incoming ?? bytesToStream(
|
|
313
|
+
params.contentBase64 == null ? new Uint8Array() : base64ToBytes(params.contentBase64)
|
|
314
|
+
);
|
|
315
|
+
await target.writeFile({ path: params.path, content, abortSignal });
|
|
316
|
+
incomingByRequest.delete(context.id);
|
|
317
|
+
return {};
|
|
318
|
+
}
|
|
319
|
+
case HandleRpcMethod.Spawn: {
|
|
320
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
321
|
+
const stdin = incomingByRequest.get(context.id)?.stream ?? null;
|
|
322
|
+
if (processes.has(params.processId)) {
|
|
323
|
+
throw handleRpcError({
|
|
324
|
+
code: HandleRpcErrorCode.InvalidParams,
|
|
325
|
+
message: "processId already in use"
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
const child = await target.spawn({
|
|
329
|
+
command: params.command,
|
|
330
|
+
args: params.args,
|
|
331
|
+
cwd: params.cwd,
|
|
332
|
+
env: params.env,
|
|
333
|
+
shell: params.shell,
|
|
334
|
+
timeoutMs: params.timeoutMs,
|
|
335
|
+
// A closed stdin is an empty stream.
|
|
336
|
+
stdin: stdin ?? ""
|
|
337
|
+
});
|
|
338
|
+
incomingByRequest.delete(context.id);
|
|
339
|
+
processes.set(params.processId, child);
|
|
340
|
+
pump(params.stdoutStreamId, child.stdout);
|
|
341
|
+
pump(params.stderrStreamId, child.stderr);
|
|
342
|
+
return { pid: child.pid };
|
|
343
|
+
}
|
|
344
|
+
case HandleRpcMethod.ProcessWait: {
|
|
345
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
346
|
+
const child = processes.get(params.processId);
|
|
347
|
+
if (child == null)
|
|
348
|
+
throw handleRpcError({ code: HandleRpcErrorCode.NotFound, message: "no such process" });
|
|
349
|
+
const result = await new Promise((resolve, reject) => {
|
|
350
|
+
const onAbort = () => reject(handleRpcError({ code: HandleRpcErrorCode.Cancelled, message: "cancelled" }));
|
|
351
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
352
|
+
child.wait().then(
|
|
353
|
+
(value) => {
|
|
354
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
355
|
+
resolve(value);
|
|
356
|
+
},
|
|
357
|
+
(cause) => {
|
|
358
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
359
|
+
reject(cause);
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
});
|
|
363
|
+
processes.delete(params.processId);
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
case HandleRpcMethod.ProcessKill: {
|
|
367
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
368
|
+
const child = processes.get(params.processId);
|
|
369
|
+
if (child == null)
|
|
370
|
+
throw handleRpcError({ code: HandleRpcErrorCode.NotFound, message: "no such process" });
|
|
371
|
+
await child.kill(params.signal);
|
|
372
|
+
return {};
|
|
373
|
+
}
|
|
374
|
+
case HandleRpcMethod.Run: {
|
|
375
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
376
|
+
return target.run({ ...params, abortSignal });
|
|
377
|
+
}
|
|
378
|
+
case HandleRpcMethod.Stat: {
|
|
379
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
380
|
+
return {
|
|
381
|
+
stat: params.root == null ? await target.stat({ path: params.path, abortSignal }) : await (target.confinedFileReader?.stat ?? ((options) => confinedStat(target, options)))({
|
|
382
|
+
path: params.path,
|
|
383
|
+
root: params.root,
|
|
384
|
+
abortSignal
|
|
385
|
+
})
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
case HandleRpcMethod.ReadDir: {
|
|
389
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
390
|
+
return {
|
|
391
|
+
entries: params.root == null ? await target.readDir({ path: params.path, abortSignal }) : await (target.confinedFileReader?.readDir ?? ((options) => confinedReadDir(target, options)))({
|
|
392
|
+
path: params.path,
|
|
393
|
+
root: params.root,
|
|
394
|
+
abortSignal
|
|
395
|
+
})
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
case HandleRpcMethod.RemovePath: {
|
|
399
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
400
|
+
await target.removePath({ ...params, abortSignal });
|
|
401
|
+
return {};
|
|
402
|
+
}
|
|
403
|
+
case HandleRpcMethod.GetPortEndpoint: {
|
|
404
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
405
|
+
return target.getPortEndpoint(params);
|
|
406
|
+
}
|
|
407
|
+
case HandleRpcMethod.Stop:
|
|
408
|
+
await target.stop();
|
|
409
|
+
return {};
|
|
410
|
+
case HandleRpcMethod.Destroy:
|
|
411
|
+
await target.destroy();
|
|
412
|
+
return {};
|
|
413
|
+
case HandleRpcMethod.OnRuntimeShutdown: {
|
|
414
|
+
if (handle == null) throw unsupported("provider lifecycle hooks");
|
|
415
|
+
const shutdownHandle = handle;
|
|
416
|
+
shutdown ??= (async () => {
|
|
417
|
+
await Promise.allSettled([...processes.values()].map((child) => child.kill()));
|
|
418
|
+
await Promise.allSettled([...mcpConnections.values()].map((channel) => channel.close()));
|
|
419
|
+
processes.clear();
|
|
420
|
+
mcpConnections.clear();
|
|
421
|
+
mcpEndpoints.clear();
|
|
422
|
+
await shutdownHandle.onRuntimeShutdown();
|
|
423
|
+
})();
|
|
424
|
+
await shutdown;
|
|
425
|
+
return {};
|
|
426
|
+
}
|
|
427
|
+
case HandleRpcMethod.OnSandboxStop:
|
|
428
|
+
if (handle == null) throw unsupported("provider lifecycle hooks");
|
|
429
|
+
await handle.onSandboxStop();
|
|
430
|
+
return {};
|
|
431
|
+
case HandleRpcMethod.OnSandboxDelete: {
|
|
432
|
+
if (handle == null) throw unsupported("provider lifecycle hooks");
|
|
433
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
434
|
+
await handle.onSandboxDelete(params);
|
|
435
|
+
return {};
|
|
436
|
+
}
|
|
437
|
+
case HandleRpcMethod.SetNetworkPolicy: {
|
|
438
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
439
|
+
if (target.setNetworkPolicy == null) throw unsupported("network policy");
|
|
440
|
+
await target.setNetworkPolicy(params);
|
|
441
|
+
return {};
|
|
442
|
+
}
|
|
443
|
+
case HandleRpcMethod.ComputerUse: {
|
|
444
|
+
if (target.computerUse == null) throw unsupported("computer use");
|
|
445
|
+
const endpoint = await target.computerUse();
|
|
446
|
+
return mcpDescriptor(endpoint, "computerUse");
|
|
447
|
+
}
|
|
448
|
+
case HandleRpcMethod.McpOpen: {
|
|
449
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
450
|
+
const endpoint = mcpEndpoints.get(params.endpointKey);
|
|
451
|
+
if (args.mcpChannels !== true || endpoint == null)
|
|
452
|
+
throw unsupported("MCP channel endpoint");
|
|
453
|
+
const channel = await endpoint.connect({ abortSignal });
|
|
454
|
+
if (abortSignal.aborted) {
|
|
455
|
+
await channel.close();
|
|
456
|
+
abortSignal.throwIfAborted();
|
|
457
|
+
}
|
|
458
|
+
const channelId = String(++nextMcpChannelId);
|
|
459
|
+
mcpConnections.set(channelId, channel);
|
|
460
|
+
return { channelId };
|
|
461
|
+
}
|
|
462
|
+
case HandleRpcMethod.McpSend: {
|
|
463
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
464
|
+
await mcpConnection(params.channelId).send(params.message, { abortSignal });
|
|
465
|
+
return {};
|
|
466
|
+
}
|
|
467
|
+
case HandleRpcMethod.McpReceive: {
|
|
468
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
469
|
+
return { messages: await mcpConnection(params.channelId).receive({ abortSignal }) };
|
|
470
|
+
}
|
|
471
|
+
case HandleRpcMethod.McpClose: {
|
|
472
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
473
|
+
const channel = mcpConnection(params.channelId);
|
|
474
|
+
await channel.close();
|
|
475
|
+
mcpConnections.delete(params.channelId);
|
|
476
|
+
return {};
|
|
477
|
+
}
|
|
478
|
+
case HandleRpcMethod.Screen: {
|
|
479
|
+
if (target.screen == null) throw unsupported("screen");
|
|
480
|
+
const params = parseParams(handleRpcMethodSchemas[method].params, context.params);
|
|
481
|
+
return target.screen(params);
|
|
482
|
+
}
|
|
483
|
+
case HandleRpcMethod.LocalMcp:
|
|
484
|
+
if (target.localMcp == null) throw unsupported("local MCP servers");
|
|
485
|
+
return {
|
|
486
|
+
endpoints: (await target.localMcp()).flatMap(
|
|
487
|
+
(endpoint, index) => args.mcpChannels !== true && isMcpChannelEndpoint(endpoint) ? [] : [mcpDescriptor(endpoint, `localMcp:${index}:${endpoint.name}`)]
|
|
488
|
+
)
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
const beforeRequest = (context) => {
|
|
493
|
+
if (context.method !== HandleRpcMethod.WriteFile && context.method !== HandleRpcMethod.Spawn)
|
|
494
|
+
return;
|
|
495
|
+
const ids = uploadStreamIdsSchema.safeParse(context.params);
|
|
496
|
+
if (!ids.success) return;
|
|
497
|
+
const streamId = context.method === HandleRpcMethod.WriteFile ? ids.data.streamId : ids.data.stdinStreamId;
|
|
498
|
+
if (streamId == null) return;
|
|
499
|
+
const stream = peer.streams.openIncoming(streamId);
|
|
500
|
+
const floor = context.method === HandleRpcMethod.WriteFile ? SandboxAccess.Write : SandboxAccess.Execute;
|
|
501
|
+
if (sandbox == null || !sandboxAccessAtLeast(access.mode, floor)) {
|
|
502
|
+
peer.streams.cancelIncoming(streamId, "rejected");
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
incomingByRequest.set(context.id, { streamId, stream });
|
|
506
|
+
};
|
|
507
|
+
const onClose = () => {
|
|
508
|
+
if (expiryTimer != null) clearTimeout(expiryTimer);
|
|
509
|
+
for (const child of processes.values()) child.kill().catch(() => void 0);
|
|
510
|
+
for (const channel of mcpConnections.values()) void channel.close().catch(() => void 0);
|
|
511
|
+
mcpConnections.clear();
|
|
512
|
+
mcpEndpoints.clear();
|
|
513
|
+
processes.clear();
|
|
514
|
+
incomingByRequest.clear();
|
|
515
|
+
};
|
|
516
|
+
const peer = createRpcPeer({
|
|
517
|
+
channel: args.channel,
|
|
518
|
+
binary: args.binary,
|
|
519
|
+
onRequest: dispatch,
|
|
520
|
+
beforeRequest,
|
|
521
|
+
onClose
|
|
522
|
+
});
|
|
523
|
+
return { close: (code, reason) => peer.close(code, reason) };
|
|
524
|
+
};
|
|
525
|
+
const serveSandboxHandle = (args) => {
|
|
526
|
+
const access = args.access ?? DEFAULT_HANDLE_ACCESS;
|
|
527
|
+
const resolve = async () => ({
|
|
528
|
+
sandbox: args.sandbox,
|
|
529
|
+
handle: args.handle
|
|
530
|
+
});
|
|
531
|
+
const attach = (channel, context) => {
|
|
532
|
+
const connection = createServerConnection({
|
|
533
|
+
channel,
|
|
534
|
+
authorize: args.authorize,
|
|
535
|
+
resolve,
|
|
536
|
+
access,
|
|
537
|
+
connectionToken: context?.token ?? null,
|
|
538
|
+
binary: args.binary ?? true,
|
|
539
|
+
mcpChannels: args.mcpChannels,
|
|
540
|
+
now: args.now ?? Date.now
|
|
541
|
+
});
|
|
542
|
+
return () => connection.close(HandleRpcCloseCode.Normal, "closed");
|
|
543
|
+
};
|
|
544
|
+
return {
|
|
545
|
+
attach,
|
|
546
|
+
attachWebSocket: (socket, context) => attach(frameChannelFromWebSocket(socket).channel, context),
|
|
547
|
+
attachStream: (stream, context) => attach(frameChannelFromStream(stream), context),
|
|
548
|
+
messageHandler: (handlerArgs) => createHandleRpcMessageHandler({
|
|
549
|
+
send: handlerArgs.send,
|
|
550
|
+
close: handlerArgs.close,
|
|
551
|
+
authorize: args.authorize,
|
|
552
|
+
resolve,
|
|
553
|
+
access,
|
|
554
|
+
connectionToken: handlerArgs.token ?? null,
|
|
555
|
+
binary: args.binary,
|
|
556
|
+
mcpChannels: args.mcpChannels,
|
|
557
|
+
now: args.now
|
|
558
|
+
})
|
|
559
|
+
};
|
|
560
|
+
};
|
|
561
|
+
export {
|
|
562
|
+
DEFAULT_HANDLE_ACCESS,
|
|
563
|
+
createHandleRpcMessageHandler,
|
|
564
|
+
describeSandbox,
|
|
565
|
+
serveSandboxHandle
|
|
566
|
+
};
|
|
567
|
+
//# sourceMappingURL=server.mjs.map
|