@finalai/final-agent-provider 0.10.1 → 0.12.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.
Files changed (198) hide show
  1. package/HOSTING.md +334 -245
  2. package/README.md +125 -46
  3. package/WORKSPACE-EGRESS.md +11 -11
  4. package/dist/modules/catalog.d.mts +9 -0
  5. package/dist/modules/catalog.mjs +21 -0
  6. package/dist/modules/catalog.mjs.map +7 -0
  7. package/dist/modules/harnesses/acp-agent.d.mts +4 -0
  8. package/dist/modules/harnesses/acp-agent.mjs +35 -0
  9. package/dist/modules/harnesses/acp-agent.mjs.map +7 -0
  10. package/dist/modules/harnesses/adapters.d.mts +7 -0
  11. package/dist/modules/harnesses/adapters.mjs +74 -0
  12. package/dist/modules/harnesses/adapters.mjs.map +7 -0
  13. package/dist/modules/harnesses/claude-code.d.mts +14 -0
  14. package/dist/modules/harnesses/claude-code.mjs +79 -0
  15. package/dist/modules/harnesses/claude-code.mjs.map +7 -0
  16. package/dist/modules/harnesses/codex.d.mts +12 -0
  17. package/dist/modules/harnesses/codex.mjs +90 -0
  18. package/dist/modules/harnesses/codex.mjs.map +7 -0
  19. package/dist/modules/harnesses/config-fields.d.mts +98 -57
  20. package/dist/modules/harnesses/config-fields.mjs +58 -35
  21. package/dist/modules/harnesses/config-fields.mjs.map +3 -3
  22. package/dist/modules/harnesses/definitions.d.mts +3 -0
  23. package/dist/modules/harnesses/definitions.mjs +21 -0
  24. package/dist/modules/harnesses/definitions.mjs.map +7 -0
  25. package/dist/modules/harnesses/fidelity.d.mts +1 -1
  26. package/dist/modules/harnesses/fidelity.mjs +17 -14
  27. package/dist/modules/harnesses/fidelity.mjs.map +2 -2
  28. package/dist/modules/harnesses/final.d.mts +12 -0
  29. package/dist/modules/harnesses/final.mjs +70 -0
  30. package/dist/modules/harnesses/final.mjs.map +7 -0
  31. package/dist/modules/harnesses/index.d.mts +13 -12
  32. package/dist/modules/harnesses/index.mjs +86 -45
  33. package/dist/modules/harnesses/index.mjs.map +3 -3
  34. package/dist/modules/harnesses/names.d.mts +43 -0
  35. package/dist/modules/harnesses/names.mjs +59 -0
  36. package/dist/modules/harnesses/names.mjs.map +7 -0
  37. package/dist/modules/harnesses/nanocode-claude.d.mts +18 -0
  38. package/dist/modules/harnesses/nanocode-claude.mjs +101 -0
  39. package/dist/modules/harnesses/nanocode-claude.mjs.map +7 -0
  40. package/dist/modules/harnesses/nanocode-codex.d.mts +13 -0
  41. package/dist/modules/harnesses/nanocode-codex.mjs +64 -0
  42. package/dist/modules/harnesses/nanocode-codex.mjs.map +7 -0
  43. package/dist/modules/harnesses/pi.d.mts +12 -0
  44. package/dist/modules/harnesses/pi.mjs +71 -0
  45. package/dist/modules/harnesses/pi.mjs.map +7 -0
  46. package/dist/modules/integrations.d.mts +9 -0
  47. package/dist/modules/integrations.mjs +29 -0
  48. package/dist/modules/integrations.mjs.map +7 -0
  49. package/dist/modules/provider/general.bundle.d.mts +1 -0
  50. package/dist/modules/provider/general.bundle.mjs +5 -0
  51. package/dist/modules/provider/general.bundle.mjs.map +7 -0
  52. package/dist/modules/provider/general.d.mts +11 -0
  53. package/dist/modules/provider/general.mjs +130 -0
  54. package/dist/modules/provider/general.mjs.map +7 -0
  55. package/dist/modules/provider/index.d.mts +3 -0
  56. package/dist/modules/provider/index.mjs +13 -0
  57. package/dist/modules/provider/index.mjs.map +7 -0
  58. package/dist/modules/sandboxes/access.d.mts +34 -0
  59. package/dist/modules/sandboxes/access.mjs +15 -0
  60. package/dist/modules/sandboxes/access.mjs.map +7 -0
  61. package/dist/modules/sandboxes/computer.d.mts +24 -51
  62. package/dist/modules/sandboxes/computer.mjs +523 -888
  63. package/dist/modules/sandboxes/computer.mjs.map +3 -3
  64. package/dist/modules/sandboxes/computers-api.d.mts +3 -2
  65. package/dist/modules/sandboxes/computers-api.mjs +2 -4
  66. package/dist/modules/sandboxes/computers-api.mjs.map +2 -2
  67. package/dist/modules/sandboxes/device-api.d.mts +4 -3
  68. package/dist/modules/sandboxes/device-api.mjs +2 -4
  69. package/dist/modules/sandboxes/device-api.mjs.map +2 -2
  70. package/dist/modules/sandboxes/device.d.mts +6 -6
  71. package/dist/modules/sandboxes/device.mjs +126 -121
  72. package/dist/modules/sandboxes/device.mjs.map +3 -3
  73. package/dist/modules/sandboxes/egress.d.mts +10 -9
  74. package/dist/modules/sandboxes/egress.mjs +73 -56
  75. package/dist/modules/sandboxes/egress.mjs.map +2 -2
  76. package/dist/modules/sandboxes/environment.d.mts +35 -269
  77. package/dist/modules/sandboxes/environment.mjs +27 -104
  78. package/dist/modules/sandboxes/environment.mjs.map +3 -3
  79. package/dist/modules/sandboxes/index.d.mts +9 -69
  80. package/dist/modules/sandboxes/index.mjs +35 -95
  81. package/dist/modules/sandboxes/index.mjs.map +3 -3
  82. package/dist/modules/sandboxes/local.d.mts +29 -0
  83. package/dist/modules/sandboxes/local.mjs +555 -0
  84. package/dist/modules/sandboxes/local.mjs.map +7 -0
  85. package/dist/modules/sandboxes/session.d.mts +0 -3
  86. package/dist/modules/sandboxes/session.mjs +2 -22
  87. package/dist/modules/sandboxes/session.mjs.map +2 -2
  88. package/dist/modules/sandboxes/testing/fake-machine.mjs +0 -28
  89. package/dist/modules/sandboxes/testing/fake-machine.mjs.map +2 -2
  90. package/package.json +73 -137
  91. package/dist/modules/authoring-final-channel.d.mts +0 -3
  92. package/dist/modules/authoring-final-channel.mjs +0 -10
  93. package/dist/modules/authoring-final-channel.mjs.map +0 -7
  94. package/dist/modules/channel-factories.d.mts +0 -40
  95. package/dist/modules/channel-factories.mjs +0 -212
  96. package/dist/modules/channel-factories.mjs.map +0 -7
  97. package/dist/modules/channels/content.d.mts +0 -6
  98. package/dist/modules/channels/content.mjs +0 -31
  99. package/dist/modules/channels/content.mjs.map +0 -7
  100. package/dist/modules/channels/delivery.d.mts +0 -54
  101. package/dist/modules/channels/delivery.mjs +0 -243
  102. package/dist/modules/channels/delivery.mjs.map +0 -7
  103. package/dist/modules/channels/direct-messaging.d.mts +0 -5
  104. package/dist/modules/channels/direct-messaging.mjs +0 -8
  105. package/dist/modules/channels/direct-messaging.mjs.map +0 -7
  106. package/dist/modules/channels/fake-platform.d.mts +0 -36
  107. package/dist/modules/channels/fake-platform.mjs +0 -168
  108. package/dist/modules/channels/fake-platform.mjs.map +0 -7
  109. package/dist/modules/channels/group-messaging.d.mts +0 -5
  110. package/dist/modules/channels/group-messaging.mjs +0 -8
  111. package/dist/modules/channels/group-messaging.mjs.map +0 -7
  112. package/dist/modules/channels/inbound.d.mts +0 -52
  113. package/dist/modules/channels/inbound.mjs +0 -42
  114. package/dist/modules/channels/inbound.mjs.map +0 -7
  115. package/dist/modules/channels/index.d.mts +0 -9
  116. package/dist/modules/channels/index.mjs +0 -10
  117. package/dist/modules/channels/index.mjs.map +0 -7
  118. package/dist/modules/channels/messaging-channel.d.mts +0 -7
  119. package/dist/modules/channels/messaging-channel.mjs +0 -99
  120. package/dist/modules/channels/messaging-channel.mjs.map +0 -7
  121. package/dist/modules/channels/projection.d.mts +0 -36
  122. package/dist/modules/channels/projection.mjs +0 -233
  123. package/dist/modules/channels/projection.mjs.map +0 -7
  124. package/dist/modules/channels/prompt.d.mts +0 -72
  125. package/dist/modules/channels/prompt.mjs +0 -208
  126. package/dist/modules/channels/prompt.mjs.map +0 -7
  127. package/dist/modules/channels/routing.d.mts +0 -5
  128. package/dist/modules/channels/routing.mjs +0 -53
  129. package/dist/modules/channels/routing.mjs.map +0 -7
  130. package/dist/modules/connections.d.mts +0 -11
  131. package/dist/modules/connections.mjs +0 -16
  132. package/dist/modules/connections.mjs.map +0 -7
  133. package/dist/modules/harnesses/acp-describe.d.mts +0 -20
  134. package/dist/modules/harnesses/acp-describe.mjs +0 -110
  135. package/dist/modules/harnesses/acp-describe.mjs.map +0 -7
  136. package/dist/modules/harnesses/local-stdio.d.mts +0 -47
  137. package/dist/modules/harnesses/local-stdio.mjs +0 -41
  138. package/dist/modules/harnesses/local-stdio.mjs.map +0 -7
  139. package/dist/modules/harnesses/remote-acp.d.mts +0 -76
  140. package/dist/modules/harnesses/remote-acp.mjs +0 -83
  141. package/dist/modules/harnesses/remote-acp.mjs.map +0 -7
  142. package/dist/modules/harnesses/remote-claude-code.d.mts +0 -88
  143. package/dist/modules/harnesses/remote-claude-code.mjs +0 -113
  144. package/dist/modules/harnesses/remote-claude-code.mjs.map +0 -7
  145. package/dist/modules/harnesses/remote-client-tls.d.mts +0 -35
  146. package/dist/modules/harnesses/remote-client-tls.mjs +0 -37
  147. package/dist/modules/harnesses/remote-client-tls.mjs.map +0 -7
  148. package/dist/modules/harnesses/remote-codex.d.mts +0 -98
  149. package/dist/modules/harnesses/remote-codex.mjs +0 -128
  150. package/dist/modules/harnesses/remote-codex.mjs.map +0 -7
  151. package/dist/modules/harnesses/remote-pi.d.mts +0 -78
  152. package/dist/modules/harnesses/remote-pi.mjs +0 -104
  153. package/dist/modules/harnesses/remote-pi.mjs.map +0 -7
  154. package/dist/modules/harnesses/remote-url.d.mts +0 -5
  155. package/dist/modules/harnesses/remote-url.mjs +0 -19
  156. package/dist/modules/harnesses/remote-url.mjs.map +0 -7
  157. package/dist/modules/harnesses/serverless-final.d.mts +0 -63
  158. package/dist/modules/harnesses/serverless-final.mjs +0 -88
  159. package/dist/modules/harnesses/serverless-final.mjs.map +0 -7
  160. package/dist/modules/harnesses/serverless-nanocode-claude.d.mts +0 -64
  161. package/dist/modules/harnesses/serverless-nanocode-claude.mjs +0 -105
  162. package/dist/modules/harnesses/serverless-nanocode-claude.mjs.map +0 -7
  163. package/dist/modules/harnesses/serverless-nanocode-codex.d.mts +0 -66
  164. package/dist/modules/harnesses/serverless-nanocode-codex.mjs +0 -113
  165. package/dist/modules/harnesses/serverless-nanocode-codex.mjs.map +0 -7
  166. package/dist/modules/harnesses/serverless-pi.d.mts +0 -64
  167. package/dist/modules/harnesses/serverless-pi.mjs +0 -98
  168. package/dist/modules/harnesses/serverless-pi.mjs.map +0 -7
  169. package/dist/modules/runtime/index.d.mts +0 -7
  170. package/dist/modules/runtime/index.mjs +0 -18
  171. package/dist/modules/runtime/index.mjs.map +0 -7
  172. package/dist/modules/runtime/local-stdio.d.mts +0 -10
  173. package/dist/modules/runtime/local-stdio.mjs +0 -106
  174. package/dist/modules/runtime/local-stdio.mjs.map +0 -7
  175. package/dist/modules/runtime/remote-acp.d.mts +0 -16
  176. package/dist/modules/runtime/remote-acp.mjs +0 -152
  177. package/dist/modules/runtime/remote-acp.mjs.map +0 -7
  178. package/dist/modules/runtime/remote-claude-code.d.mts +0 -5
  179. package/dist/modules/runtime/remote-claude-code.mjs +0 -47
  180. package/dist/modules/runtime/remote-claude-code.mjs.map +0 -7
  181. package/dist/modules/runtime/remote-codex.d.mts +0 -5
  182. package/dist/modules/runtime/remote-codex.mjs +0 -47
  183. package/dist/modules/runtime/remote-codex.mjs.map +0 -7
  184. package/dist/modules/runtime/remote-host.d.mts +0 -127
  185. package/dist/modules/runtime/remote-host.mjs +0 -387
  186. package/dist/modules/runtime/remote-host.mjs.map +0 -7
  187. package/dist/modules/runtime/remote-pi.d.mts +0 -5
  188. package/dist/modules/runtime/remote-pi.mjs +0 -44
  189. package/dist/modules/runtime/remote-pi.mjs.map +0 -7
  190. package/dist/modules/sandboxes/guide.d.mts +0 -35
  191. package/dist/modules/sandboxes/guide.mjs +0 -119
  192. package/dist/modules/sandboxes/guide.mjs.map +0 -7
  193. package/dist/modules/sandboxes/workspace-setup.d.mts +0 -42
  194. package/dist/modules/sandboxes/workspace-setup.mjs +0 -242
  195. package/dist/modules/sandboxes/workspace-setup.mjs.map +0 -7
  196. package/dist/modules/testing/harness.d.mts +0 -9
  197. package/dist/modules/testing/harness.mjs +0 -123
  198. package/dist/modules/testing/harness.mjs.map +0 -7
@@ -0,0 +1,555 @@
1
+ import { Capability, FilesAccess, ShellAccess } from "@finalai/agent-protocol";
2
+ import { NetworkPolicy } from "@finalai/agent-provider";
3
+ import {
4
+ defineSandboxProvider,
5
+ encodeSandboxText,
6
+ PLATFORM_ENVIRONMENT_NAMES,
7
+ platformProcessEnvironment,
8
+ PortProtocol,
9
+ readTextFileStream,
10
+ reportPlatformNetworkPolicy,
11
+ runCollect,
12
+ SandboxEntryType
13
+ } from "@finalai/agent-provider/sandbox";
14
+ import * as z from "zod";
15
+ const LOCAL_PROVIDER = "local";
16
+ const LOCAL_INHERITED_ENV = [
17
+ "PATH",
18
+ "HOME",
19
+ "USER",
20
+ "LANG",
21
+ "LC_ALL",
22
+ "TMPDIR",
23
+ "TERM",
24
+ "SHELL"
25
+ ];
26
+ const fsError = (code, message) => Object.assign(new Error(`${code}: ${message}`), { code });
27
+ const errorCode = (error) => {
28
+ const parsed = z.object({ code: z.string() }).safeParse(error);
29
+ return parsed.success ? parsed.data.code : null;
30
+ };
31
+ const missing = (error) => {
32
+ const code = errorCode(error);
33
+ return code === "ENOENT" || code === "ENOTDIR";
34
+ };
35
+ const signalExitCode = (signal) => {
36
+ if (signal === "SIGKILL") return 137;
37
+ if (signal === "SIGINT") return 130;
38
+ return 143;
39
+ };
40
+ const loadNode = () => {
41
+ if (globalThis.process?.getBuiltinModule == null)
42
+ throw new Error("A local sandbox runs only in Node");
43
+ return {
44
+ childProcess: process.getBuiltinModule("node:child_process"),
45
+ fs: process.getBuiltinModule("node:fs"),
46
+ fsPromises: process.getBuiltinModule("node:fs/promises"),
47
+ os: process.getBuiltinModule("node:os"),
48
+ path: process.getBuiltinModule("node:path"),
49
+ streamPromises: process.getBuiltinModule("node:stream/promises")
50
+ };
51
+ };
52
+ let loaded = null;
53
+ const node = () => loaded ??= loadNode();
54
+ const isSignal = (value) => value in node().os.constants.signals;
55
+ const drained = (stream) => new Promise((resolve) => {
56
+ const done = () => {
57
+ stream.off("drain", done);
58
+ stream.off("close", done);
59
+ stream.off("error", done);
60
+ resolve();
61
+ };
62
+ stream.once("drain", done);
63
+ stream.once("close", done);
64
+ stream.once("error", done);
65
+ });
66
+ const BRIDGE_HIGH_WATER_BYTES = 64 * 1024;
67
+ const nodeToWeb = (readable, extra) => {
68
+ let open = true;
69
+ return new ReadableStream(
70
+ {
71
+ start: (controller) => {
72
+ const close = () => {
73
+ if (!open) return;
74
+ open = false;
75
+ controller.close();
76
+ };
77
+ const push = (bytes) => {
78
+ if (!open) return;
79
+ controller.enqueue(bytes);
80
+ if ((controller.desiredSize ?? 0) <= 0) readable?.pause();
81
+ };
82
+ extra?.({ push, close });
83
+ if (readable == null) {
84
+ close();
85
+ return;
86
+ }
87
+ readable.on("data", (chunk) => push(new Uint8Array(chunk)));
88
+ readable.pause();
89
+ readable.once("end", close);
90
+ readable.once("error", (error) => {
91
+ if (!open) return;
92
+ open = false;
93
+ controller.error(error);
94
+ });
95
+ },
96
+ pull: () => {
97
+ readable?.resume();
98
+ },
99
+ cancel: () => {
100
+ open = false;
101
+ readable?.destroy();
102
+ }
103
+ },
104
+ { highWaterMark: BRIDGE_HIGH_WATER_BYTES, size: (chunk) => chunk.byteLength }
105
+ );
106
+ };
107
+ const LOCAL_STOP_GRACE_MS = 2e3;
108
+ const pause = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
109
+ const within = async (promise, ms) => {
110
+ let timer;
111
+ try {
112
+ return await Promise.race([
113
+ promise.then(() => true),
114
+ new Promise((resolve) => {
115
+ timer = setTimeout(() => resolve(false), Math.max(0, ms));
116
+ })
117
+ ]);
118
+ } finally {
119
+ clearTimeout(timer);
120
+ }
121
+ };
122
+ const MAX_SYMLINKS = 40;
123
+ const ownGroup = () => process.platform !== "win32";
124
+ const signalProcessTree = (child, signal) => {
125
+ if (ownGroup() && child.pid != null) {
126
+ try {
127
+ process.kill(-child.pid, signal);
128
+ return;
129
+ } catch {
130
+ }
131
+ }
132
+ child.kill(signal);
133
+ };
134
+ const inside = (root, path) => {
135
+ const { isAbsolute, relative, sep } = node().path;
136
+ const rel = relative(root, path);
137
+ return rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
138
+ };
139
+ const createLocalSandbox = async (options) => {
140
+ const { childProcess, fs, fsPromises, path: paths, streamPromises } = node();
141
+ const root = paths.resolve(options.root);
142
+ await fsPromises.mkdir(root, { recursive: true });
143
+ const realRoot = await fsPromises.realpath(root);
144
+ const id = options.id ?? `local-${crypto.randomUUID()}`;
145
+ const processes = /* @__PURE__ */ new Set();
146
+ const groups = /* @__PURE__ */ new Set();
147
+ const groupAlive = (pgid) => {
148
+ try {
149
+ process.kill(-pgid, 0);
150
+ return true;
151
+ } catch {
152
+ return false;
153
+ }
154
+ };
155
+ const inherited = {};
156
+ for (const name of options.inheritEnv ?? LOCAL_INHERITED_ENV) {
157
+ const value = process.env[name];
158
+ if (value != null) inherited[name] = value;
159
+ }
160
+ const resolvePath = (path) => paths.isAbsolute(path) ? paths.resolve(path) : paths.join(root, path);
161
+ const confined = async (path, within2) => {
162
+ const bounds = within2 == null ? [realRoot] : [realRoot, await confined(within2)];
163
+ let existing = resolvePath(path);
164
+ const rest = [];
165
+ let links = 0;
166
+ for (; ; ) {
167
+ const real = await fsPromises.realpath(existing).catch((error) => {
168
+ if (missing(error)) return null;
169
+ throw error;
170
+ });
171
+ if (real != null) {
172
+ const target = paths.join(real, ...rest.toReversed());
173
+ for (const bound of bounds)
174
+ if (!inside(bound, target)) throw fsError("EACCES", `${path} is outside the sandbox`);
175
+ return target;
176
+ }
177
+ const entry = await fsPromises.lstat(existing).catch((error) => {
178
+ if (missing(error)) return null;
179
+ throw error;
180
+ });
181
+ if (entry?.isSymbolicLink() === true) {
182
+ links += 1;
183
+ if (links > MAX_SYMLINKS) throw fsError("ELOOP", `${path} has too many symlinks`);
184
+ const directory = await fsPromises.realpath(paths.dirname(existing));
185
+ existing = paths.resolve(directory, await fsPromises.readlink(existing));
186
+ continue;
187
+ }
188
+ const parent = paths.dirname(existing);
189
+ if (parent === existing) throw fsError("ENOENT", `${path} does not exist`);
190
+ rest.push(paths.basename(existing));
191
+ existing = parent;
192
+ }
193
+ };
194
+ const confinedEntry = async (path) => {
195
+ const logical = resolvePath(path);
196
+ if (logical === root) throw fsError("EPERM", "refusing to remove the sandbox root");
197
+ return paths.join(await confined(paths.dirname(logical)), paths.basename(logical));
198
+ };
199
+ const statOf = async (path, within2) => {
200
+ let target;
201
+ try {
202
+ target = await confined(path, within2);
203
+ const entry = await fsPromises.stat(target);
204
+ return {
205
+ path: resolvePath(path),
206
+ type: entry.isDirectory() ? SandboxEntryType.Directory : entry.isFile() ? SandboxEntryType.File : SandboxEntryType.Other,
207
+ size: entry.isDirectory() ? 0 : entry.size,
208
+ modifiedAt: entry.mtime.toISOString(),
209
+ mode: entry.mode & 4095
210
+ };
211
+ } catch (error) {
212
+ if (missing(error)) return null;
213
+ throw error;
214
+ }
215
+ };
216
+ const writeBytes = async (path, data) => {
217
+ const target = await confined(path);
218
+ await fsPromises.mkdir(paths.dirname(target), { recursive: true });
219
+ await fsPromises.writeFile(target, data);
220
+ };
221
+ const spawn = async (spawnOptions) => {
222
+ const signal = spawnOptions.abortSignal;
223
+ signal?.throwIfAborted();
224
+ const cwd = await confined(spawnOptions.cwd ?? ".");
225
+ signal?.throwIfAborted();
226
+ const base = await options.baseEnv?.();
227
+ signal?.throwIfAborted();
228
+ const env = { ...inherited, ...options.env, ...base, ...spawnOptions.env };
229
+ const shell = spawnOptions.shell === true;
230
+ const child = childProcess.spawn(
231
+ shell ? [spawnOptions.command, ...spawnOptions.args ?? []].join(" ") : spawnOptions.command,
232
+ shell ? [] : spawnOptions.args ?? [],
233
+ { cwd, env, shell, stdio: ["pipe", "pipe", "pipe"], detached: ownGroup() }
234
+ );
235
+ processes.add(child);
236
+ if (ownGroup() && child.pid != null) {
237
+ for (const pgid of groups) if (!groupAlive(pgid)) groups.delete(pgid);
238
+ groups.add(child.pid);
239
+ }
240
+ let timedOut = false;
241
+ const stderr = nodeToWeb(
242
+ child.stderr,
243
+ ({ push, close }) => child.once("error", (error) => {
244
+ push(new TextEncoder().encode(`${error.message}
245
+ `));
246
+ close();
247
+ })
248
+ );
249
+ const exited = new Promise((settle) => {
250
+ child.once("error", (error) => {
251
+ processes.delete(child);
252
+ settle({ exitCode: errorCode(error) === "ENOENT" ? 127 : 126 });
253
+ });
254
+ child.once("exit", (code, signal2) => {
255
+ processes.delete(child);
256
+ settle({ exitCode: timedOut ? 124 : code ?? signalExitCode(signal2) });
257
+ });
258
+ });
259
+ const timer = spawnOptions.timeoutMs == null ? null : setTimeout(() => {
260
+ timedOut = true;
261
+ signalProcessTree(child, "SIGKILL");
262
+ }, spawnOptions.timeoutMs);
263
+ let escalation = null;
264
+ const terminate = (signal2) => {
265
+ signalProcessTree(child, signal2);
266
+ if (signal2 !== "SIGTERM" || escalation != null) return;
267
+ escalation = setTimeout(() => signalProcessTree(child, "SIGKILL"), LOCAL_STOP_GRACE_MS);
268
+ };
269
+ const onAbort = () => terminate("SIGTERM");
270
+ spawnOptions.abortSignal?.addEventListener("abort", onAbort, { once: true });
271
+ const settled = () => {
272
+ if (timer != null) clearTimeout(timer);
273
+ const groupLeft = ownGroup() && child.pid != null && groupAlive(child.pid);
274
+ if (escalation != null && !groupLeft) clearTimeout(escalation);
275
+ spawnOptions.abortSignal?.removeEventListener("abort", onAbort);
276
+ };
277
+ child.once("close", settled);
278
+ child.once("error", settled);
279
+ const stdin = child.stdin;
280
+ stdin?.on("error", () => void 0);
281
+ if (typeof spawnOptions.stdin === "string") stdin?.end(spawnOptions.stdin);
282
+ else if (spawnOptions.stdin != null) {
283
+ const reader = spawnOptions.stdin.getReader();
284
+ let finished = false;
285
+ void exited.then(() => {
286
+ finished = true;
287
+ void reader.cancel().catch(() => void 0);
288
+ });
289
+ void (async () => {
290
+ for (; ; ) {
291
+ const next = await reader.read();
292
+ if (next.done || finished || stdin == null || stdin.destroyed) break;
293
+ if (!stdin.write(next.value)) await Promise.race([drained(stdin), exited]);
294
+ }
295
+ stdin?.end();
296
+ })().catch(() => stdin?.destroy());
297
+ }
298
+ return {
299
+ pid: child.pid == null ? null : String(child.pid),
300
+ ref: null,
301
+ stdout: nodeToWeb(child.stdout),
302
+ stderr,
303
+ write: async (data, writeOptions) => {
304
+ if (spawnOptions.stdin != null) throw new Error("stdin was provided at spawn");
305
+ if (stdin == null) throw new Error("the process has no stdin");
306
+ await new Promise(
307
+ (done, fail) => stdin.write(data, (error) => error == null ? done() : fail(error))
308
+ );
309
+ if (writeOptions?.end === true) stdin.end();
310
+ },
311
+ wait: () => exited,
312
+ // SIGTERM (killed after the grace period if ignored) and SIGKILL resolve once the
313
+ // command has ended; any other signal (SIGSTOP, SIGCONT, ...) once it is sent.
314
+ kill: async (signal2) => {
315
+ const name = signal2 ?? "SIGTERM";
316
+ const sent = isSignal(name) ? name : "SIGTERM";
317
+ terminate(sent);
318
+ if (sent === "SIGTERM" || sent === "SIGKILL") await exited;
319
+ }
320
+ };
321
+ };
322
+ const sandbox = {
323
+ id,
324
+ root,
325
+ defaultWorkingDirectory: root,
326
+ ports: [],
327
+ description: `This machine, in ${root}.`,
328
+ readFile: async ({ path, root: within2 }) => {
329
+ let target;
330
+ try {
331
+ target = await confined(path, within2);
332
+ const entry = await fsPromises.stat(target);
333
+ if (entry.isDirectory()) throw fsError("EISDIR", `${path} is a directory`);
334
+ } catch (error) {
335
+ if (missing(error)) return null;
336
+ throw error;
337
+ }
338
+ return nodeToWeb(fs.createReadStream(target));
339
+ },
340
+ readBinaryFile: async ({ path }) => {
341
+ try {
342
+ return new Uint8Array(await fsPromises.readFile(await confined(path)));
343
+ } catch (error) {
344
+ if (missing(error)) return null;
345
+ throw error;
346
+ }
347
+ },
348
+ readTextFile: async (readOptions) => {
349
+ const stream = await sandbox.readFile({ path: readOptions.path });
350
+ return stream == null ? null : readTextFileStream(stream, readOptions);
351
+ },
352
+ writeFile: async ({ path, content }) => {
353
+ const target = await confined(path);
354
+ await fsPromises.mkdir(paths.dirname(target), { recursive: true });
355
+ const reader = content.getReader();
356
+ const output = fs.createWriteStream(target);
357
+ await streamPromises.pipeline(
358
+ (async function* () {
359
+ for (; ; ) {
360
+ const next = await reader.read();
361
+ if (next.done) return;
362
+ yield next.value;
363
+ }
364
+ })(),
365
+ output
366
+ );
367
+ },
368
+ writeBinaryFile: ({ path, content }) => writeBytes(path, content),
369
+ writeTextFile: ({ path, content, encoding }) => writeBytes(path, encodeSandboxText(content, encoding)),
370
+ spawn,
371
+ run: (runOptions) => runCollect({ spawn }, runOptions),
372
+ stat: ({ path, root: within2 }) => statOf(path, within2),
373
+ readDir: async ({ path, root: within2 }) => {
374
+ const target = await confined(path, within2);
375
+ const logical = resolvePath(path);
376
+ const entries = await fsPromises.readdir(target, { withFileTypes: true });
377
+ return Promise.all(
378
+ entries.map(async (entry) => {
379
+ const type = entry.isDirectory() ? SandboxEntryType.Directory : entry.isFile() ? SandboxEntryType.File : entry.isSymbolicLink() ? SandboxEntryType.Symlink : SandboxEntryType.Other;
380
+ const size = entry.isFile() ? (await fsPromises.lstat(paths.join(target, entry.name))).size : null;
381
+ return { name: entry.name, path: paths.join(logical, entry.name), type, size };
382
+ })
383
+ );
384
+ },
385
+ resolvePath,
386
+ removePath: async ({ path, recursive, force }) => {
387
+ const target = await confinedEntry(path);
388
+ await fsPromises.rm(target, { recursive: recursive === true, force: force === true });
389
+ },
390
+ getPortEndpoint: async ({ port, protocol }) => ({
391
+ url: `${protocol ?? PortProtocol.Http}://127.0.0.1:${port}`
392
+ }),
393
+ getPortUrl: async (portOptions) => (await sandbox.getPortEndpoint(portOptions)).url,
394
+ // Stopping ends the commands it started; the directory is the caller's and stays.
395
+ // A command that ignores SIGTERM is killed once the grace period ends.
396
+ stop: async () => {
397
+ const children = [...processes];
398
+ const pgids = new Set(groups);
399
+ groups.clear();
400
+ for (const child of children) if (ownGroup() && child.pid != null) pgids.add(child.pid);
401
+ const closed = Promise.all(
402
+ children.map(
403
+ (child) => new Promise((done) => {
404
+ if (child.exitCode != null || child.signalCode != null) done();
405
+ else child.once("exit", () => done());
406
+ })
407
+ )
408
+ );
409
+ const signalAll = (signal) => {
410
+ for (const child of children) signalProcessTree(child, signal);
411
+ for (const pgid of pgids) {
412
+ try {
413
+ process.kill(-pgid, signal);
414
+ } catch {
415
+ }
416
+ }
417
+ };
418
+ const settled = async (deadline) => {
419
+ if (!await within(closed, deadline - Date.now())) return false;
420
+ while ([...pgids].some(groupAlive)) {
421
+ if (Date.now() >= deadline) return false;
422
+ await pause(25);
423
+ }
424
+ return true;
425
+ };
426
+ signalAll("SIGTERM");
427
+ if (await settled(Date.now() + LOCAL_STOP_GRACE_MS)) return;
428
+ signalAll("SIGKILL");
429
+ await settled(Date.now() + LOCAL_STOP_GRACE_MS);
430
+ },
431
+ destroy: () => sandbox.stop()
432
+ };
433
+ return sandbox;
434
+ };
435
+ const localEnvironmentSchema = z.strictObject({
436
+ root: z.string().min(1),
437
+ // The platform's variables (its proxy, its CA) are its own to set.
438
+ env: z.record(z.string(), z.string()).refine(
439
+ (env) => Object.keys(env).every((name) => !PLATFORM_ENVIRONMENT_NAMES.has(name)),
440
+ "env sets a variable the platform owns"
441
+ ).optional(),
442
+ inheritEnv: z.array(z.string().min(1)).optional()
443
+ });
444
+ const localStateSchema = z.object({ version: z.literal(1), root: z.string() });
445
+ const LOCAL_PLATFORM_DIRECTORY = ".final";
446
+ const platformFileTarget = (root, path) => {
447
+ const paths = node().path;
448
+ const components = path.slice(paths.parse(path).root.length).split(/[\\/]/).filter((component) => component !== "" && component !== ".");
449
+ if (components.length === 0 || components.includes(".."))
450
+ throw new Error(
451
+ `refusing the platform file ${JSON.stringify(path)}: it must name a file without ..`
452
+ );
453
+ return paths.join(root, LOCAL_PLATFORM_DIRECTORY, ...components);
454
+ };
455
+ const relocatedEnvironment = (env, moved) => {
456
+ if (moved == null || moved.size === 0) return env;
457
+ const result = {};
458
+ for (const [name, value] of Object.entries(env)) result[name] = moved.get(value) ?? value;
459
+ return result;
460
+ };
461
+ const handleOf = (sandbox, forget) => ({
462
+ sandbox,
463
+ onSandboxStop: () => {
464
+ forget();
465
+ return sandbox.stop();
466
+ },
467
+ onSandboxDelete: () => {
468
+ forget();
469
+ return sandbox.destroy();
470
+ },
471
+ onRuntimeShutdown: () => {
472
+ forget();
473
+ return sandbox.stop();
474
+ }
475
+ });
476
+ const createLocalSandboxProvider = () => {
477
+ const live = /* @__PURE__ */ new Map();
478
+ const relocated = /* @__PURE__ */ new Map();
479
+ return defineSandboxProvider({
480
+ name: LOCAL_PROVIDER,
481
+ environment: (rawOptions) => {
482
+ const options = localEnvironmentSchema.parse(rawOptions);
483
+ const root = node().path.resolve(options.root);
484
+ const open = async (ctx, sandboxId) => {
485
+ const sandbox = await createLocalSandbox({
486
+ root,
487
+ id: sandboxId,
488
+ env: options.env,
489
+ inheritEnv: options.inheritEnv,
490
+ baseEnv: async () => relocatedEnvironment(
491
+ await platformProcessEnvironment(ctx, {})(),
492
+ relocated.get(sandboxId)
493
+ )
494
+ });
495
+ live.set(sandboxId, sandbox);
496
+ return sandbox;
497
+ };
498
+ return {
499
+ capabilities: async () => ({
500
+ [Capability.Files]: FilesAccess.Write,
501
+ [Capability.Shell]: ShellAccess.Execute
502
+ }),
503
+ artifactKey: async () => `local:${root}`,
504
+ prepare: async () => ({ version: 1, root }),
505
+ // Commands run on this machine's own network: a policy could not be enforced.
506
+ create: async (_ctx, { setup }) => {
507
+ if (setup?.network != null)
508
+ throw new Error(
509
+ "a local sandbox runs on this machine's network and cannot enforce a network policy; remove the setup's network"
510
+ );
511
+ return { state: { version: 1, root } };
512
+ },
513
+ // This process is the machine: it runs as long as the sandbox can be reached.
514
+ awaitRunning: async () => void 0,
515
+ attach: async (ctx, { state }) => {
516
+ const existing = live.get(ctx.sandboxId);
517
+ const fresh = existing == null && await node().fsPromises.stat(root).catch(() => null) == null;
518
+ const sandbox = existing ?? await open(ctx, ctx.sandboxId);
519
+ await reportPlatformNetworkPolicy(ctx, { mode: NetworkPolicy.AllowAll });
520
+ const moved = /* @__PURE__ */ new Map();
521
+ for (const [path, content] of Object.entries(await ctx.platformFiles?.() ?? {})) {
522
+ const target = platformFileTarget(root, path);
523
+ await sandbox.writeTextFile({ path: target, content });
524
+ moved.set(path, target);
525
+ }
526
+ relocated.set(ctx.sandboxId, moved);
527
+ const forget = () => {
528
+ if (live.get(ctx.sandboxId) === sandbox) live.delete(ctx.sandboxId);
529
+ };
530
+ return { handle: handleOf(sandbox, forget), state, fresh, booted: existing == null };
531
+ },
532
+ detach: async (_ctx, { state }) => state,
533
+ park: async (ctx, { state }) => {
534
+ await live.get(ctx.sandboxId)?.stop();
535
+ live.delete(ctx.sandboxId);
536
+ return state;
537
+ },
538
+ delete: async (ctx) => {
539
+ await live.get(ctx.sandboxId)?.destroy();
540
+ live.delete(ctx.sandboxId);
541
+ relocated.delete(ctx.sandboxId);
542
+ }
543
+ };
544
+ }
545
+ });
546
+ };
547
+ export {
548
+ LOCAL_INHERITED_ENV,
549
+ LOCAL_PLATFORM_DIRECTORY,
550
+ LOCAL_PROVIDER,
551
+ LOCAL_STOP_GRACE_MS,
552
+ createLocalSandbox,
553
+ createLocalSandboxProvider
554
+ };
555
+ //# sourceMappingURL=local.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/sandboxes/local.ts"],
4
+ "sourcesContent": ["import { Capability, FilesAccess, ShellAccess } from '@finalai/agent-protocol';\nimport { NetworkPolicy, type JsonValue } from '@finalai/agent-provider';\nimport {\n defineSandboxProvider,\n encodeSandboxText,\n PLATFORM_ENVIRONMENT_NAMES,\n platformProcessEnvironment,\n PortProtocol,\n readTextFileStream,\n reportPlatformNetworkPolicy,\n runCollect,\n SandboxEntryType,\n type DirEntryIface,\n type NetworkSandboxSessionIface,\n type SandboxProcessIface,\n type SandboxProcessOptionsIface,\n type SandboxProviderHandleIface,\n type SandboxProviderIface,\n type SandboxResourceContextIface,\n type StatIface,\n} from '@finalai/agent-provider/sandbox';\nimport type { ChildProcess } from 'node:child_process';\nimport type { Readable, Writable } from 'node:stream';\nimport * as z from 'zod';\n\n// A sandbox served from the calling process: files under one directory of\n// this machine and commands run in it, with Node's own fs and child_process.\n// The agents client provides it for any `files` or `shell` capability the\n// caller left out; nothing it does leaves this machine except what the model\n// asks for through the handle. Node only.\n\nexport const LOCAL_PROVIDER = 'local';\n\n// Variables a local command inherits from this process; anything else (API\n// keys, tokens) stays out of the model's shell unless passed in `env`.\nexport const LOCAL_INHERITED_ENV = [\n 'PATH',\n 'HOME',\n 'USER',\n 'LANG',\n 'LC_ALL',\n 'TMPDIR',\n 'TERM',\n 'SHELL',\n];\n\nexport interface LocalSandboxOptionsIface {\n // The directory the sandbox is confined to; created when missing.\n root: string;\n // Plain variables for every command, over the inherited ones.\n env?: Record<string, string>;\n // Names inherited from this process's environment (default LOCAL_INHERITED_ENV).\n inheritEnv?: string[];\n id?: string;\n // Every process's environment from the host, read again for each process.\n baseEnv?: () => Promise<Record<string, string>>;\n}\n\nexport interface LocalSandboxIface extends NetworkSandboxSessionIface {\n readonly root: string;\n}\n\nconst fsError = (code: string, message: string) =>\n Object.assign(new Error(`${code}: ${message}`), { code });\n\nconst errorCode = (error: unknown): string | null => {\n const parsed = z.object({ code: z.string() }).safeParse(error);\n return parsed.success ? parsed.data.code : null;\n};\n\nconst missing = (error: unknown) => {\n const code = errorCode(error);\n return code === 'ENOENT' || code === 'ENOTDIR';\n};\n\nconst signalExitCode = (signal: NodeJS.Signals | null): number => {\n if (signal === 'SIGKILL') return 137;\n if (signal === 'SIGINT') return 130;\n return 143;\n};\n\n// Node's built-ins, read on first use so that importing this module does not\n// tie a browser bundle of the client to Node.\nconst loadNode = () => {\n if (globalThis.process?.getBuiltinModule == null)\n throw new Error('A local sandbox runs only in Node');\n return {\n childProcess: process.getBuiltinModule('node:child_process'),\n fs: process.getBuiltinModule('node:fs'),\n fsPromises: process.getBuiltinModule('node:fs/promises'),\n os: process.getBuiltinModule('node:os'),\n path: process.getBuiltinModule('node:path'),\n streamPromises: process.getBuiltinModule('node:stream/promises'),\n };\n};\nlet loaded: ReturnType<typeof loadNode> | null = null;\nconst node = () => (loaded ??= loadNode());\n\nconst isSignal = (value: string): value is NodeJS.Signals => value in node().os.constants.signals;\n\n// Settles when a writable can take more, or will take nothing more.\nconst drained = (stream: Writable): Promise<void> =>\n new Promise((resolve) => {\n const done = () => {\n stream.off('drain', done);\n stream.off('close', done);\n stream.off('error', done);\n resolve();\n };\n stream.once('drain', done);\n stream.once('close', done);\n stream.once('error', done);\n });\n\n// How much a bridged stream buffers before it stops reading its Node stream.\nconst BRIDGE_HIGH_WATER_BYTES = 64 * 1024;\n\n// A Node stream as a web stream, with backpressure: the Node stream pauses\n// whenever the web stream's queue is full and reads on when its reader pulls.\n// `extra` may push bytes and close the stream from elsewhere.\nconst nodeToWeb = (\n readable: Readable | null,\n extra?: (bridge: { push: (bytes: Uint8Array) => void; close: () => void }) => void,\n): ReadableStream<Uint8Array> => {\n let open = true;\n return new ReadableStream<Uint8Array>(\n {\n start: (controller) => {\n const close = () => {\n if (!open) return;\n open = false;\n controller.close();\n };\n const push = (bytes: Uint8Array) => {\n if (!open) return;\n controller.enqueue(bytes);\n if ((controller.desiredSize ?? 0) <= 0) readable?.pause();\n };\n extra?.({ push, close });\n if (readable == null) {\n close();\n return;\n }\n readable.on('data', (chunk: Buffer) => push(new Uint8Array(chunk)));\n // Reads start when the reader pulls.\n readable.pause();\n readable.once('end', close);\n readable.once('error', (error) => {\n if (!open) return;\n open = false;\n controller.error(error);\n });\n },\n pull: () => {\n readable?.resume();\n },\n cancel: () => {\n open = false;\n readable?.destroy();\n },\n },\n { highWaterMark: BRIDGE_HIGH_WATER_BYTES, size: (chunk) => chunk.byteLength },\n );\n};\n\n// How long stopping waits for commands to end on SIGTERM before SIGKILL.\nexport const LOCAL_STOP_GRACE_MS = 2_000;\n\n// Referenced on purpose: a script that ends with `await sandbox.stop()` stays\n// alive until a stubborn command has been killed.\nconst pause = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));\n\n// Whether `promise` settles within `ms`; the timer is cleared either way.\nconst within = async (promise: Promise<unknown>, ms: number): Promise<boolean> => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise.then(() => true),\n new Promise<boolean>((resolve) => {\n timer = setTimeout(() => resolve(false), Math.max(0, ms));\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n};\n\n// Symlinks one path may pass through before it is refused as a loop.\nconst MAX_SYMLINKS = 40;\n\n// A command runs in its own process group (POSIX), so that a timeout, a cancel\n// or a stop ends everything it started; a shell's children would otherwise\n// outlive it and hold its output open.\nconst ownGroup = (): boolean => process.platform !== 'win32';\n\nconst signalProcessTree = (child: ChildProcess, signal: NodeJS.Signals): void => {\n if (ownGroup() && child.pid != null) {\n try {\n process.kill(-child.pid, signal);\n return;\n } catch {\n // The group has already exited; signal the child itself.\n }\n }\n child.kill(signal);\n};\n\n// A leading `..` component leaves the root; a name that merely starts with\n// two dots (`..config`) does not.\nconst inside = (root: string, path: string): boolean => {\n const { isAbsolute, relative, sep } = node().path;\n const rel = relative(root, path);\n return rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n};\n\nexport const createLocalSandbox = async (\n options: LocalSandboxOptionsIface,\n): Promise<LocalSandboxIface> => {\n const { childProcess, fs, fsPromises, path: paths, streamPromises } = node();\n const root = paths.resolve(options.root);\n await fsPromises.mkdir(root, { recursive: true });\n const realRoot = await fsPromises.realpath(root);\n const id = options.id ?? `local-${crypto.randomUUID()}`;\n const processes = new Set<ChildProcess>();\n // Every process group a command started: a shell's backgrounded children\n // outlive it in its group, and stopping the sandbox ends them too.\n const groups = new Set<number>();\n const groupAlive = (pgid: number): boolean => {\n try {\n process.kill(-pgid, 0);\n return true;\n } catch {\n return false;\n }\n };\n const inherited: Record<string, string> = {};\n for (const name of options.inheritEnv ?? LOCAL_INHERITED_ENV) {\n const value = process.env[name];\n if (value != null) inherited[name] = value;\n }\n\n const resolvePath = (path: string): string =>\n paths.isAbsolute(path) ? paths.resolve(path) : paths.join(root, path);\n\n // The real location of `path` (or of its nearest existing ancestor, for a\n // path about to be created), refused unless it stays under `within`: no `..`\n // and no symlink leads out of the sandbox. A dangling symlink is followed to\n // where it points, since writing through it creates its target.\n const confined = async (path: string, within?: string): Promise<string> => {\n const bounds = within == null ? [realRoot] : [realRoot, await confined(within)];\n let existing = resolvePath(path);\n const rest: string[] = [];\n let links = 0;\n for (;;) {\n const real = await fsPromises.realpath(existing).catch((error: unknown) => {\n if (missing(error)) return null;\n throw error;\n });\n if (real != null) {\n const target = paths.join(real, ...rest.toReversed());\n for (const bound of bounds)\n if (!inside(bound, target)) throw fsError('EACCES', `${path} is outside the sandbox`);\n return target;\n }\n const entry = await fsPromises.lstat(existing).catch((error: unknown) => {\n if (missing(error)) return null;\n throw error;\n });\n if (entry?.isSymbolicLink() === true) {\n links += 1;\n if (links > MAX_SYMLINKS) throw fsError('ELOOP', `${path} has too many symlinks`);\n // Relative to the link's real directory, as the kernel resolves it.\n const directory = await fsPromises.realpath(paths.dirname(existing));\n existing = paths.resolve(directory, await fsPromises.readlink(existing));\n continue;\n }\n const parent = paths.dirname(existing);\n if (parent === existing) throw fsError('ENOENT', `${path} does not exist`);\n rest.push(paths.basename(existing));\n existing = parent;\n }\n };\n\n // The real location of the entry `path` names, its last component not\n // followed: removing a symlink removes the link, not what it points to.\n const confinedEntry = async (path: string): Promise<string> => {\n const logical = resolvePath(path);\n if (logical === root) throw fsError('EPERM', 'refusing to remove the sandbox root');\n return paths.join(await confined(paths.dirname(logical)), paths.basename(logical));\n };\n\n const statOf = async (path: string, within?: string): Promise<StatIface | null> => {\n let target: string;\n try {\n target = await confined(path, within);\n const entry = await fsPromises.stat(target);\n return {\n path: resolvePath(path),\n type: entry.isDirectory()\n ? SandboxEntryType.Directory\n : entry.isFile()\n ? SandboxEntryType.File\n : SandboxEntryType.Other,\n size: entry.isDirectory() ? 0 : entry.size,\n modifiedAt: entry.mtime.toISOString(),\n mode: entry.mode & 0o7777,\n };\n } catch (error) {\n if (missing(error)) return null;\n throw error;\n }\n };\n\n const writeBytes = async (path: string, data: Uint8Array): Promise<void> => {\n const target = await confined(path);\n await fsPromises.mkdir(paths.dirname(target), { recursive: true });\n await fsPromises.writeFile(target, data);\n };\n\n const spawn = async (spawnOptions: SandboxProcessOptionsIface): Promise<SandboxProcessIface> => {\n // A command cancelled before it starts never runs.\n const signal = spawnOptions.abortSignal;\n signal?.throwIfAborted();\n const cwd = await confined(spawnOptions.cwd ?? '.');\n signal?.throwIfAborted();\n const base = await options.baseEnv?.();\n signal?.throwIfAborted();\n const env = { ...inherited, ...options.env, ...base, ...spawnOptions.env };\n const shell = spawnOptions.shell === true;\n const child = childProcess.spawn(\n shell ? [spawnOptions.command, ...(spawnOptions.args ?? [])].join(' ') : spawnOptions.command,\n shell ? [] : (spawnOptions.args ?? []),\n { cwd, env, shell, stdio: ['pipe', 'pipe', 'pipe'], detached: ownGroup() },\n );\n processes.add(child);\n if (ownGroup() && child.pid != null) {\n for (const pgid of groups) if (!groupAlive(pgid)) groups.delete(pgid);\n groups.add(child.pid);\n }\n let timedOut = false;\n // A command that never started reports why on stderr.\n const stderr = nodeToWeb(child.stderr, ({ push, close }) =>\n child.once('error', (error) => {\n push(new TextEncoder().encode(`${error.message}\\n`));\n close();\n }),\n );\n const exited = new Promise<{ exitCode: number }>((settle) => {\n child.once('error', (error) => {\n processes.delete(child);\n settle({ exitCode: errorCode(error) === 'ENOENT' ? 127 : 126 });\n });\n // Exit, not close: output nobody reads holds the pipes (and `close`) open, and the\n // command has ended all the same.\n child.once('exit', (code, signal) => {\n processes.delete(child);\n settle({ exitCode: timedOut ? 124 : (code ?? signalExitCode(signal)) });\n });\n });\n const timer =\n spawnOptions.timeoutMs == null\n ? null\n : setTimeout(() => {\n timedOut = true;\n signalProcessTree(child, 'SIGKILL');\n }, spawnOptions.timeoutMs);\n // A command that ignores SIGTERM is killed once the stop grace period ends.\n let escalation: ReturnType<typeof setTimeout> | null = null;\n const terminate = (signal: NodeJS.Signals) => {\n signalProcessTree(child, signal);\n if (signal !== 'SIGTERM' || escalation != null) return;\n escalation = setTimeout(() => signalProcessTree(child, 'SIGKILL'), LOCAL_STOP_GRACE_MS);\n };\n const onAbort = () => terminate('SIGTERM');\n spawnOptions.abortSignal?.addEventListener('abort', onAbort, { once: true });\n // The deadline, a cancel and the SIGKILL escalation stand until the output closes: a\n // descendant that outlives the command holds it open and is ended with the group.\n const settled = () => {\n if (timer != null) clearTimeout(timer);\n const groupLeft = ownGroup() && child.pid != null && groupAlive(child.pid);\n if (escalation != null && !groupLeft) clearTimeout(escalation);\n spawnOptions.abortSignal?.removeEventListener('abort', onAbort);\n };\n child.once('close', settled);\n child.once('error', settled);\n const stdin = child.stdin;\n stdin?.on('error', () => undefined);\n if (typeof spawnOptions.stdin === 'string') stdin?.end(spawnOptions.stdin);\n else if (spawnOptions.stdin != null) {\n const reader = spawnOptions.stdin.getReader();\n // Reads on only as fast as the command takes its input, and stops when it exits.\n let finished = false;\n void exited.then(() => {\n finished = true;\n void reader.cancel().catch(() => undefined);\n });\n void (async () => {\n for (;;) {\n const next = await reader.read();\n if (next.done || finished || stdin == null || stdin.destroyed) break;\n if (!stdin.write(next.value)) await Promise.race([drained(stdin), exited]);\n }\n stdin?.end();\n })().catch(() => stdin?.destroy());\n }\n return {\n pid: child.pid == null ? null : String(child.pid),\n ref: null,\n stdout: nodeToWeb(child.stdout),\n stderr,\n write: async (data, writeOptions) => {\n if (spawnOptions.stdin != null) throw new Error('stdin was provided at spawn');\n if (stdin == null) throw new Error('the process has no stdin');\n await new Promise<void>((done, fail) =>\n stdin.write(data, (error) => (error == null ? done() : fail(error))),\n );\n if (writeOptions?.end === true) stdin.end();\n },\n wait: () => exited,\n // SIGTERM (killed after the grace period if ignored) and SIGKILL resolve once the\n // command has ended; any other signal (SIGSTOP, SIGCONT, ...) once it is sent.\n kill: async (signal) => {\n const name = signal ?? 'SIGTERM';\n const sent = isSignal(name) ? name : 'SIGTERM';\n terminate(sent);\n if (sent === 'SIGTERM' || sent === 'SIGKILL') await exited;\n },\n };\n };\n\n const sandbox: LocalSandboxIface = {\n id,\n root,\n defaultWorkingDirectory: root,\n ports: [],\n description: `This machine, in ${root}.`,\n readFile: async ({ path, root: within }) => {\n let target: string;\n try {\n target = await confined(path, within);\n const entry = await fsPromises.stat(target);\n if (entry.isDirectory()) throw fsError('EISDIR', `${path} is a directory`);\n } catch (error) {\n if (missing(error)) return null;\n throw error;\n }\n return nodeToWeb(fs.createReadStream(target));\n },\n readBinaryFile: async ({ path }) => {\n try {\n return new Uint8Array(await fsPromises.readFile(await confined(path)));\n } catch (error) {\n if (missing(error)) return null;\n throw error;\n }\n },\n readTextFile: async (readOptions) => {\n const stream = await sandbox.readFile({ path: readOptions.path });\n return stream == null ? null : readTextFileStream(stream, readOptions);\n },\n writeFile: async ({ path, content }) => {\n const target = await confined(path);\n await fsPromises.mkdir(paths.dirname(target), { recursive: true });\n const reader = content.getReader();\n const output = fs.createWriteStream(target);\n await streamPromises.pipeline(\n (async function* () {\n for (;;) {\n const next = await reader.read();\n if (next.done) return;\n yield next.value;\n }\n })(),\n output,\n );\n },\n writeBinaryFile: ({ path, content }) => writeBytes(path, content),\n writeTextFile: ({ path, content, encoding }) =>\n writeBytes(path, encodeSandboxText(content, encoding)),\n spawn,\n run: (runOptions) => runCollect({ spawn }, runOptions),\n stat: ({ path, root: within }) => statOf(path, within),\n readDir: async ({ path, root: within }): Promise<DirEntryIface[]> => {\n const target = await confined(path, within);\n const logical = resolvePath(path);\n const entries = await fsPromises.readdir(target, { withFileTypes: true });\n return Promise.all(\n entries.map(async (entry) => {\n const type = entry.isDirectory()\n ? SandboxEntryType.Directory\n : entry.isFile()\n ? SandboxEntryType.File\n : entry.isSymbolicLink()\n ? SandboxEntryType.Symlink\n : SandboxEntryType.Other;\n const size = entry.isFile()\n ? (await fsPromises.lstat(paths.join(target, entry.name))).size\n : null;\n return { name: entry.name, path: paths.join(logical, entry.name), type, size };\n }),\n );\n },\n resolvePath,\n removePath: async ({ path, recursive, force }) => {\n const target = await confinedEntry(path);\n await fsPromises.rm(target, { recursive: recursive === true, force: force === true });\n },\n getPortEndpoint: async ({ port, protocol }) => ({\n url: `${protocol ?? PortProtocol.Http}://127.0.0.1:${port}`,\n }),\n getPortUrl: async (portOptions) => (await sandbox.getPortEndpoint(portOptions)).url,\n // Stopping ends the commands it started; the directory is the caller's and stays.\n // A command that ignores SIGTERM is killed once the grace period ends.\n stop: async () => {\n const children = [...processes];\n const pgids = new Set(groups);\n groups.clear();\n for (const child of children) if (ownGroup() && child.pid != null) pgids.add(child.pid);\n const closed = Promise.all(\n children.map(\n (child) =>\n new Promise<void>((done) => {\n if (child.exitCode != null || child.signalCode != null) done();\n else child.once('exit', () => done());\n }),\n ),\n );\n const signalAll = (signal: NodeJS.Signals) => {\n for (const child of children) signalProcessTree(child, signal);\n for (const pgid of pgids) {\n try {\n process.kill(-pgid, signal);\n } catch {\n // The group has already exited.\n }\n }\n };\n // Whether every command closed and every group is gone by the deadline.\n const settled = async (deadline: number): Promise<boolean> => {\n if (!(await within(closed, deadline - Date.now()))) return false;\n while ([...pgids].some(groupAlive)) {\n if (Date.now() >= deadline) return false;\n await pause(25);\n }\n return true;\n };\n signalAll('SIGTERM');\n if (await settled(Date.now() + LOCAL_STOP_GRACE_MS)) return;\n signalAll('SIGKILL');\n await settled(Date.now() + LOCAL_STOP_GRACE_MS);\n },\n destroy: () => sandbox.stop(),\n };\n return sandbox;\n};\n\nconst localEnvironmentSchema = z.strictObject({\n root: z.string().min(1),\n // The platform's variables (its proxy, its CA) are its own to set.\n env: z\n .record(z.string(), z.string())\n .refine(\n (env) => Object.keys(env).every((name) => !PLATFORM_ENVIRONMENT_NAMES.has(name)),\n 'env sets a variable the platform owns',\n )\n .optional(),\n inheritEnv: z.array(z.string().min(1)).optional(),\n});\n\nconst localStateSchema = z.object({ version: z.literal(1), root: z.string() });\n\n// The directory under the sandbox root that holds the platform's files (its CA certificate\n// and the like). They are written on this machine, so the paths the platform names are\n// re-rooted here rather than taken as locations outside the sandbox.\nexport const LOCAL_PLATFORM_DIRECTORY = '.final';\n\n// Where a platform file goes: its path re-rooted under the reserved directory. A path\n// with a `..` component is refused.\nconst platformFileTarget = (root: string, path: string): string => {\n const paths = node().path;\n const components = path\n .slice(paths.parse(path).root.length)\n .split(/[\\\\/]/)\n .filter((component) => component !== '' && component !== '.');\n if (components.length === 0 || components.includes('..'))\n throw new Error(\n `refusing the platform file ${JSON.stringify(path)}: it must name a file without ..`,\n );\n return paths.join(root, LOCAL_PLATFORM_DIRECTORY, ...components);\n};\n\n// The platform's variables with every value that names a platform file pointed at the\n// file's confined location.\nconst relocatedEnvironment = (\n env: Record<string, string>,\n moved: ReadonlyMap<string, string> | undefined,\n): Record<string, string> => {\n if (moved == null || moved.size === 0) return env;\n const result: Record<string, string> = {};\n for (const [name, value] of Object.entries(env)) result[name] = moved.get(value) ?? value;\n return result;\n};\n\ntype LocalArtifact = { version: 1; root: string };\ntype LocalState = z.infer<typeof localStateSchema>;\n\n// Stopping ends the sandbox's commands, its services among them: the next attach opens it\n// again and reports a boot, so they are started again.\nconst handleOf = (\n sandbox: LocalSandboxIface,\n forget: () => void,\n): SandboxProviderHandleIface<LocalSandboxIface> => ({\n sandbox,\n onSandboxStop: () => {\n forget();\n return sandbox.stop();\n },\n onSandboxDelete: () => {\n forget();\n return sandbox.destroy();\n },\n onRuntimeShutdown: () => {\n forget();\n return sandbox.stop();\n },\n});\n\n// The local sandbox as a provider, for a host that drives sandboxes through\n// the provider lifecycle. Deleting it stops its commands and leaves the\n// directory, which belongs to whoever runs this process.\nexport const createLocalSandboxProvider = (): SandboxProviderIface<\n JsonValue,\n LocalArtifact,\n LocalState,\n LocalSandboxIface\n> => {\n const live = new Map<string, LocalSandboxIface>();\n // Per sandbox, each platform file's path as the platform named it \u2192 where it was written.\n const relocated = new Map<string, Map<string, string>>();\n return defineSandboxProvider<JsonValue, LocalArtifact, LocalState, LocalSandboxIface>({\n name: LOCAL_PROVIDER,\n environment: (rawOptions) => {\n const options = localEnvironmentSchema.parse(rawOptions);\n const root = node().path.resolve(options.root);\n const open = async (ctx: SandboxResourceContextIface, sandboxId: string) => {\n const sandbox = await createLocalSandbox({\n root,\n id: sandboxId,\n env: options.env,\n inheritEnv: options.inheritEnv,\n baseEnv: async () =>\n relocatedEnvironment(\n await platformProcessEnvironment(ctx, {})(),\n relocated.get(sandboxId),\n ),\n });\n live.set(sandboxId, sandbox);\n return sandbox;\n };\n return {\n capabilities: async () => ({\n [Capability.Files]: FilesAccess.Write,\n [Capability.Shell]: ShellAccess.Execute,\n }),\n artifactKey: async () => `local:${root}`,\n prepare: async () => ({ version: 1, root }),\n // Commands run on this machine's own network: a policy could not be enforced.\n create: async (_ctx, { setup }) => {\n if (setup?.network != null)\n throw new Error(\n \"a local sandbox runs on this machine's network and cannot enforce a network policy; remove the setup's network\",\n );\n return { state: { version: 1, root } };\n },\n // This process is the machine: it runs as long as the sandbox can be reached.\n awaitRunning: async () => undefined,\n attach: async (ctx, { state }) => {\n const existing = live.get(ctx.sandboxId);\n const fresh =\n existing == null &&\n (await node()\n .fsPromises.stat(root)\n .catch(() => null)) == null;\n const sandbox = existing ?? (await open(ctx, ctx.sandboxId));\n // Every destination is reachable from here. The platform's files are written under\n // the reserved directory (through the sandbox's own confinement, so no symlink\n // leads them out of the root) before the handle runs anything, and the variables\n // that name them are pointed there.\n await reportPlatformNetworkPolicy(ctx, { mode: NetworkPolicy.AllowAll });\n const moved = new Map<string, string>();\n for (const [path, content] of Object.entries((await ctx.platformFiles?.()) ?? {})) {\n const target = platformFileTarget(root, path);\n await sandbox.writeTextFile({ path: target, content });\n moved.set(path, target);\n }\n relocated.set(ctx.sandboxId, moved);\n const forget = () => {\n if (live.get(ctx.sandboxId) === sandbox) live.delete(ctx.sandboxId);\n };\n return { handle: handleOf(sandbox, forget), state, fresh, booted: existing == null };\n },\n detach: async (_ctx, { state }) => state,\n park: async (ctx, { state }) => {\n await live.get(ctx.sandboxId)?.stop();\n live.delete(ctx.sandboxId);\n return state;\n },\n delete: async (ctx) => {\n await live.get(ctx.sandboxId)?.destroy();\n live.delete(ctx.sandboxId);\n relocated.delete(ctx.sandboxId);\n },\n };\n },\n });\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["within", "signal"]
7
+ }
@@ -1,4 +1,3 @@
1
- import { SandboxAccess } from '@finalai/agent-provider';
2
1
  import type { NetworkSandboxSessionIface, PortProtocol } from '@finalai/agent-provider/sandbox';
3
2
  import { type SandboxCommandEncoderIface } from "./commands.mjs";
4
3
  import { type SandboxPathsIface } from "./paths.mjs";
@@ -29,5 +28,3 @@ export interface CreateTransportSessionArgsIface {
29
28
  }
30
29
  export declare const createTransportSession: (args: CreateTransportSessionArgsIface) => NetworkSandboxSessionIface;
31
30
  export declare const readOnlySession: <S extends NetworkSandboxSessionIface>(session: S) => S;
32
- export declare const executeOnlySession: <S extends NetworkSandboxSessionIface>(session: S) => S;
33
- export declare const sessionForAccess: <S extends NetworkSandboxSessionIface>(session: S, access: SandboxAccess) => S;