@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
@@ -1,4 +1,3 @@
1
- import { SandboxAccess } from "@finalai/agent-provider";
2
1
  import { createConfinedFileReader, SandboxEntryType } from "@finalai/agent-provider/sandbox";
3
2
  import { encodeSandboxText } from "@finalai/agent-provider/sandbox/bytes";
4
3
  import { readTextFileStream } from "@finalai/agent-provider/sandbox/convenience";
@@ -299,7 +298,7 @@ const createTransportSession = (args) => {
299
298
  return { ...session, confinedFileReader: createConfinedFileReader(session) };
300
299
  };
301
300
  const readOnlyRefusal = async () => {
302
- throw new Error("this sandbox binding is read-only");
301
+ throw new Error("this sandbox handle is read-only");
303
302
  };
304
303
  const readOnlySession = (session) => {
305
304
  const restricted = {
@@ -324,27 +323,8 @@ const readOnlySession = (session) => {
324
323
  };
325
324
  return restricted;
326
325
  };
327
- const fileWriteRefusal = async () => {
328
- throw new Error("this sandbox binding runs processes but does not write files");
329
- };
330
- const executeOnlySession = (session) => {
331
- const restricted = {
332
- ...session,
333
- writeFile: fileWriteRefusal,
334
- writeBinaryFile: fileWriteRefusal,
335
- writeTextFile: fileWriteRefusal,
336
- removePath: fileWriteRefusal,
337
- stop: fileWriteRefusal,
338
- destroy: fileWriteRefusal
339
- };
340
- delete restricted.egress;
341
- return restricted;
342
- };
343
- const sessionForAccess = (session, access) => access === SandboxAccess.Read ? readOnlySession(session) : access === SandboxAccess.Execute ? executeOnlySession(session) : session;
344
326
  export {
345
327
  createTransportSession,
346
- executeOnlySession,
347
- readOnlySession,
348
- sessionForAccess
328
+ readOnlySession
349
329
  };
350
330
  //# sourceMappingURL=session.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/sandboxes/session.ts"],
4
- "sourcesContent": ["import { SandboxAccess } from '@finalai/agent-provider';\nimport type {\n DirEntryIface,\n NetworkSandboxSessionIface,\n PortProtocol,\n SandboxAttachedProcessIface,\n SandboxAttachProcessOptionsIface,\n SandboxProcessIface,\n SandboxProcessOptionsIface,\n SandboxRunResultIface,\n StatIface,\n} from '@finalai/agent-provider/sandbox';\nimport { createConfinedFileReader, SandboxEntryType } from '@finalai/agent-provider/sandbox';\nimport { encodeSandboxText } from '@finalai/agent-provider/sandbox/bytes';\nimport { readTextFileStream } from '@finalai/agent-provider/sandbox/convenience';\nimport { collectStream, errorMessage, isNotFoundMessage, rechunk, splitChunks } from \"./bytes.mjs\";\nimport { posixCommandLine, type SandboxCommandEncoderIface } from \"./commands.mjs\";\nimport { POSIX_PATHS, type SandboxPathsIface } from \"./paths.mjs\";\nimport {\n exitStatus,\n type SandboxTransportIface,\n type TransportOutputIface,\n type TransportOutputStreamIface,\n type TransportProcessIface,\n} from \"./transport.mjs\";\n\n// NetworkSandboxSessionIface over any SandboxTransportIface. Provider specifics\n// (lifecycle, ports, extra capabilities) come in through `network`.\n\nexport interface TransportSessionNetworkIface {\n ports: readonly number[];\n getPortEndpoint(options: {\n port: number;\n protocol?: PortProtocol;\n }): Promise<{ url: string; headers?: Record<string, string> }>;\n stop(): Promise<void>;\n destroy(): Promise<void>;\n}\n\nexport interface CreateTransportSessionArgsIface {\n id: string;\n description: string;\n workspaceRoot: string;\n transport: SandboxTransportIface;\n // Environment every process gets (injected variables), under per-call env;\n // read again for every process.\n baseEnv: () => Promise<Record<string, string>>;\n randomUuid: () => string;\n network: TransportSessionNetworkIface;\n // The sandbox's path flavour and command encoding; POSIX unless a Device says otherwise.\n paths?: SandboxPathsIface;\n commands?: SandboxCommandEncoderIface;\n // What else a process ref must match beyond this session and the process's\n // boot, read when spawning and attaching (a Device's lease generation).\n processScope?: () => string;\n}\n\n// A durable process's ref: this session, the process and its boot, and the scope.\nconst PROCESS_REF_PREFIX = 'final-process.v1';\n\nconst encodeProcessRef = (parts: {\n session: string;\n process: TransportProcessIface;\n scope: string;\n}): string =>\n [PROCESS_REF_PREFIX, parts.session, parts.process.id, parts.process.bootId, parts.scope]\n .map(encodeURIComponent)\n .join(':');\n\nconst decodeProcessRef = (\n ref: string,\n): { session: string; process: TransportProcessIface; scope: string } | null => {\n const parts = ref.split(':');\n if (parts.length !== 5 || parts[0] !== PROCESS_REF_PREFIX) return null;\n try {\n const [session = '', id = '', bootId = '', scope = ''] = parts.slice(1).map(decodeURIComponent);\n return { session, process: { id, bootId }, scope };\n } catch {\n return null;\n }\n};\n\n// Where output read from `requested` starts: there, or later when the\n// backend no longer retains the bytes from there.\nconst outputStart = (chunk: TransportOutputStreamIface, requested: number): number =>\n Math.max(requested, chunk.nextOffset - chunk.data.byteLength);\n\nconst textDecoder = (): TextDecoder => new TextDecoder('utf-8');\n\ninterface PushStreamIface {\n stream: ReadableStream<Uint8Array>;\n controller?: ReadableStreamDefaultController<Uint8Array>;\n}\n\ninterface ControllerHolderIface {\n controller?: ReadableStreamDefaultController<Uint8Array>;\n}\n\n// A stream the output pump pushes into; unread output stays queued in memory.\nconst pushStream = (): PushStreamIface => {\n const holder: ControllerHolderIface = {};\n const stream = new ReadableStream<Uint8Array>({\n start: (controller) => {\n holder.controller = controller;\n },\n });\n return { stream, controller: holder.controller };\n};\n\nconst toStatEntry = (\n path: string,\n stat: { type: SandboxEntryType; size: number; modifiedAtMs: number | null; mode: number | null },\n): StatIface => ({\n path,\n type: stat.type,\n size: stat.size,\n modifiedAt: stat.modifiedAtMs == null ? null : new Date(stat.modifiedAtMs).toISOString(),\n mode: stat.mode,\n});\n\nexport const createTransportSession = (\n args: CreateTransportSessionArgsIface,\n): NetworkSandboxSessionIface => {\n const { transport } = args;\n const paths = args.paths ?? POSIX_PATHS;\n const commandLine = args.commands ?? posixCommandLine;\n const resolvePath = (path: string): string => paths.resolve(args.workspaceRoot, path);\n\n const kill =\n (process: TransportProcessIface) =>\n async (signal?: string): Promise<void> => {\n await transport.input(\n signal == null || signal === 'SIGKILL' ? { process, terminate: true } : { process, signal },\n );\n };\n\n // Polls a process's output from the given offsets (after `first`, output\n // already read from there) until it exits. Aborting `detach` stops polling\n // and fails the streams and the exit; the process is untouched.\n const followProcess = (args: {\n process: TransportProcessIface;\n stdoutOffset: number;\n stderrOffset: number;\n first?: TransportOutputIface;\n detach?: AbortSignal;\n }) => {\n const { process } = args;\n const stdoutPush = pushStream();\n const stderrPush = pushStream();\n let settleExit: (value: { exitCode: number }) => void = () => undefined;\n let failExit: (error: Error) => void = () => undefined;\n const exit = new Promise<{ exitCode: number }>((resolve, reject) => {\n settleExit = resolve;\n failExit = reject;\n });\n // Avoid an unhandled rejection when the caller only reads the streams.\n exit.catch(() => undefined);\n void (async () => {\n let stdoutOffset = args.stdoutOffset;\n let stderrOffset = args.stderrOffset;\n let waitMs = transport.outputWaitMs;\n let pending = args.first;\n try {\n for (;;) {\n args.detach?.throwIfAborted();\n const output =\n pending ??\n (await transport.output({\n process,\n stdoutOffset,\n stderrOffset,\n waitMs,\n signal: args.detach,\n }));\n pending = undefined;\n args.detach?.throwIfAborted();\n if (output.stdout.data.byteLength > 0) stdoutPush.controller?.enqueue(output.stdout.data);\n if (output.stderr.data.byteLength > 0) stderrPush.controller?.enqueue(output.stderr.data);\n const advanced =\n output.stdout.nextOffset !== stdoutOffset || output.stderr.nextOffset !== stderrOffset;\n stdoutOffset = output.stdout.nextOffset;\n stderrOffset = output.stderr.nextOffset;\n if (output.exited && output.stdout.eof && output.stderr.eof) {\n stdoutPush.controller?.close();\n stderrPush.controller?.close();\n settleExit({ exitCode: exitStatus(output.exitCode, output.exitSignal) });\n return;\n }\n // Exited with unread output: drain it without waiting.\n waitMs = output.exited && advanced ? 0 : transport.outputWaitMs;\n }\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n stdoutPush.controller?.error(error);\n stderrPush.controller?.error(error);\n failExit(error);\n }\n })();\n return { stdout: stdoutPush.stream, stderr: stderrPush.stream, exit, kill: kill(process) };\n };\n\n const spawnProcess = async (\n options: SandboxProcessOptionsIface,\n closeStdin: boolean,\n ): Promise<SandboxProcessIface> => {\n options.abortSignal?.throwIfAborted();\n // Durable only where processes outlive this client (`processGone`).\n const durable = options.durable === true && transport.processGone != null;\n const process: TransportProcessIface = await transport.exec({\n id: args.randomUuid(),\n command: commandLine(options),\n cwd: resolvePath(options.cwd ?? args.workspaceRoot),\n env: { ...(await args.baseEnv()), ...options.env },\n timeoutMs: options.timeoutMs ?? null,\n signal: options.abortSignal,\n });\n const followed = followProcess({\n process,\n stdoutOffset: 0,\n stderrOffset: 0,\n detach: durable ? options.abortSignal : undefined,\n });\n if (!durable) {\n const onAbort = (): void => {\n void followed.kill().catch(() => undefined);\n };\n options.abortSignal?.addEventListener('abort', onAbort, { once: true });\n if (options.abortSignal?.aborted === true) onAbort();\n void followed.exit\n .catch(() => undefined)\n .finally(() => options.abortSignal?.removeEventListener('abort', onAbort));\n }\n\n // A detached durable handle neither writes to nor closes the process's stdin.\n const write = async (data: Uint8Array | string, writeOptions?: { end?: boolean }) => {\n if (durable) options.abortSignal?.throwIfAborted();\n const bytes = data instanceof Uint8Array ? data : new TextEncoder().encode(data);\n if (bytes.byteLength > 0) await transport.input({ process, data: bytes });\n if (writeOptions?.end === true) await transport.input({ process, eof: true });\n };\n\n const input = options.stdin;\n if (input instanceof ReadableStream) {\n void (async () => {\n // Forward input as it arrives: a stdin stream is often interactive.\n for await (const chunk of splitChunks(input, 64 * 1024)) await write(chunk);\n await write(new Uint8Array(), { end: true });\n })().catch(() => undefined);\n } else if (input != null) {\n await write(input, { end: true });\n } else if (closeStdin) {\n await transport.input({ process, eof: true });\n }\n\n return {\n pid: process.id,\n ref: durable\n ? encodeProcessRef({ session: args.id, process, scope: args.processScope?.() ?? '' })\n : null,\n stdout: followed.stdout,\n stderr: followed.stderr,\n write,\n wait: () => followed.exit,\n kill: followed.kill,\n };\n };\n\n // Finds a durable process again: null for a ref of another session or scope,\n // or a process the backend no longer knows.\n const attachProcess = async (\n options: SandboxAttachProcessOptionsIface,\n ): Promise<SandboxAttachedProcessIface | null> => {\n options.abortSignal?.throwIfAborted();\n const decoded = decodeProcessRef(options.ref);\n if (\n transport.processGone == null ||\n decoded == null ||\n decoded.session !== args.id ||\n decoded.scope !== (args.processScope?.() ?? '')\n )\n return null;\n const { process } = decoded;\n let first: TransportOutputIface;\n try {\n first = await transport.output({\n process,\n stdoutOffset: options.stdoutOffset,\n stderrOffset: options.stderrOffset,\n waitMs: 0,\n signal: options.abortSignal,\n });\n } catch (cause) {\n if (transport.processGone(cause)) return null;\n throw cause;\n }\n const followed = followProcess({\n process,\n stdoutOffset: options.stdoutOffset,\n stderrOffset: options.stderrOffset,\n first,\n detach: options.abortSignal,\n });\n return {\n ref: options.ref,\n stdoutOffset: outputStart(first.stdout, options.stdoutOffset),\n stderrOffset: outputStart(first.stderr, options.stderrOffset),\n stdout: followed.stdout,\n stderr: followed.stderr,\n wait: () => followed.exit,\n kill: followed.kill,\n };\n };\n\n const readStream = async (\n path: string,\n signal: AbortSignal | undefined,\n ): Promise<ReadableStream<Uint8Array> | null> => {\n const resolved = resolvePath(path);\n const stat = await transport.stat({ path: resolved, signal });\n if (stat == null) return null;\n if (stat.type === SandboxEntryType.Directory) throw new Error(`${resolved} is a directory`);\n // Read to end of file rather than to the stat size: a symlink's stat is the\n // link's own length, not its target's.\n let offset = 0;\n let done = false;\n return new ReadableStream<Uint8Array>({\n pull: async (controller) => {\n if (done) {\n controller.close();\n return;\n }\n const chunk = await transport.readChunk({\n path: resolved,\n offset,\n length: transport.fileChunkBytes,\n signal,\n });\n done = chunk.eof || chunk.bytes.byteLength === 0;\n offset += chunk.bytes.byteLength;\n if (chunk.bytes.byteLength > 0) controller.enqueue(chunk.bytes);\n if (done) controller.close();\n },\n });\n };\n\n const writeStream = async (\n path: string,\n content: ReadableStream<Uint8Array>,\n signal: AbortSignal | undefined,\n ): Promise<void> => {\n const resolved = resolvePath(path);\n await transport.createDirectory({ path: paths.dirname(resolved), signal });\n let offset = 0;\n for await (const chunk of rechunk(content, transport.fileChunkBytes)) {\n await transport.writeChunk({ path: resolved, offset, bytes: chunk, signal });\n offset += chunk.byteLength;\n }\n if (offset === 0)\n await transport.writeChunk({ path: resolved, offset: 0, bytes: new Uint8Array(), signal });\n };\n\n const bytesStream = (bytes: Uint8Array): ReadableStream<Uint8Array> =>\n new ReadableStream<Uint8Array>({\n start: (controller) => {\n if (bytes.byteLength > 0) controller.enqueue(bytes);\n controller.close();\n },\n });\n\n const session: NetworkSandboxSessionIface = {\n id: args.id,\n description: args.description,\n defaultWorkingDirectory: args.workspaceRoot,\n ports: args.network.ports,\n resolvePath,\n readFile: async ({ path, abortSignal }) => readStream(path, abortSignal),\n readBinaryFile: async ({ path, abortSignal }) => {\n const stream = await readStream(path, abortSignal);\n return stream == null ? null : collectStream(stream);\n },\n readTextFile: async (options) => {\n const stream = await readStream(options.path, options.abortSignal);\n return stream == null ? null : readTextFileStream(stream, options);\n },\n writeFile: async ({ path, content, abortSignal }) => writeStream(path, content, abortSignal),\n writeBinaryFile: async ({ path, content, abortSignal }) =>\n writeStream(path, bytesStream(content), abortSignal),\n writeTextFile: async ({ path, content, encoding, abortSignal }) =>\n writeStream(path, bytesStream(encodeSandboxText(content, encoding)), abortSignal),\n spawn: (options) => spawnProcess(options, false),\n run: async (options): Promise<SandboxRunResultIface> => {\n const process = await spawnProcess({ ...options, durable: false }, true);\n const [stdout, stderr, exit] = await Promise.all([\n collectStream(process.stdout),\n collectStream(process.stderr),\n process.wait(),\n ]);\n return {\n exitCode: exit.exitCode,\n stdout: textDecoder().decode(stdout),\n stderr: textDecoder().decode(stderr),\n };\n },\n stat: async ({ path, abortSignal }) => {\n const resolved = resolvePath(path);\n const stat = await transport.stat({ path: resolved, signal: abortSignal });\n return stat == null ? null : toStatEntry(resolved, stat);\n },\n readDir: async ({ path, abortSignal }): Promise<DirEntryIface[]> => {\n const resolved = resolvePath(path);\n const entries = await transport.readDir({ path: resolved, signal: abortSignal });\n return entries.map((entry) => ({\n name: entry.name,\n path: paths.join(resolved, entry.name),\n type: entry.type,\n size: entry.size,\n }));\n },\n removePath: async ({ path, recursive, force, abortSignal }) => {\n const resolved = resolvePath(path);\n try {\n await transport.remove({\n path: resolved,\n recursive: recursive === true,\n force: force === true,\n signal: abortSignal,\n });\n } catch (error) {\n if (force === true && isNotFoundMessage(errorMessage(error))) return;\n throw error;\n }\n },\n getPortEndpoint: (options) => args.network.getPortEndpoint(options),\n getPortUrl: async (options) => (await args.network.getPortEndpoint(options)).url,\n stop: () => args.network.stop(),\n destroy: () => args.network.destroy(),\n };\n if (transport.processGone != null) session.attachProcess = attachProcess;\n return { ...session, confinedFileReader: createConfinedFileReader(session) };\n};\n\nconst readOnlyRefusal = async (): Promise<never> => {\n throw new Error('this sandbox binding is read-only');\n};\n\n// A read binding's view of a handle: reads pass through; writes, processes and\n// lifecycle are refused here as well as by the lease the provider took.\nexport const readOnlySession = <S extends NetworkSandboxSessionIface>(session: S): S => {\n const restricted: S = {\n ...session,\n writeFile: readOnlyRefusal,\n writeBinaryFile: readOnlyRefusal,\n writeTextFile: readOnlyRefusal,\n spawn: readOnlyRefusal,\n run: readOnlyRefusal,\n removePath: readOnlyRefusal,\n stop: readOnlyRefusal,\n destroy: readOnlyRefusal,\n };\n if (session.setNetworkPolicy != null) restricted.setNetworkPolicy = readOnlyRefusal;\n delete restricted.egress;\n delete restricted.attachProcess;\n const screen = session.screen;\n if (screen != null)\n restricted.screen = async (options) => {\n if (options?.viewOnly === false) return readOnlyRefusal();\n return screen.call(session, options);\n };\n return restricted;\n};\n\nconst fileWriteRefusal = async (): Promise<never> => {\n throw new Error('this sandbox binding runs processes but does not write files');\n};\n\n// An execute binding's view of a handle: reads and processes pass through; file\n// writes and lifecycle are refused.\nexport const executeOnlySession = <S extends NetworkSandboxSessionIface>(session: S): S => {\n const restricted: S = {\n ...session,\n writeFile: fileWriteRefusal,\n writeBinaryFile: fileWriteRefusal,\n writeTextFile: fileWriteRefusal,\n removePath: fileWriteRefusal,\n stop: fileWriteRefusal,\n destroy: fileWriteRefusal,\n };\n delete restricted.egress;\n return restricted;\n};\n\n// The view of a handle that a binding's access allows.\nexport const sessionForAccess = <S extends NetworkSandboxSessionIface>(\n session: S,\n access: SandboxAccess,\n): S =>\n access === SandboxAccess.Read\n ? readOnlySession(session)\n : access === SandboxAccess.Execute\n ? executeOnlySession(session)\n : session;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n DirEntryIface,\n NetworkSandboxSessionIface,\n PortProtocol,\n SandboxAttachedProcessIface,\n SandboxAttachProcessOptionsIface,\n SandboxProcessIface,\n SandboxProcessOptionsIface,\n SandboxRunResultIface,\n StatIface,\n} from '@finalai/agent-provider/sandbox';\nimport { createConfinedFileReader, SandboxEntryType } from '@finalai/agent-provider/sandbox';\nimport { encodeSandboxText } from '@finalai/agent-provider/sandbox/bytes';\nimport { readTextFileStream } from '@finalai/agent-provider/sandbox/convenience';\nimport { collectStream, errorMessage, isNotFoundMessage, rechunk, splitChunks } from \"./bytes.mjs\";\nimport { posixCommandLine, type SandboxCommandEncoderIface } from \"./commands.mjs\";\nimport { POSIX_PATHS, type SandboxPathsIface } from \"./paths.mjs\";\nimport {\n exitStatus,\n type SandboxTransportIface,\n type TransportOutputIface,\n type TransportOutputStreamIface,\n type TransportProcessIface,\n} from \"./transport.mjs\";\n\n// NetworkSandboxSessionIface over any SandboxTransportIface. Provider specifics\n// (lifecycle, ports, extra capabilities) come in through `network`.\n\nexport interface TransportSessionNetworkIface {\n ports: readonly number[];\n getPortEndpoint(options: {\n port: number;\n protocol?: PortProtocol;\n }): Promise<{ url: string; headers?: Record<string, string> }>;\n stop(): Promise<void>;\n destroy(): Promise<void>;\n}\n\nexport interface CreateTransportSessionArgsIface {\n id: string;\n description: string;\n workspaceRoot: string;\n transport: SandboxTransportIface;\n // Environment every process gets (injected variables), under per-call env;\n // read again for every process.\n baseEnv: () => Promise<Record<string, string>>;\n randomUuid: () => string;\n network: TransportSessionNetworkIface;\n // The sandbox's path flavour and command encoding; POSIX unless a Device says otherwise.\n paths?: SandboxPathsIface;\n commands?: SandboxCommandEncoderIface;\n // What else a process ref must match beyond this session and the process's\n // boot, read when spawning and attaching (a Device's lease generation).\n processScope?: () => string;\n}\n\n// A durable process's ref: this session, the process and its boot, and the scope.\nconst PROCESS_REF_PREFIX = 'final-process.v1';\n\nconst encodeProcessRef = (parts: {\n session: string;\n process: TransportProcessIface;\n scope: string;\n}): string =>\n [PROCESS_REF_PREFIX, parts.session, parts.process.id, parts.process.bootId, parts.scope]\n .map(encodeURIComponent)\n .join(':');\n\nconst decodeProcessRef = (\n ref: string,\n): { session: string; process: TransportProcessIface; scope: string } | null => {\n const parts = ref.split(':');\n if (parts.length !== 5 || parts[0] !== PROCESS_REF_PREFIX) return null;\n try {\n const [session = '', id = '', bootId = '', scope = ''] = parts.slice(1).map(decodeURIComponent);\n return { session, process: { id, bootId }, scope };\n } catch {\n return null;\n }\n};\n\n// Where output read from `requested` starts: there, or later when the\n// backend no longer retains the bytes from there.\nconst outputStart = (chunk: TransportOutputStreamIface, requested: number): number =>\n Math.max(requested, chunk.nextOffset - chunk.data.byteLength);\n\nconst textDecoder = (): TextDecoder => new TextDecoder('utf-8');\n\ninterface PushStreamIface {\n stream: ReadableStream<Uint8Array>;\n controller?: ReadableStreamDefaultController<Uint8Array>;\n}\n\ninterface ControllerHolderIface {\n controller?: ReadableStreamDefaultController<Uint8Array>;\n}\n\n// A stream the output pump pushes into; unread output stays queued in memory.\nconst pushStream = (): PushStreamIface => {\n const holder: ControllerHolderIface = {};\n const stream = new ReadableStream<Uint8Array>({\n start: (controller) => {\n holder.controller = controller;\n },\n });\n return { stream, controller: holder.controller };\n};\n\nconst toStatEntry = (\n path: string,\n stat: { type: SandboxEntryType; size: number; modifiedAtMs: number | null; mode: number | null },\n): StatIface => ({\n path,\n type: stat.type,\n size: stat.size,\n modifiedAt: stat.modifiedAtMs == null ? null : new Date(stat.modifiedAtMs).toISOString(),\n mode: stat.mode,\n});\n\nexport const createTransportSession = (\n args: CreateTransportSessionArgsIface,\n): NetworkSandboxSessionIface => {\n const { transport } = args;\n const paths = args.paths ?? POSIX_PATHS;\n const commandLine = args.commands ?? posixCommandLine;\n const resolvePath = (path: string): string => paths.resolve(args.workspaceRoot, path);\n\n const kill =\n (process: TransportProcessIface) =>\n async (signal?: string): Promise<void> => {\n await transport.input(\n signal == null || signal === 'SIGKILL' ? { process, terminate: true } : { process, signal },\n );\n };\n\n // Polls a process's output from the given offsets (after `first`, output\n // already read from there) until it exits. Aborting `detach` stops polling\n // and fails the streams and the exit; the process is untouched.\n const followProcess = (args: {\n process: TransportProcessIface;\n stdoutOffset: number;\n stderrOffset: number;\n first?: TransportOutputIface;\n detach?: AbortSignal;\n }) => {\n const { process } = args;\n const stdoutPush = pushStream();\n const stderrPush = pushStream();\n let settleExit: (value: { exitCode: number }) => void = () => undefined;\n let failExit: (error: Error) => void = () => undefined;\n const exit = new Promise<{ exitCode: number }>((resolve, reject) => {\n settleExit = resolve;\n failExit = reject;\n });\n // Avoid an unhandled rejection when the caller only reads the streams.\n exit.catch(() => undefined);\n void (async () => {\n let stdoutOffset = args.stdoutOffset;\n let stderrOffset = args.stderrOffset;\n let waitMs = transport.outputWaitMs;\n let pending = args.first;\n try {\n for (;;) {\n args.detach?.throwIfAborted();\n const output =\n pending ??\n (await transport.output({\n process,\n stdoutOffset,\n stderrOffset,\n waitMs,\n signal: args.detach,\n }));\n pending = undefined;\n args.detach?.throwIfAborted();\n if (output.stdout.data.byteLength > 0) stdoutPush.controller?.enqueue(output.stdout.data);\n if (output.stderr.data.byteLength > 0) stderrPush.controller?.enqueue(output.stderr.data);\n const advanced =\n output.stdout.nextOffset !== stdoutOffset || output.stderr.nextOffset !== stderrOffset;\n stdoutOffset = output.stdout.nextOffset;\n stderrOffset = output.stderr.nextOffset;\n if (output.exited && output.stdout.eof && output.stderr.eof) {\n stdoutPush.controller?.close();\n stderrPush.controller?.close();\n settleExit({ exitCode: exitStatus(output.exitCode, output.exitSignal) });\n return;\n }\n // Exited with unread output: drain it without waiting.\n waitMs = output.exited && advanced ? 0 : transport.outputWaitMs;\n }\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n stdoutPush.controller?.error(error);\n stderrPush.controller?.error(error);\n failExit(error);\n }\n })();\n return { stdout: stdoutPush.stream, stderr: stderrPush.stream, exit, kill: kill(process) };\n };\n\n const spawnProcess = async (\n options: SandboxProcessOptionsIface,\n closeStdin: boolean,\n ): Promise<SandboxProcessIface> => {\n options.abortSignal?.throwIfAborted();\n // Durable only where processes outlive this client (`processGone`).\n const durable = options.durable === true && transport.processGone != null;\n const process: TransportProcessIface = await transport.exec({\n id: args.randomUuid(),\n command: commandLine(options),\n cwd: resolvePath(options.cwd ?? args.workspaceRoot),\n env: { ...(await args.baseEnv()), ...options.env },\n timeoutMs: options.timeoutMs ?? null,\n signal: options.abortSignal,\n });\n const followed = followProcess({\n process,\n stdoutOffset: 0,\n stderrOffset: 0,\n detach: durable ? options.abortSignal : undefined,\n });\n if (!durable) {\n const onAbort = (): void => {\n void followed.kill().catch(() => undefined);\n };\n options.abortSignal?.addEventListener('abort', onAbort, { once: true });\n if (options.abortSignal?.aborted === true) onAbort();\n void followed.exit\n .catch(() => undefined)\n .finally(() => options.abortSignal?.removeEventListener('abort', onAbort));\n }\n\n // A detached durable handle neither writes to nor closes the process's stdin.\n const write = async (data: Uint8Array | string, writeOptions?: { end?: boolean }) => {\n if (durable) options.abortSignal?.throwIfAborted();\n const bytes = data instanceof Uint8Array ? data : new TextEncoder().encode(data);\n if (bytes.byteLength > 0) await transport.input({ process, data: bytes });\n if (writeOptions?.end === true) await transport.input({ process, eof: true });\n };\n\n const input = options.stdin;\n if (input instanceof ReadableStream) {\n void (async () => {\n // Forward input as it arrives: a stdin stream is often interactive.\n for await (const chunk of splitChunks(input, 64 * 1024)) await write(chunk);\n await write(new Uint8Array(), { end: true });\n })().catch(() => undefined);\n } else if (input != null) {\n await write(input, { end: true });\n } else if (closeStdin) {\n await transport.input({ process, eof: true });\n }\n\n return {\n pid: process.id,\n ref: durable\n ? encodeProcessRef({ session: args.id, process, scope: args.processScope?.() ?? '' })\n : null,\n stdout: followed.stdout,\n stderr: followed.stderr,\n write,\n wait: () => followed.exit,\n kill: followed.kill,\n };\n };\n\n // Finds a durable process again: null for a ref of another session or scope,\n // or a process the backend no longer knows.\n const attachProcess = async (\n options: SandboxAttachProcessOptionsIface,\n ): Promise<SandboxAttachedProcessIface | null> => {\n options.abortSignal?.throwIfAborted();\n const decoded = decodeProcessRef(options.ref);\n if (\n transport.processGone == null ||\n decoded == null ||\n decoded.session !== args.id ||\n decoded.scope !== (args.processScope?.() ?? '')\n )\n return null;\n const { process } = decoded;\n let first: TransportOutputIface;\n try {\n first = await transport.output({\n process,\n stdoutOffset: options.stdoutOffset,\n stderrOffset: options.stderrOffset,\n waitMs: 0,\n signal: options.abortSignal,\n });\n } catch (cause) {\n if (transport.processGone(cause)) return null;\n throw cause;\n }\n const followed = followProcess({\n process,\n stdoutOffset: options.stdoutOffset,\n stderrOffset: options.stderrOffset,\n first,\n detach: options.abortSignal,\n });\n return {\n ref: options.ref,\n stdoutOffset: outputStart(first.stdout, options.stdoutOffset),\n stderrOffset: outputStart(first.stderr, options.stderrOffset),\n stdout: followed.stdout,\n stderr: followed.stderr,\n wait: () => followed.exit,\n kill: followed.kill,\n };\n };\n\n const readStream = async (\n path: string,\n signal: AbortSignal | undefined,\n ): Promise<ReadableStream<Uint8Array> | null> => {\n const resolved = resolvePath(path);\n const stat = await transport.stat({ path: resolved, signal });\n if (stat == null) return null;\n if (stat.type === SandboxEntryType.Directory) throw new Error(`${resolved} is a directory`);\n // Read to end of file rather than to the stat size: a symlink's stat is the\n // link's own length, not its target's.\n let offset = 0;\n let done = false;\n return new ReadableStream<Uint8Array>({\n pull: async (controller) => {\n if (done) {\n controller.close();\n return;\n }\n const chunk = await transport.readChunk({\n path: resolved,\n offset,\n length: transport.fileChunkBytes,\n signal,\n });\n done = chunk.eof || chunk.bytes.byteLength === 0;\n offset += chunk.bytes.byteLength;\n if (chunk.bytes.byteLength > 0) controller.enqueue(chunk.bytes);\n if (done) controller.close();\n },\n });\n };\n\n const writeStream = async (\n path: string,\n content: ReadableStream<Uint8Array>,\n signal: AbortSignal | undefined,\n ): Promise<void> => {\n const resolved = resolvePath(path);\n await transport.createDirectory({ path: paths.dirname(resolved), signal });\n let offset = 0;\n for await (const chunk of rechunk(content, transport.fileChunkBytes)) {\n await transport.writeChunk({ path: resolved, offset, bytes: chunk, signal });\n offset += chunk.byteLength;\n }\n if (offset === 0)\n await transport.writeChunk({ path: resolved, offset: 0, bytes: new Uint8Array(), signal });\n };\n\n const bytesStream = (bytes: Uint8Array): ReadableStream<Uint8Array> =>\n new ReadableStream<Uint8Array>({\n start: (controller) => {\n if (bytes.byteLength > 0) controller.enqueue(bytes);\n controller.close();\n },\n });\n\n const session: NetworkSandboxSessionIface = {\n id: args.id,\n description: args.description,\n defaultWorkingDirectory: args.workspaceRoot,\n ports: args.network.ports,\n resolvePath,\n readFile: async ({ path, abortSignal }) => readStream(path, abortSignal),\n readBinaryFile: async ({ path, abortSignal }) => {\n const stream = await readStream(path, abortSignal);\n return stream == null ? null : collectStream(stream);\n },\n readTextFile: async (options) => {\n const stream = await readStream(options.path, options.abortSignal);\n return stream == null ? null : readTextFileStream(stream, options);\n },\n writeFile: async ({ path, content, abortSignal }) => writeStream(path, content, abortSignal),\n writeBinaryFile: async ({ path, content, abortSignal }) =>\n writeStream(path, bytesStream(content), abortSignal),\n writeTextFile: async ({ path, content, encoding, abortSignal }) =>\n writeStream(path, bytesStream(encodeSandboxText(content, encoding)), abortSignal),\n spawn: (options) => spawnProcess(options, false),\n run: async (options): Promise<SandboxRunResultIface> => {\n const process = await spawnProcess({ ...options, durable: false }, true);\n const [stdout, stderr, exit] = await Promise.all([\n collectStream(process.stdout),\n collectStream(process.stderr),\n process.wait(),\n ]);\n return {\n exitCode: exit.exitCode,\n stdout: textDecoder().decode(stdout),\n stderr: textDecoder().decode(stderr),\n };\n },\n stat: async ({ path, abortSignal }) => {\n const resolved = resolvePath(path);\n const stat = await transport.stat({ path: resolved, signal: abortSignal });\n return stat == null ? null : toStatEntry(resolved, stat);\n },\n readDir: async ({ path, abortSignal }): Promise<DirEntryIface[]> => {\n const resolved = resolvePath(path);\n const entries = await transport.readDir({ path: resolved, signal: abortSignal });\n return entries.map((entry) => ({\n name: entry.name,\n path: paths.join(resolved, entry.name),\n type: entry.type,\n size: entry.size,\n }));\n },\n removePath: async ({ path, recursive, force, abortSignal }) => {\n const resolved = resolvePath(path);\n try {\n await transport.remove({\n path: resolved,\n recursive: recursive === true,\n force: force === true,\n signal: abortSignal,\n });\n } catch (error) {\n if (force === true && isNotFoundMessage(errorMessage(error))) return;\n throw error;\n }\n },\n getPortEndpoint: (options) => args.network.getPortEndpoint(options),\n getPortUrl: async (options) => (await args.network.getPortEndpoint(options)).url,\n stop: () => args.network.stop(),\n destroy: () => args.network.destroy(),\n };\n if (transport.processGone != null) session.attachProcess = attachProcess;\n return { ...session, confinedFileReader: createConfinedFileReader(session) };\n};\n\nconst readOnlyRefusal = async (): Promise<never> => {\n throw new Error('this sandbox handle is read-only');\n};\n\n// A passive viewer's view of a handle: reads pass through; writes, processes and\n// lifecycle are refused here as well as by the backend the provider asked.\nexport const readOnlySession = <S extends NetworkSandboxSessionIface>(session: S): S => {\n const restricted: S = {\n ...session,\n writeFile: readOnlyRefusal,\n writeBinaryFile: readOnlyRefusal,\n writeTextFile: readOnlyRefusal,\n spawn: readOnlyRefusal,\n run: readOnlyRefusal,\n removePath: readOnlyRefusal,\n stop: readOnlyRefusal,\n destroy: readOnlyRefusal,\n };\n if (session.setNetworkPolicy != null) restricted.setNetworkPolicy = readOnlyRefusal;\n delete restricted.egress;\n delete restricted.attachProcess;\n const screen = session.screen;\n if (screen != null)\n restricted.screen = async (options) => {\n if (options?.viewOnly === false) return readOnlyRefusal();\n return screen.call(session, options);\n };\n return restricted;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["args"]
7
7
  }
@@ -3,7 +3,6 @@ import { SANDBOX_SEED_MARKER, SANDBOX_SEED_PROTOCOL } from "@finalai/agent-provi
3
3
  import { posix } from "node:path";
4
4
  import * as z from "zod";
5
5
  import { concatBytes } from "../bytes.mjs";
6
- import { GUIDE_COMMAND_PROTOCOL } from "../workspace-setup.mjs";
7
6
  import { quotedShellArguments } from "./quoted-shell-arguments.mjs";
8
7
  const unwrapCommand = (command) => {
9
8
  if (command.startsWith("bash -lc "))
@@ -36,33 +35,6 @@ const createFakeMachine = () => {
36
35
  };
37
36
  const builtin = (control) => {
38
37
  const script = control.exec.script;
39
- if (script.includes(GUIDE_COMMAND_PROTOCOL)) {
40
- const chunks = [];
41
- control.onStdin((data) => chunks.push(data));
42
- control.onEof(() => {
43
- const payload = z.object({ root: z.string(), files: z.record(z.string(), z.string()) }).parse(JSON.parse(new TextDecoder().decode(concatBytes(chunks))));
44
- if ([...links.keys()].some(
45
- (path) => payload.root === path || payload.root.startsWith(`${path}/`)
46
- )) {
47
- control.stderr("symlink command directory");
48
- control.exit(1);
49
- return;
50
- }
51
- for (const [name, content] of Object.entries(payload.files)) {
52
- const path = posix.join(payload.root, name);
53
- const existing = files.get(path);
54
- if (links.has(path) || existing != null && new TextDecoder().decode(existing) !== content) {
55
- control.stderr("guide command differs from its pinned source");
56
- control.exit(1);
57
- return;
58
- }
59
- mkdirp(payload.root);
60
- files.set(path, bytes(content));
61
- }
62
- control.exit(0);
63
- });
64
- return true;
65
- }
66
38
  if (script.includes(SANDBOX_SEED_PROTOCOL)) {
67
39
  const chunks = [];
68
40
  control.onStdin((data) => chunks.push(data));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/sandboxes/testing/fake-machine.ts"],
4
- "sourcesContent": ["import { DURABLE_CONFORMANCE_SCRIPT } from '@finalai/agent-provider/conformance';\nimport { SANDBOX_SEED_MARKER, SANDBOX_SEED_PROTOCOL } from '@finalai/agent-provider/sandbox';\nimport { posix } from 'node:path';\nimport * as z from 'zod';\nimport { concatBytes } from \"../bytes.mjs\";\nimport { GUIDE_COMMAND_PROTOCOL } from \"../workspace-setup.mjs\";\nimport { quotedShellArguments } from \"./quoted-shell-arguments.mjs\";\n\n// An in-memory machine behind the fake Computers API, data plane and Device: a file\n// tree plus managed processes whose behaviour tests script by command.\n\nexport interface FakeExecIface {\n command: string;\n // The command with the provider's `bash -lc '\u2026'` / `exec '\u2026'` wrapper removed.\n script: string;\n cwd: string;\n env: Record<string, string>;\n}\n\nexport interface FakeProcessControlIface {\n readonly exec: FakeExecIface;\n stdout(text: string | Uint8Array): void;\n stderr(text: string | Uint8Array): void;\n exit(code: number, signal?: string | null): void;\n onStdin(listener: (data: Uint8Array) => void): void;\n onEof(listener: () => void): void;\n}\n\nexport interface FakeBehaviorIface {\n (process: FakeProcessControlIface): void;\n}\n\nexport interface FakeProcessIface {\n id: string;\n bootId: string;\n exec: FakeExecIface;\n stdout: Uint8Array;\n stderr: Uint8Array;\n exited: boolean;\n exitCode: number | null;\n signal: string | null;\n write(data: Uint8Array): void;\n eof(): void;\n terminate(signal?: string): void;\n // Resolves on the next change (output or exit), or after `ms`.\n changed(ms: number): Promise<void>;\n}\n\nexport interface FakeMachineIface {\n files: Map<string, Uint8Array>;\n dirs: Set<string>;\n // Symlink path \u2192 target path.\n links: Map<string, string>;\n execs: FakeExecIface[];\n processes: Map<string, FakeProcessIface>;\n // Tests register behaviours; the first whose predicate matches runs.\n on(match: (exec: FakeExecIface) => boolean, behavior: FakeBehaviorIface): void;\n exec(args: {\n id: string;\n command: string;\n cwd: string;\n env: Record<string, string>;\n }): FakeProcessIface;\n mkdirp(path: string): void;\n readText(path: string): string | null;\n}\n\n// Removes the session handle's `bash -lc '\u2026'` or `exec '\u2026' '\u2026'` wrapper.\nexport const unwrapCommand = (command: string): string => {\n if (command.startsWith('bash -lc '))\n return quotedShellArguments(command.slice('bash -lc '.length)).join(' ');\n if (command.startsWith('exec bash -lc '))\n return quotedShellArguments(command.slice('exec bash -lc '.length)).join(' ');\n if (command.startsWith('exec '))\n return quotedShellArguments(command.slice('exec '.length)).join(' ');\n return command;\n};\n\n// The first single-quoted argument after `marker` in a script.\nexport const quotedAfter = (script: string, marker: string): string | null => {\n const index = script.indexOf(marker);\n if (index < 0) return null;\n return quotedShellArguments(script.slice(index + marker.length))[0] ?? null;\n};\n\nconst bytes = (data: string | Uint8Array): Uint8Array =>\n data instanceof Uint8Array ? data : new TextEncoder().encode(data);\n\nexport const createFakeMachine = (): FakeMachineIface => {\n const files = new Map<string, Uint8Array>();\n const dirs = new Set<string>(['/', '/workspaces', '/tmp']);\n const links = new Map<string, string>();\n const behaviors: { match: (exec: FakeExecIface) => boolean; behavior: FakeBehaviorIface }[] = [];\n const execs: FakeExecIface[] = [];\n const processes = new Map<string, FakeProcessIface>();\n\n const mkdirp = (path: string): void => {\n let current = posix.normalize(path);\n while (current !== '/' && !dirs.has(current)) {\n dirs.add(current);\n current = posix.dirname(current);\n }\n };\n\n // Built-in behaviour for the provider's own helper scripts.\n const builtin = (control: FakeProcessControlIface): boolean => {\n const script = control.exec.script;\n if (script.includes(GUIDE_COMMAND_PROTOCOL)) {\n const chunks: Uint8Array[] = [];\n control.onStdin((data) => chunks.push(data));\n control.onEof(() => {\n const payload = z\n .object({ root: z.string(), files: z.record(z.string(), z.string()) })\n .parse(JSON.parse(new TextDecoder().decode(concatBytes(chunks))));\n if (\n [...links.keys()].some(\n (path) => payload.root === path || payload.root.startsWith(`${path}/`),\n )\n ) {\n control.stderr('symlink command directory');\n control.exit(1);\n return;\n }\n for (const [name, content] of Object.entries(payload.files)) {\n const path = posix.join(payload.root, name);\n const existing = files.get(path);\n if (\n links.has(path) ||\n (existing != null && new TextDecoder().decode(existing) !== content)\n ) {\n control.stderr('guide command differs from its pinned source');\n control.exit(1);\n return;\n }\n mkdirp(payload.root);\n files.set(path, bytes(content));\n }\n control.exit(0);\n });\n return true;\n }\n if (script.includes(SANDBOX_SEED_PROTOCOL)) {\n const chunks: Uint8Array[] = [];\n control.onStdin((data) => chunks.push(data));\n control.onEof(() => {\n const payload = z\n .object({ root: z.string(), files: z.record(z.string(), z.string()) })\n .parse(JSON.parse(new TextDecoder().decode(concatBytes(chunks))));\n const marker = posix.join(payload.root, '.final', SANDBOX_SEED_MARKER);\n if (files.has(marker)) {\n control.exit(0);\n return;\n }\n for (const [path, content] of Object.entries(payload.files)) {\n const target = posix.join(payload.root, path);\n if (files.has(target)) continue;\n mkdirp(posix.dirname(target));\n files.set(target, bytes(content));\n }\n mkdirp(posix.dirname(marker));\n files.set(marker, bytes(SANDBOX_SEED_PROTOCOL));\n control.exit(0);\n });\n return true;\n }\n // The provider's helper scripts, matched by how they start.\n const leading = (marker: string): string | null =>\n script.startsWith(marker) ? quotedAfter(script, marker) : null;\n const statPath = leading('if [ ! -e ');\n if (statPath != null && script.includes('stat -c')) {\n // Like `stat` without -L: a symlink reports its own length.\n const link = links.get(statPath);\n if (link != null) control.stdout(`symbolic link|${link.length}|1700000000|777\\n`);\n else if (dirs.has(statPath)) control.stdout(`directory|4096|1700000000|755\\n`);\n else if (files.has(statPath))\n control.stdout(`regular file|${files.get(statPath)?.byteLength ?? 0}|1700000000|644\\n`);\n else control.stdout('missing\\n');\n control.exit(0);\n return true;\n }\n const listPath = leading('[ -d ');\n if (listPath != null && script.includes('find ')) {\n if (!dirs.has(listPath)) {\n control.stderr('Not a directory\\n');\n control.exit(2);\n return true;\n }\n const entries: string[] = [];\n for (const dir of dirs) {\n if (dir !== listPath && posix.dirname(dir) === listPath)\n entries.push(`d\\t4096\\t${posix.basename(dir)}\\0`);\n }\n for (const [path, content] of files) {\n if (posix.dirname(path) === listPath)\n entries.push(`f\\t${content.byteLength}\\t${posix.basename(path)}\\0`);\n }\n control.stdout(entries.join(''));\n control.exit(0);\n return true;\n }\n const mkdirPath = leading('mkdir -p -- ');\n if (mkdirPath != null) {\n mkdirp(mkdirPath);\n control.exit(0);\n return true;\n }\n const removePath = leading('if [ -d ');\n if (removePath != null && script.includes('rm')) {\n if (dirs.has(removePath)) {\n for (const dir of [...dirs])\n if (dir === removePath || dir.startsWith(`${removePath}/`)) dirs.delete(dir);\n for (const path of [...files.keys()])\n if (path.startsWith(`${removePath}/`)) files.delete(path);\n } else if (files.has(removePath)) {\n files.delete(removePath);\n } else if (!script.includes('-f')) {\n control.stderr(`rm: cannot remove: No such file or directory\\n`);\n control.exit(1);\n return true;\n }\n control.exit(0);\n return true;\n }\n if (script.includes('git clone')) {\n const destination = quotedAfter(script.slice(script.indexOf('git clone')), \"' \");\n if (destination != null) mkdirp(`${destination}/.git`);\n control.exit(0);\n return true;\n }\n // Enough of a shell for the conformance kit's process cases.\n if (script === 'cat') {\n control.onStdin((data) => control.stdout(data));\n control.onEof(() => control.exit(0));\n return true;\n }\n if (script.startsWith('sleep ')) return true;\n if (script === DURABLE_CONFORMANCE_SCRIPT) {\n control.stdout('one\\n');\n control.stderr('err-one\\n');\n setTimeout(() => {\n control.stdout('two\\n');\n control.stderr('err-two\\n');\n control.exit(7);\n }, 100);\n return true;\n }\n if (script === 'echo out; echo err >&2; exit 3') {\n control.stdout('out\\n');\n control.stderr('err\\n');\n control.exit(3);\n return true;\n }\n if (script.startsWith('printenv ')) {\n const name = script.slice('printenv '.length);\n const value = Object.hasOwn(control.exec.env, name) ? control.exec.env[name] : undefined;\n if (value != null) control.stdout(`${value}\\n`);\n control.exit(value == null ? 1 : 0);\n return true;\n }\n if (script === 'echo' || script.startsWith('echo ')) {\n control.stdout(`${script.slice('echo '.length)}\\n`);\n control.exit(0);\n return true;\n }\n return false;\n };\n\n const exec: FakeMachineIface['exec'] = (args) => {\n const record: FakeExecIface = {\n command: args.command,\n script: unwrapCommand(args.command),\n cwd: args.cwd,\n env: args.env,\n };\n execs.push(record);\n const stdinListeners: ((data: Uint8Array) => void)[] = [];\n const eofListeners: (() => void)[] = [];\n let waiters: (() => void)[] = [];\n const notify = (): void => {\n const pending = waiters;\n waiters = [];\n for (const wake of pending) wake();\n };\n const process: FakeProcessIface = {\n id: args.id,\n bootId: 'boot-1',\n exec: record,\n stdout: new Uint8Array(),\n stderr: new Uint8Array(),\n exited: false,\n exitCode: null,\n signal: null,\n write: (data) => {\n for (const listener of stdinListeners) listener(data);\n },\n eof: () => {\n for (const listener of eofListeners) listener();\n },\n terminate: (signal) => {\n if (process.exited) return;\n process.exited = true;\n process.signal = signal ?? 'SIGKILL';\n notify();\n },\n changed: (ms) =>\n new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n waiters.push(() => {\n clearTimeout(timer);\n resolve();\n });\n }),\n };\n const control: FakeProcessControlIface = {\n exec: record,\n stdout: (data) => {\n process.stdout = concatBytes([process.stdout, bytes(data)]);\n notify();\n },\n stderr: (data) => {\n process.stderr = concatBytes([process.stderr, bytes(data)]);\n notify();\n },\n exit: (code, signal = null) => {\n if (process.exited) return;\n process.exited = true;\n process.exitCode = signal == null ? code : null;\n process.signal = signal;\n notify();\n },\n onStdin: (listener) => stdinListeners.push(listener),\n onEof: (listener) => eofListeners.push(listener),\n };\n processes.set(args.id, process);\n const custom = behaviors.find((entry) => entry.match(record));\n if (custom != null) custom.behavior(control);\n else if (!builtin(control)) control.exit(0);\n return process;\n };\n\n return {\n files,\n dirs,\n links,\n execs,\n processes,\n on: (match, behavior) => behaviors.push({ match, behavior }),\n exec,\n mkdirp,\n readText: (path) => {\n const content = files.get(path);\n return content == null ? null : new TextDecoder().decode(content);\n },\n };\n};\n\n// Output from offsets, waiting up to `waitMs` (capped for fast tests) for news.\nexport const readFakeOutput = async (\n process: FakeProcessIface,\n offsets: { stdout: number; stderr: number; waitMs: number },\n): Promise<{ stdout: Uint8Array; stderr: Uint8Array; exited: boolean }> => {\n if (\n !process.exited &&\n process.stdout.byteLength <= offsets.stdout &&\n process.stderr.byteLength <= offsets.stderr &&\n offsets.waitMs > 0\n ) {\n await process.changed(Math.min(offsets.waitMs, 50));\n }\n return {\n stdout: process.stdout.subarray(offsets.stdout),\n stderr: process.stderr.subarray(offsets.stderr),\n exited: process.exited,\n };\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { DURABLE_CONFORMANCE_SCRIPT } from '@finalai/agent-provider/conformance';\nimport { SANDBOX_SEED_MARKER, SANDBOX_SEED_PROTOCOL } from '@finalai/agent-provider/sandbox';\nimport { posix } from 'node:path';\nimport * as z from 'zod';\nimport { concatBytes } from \"../bytes.mjs\";\nimport { quotedShellArguments } from \"./quoted-shell-arguments.mjs\";\n\n// An in-memory machine behind the fake Computers API, data plane and Device: a file\n// tree plus managed processes whose behaviour tests script by command.\n\nexport interface FakeExecIface {\n command: string;\n // The command with the provider's `bash -lc '\u2026'` / `exec '\u2026'` wrapper removed.\n script: string;\n cwd: string;\n env: Record<string, string>;\n}\n\nexport interface FakeProcessControlIface {\n readonly exec: FakeExecIface;\n stdout(text: string | Uint8Array): void;\n stderr(text: string | Uint8Array): void;\n exit(code: number, signal?: string | null): void;\n onStdin(listener: (data: Uint8Array) => void): void;\n onEof(listener: () => void): void;\n}\n\nexport interface FakeBehaviorIface {\n (process: FakeProcessControlIface): void;\n}\n\nexport interface FakeProcessIface {\n id: string;\n bootId: string;\n exec: FakeExecIface;\n stdout: Uint8Array;\n stderr: Uint8Array;\n exited: boolean;\n exitCode: number | null;\n signal: string | null;\n write(data: Uint8Array): void;\n eof(): void;\n terminate(signal?: string): void;\n // Resolves on the next change (output or exit), or after `ms`.\n changed(ms: number): Promise<void>;\n}\n\nexport interface FakeMachineIface {\n files: Map<string, Uint8Array>;\n dirs: Set<string>;\n // Symlink path \u2192 target path.\n links: Map<string, string>;\n execs: FakeExecIface[];\n processes: Map<string, FakeProcessIface>;\n // Tests register behaviours; the first whose predicate matches runs.\n on(match: (exec: FakeExecIface) => boolean, behavior: FakeBehaviorIface): void;\n exec(args: {\n id: string;\n command: string;\n cwd: string;\n env: Record<string, string>;\n }): FakeProcessIface;\n mkdirp(path: string): void;\n readText(path: string): string | null;\n}\n\n// Removes the session handle's `bash -lc '\u2026'` or `exec '\u2026' '\u2026'` wrapper.\nexport const unwrapCommand = (command: string): string => {\n if (command.startsWith('bash -lc '))\n return quotedShellArguments(command.slice('bash -lc '.length)).join(' ');\n if (command.startsWith('exec bash -lc '))\n return quotedShellArguments(command.slice('exec bash -lc '.length)).join(' ');\n if (command.startsWith('exec '))\n return quotedShellArguments(command.slice('exec '.length)).join(' ');\n return command;\n};\n\n// The first single-quoted argument after `marker` in a script.\nexport const quotedAfter = (script: string, marker: string): string | null => {\n const index = script.indexOf(marker);\n if (index < 0) return null;\n return quotedShellArguments(script.slice(index + marker.length))[0] ?? null;\n};\n\nconst bytes = (data: string | Uint8Array): Uint8Array =>\n data instanceof Uint8Array ? data : new TextEncoder().encode(data);\n\nexport const createFakeMachine = (): FakeMachineIface => {\n const files = new Map<string, Uint8Array>();\n const dirs = new Set<string>(['/', '/workspaces', '/tmp']);\n const links = new Map<string, string>();\n const behaviors: { match: (exec: FakeExecIface) => boolean; behavior: FakeBehaviorIface }[] = [];\n const execs: FakeExecIface[] = [];\n const processes = new Map<string, FakeProcessIface>();\n\n const mkdirp = (path: string): void => {\n let current = posix.normalize(path);\n while (current !== '/' && !dirs.has(current)) {\n dirs.add(current);\n current = posix.dirname(current);\n }\n };\n\n // Built-in behaviour for the provider's own helper scripts.\n const builtin = (control: FakeProcessControlIface): boolean => {\n const script = control.exec.script;\n if (script.includes(SANDBOX_SEED_PROTOCOL)) {\n const chunks: Uint8Array[] = [];\n control.onStdin((data) => chunks.push(data));\n control.onEof(() => {\n const payload = z\n .object({ root: z.string(), files: z.record(z.string(), z.string()) })\n .parse(JSON.parse(new TextDecoder().decode(concatBytes(chunks))));\n const marker = posix.join(payload.root, '.final', SANDBOX_SEED_MARKER);\n if (files.has(marker)) {\n control.exit(0);\n return;\n }\n for (const [path, content] of Object.entries(payload.files)) {\n const target = posix.join(payload.root, path);\n if (files.has(target)) continue;\n mkdirp(posix.dirname(target));\n files.set(target, bytes(content));\n }\n mkdirp(posix.dirname(marker));\n files.set(marker, bytes(SANDBOX_SEED_PROTOCOL));\n control.exit(0);\n });\n return true;\n }\n // The provider's helper scripts, matched by how they start.\n const leading = (marker: string): string | null =>\n script.startsWith(marker) ? quotedAfter(script, marker) : null;\n const statPath = leading('if [ ! -e ');\n if (statPath != null && script.includes('stat -c')) {\n // Like `stat` without -L: a symlink reports its own length.\n const link = links.get(statPath);\n if (link != null) control.stdout(`symbolic link|${link.length}|1700000000|777\\n`);\n else if (dirs.has(statPath)) control.stdout(`directory|4096|1700000000|755\\n`);\n else if (files.has(statPath))\n control.stdout(`regular file|${files.get(statPath)?.byteLength ?? 0}|1700000000|644\\n`);\n else control.stdout('missing\\n');\n control.exit(0);\n return true;\n }\n const listPath = leading('[ -d ');\n if (listPath != null && script.includes('find ')) {\n if (!dirs.has(listPath)) {\n control.stderr('Not a directory\\n');\n control.exit(2);\n return true;\n }\n const entries: string[] = [];\n for (const dir of dirs) {\n if (dir !== listPath && posix.dirname(dir) === listPath)\n entries.push(`d\\t4096\\t${posix.basename(dir)}\\0`);\n }\n for (const [path, content] of files) {\n if (posix.dirname(path) === listPath)\n entries.push(`f\\t${content.byteLength}\\t${posix.basename(path)}\\0`);\n }\n control.stdout(entries.join(''));\n control.exit(0);\n return true;\n }\n const mkdirPath = leading('mkdir -p -- ');\n if (mkdirPath != null) {\n mkdirp(mkdirPath);\n control.exit(0);\n return true;\n }\n const removePath = leading('if [ -d ');\n if (removePath != null && script.includes('rm')) {\n if (dirs.has(removePath)) {\n for (const dir of [...dirs])\n if (dir === removePath || dir.startsWith(`${removePath}/`)) dirs.delete(dir);\n for (const path of [...files.keys()])\n if (path.startsWith(`${removePath}/`)) files.delete(path);\n } else if (files.has(removePath)) {\n files.delete(removePath);\n } else if (!script.includes('-f')) {\n control.stderr(`rm: cannot remove: No such file or directory\\n`);\n control.exit(1);\n return true;\n }\n control.exit(0);\n return true;\n }\n if (script.includes('git clone')) {\n const destination = quotedAfter(script.slice(script.indexOf('git clone')), \"' \");\n if (destination != null) mkdirp(`${destination}/.git`);\n control.exit(0);\n return true;\n }\n // Enough of a shell for the conformance kit's process cases.\n if (script === 'cat') {\n control.onStdin((data) => control.stdout(data));\n control.onEof(() => control.exit(0));\n return true;\n }\n if (script.startsWith('sleep ')) return true;\n if (script === DURABLE_CONFORMANCE_SCRIPT) {\n control.stdout('one\\n');\n control.stderr('err-one\\n');\n setTimeout(() => {\n control.stdout('two\\n');\n control.stderr('err-two\\n');\n control.exit(7);\n }, 100);\n return true;\n }\n if (script === 'echo out; echo err >&2; exit 3') {\n control.stdout('out\\n');\n control.stderr('err\\n');\n control.exit(3);\n return true;\n }\n if (script.startsWith('printenv ')) {\n const name = script.slice('printenv '.length);\n const value = Object.hasOwn(control.exec.env, name) ? control.exec.env[name] : undefined;\n if (value != null) control.stdout(`${value}\\n`);\n control.exit(value == null ? 1 : 0);\n return true;\n }\n if (script === 'echo' || script.startsWith('echo ')) {\n control.stdout(`${script.slice('echo '.length)}\\n`);\n control.exit(0);\n return true;\n }\n return false;\n };\n\n const exec: FakeMachineIface['exec'] = (args) => {\n const record: FakeExecIface = {\n command: args.command,\n script: unwrapCommand(args.command),\n cwd: args.cwd,\n env: args.env,\n };\n execs.push(record);\n const stdinListeners: ((data: Uint8Array) => void)[] = [];\n const eofListeners: (() => void)[] = [];\n let waiters: (() => void)[] = [];\n const notify = (): void => {\n const pending = waiters;\n waiters = [];\n for (const wake of pending) wake();\n };\n const process: FakeProcessIface = {\n id: args.id,\n bootId: 'boot-1',\n exec: record,\n stdout: new Uint8Array(),\n stderr: new Uint8Array(),\n exited: false,\n exitCode: null,\n signal: null,\n write: (data) => {\n for (const listener of stdinListeners) listener(data);\n },\n eof: () => {\n for (const listener of eofListeners) listener();\n },\n terminate: (signal) => {\n if (process.exited) return;\n process.exited = true;\n process.signal = signal ?? 'SIGKILL';\n notify();\n },\n changed: (ms) =>\n new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n waiters.push(() => {\n clearTimeout(timer);\n resolve();\n });\n }),\n };\n const control: FakeProcessControlIface = {\n exec: record,\n stdout: (data) => {\n process.stdout = concatBytes([process.stdout, bytes(data)]);\n notify();\n },\n stderr: (data) => {\n process.stderr = concatBytes([process.stderr, bytes(data)]);\n notify();\n },\n exit: (code, signal = null) => {\n if (process.exited) return;\n process.exited = true;\n process.exitCode = signal == null ? code : null;\n process.signal = signal;\n notify();\n },\n onStdin: (listener) => stdinListeners.push(listener),\n onEof: (listener) => eofListeners.push(listener),\n };\n processes.set(args.id, process);\n const custom = behaviors.find((entry) => entry.match(record));\n if (custom != null) custom.behavior(control);\n else if (!builtin(control)) control.exit(0);\n return process;\n };\n\n return {\n files,\n dirs,\n links,\n execs,\n processes,\n on: (match, behavior) => behaviors.push({ match, behavior }),\n exec,\n mkdirp,\n readText: (path) => {\n const content = files.get(path);\n return content == null ? null : new TextDecoder().decode(content);\n },\n };\n};\n\n// Output from offsets, waiting up to `waitMs` (capped for fast tests) for news.\nexport const readFakeOutput = async (\n process: FakeProcessIface,\n offsets: { stdout: number; stderr: number; waitMs: number },\n): Promise<{ stdout: Uint8Array; stderr: Uint8Array; exited: boolean }> => {\n if (\n !process.exited &&\n process.stdout.byteLength <= offsets.stdout &&\n process.stderr.byteLength <= offsets.stderr &&\n offsets.waitMs > 0\n ) {\n await process.changed(Math.min(offsets.waitMs, 50));\n }\n return {\n stdout: process.stdout.subarray(offsets.stdout),\n stderr: process.stderr.subarray(offsets.stderr),\n exited: process.exited,\n };\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@finalai/final-agent-provider",
3
- "version": "0.10.1",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
- "description": "Final provider helpers for harnesses, computer and device sandboxes, the Final room surface, and external provider channels.",
5
+ "description": "Final's harness and ACP adapter definitions and the general harness provider, computer, device and local sandbox providers, and Final's MCP gateway integration.",
6
6
  "license": "Apache-2.0",
7
7
  "files": [
8
8
  "dist",
@@ -10,8 +10,7 @@
10
10
  "WORKSPACE-EGRESS.md",
11
11
  "LICENSE",
12
12
  "NOTICE",
13
- "HOSTING.md",
14
- "THIRD_PARTY_NOTICES.md"
13
+ "HOSTING.md"
15
14
  ],
16
15
  "type": "module",
17
16
  "sideEffects": false,
@@ -21,50 +20,60 @@
21
20
  "import": "./dist/modules/harnesses/index.mjs",
22
21
  "default": "./dist/modules/harnesses/index.mjs"
23
22
  },
24
- "./harnesses/serverless-final": {
25
- "types": "./dist/modules/harnesses/serverless-final.d.mts",
26
- "import": "./dist/modules/harnesses/serverless-final.mjs",
27
- "default": "./dist/modules/harnesses/serverless-final.mjs"
28
- },
29
- "./harnesses/serverless-pi": {
30
- "types": "./dist/modules/harnesses/serverless-pi.d.mts",
31
- "import": "./dist/modules/harnesses/serverless-pi.mjs",
32
- "default": "./dist/modules/harnesses/serverless-pi.mjs"
33
- },
34
- "./harnesses/serverless-nanocode-codex": {
35
- "types": "./dist/modules/harnesses/serverless-nanocode-codex.d.mts",
36
- "import": "./dist/modules/harnesses/serverless-nanocode-codex.mjs",
37
- "default": "./dist/modules/harnesses/serverless-nanocode-codex.mjs"
38
- },
39
- "./harnesses/serverless-nanocode-claude": {
40
- "types": "./dist/modules/harnesses/serverless-nanocode-claude.d.mts",
41
- "import": "./dist/modules/harnesses/serverless-nanocode-claude.mjs",
42
- "default": "./dist/modules/harnesses/serverless-nanocode-claude.mjs"
43
- },
44
- "./harnesses/remote-claude-code": {
45
- "types": "./dist/modules/harnesses/remote-claude-code.d.mts",
46
- "import": "./dist/modules/harnesses/remote-claude-code.mjs",
47
- "default": "./dist/modules/harnesses/remote-claude-code.mjs"
48
- },
49
- "./harnesses/remote-codex": {
50
- "types": "./dist/modules/harnesses/remote-codex.d.mts",
51
- "import": "./dist/modules/harnesses/remote-codex.mjs",
52
- "default": "./dist/modules/harnesses/remote-codex.mjs"
53
- },
54
- "./harnesses/remote-pi": {
55
- "types": "./dist/modules/harnesses/remote-pi.d.mts",
56
- "import": "./dist/modules/harnesses/remote-pi.mjs",
57
- "default": "./dist/modules/harnesses/remote-pi.mjs"
58
- },
59
- "./harnesses/remote-acp": {
60
- "types": "./dist/modules/harnesses/remote-acp.d.mts",
61
- "import": "./dist/modules/harnesses/remote-acp.mjs",
62
- "default": "./dist/modules/harnesses/remote-acp.mjs"
63
- },
64
- "./harnesses/local-stdio": {
65
- "types": "./dist/modules/harnesses/local-stdio.d.mts",
66
- "import": "./dist/modules/harnesses/local-stdio.mjs",
67
- "default": "./dist/modules/harnesses/local-stdio.mjs"
23
+ "./harnesses/final": {
24
+ "types": "./dist/modules/harnesses/final.d.mts",
25
+ "import": "./dist/modules/harnesses/final.mjs",
26
+ "default": "./dist/modules/harnesses/final.mjs"
27
+ },
28
+ "./harnesses/pi": {
29
+ "types": "./dist/modules/harnesses/pi.d.mts",
30
+ "import": "./dist/modules/harnesses/pi.mjs",
31
+ "default": "./dist/modules/harnesses/pi.mjs"
32
+ },
33
+ "./harnesses/nanocode-claude": {
34
+ "types": "./dist/modules/harnesses/nanocode-claude.d.mts",
35
+ "import": "./dist/modules/harnesses/nanocode-claude.mjs",
36
+ "default": "./dist/modules/harnesses/nanocode-claude.mjs"
37
+ },
38
+ "./harnesses/nanocode-codex": {
39
+ "types": "./dist/modules/harnesses/nanocode-codex.d.mts",
40
+ "import": "./dist/modules/harnesses/nanocode-codex.mjs",
41
+ "default": "./dist/modules/harnesses/nanocode-codex.mjs"
42
+ },
43
+ "./harnesses/claude-code": {
44
+ "types": "./dist/modules/harnesses/claude-code.d.mts",
45
+ "import": "./dist/modules/harnesses/claude-code.mjs",
46
+ "default": "./dist/modules/harnesses/claude-code.mjs"
47
+ },
48
+ "./harnesses/codex": {
49
+ "types": "./dist/modules/harnesses/codex.d.mts",
50
+ "import": "./dist/modules/harnesses/codex.mjs",
51
+ "default": "./dist/modules/harnesses/codex.mjs"
52
+ },
53
+ "./harnesses/adapters": {
54
+ "types": "./dist/modules/harnesses/adapters.d.mts",
55
+ "import": "./dist/modules/harnesses/adapters.mjs",
56
+ "default": "./dist/modules/harnesses/adapters.mjs"
57
+ },
58
+ "./harnesses/definitions": {
59
+ "types": "./dist/modules/harnesses/definitions.d.mts",
60
+ "import": "./dist/modules/harnesses/definitions.mjs",
61
+ "default": "./dist/modules/harnesses/definitions.mjs"
62
+ },
63
+ "./provider": {
64
+ "types": "./dist/modules/provider/index.d.mts",
65
+ "import": "./dist/modules/provider/index.mjs",
66
+ "default": "./dist/modules/provider/index.mjs"
67
+ },
68
+ "./provider/general": {
69
+ "types": "./dist/modules/provider/general.d.mts",
70
+ "import": "./dist/modules/provider/general.mjs",
71
+ "default": "./dist/modules/provider/general.mjs"
72
+ },
73
+ "./catalog": {
74
+ "types": "./dist/modules/catalog.d.mts",
75
+ "import": "./dist/modules/catalog.mjs",
76
+ "default": "./dist/modules/catalog.mjs"
68
77
  },
69
78
  "./harnesses/fidelity": {
70
79
  "types": "./dist/modules/harnesses/fidelity.d.mts",
@@ -86,37 +95,17 @@
86
95
  "import": "./dist/modules/sandboxes/device.mjs",
87
96
  "default": "./dist/modules/sandboxes/device.mjs"
88
97
  },
89
- "./channels": {
90
- "types": "./dist/modules/channels/index.d.mts",
91
- "import": "./dist/modules/channels/index.mjs",
92
- "default": "./dist/modules/channels/index.mjs"
98
+ "./sandboxes/local": {
99
+ "types": "./dist/modules/sandboxes/local.d.mts",
100
+ "import": "./dist/modules/sandboxes/local.mjs",
101
+ "default": "./dist/modules/sandboxes/local.mjs"
93
102
  },
94
- "./channels/direct-messaging": {
95
- "types": "./dist/modules/channels/direct-messaging.d.mts",
96
- "import": "./dist/modules/channels/direct-messaging.mjs",
97
- "default": "./dist/modules/channels/direct-messaging.mjs"
98
- },
99
- "./channels/group-messaging": {
100
- "types": "./dist/modules/channels/group-messaging.d.mts",
101
- "import": "./dist/modules/channels/group-messaging.mjs",
102
- "default": "./dist/modules/channels/group-messaging.mjs"
103
+ "./sandboxes/access": {
104
+ "types": "./dist/modules/sandboxes/access.d.mts",
105
+ "import": "./dist/modules/sandboxes/access.mjs",
106
+ "default": "./dist/modules/sandboxes/access.mjs"
103
107
  },
104
108
  "./package.json": "./package.json",
105
- "./channel-factories": {
106
- "types": "./dist/modules/channel-factories.d.mts",
107
- "import": "./dist/modules/channel-factories.mjs",
108
- "default": "./dist/modules/channel-factories.mjs"
109
- },
110
- "./channels/final": {
111
- "types": "./dist/modules/authoring-final-channel.d.mts",
112
- "import": "./dist/modules/authoring-final-channel.mjs",
113
- "default": "./dist/modules/authoring-final-channel.mjs"
114
- },
115
- "./channels/inbound": {
116
- "types": "./dist/modules/channels/inbound.d.mts",
117
- "import": "./dist/modules/channels/inbound.mjs",
118
- "default": "./dist/modules/channels/inbound.mjs"
119
- },
120
109
  "./harnesses/config-fields": {
121
110
  "types": "./dist/modules/harnesses/config-fields.d.mts",
122
111
  "import": "./dist/modules/harnesses/config-fields.mjs",
@@ -137,61 +126,6 @@
137
126
  "import": "./dist/modules/sandboxes/testing/quoted-shell-arguments.mjs",
138
127
  "default": "./dist/modules/sandboxes/testing/quoted-shell-arguments.mjs"
139
128
  },
140
- "./runtime/local-stdio": {
141
- "types": "./dist/modules/runtime/local-stdio.d.mts",
142
- "import": "./dist/modules/runtime/local-stdio.mjs",
143
- "default": "./dist/modules/runtime/local-stdio.mjs"
144
- },
145
- "./runtime/remote-acp": {
146
- "types": "./dist/modules/runtime/remote-acp.d.mts",
147
- "import": "./dist/modules/runtime/remote-acp.mjs",
148
- "default": "./dist/modules/runtime/remote-acp.mjs"
149
- },
150
- "./runtime/remote-claude-code": {
151
- "types": "./dist/modules/runtime/remote-claude-code.d.mts",
152
- "import": "./dist/modules/runtime/remote-claude-code.mjs",
153
- "default": "./dist/modules/runtime/remote-claude-code.mjs"
154
- },
155
- "./runtime/remote-codex": {
156
- "types": "./dist/modules/runtime/remote-codex.d.mts",
157
- "import": "./dist/modules/runtime/remote-codex.mjs",
158
- "default": "./dist/modules/runtime/remote-codex.mjs"
159
- },
160
- "./runtime/remote-pi": {
161
- "types": "./dist/modules/runtime/remote-pi.d.mts",
162
- "import": "./dist/modules/runtime/remote-pi.mjs",
163
- "default": "./dist/modules/runtime/remote-pi.mjs"
164
- },
165
- "./runtime/remote-host": {
166
- "types": "./dist/modules/runtime/remote-host.d.mts",
167
- "import": "./dist/modules/runtime/remote-host.mjs",
168
- "default": "./dist/modules/runtime/remote-host.mjs"
169
- },
170
- "./harnesses/remote-url": {
171
- "types": "./dist/modules/harnesses/remote-url.d.mts",
172
- "import": "./dist/modules/harnesses/remote-url.mjs",
173
- "default": "./dist/modules/harnesses/remote-url.mjs"
174
- },
175
- "./runtime": {
176
- "types": "./dist/modules/runtime/index.d.mts",
177
- "import": "./dist/modules/runtime/index.mjs",
178
- "default": "./dist/modules/runtime/index.mjs"
179
- },
180
- "./testing/harness": {
181
- "types": "./dist/modules/testing/harness.d.mts",
182
- "import": "./dist/modules/testing/harness.mjs",
183
- "default": "./dist/modules/testing/harness.mjs"
184
- },
185
- "./testing/fake-platform": {
186
- "types": "./dist/modules/channels/fake-platform.d.mts",
187
- "import": "./dist/modules/channels/fake-platform.mjs",
188
- "default": "./dist/modules/channels/fake-platform.mjs"
189
- },
190
- "./connections": {
191
- "types": "./dist/modules/connections.d.mts",
192
- "import": "./dist/modules/connections.mjs",
193
- "default": "./dist/modules/connections.mjs"
194
- },
195
129
  "./sandboxes/egress": {
196
130
  "types": "./dist/modules/sandboxes/egress.d.mts",
197
131
  "import": "./dist/modules/sandboxes/egress.mjs",
@@ -201,6 +135,11 @@
201
135
  "types": "./dist/modules/sandboxes/egress-bootstrap.d.mts",
202
136
  "import": "./dist/modules/sandboxes/egress-bootstrap.mjs",
203
137
  "default": "./dist/modules/sandboxes/egress-bootstrap.mjs"
138
+ },
139
+ "./integrations": {
140
+ "types": "./dist/modules/integrations.d.mts",
141
+ "import": "./dist/modules/integrations.mjs",
142
+ "default": "./dist/modules/integrations.mjs"
204
143
  }
205
144
  },
206
145
  "publishConfig": {
@@ -209,14 +148,11 @@
209
148
  },
210
149
  "dependencies": {
211
150
  "@agentclientprotocol/sdk": "1.8.0",
212
- "@finalai/acp-session": "0.1.12",
213
- "@finalai/agent-protocol": "0.8.0",
214
- "@finalai/agent-provider": "0.9.0",
151
+ "@finalai/agent-protocol": "0.10.0",
152
+ "@finalai/agent-provider": "0.11.0",
215
153
  "@finalai/computers": "0.3.1",
216
- "@finalai/websockets": "0.1.7",
217
- "ws": "^8.21.3",
218
154
  "zod": "4.6.6",
219
- "@finalai/agent-definition": "0.8.0"
155
+ "@finalai/agent-definition": "0.10.0"
220
156
  },
221
157
  "engines": {
222
158
  "node": ">=26"
@@ -1,3 +0,0 @@
1
- import { finalChannel as createFinalChannel, type FinalChannelOptionsIface } from "./channel-factories.mjs";
2
- export * from "./channel-factories.mjs";
3
- export declare const finalChannel: (options?: FinalChannelOptionsIface) => ReturnType<typeof createFinalChannel>;
@@ -1,10 +0,0 @@
1
- import { defineRoomSurface } from "@finalai/agent-definition/authoring";
2
- import {
3
- finalChannel as createFinalChannel
4
- } from "./channel-factories.mjs";
5
- export * from "./channel-factories.mjs";
6
- const finalChannel = (options = {}) => defineRoomSurface(createFinalChannel(options));
7
- export {
8
- finalChannel
9
- };
10
- //# sourceMappingURL=authoring-final-channel.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/authoring-final-channel.ts"],
4
- "sourcesContent": ["import { defineRoomSurface } from '@finalai/agent-definition/authoring';\nimport {\n finalChannel as createFinalChannel,\n type FinalChannelOptionsIface,\n} from \"./channel-factories.mjs\";\nexport * from \"./channel-factories.mjs\";\nexport const finalChannel = (\n options: FinalChannelOptionsIface = {},\n): ReturnType<typeof createFinalChannel> => defineRoomSurface(createFinalChannel(options));\n"],
5
- "mappings": "AAAA,SAAS,yBAAyB;AAClC;AAAA,EACE,gBAAgB;AAAA,OAEX;AACP,cAAc;AACP,MAAM,eAAe,CAC1B,UAAoC,CAAC,MACK,kBAAkB,mBAAmB,OAAO,CAAC;",
6
- "names": []
7
- }