@cloudflare/sandbox 0.3.7 → 0.4.2
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.
- package/.turbo/turbo-build.log +44 -0
- package/CHANGELOG.md +8 -10
- package/Dockerfile +82 -18
- package/README.md +89 -824
- package/dist/chunk-53JFOF7F.js +2352 -0
- package/dist/chunk-53JFOF7F.js.map +1 -0
- package/dist/chunk-BFVUNTP4.js +104 -0
- package/dist/chunk-BFVUNTP4.js.map +1 -0
- package/dist/{chunk-NNGBXDMY.js → chunk-EKSWCBCA.js} +3 -6
- package/dist/chunk-EKSWCBCA.js.map +1 -0
- package/dist/chunk-JXZMAU2C.js +559 -0
- package/dist/chunk-JXZMAU2C.js.map +1 -0
- package/dist/{chunk-6UAWTJ5S.js → chunk-Z532A7QC.js} +13 -20
- package/dist/{chunk-6UAWTJ5S.js.map → chunk-Z532A7QC.js.map} +1 -1
- package/dist/file-stream.d.ts +16 -38
- package/dist/file-stream.js +1 -2
- package/dist/index.d.ts +6 -5
- package/dist/index.js +45 -38
- package/dist/interpreter.d.ts +3 -3
- package/dist/interpreter.js +2 -2
- package/dist/request-handler.d.ts +4 -3
- package/dist/request-handler.js +4 -7
- package/dist/sandbox-D9K2ypln.d.ts +583 -0
- package/dist/sandbox.d.ts +3 -3
- package/dist/sandbox.js +4 -7
- package/dist/security.d.ts +4 -3
- package/dist/security.js +3 -3
- package/dist/sse-parser.js +1 -1
- package/package.json +12 -4
- package/src/clients/base-client.ts +280 -0
- package/src/clients/command-client.ts +115 -0
- package/src/clients/file-client.ts +269 -0
- package/src/clients/git-client.ts +92 -0
- package/src/clients/index.ts +63 -0
- package/src/{interpreter-client.ts → clients/interpreter-client.ts} +148 -171
- package/src/clients/port-client.ts +105 -0
- package/src/clients/process-client.ts +177 -0
- package/src/clients/sandbox-client.ts +41 -0
- package/src/clients/types.ts +84 -0
- package/src/clients/utility-client.ts +94 -0
- package/src/errors/adapter.ts +180 -0
- package/src/errors/classes.ts +469 -0
- package/src/errors/index.ts +105 -0
- package/src/file-stream.ts +119 -117
- package/src/index.ts +81 -69
- package/src/interpreter.ts +17 -8
- package/src/request-handler.ts +69 -43
- package/src/sandbox.ts +694 -533
- package/src/security.ts +14 -23
- package/src/sse-parser.ts +4 -8
- package/startup.sh +3 -0
- package/tests/base-client.test.ts +328 -0
- package/tests/command-client.test.ts +407 -0
- package/tests/file-client.test.ts +643 -0
- package/tests/file-stream.test.ts +306 -0
- package/tests/git-client.test.ts +328 -0
- package/tests/port-client.test.ts +301 -0
- package/tests/process-client.test.ts +658 -0
- package/tests/sandbox.test.ts +465 -0
- package/tests/sse-parser.test.ts +290 -0
- package/tests/utility-client.test.ts +266 -0
- package/tests/wrangler.jsonc +35 -0
- package/tsconfig.json +9 -1
- package/vitest.config.ts +31 -0
- package/container_src/bun.lock +0 -76
- package/container_src/circuit-breaker.ts +0 -121
- package/container_src/control-process.ts +0 -784
- package/container_src/handler/exec.ts +0 -185
- package/container_src/handler/file.ts +0 -457
- package/container_src/handler/git.ts +0 -130
- package/container_src/handler/ports.ts +0 -314
- package/container_src/handler/process.ts +0 -568
- package/container_src/handler/session.ts +0 -92
- package/container_src/index.ts +0 -601
- package/container_src/interpreter-service.ts +0 -276
- package/container_src/isolation.ts +0 -1213
- package/container_src/mime-processor.ts +0 -255
- package/container_src/package.json +0 -18
- package/container_src/runtime/executors/javascript/node_executor.ts +0 -123
- package/container_src/runtime/executors/python/ipython_executor.py +0 -338
- package/container_src/runtime/executors/typescript/ts_executor.ts +0 -138
- package/container_src/runtime/process-pool.ts +0 -464
- package/container_src/shell-escape.ts +0 -42
- package/container_src/startup.sh +0 -11
- package/container_src/types.ts +0 -131
- package/dist/chunk-32UDXUPC.js +0 -671
- package/dist/chunk-32UDXUPC.js.map +0 -1
- package/dist/chunk-5DILEXGY.js +0 -85
- package/dist/chunk-5DILEXGY.js.map +0 -1
- package/dist/chunk-D3U63BZP.js +0 -240
- package/dist/chunk-D3U63BZP.js.map +0 -1
- package/dist/chunk-FXYPFGOZ.js +0 -129
- package/dist/chunk-FXYPFGOZ.js.map +0 -1
- package/dist/chunk-JTKON2SH.js +0 -113
- package/dist/chunk-JTKON2SH.js.map +0 -1
- package/dist/chunk-NNGBXDMY.js.map +0 -1
- package/dist/chunk-SQLJNZ3K.js +0 -674
- package/dist/chunk-SQLJNZ3K.js.map +0 -1
- package/dist/chunk-W7TVRPBG.js +0 -108
- package/dist/chunk-W7TVRPBG.js.map +0 -1
- package/dist/client-B3RUab0s.d.ts +0 -225
- package/dist/client.d.ts +0 -4
- package/dist/client.js +0 -7
- package/dist/client.js.map +0 -1
- package/dist/errors.d.ts +0 -95
- package/dist/errors.js +0 -27
- package/dist/errors.js.map +0 -1
- package/dist/interpreter-client.d.ts +0 -4
- package/dist/interpreter-client.js +0 -9
- package/dist/interpreter-client.js.map +0 -1
- package/dist/interpreter-types.d.ts +0 -259
- package/dist/interpreter-types.js +0 -9
- package/dist/interpreter-types.js.map +0 -1
- package/dist/types.d.ts +0 -453
- package/dist/types.js +0 -45
- package/dist/types.js.map +0 -1
- package/src/client.ts +0 -1048
- package/src/errors.ts +0 -219
- package/src/interpreter-types.ts +0 -390
- package/src/types.ts +0 -571
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type { ExecuteRequest } from \"../container_src/types\";\nimport type { Sandbox } from \"./index\";\nimport type {\n BaseExecOptions,\n DeleteFileResponse,\n ExecuteResponse,\n GetProcessLogsResponse,\n GetProcessResponse,\n GitCheckoutResponse,\n ListFilesResponse,\n ListProcessesResponse,\n MkdirResponse,\n MoveFileResponse,\n ReadFileResponse,\n RenameFileResponse,\n StartProcessRequest,\n StartProcessResponse,\n WriteFileResponse,\n} from \"./types\";\n\n\ninterface CommandsResponse {\n availableCommands: string[];\n timestamp: string;\n}\n\ninterface GitCheckoutRequest {\n repoUrl: string;\n branch?: string;\n targetDir?: string;\n sessionId: string;\n}\n\n\ninterface MkdirRequest {\n path: string;\n recursive?: boolean;\n sessionId: string;\n}\n\n\ninterface WriteFileRequest {\n path: string;\n content: string;\n encoding?: string;\n sessionId: string;\n}\n\n\ninterface ReadFileRequest {\n path: string;\n encoding?: string;\n sessionId: string;\n}\n\n\ninterface DeleteFileRequest {\n path: string;\n sessionId: string;\n}\n\n\ninterface RenameFileRequest {\n oldPath: string;\n newPath: string;\n sessionId: string;\n}\n\n\ninterface MoveFileRequest {\n sourcePath: string;\n destinationPath: string;\n sessionId: string;\n}\n\n\ninterface ListFilesRequest {\n path: string;\n options?: {\n recursive?: boolean;\n includeHidden?: boolean;\n };\n sessionId: string;\n}\n\n\ninterface PreviewInfo {\n url: string;\n port: number;\n name?: string;\n}\n\ninterface ExposedPort extends PreviewInfo {\n exposedAt: string;\n timestamp: string;\n}\n\ninterface ExposePortResponse {\n success: boolean;\n port: number;\n name?: string;\n exposedAt: string;\n timestamp: string;\n}\n\ninterface UnexposePortResponse {\n success: boolean;\n port: number;\n timestamp: string;\n}\n\ninterface GetExposedPortsResponse {\n ports: ExposedPort[];\n count: number;\n timestamp: string;\n}\n\ninterface PingResponse {\n message: string;\n timestamp: string;\n}\n\ninterface HttpClientOptions {\n stub?: Sandbox;\n baseUrl?: string;\n port?: number;\n onCommandStart?: (command: string) => void;\n onOutput?: (\n stream: \"stdout\" | \"stderr\",\n data: string,\n command: string\n ) => void;\n onCommandComplete?: (\n success: boolean,\n exitCode: number,\n stdout: string,\n stderr: string,\n command: string\n ) => void;\n onError?: (error: string, command?: string) => void;\n}\n\nexport class HttpClient {\n private baseUrl: string;\n private options: HttpClientOptions;\n\n constructor(options: HttpClientOptions = {}) {\n this.options = {\n ...options,\n };\n this.baseUrl = this.options.baseUrl!;\n }\n\n protected async doFetch(\n path: string,\n options?: RequestInit\n ): Promise<Response> {\n const url = this.options.stub\n ? `http://localhost:${this.options.port}${path}`\n : `${this.baseUrl}${path}`;\n const method = options?.method || \"GET\";\n\n console.log(`[HTTP Client] Making ${method} request to ${url}`);\n\n try {\n let response: Response;\n\n if (this.options.stub) {\n response = await this.options.stub.containerFetch(\n url,\n options,\n this.options.port\n );\n } else {\n response = await fetch(url, options);\n }\n\n console.log(\n `[HTTP Client] Response: ${response.status} ${response.statusText}`\n );\n\n if (!response.ok) {\n console.error(\n `[HTTP Client] Request failed: ${method} ${url} - ${response.status} ${response.statusText}`\n );\n }\n\n return response;\n } catch (error) {\n console.error(`[HTTP Client] Request error: ${method} ${url}`, error);\n throw error;\n }\n }\n\n async createSession(options: {\n id: string;\n env?: Record<string, string>;\n cwd?: string;\n isolation?: boolean;\n }): Promise<{ success: boolean; id: string; message: string }> {\n try {\n const response = await this.doFetch(`/api/session/create`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(options),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `Failed to create session: ${response.status}`\n );\n }\n\n const data = await response.json() as { success: boolean; id: string; message: string };\n console.log(`[HTTP Client] Session created: ${options.id}`);\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error creating session:\", error);\n throw error;\n }\n }\n\n async exec(\n sessionId: string,\n command: string,\n options?: Pick<BaseExecOptions, \"cwd\" | \"env\">\n ): Promise<ExecuteResponse> {\n try {\n // Always use session-specific endpoint\n const response = await this.doFetch(`/api/execute`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ id: sessionId, command }),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `Failed to execute in session: ${response.status}`\n );\n }\n\n const data = await response.json() as { stdout: string; stderr: string; exitCode: number; success: boolean };\n console.log(\n `[HTTP Client] Command executed in session ${sessionId}: ${command}`\n );\n \n // Convert to ExecuteResponse format for consistency\n const executeResponse: ExecuteResponse = {\n ...data,\n command,\n timestamp: new Date().toISOString()\n };\n\n // Call the callback if provided\n this.options.onCommandComplete?.(\n executeResponse.success,\n executeResponse.exitCode,\n executeResponse.stdout,\n executeResponse.stderr,\n executeResponse.command\n );\n\n return executeResponse;\n } catch (error) {\n console.error(\"[HTTP Client] Error executing in session:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n command\n );\n throw error;\n }\n }\n\n async execStream(\n sessionId: string,\n command: string\n ): Promise<ReadableStream<Uint8Array>> {\n try {\n // Always use session-specific streaming endpoint\n const response = await this.doFetch(`/api/execute/stream`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ \n id: sessionId,\n command\n }),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `Failed to stream execute in session: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming execution\");\n }\n\n console.log(\n `[HTTP Client] Started streaming command in session ${sessionId}: ${command}`\n );\n return response.body;\n } catch (error) {\n console.error(\"[HTTP Client] Error streaming execute in session:\", error);\n throw error;\n }\n }\n\n async gitCheckout(\n repoUrl: string,\n sessionId: string,\n branch: string = \"main\",\n targetDir?: string\n ): Promise<GitCheckoutResponse> {\n try {\n const response = await this.doFetch(`/api/git/checkout`, {\n body: JSON.stringify({\n branch,\n repoUrl,\n targetDir,\n sessionId,\n } as GitCheckoutRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: GitCheckoutResponse = await response.json();\n console.log(\n `[HTTP Client] Git checkout completed: ${repoUrl}, Success: ${data.success}, Target: ${data.targetDir}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error in git checkout:\", error);\n throw error;\n }\n }\n\n async mkdir(\n path: string,\n recursive: boolean = false,\n sessionId: string\n ): Promise<MkdirResponse> {\n try {\n const response = await this.doFetch(`/api/mkdir`, {\n body: JSON.stringify({\n path,\n recursive,\n sessionId,\n } as MkdirRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: MkdirResponse = await response.json();\n console.log(\n `[HTTP Client] Directory created: ${path}, Success: ${data.success}, Recursive: ${data.recursive}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error creating directory:\", error);\n throw error;\n }\n }\n\n async writeFile(\n path: string,\n content: string,\n encoding: string = \"utf-8\",\n sessionId: string\n ): Promise<WriteFileResponse> {\n try {\n const response = await this.doFetch(`/api/write`, {\n body: JSON.stringify({\n content,\n encoding,\n path,\n sessionId,\n } as WriteFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: WriteFileResponse = await response.json();\n console.log(\n `[HTTP Client] File written: ${path}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error writing file:\", error);\n throw error;\n }\n }\n\n async readFile(\n path: string,\n encoding: string = \"utf-8\",\n sessionId: string\n ): Promise<ReadFileResponse> {\n try {\n const response = await this.doFetch(`/api/read`, {\n body: JSON.stringify({\n encoding,\n path,\n sessionId,\n } as ReadFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: ReadFileResponse = await response.json();\n console.log(\n `[HTTP Client] File read: ${path}, Success: ${data.success}, Content length: ${data.content.length}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error reading file:\", error);\n throw error;\n }\n }\n\n async readFileStream(\n path: string,\n sessionId: string\n ): Promise<ReadableStream<Uint8Array>> {\n try {\n const response = await this.doFetch(`/api/read/stream`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n path,\n sessionId,\n } as ReadFileRequest),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for file streaming\");\n }\n\n console.log(\n `[HTTP Client] Started streaming file: ${path}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n return response.body;\n } catch (error) {\n console.error(\"[HTTP Client] Error streaming file:\", error);\n throw error;\n }\n }\n\n async deleteFile(\n path: string,\n sessionId: string\n ): Promise<DeleteFileResponse> {\n try {\n const response = await this.doFetch(`/api/delete`, {\n body: JSON.stringify({\n path,\n sessionId,\n } as DeleteFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: DeleteFileResponse = await response.json();\n console.log(\n `[HTTP Client] File deleted: ${path}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error deleting file:\", error);\n throw error;\n }\n }\n\n async renameFile(\n oldPath: string,\n newPath: string,\n sessionId: string\n ): Promise<RenameFileResponse> {\n try {\n const response = await this.doFetch(`/api/rename`, {\n body: JSON.stringify({\n newPath,\n oldPath,\n sessionId,\n } as RenameFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: RenameFileResponse = await response.json();\n console.log(\n `[HTTP Client] File renamed: ${oldPath} -> ${newPath}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error renaming file:\", error);\n throw error;\n }\n }\n\n async moveFile(\n sourcePath: string,\n destinationPath: string,\n sessionId: string\n ): Promise<MoveFileResponse> {\n try {\n const response = await this.doFetch(`/api/move`, {\n body: JSON.stringify({\n destinationPath,\n sourcePath,\n sessionId,\n } as MoveFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: MoveFileResponse = await response.json();\n console.log(\n `[HTTP Client] File moved: ${sourcePath} -> ${destinationPath}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error moving file:\", error);\n throw error;\n }\n }\n\n async listFiles(\n path: string,\n sessionId: string,\n options?: {\n recursive?: boolean;\n includeHidden?: boolean;\n }\n ): Promise<ListFilesResponse> {\n try {\n const response = await this.doFetch(`/api/list-files`, {\n body: JSON.stringify({\n path,\n options,\n sessionId,\n } as ListFilesRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: ListFilesResponse = await response.json();\n console.log(\n `[HTTP Client] Listed ${data.files.length} files in: ${path}, Success: ${data.success}${sessionId ? ` in session: ${sessionId}` : ''}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error listing files:\", error);\n throw error;\n }\n }\n\n async exposePort(port: number, name?: string): Promise<ExposePortResponse> {\n try {\n const response = await this.doFetch(`/api/expose-port`, {\n body: JSON.stringify({\n port,\n name,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n console.log(errorData);\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: ExposePortResponse = await response.json();\n console.log(\n `[HTTP Client] Port exposed: ${port}${\n name ? ` (${name})` : \"\"\n }, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error exposing port:\", error);\n throw error;\n }\n }\n\n async unexposePort(port: number): Promise<UnexposePortResponse> {\n try {\n const response = await this.doFetch(`/api/unexpose-port`, {\n body: JSON.stringify({\n port,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"DELETE\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: UnexposePortResponse = await response.json();\n console.log(\n `[HTTP Client] Port unexposed: ${port}, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error unexposing port:\", error);\n throw error;\n }\n }\n\n async getExposedPorts(): Promise<GetExposedPortsResponse> {\n try {\n const response = await this.doFetch(`/api/exposed-ports`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: GetExposedPortsResponse = await response.json();\n console.log(`[HTTP Client] Got ${data.count} exposed ports`);\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error getting exposed ports:\", error);\n throw error;\n }\n }\n\n async ping(): Promise<string> {\n try {\n const response = await this.doFetch(`/api/ping`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data: PingResponse = await response.json();\n console.log(`[HTTP Client] Ping response: ${data.message}`);\n return data.timestamp;\n } catch (error) {\n console.error(\"[HTTP Client] Error pinging server:\", error);\n throw error;\n }\n }\n\n\n // Process management methods\n async startProcess(\n command: string,\n sessionId: string,\n options?: {\n processId?: string;\n timeout?: number;\n env?: Record<string, string>;\n cwd?: string;\n encoding?: string;\n autoCleanup?: boolean;\n }\n ): Promise<StartProcessResponse> {\n try {\n const response = await this.doFetch(\"/api/process/start\", {\n body: JSON.stringify({\n command,\n sessionId,\n options,\n } as StartProcessRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: StartProcessResponse = await response.json();\n console.log(\n `[HTTP Client] Process started: ${command}, ID: ${data.process.id}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error starting process:\", error);\n throw error;\n }\n }\n\n async listProcesses(sessionId?: string): Promise<ListProcessesResponse> {\n try {\n const url = sessionId \n ? `/api/process/list?session=${encodeURIComponent(sessionId)}`\n : \"/api/process/list\";\n const response = await this.doFetch(url, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: ListProcessesResponse = await response.json();\n console.log(`[HTTP Client] Listed ${data.processes.length} processes`);\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error listing processes:\", error);\n throw error;\n }\n }\n\n async getProcess(processId: string): Promise<GetProcessResponse> {\n try {\n const response = await this.doFetch(`/api/process/${processId}`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: GetProcessResponse = await response.json();\n console.log(\n `[HTTP Client] Got process ${processId}: ${\n data.process?.status || \"not found\"\n }`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error getting process:\", error);\n throw error;\n }\n }\n\n async killProcess(\n processId: string\n ): Promise<{ success: boolean; message: string }> {\n try {\n const response = await this.doFetch(`/api/process/${processId}`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"DELETE\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data = (await response.json()) as {\n success: boolean;\n message: string;\n };\n console.log(`[HTTP Client] Killed process ${processId}`);\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error killing process:\", error);\n throw error;\n }\n }\n\n async killAllProcesses(sessionId?: string): Promise<{\n success: boolean;\n killedCount: number;\n message: string;\n }> {\n try {\n const url = sessionId \n ? `/api/process/kill-all?session=${encodeURIComponent(sessionId)}`\n : \"/api/process/kill-all\";\n const response = await this.doFetch(url, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"DELETE\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data = (await response.json()) as {\n success: boolean;\n killedCount: number;\n message: string;\n };\n console.log(`[HTTP Client] Killed ${data.killedCount} processes`);\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error killing all processes:\", error);\n throw error;\n }\n }\n\n async getProcessLogs(processId: string): Promise<GetProcessLogsResponse> {\n try {\n const response = await this.doFetch(`/api/process/${processId}/logs`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: GetProcessLogsResponse = await response.json();\n console.log(`[HTTP Client] Got logs for process ${processId}`);\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error getting process logs:\", error);\n throw error;\n }\n }\n\n async streamProcessLogs(\n processId: string,\n options?: { signal?: AbortSignal }\n ): Promise<ReadableStream<Uint8Array>> {\n try {\n const response = await this.doFetch(`/api/process/${processId}/stream`, {\n headers: {\n Accept: \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n },\n method: \"GET\",\n signal: options?.signal,\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n console.log(\n `[HTTP Client] Started streaming logs for process ${processId}`\n );\n\n return response.body;\n } catch (error) {\n console.error(\"[HTTP Client] Error streaming process logs:\", error);\n throw error;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-5DILEXGY.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseSSEStream
|
|
3
|
-
} from "./chunk-NNGBXDMY.js";
|
|
4
|
-
|
|
5
|
-
// src/file-stream.ts
|
|
6
|
-
async function* streamFile(stream, signal) {
|
|
7
|
-
let metadata;
|
|
8
|
-
try {
|
|
9
|
-
for await (const event of parseSSEStream(stream, signal)) {
|
|
10
|
-
switch (event.type) {
|
|
11
|
-
case "metadata":
|
|
12
|
-
metadata = {
|
|
13
|
-
mimeType: event.mimeType,
|
|
14
|
-
size: event.size,
|
|
15
|
-
isBinary: event.isBinary,
|
|
16
|
-
encoding: event.encoding
|
|
17
|
-
};
|
|
18
|
-
streamFile.metadata = metadata;
|
|
19
|
-
break;
|
|
20
|
-
case "chunk":
|
|
21
|
-
if (metadata?.isBinary && metadata?.encoding === "base64") {
|
|
22
|
-
const binaryString = atob(event.data);
|
|
23
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
24
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
25
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
26
|
-
}
|
|
27
|
-
yield bytes;
|
|
28
|
-
} else {
|
|
29
|
-
yield event.data;
|
|
30
|
-
}
|
|
31
|
-
break;
|
|
32
|
-
case "complete":
|
|
33
|
-
console.log(`[streamFile] File streaming complete: ${event.bytesRead} bytes read`);
|
|
34
|
-
return;
|
|
35
|
-
case "error":
|
|
36
|
-
throw new Error(`File streaming error: ${event.error}`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error("[streamFile] Error streaming file:", error);
|
|
41
|
-
throw error;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
async function collectFile(stream, signal) {
|
|
45
|
-
let metadata;
|
|
46
|
-
const chunks = [];
|
|
47
|
-
for await (const chunk of streamFile(stream, signal)) {
|
|
48
|
-
chunks.push(chunk);
|
|
49
|
-
if (!metadata && streamFile.metadata) {
|
|
50
|
-
metadata = streamFile.metadata;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
if (!metadata) {
|
|
54
|
-
throw new Error("No metadata received from file stream");
|
|
55
|
-
}
|
|
56
|
-
if (chunks.length === 0) {
|
|
57
|
-
return {
|
|
58
|
-
content: metadata.isBinary ? new Uint8Array(0) : "",
|
|
59
|
-
metadata
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (chunks[0] instanceof Uint8Array) {
|
|
63
|
-
const totalLength = chunks.reduce((sum, chunk) => {
|
|
64
|
-
return sum + chunk.byteLength;
|
|
65
|
-
}, 0);
|
|
66
|
-
const result = new Uint8Array(totalLength);
|
|
67
|
-
let offset = 0;
|
|
68
|
-
for (const chunk of chunks) {
|
|
69
|
-
result.set(chunk, offset);
|
|
70
|
-
offset += chunk.byteLength;
|
|
71
|
-
}
|
|
72
|
-
return { content: result, metadata };
|
|
73
|
-
} else {
|
|
74
|
-
return {
|
|
75
|
-
content: chunks.join(""),
|
|
76
|
-
metadata
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export {
|
|
82
|
-
streamFile,
|
|
83
|
-
collectFile
|
|
84
|
-
};
|
|
85
|
-
//# sourceMappingURL=chunk-5DILEXGY.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/file-stream.ts"],"sourcesContent":["/**\n * File streaming utilities for reading binary and text files\n * Provides simple AsyncIterable API over SSE stream with automatic base64 decoding\n */\n\nimport { parseSSEStream } from './sse-parser';\nimport type { FileChunk, FileMetadata, FileStreamEvent } from './types';\n\n/**\n * Convert ReadableStream of SSE file events to AsyncIterable of file chunks\n * Automatically decodes base64 for binary files and provides metadata\n *\n * @param stream - The SSE ReadableStream from readFileStream()\n * @param signal - Optional AbortSignal for cancellation\n * @returns AsyncIterable that yields file chunks (string for text, Uint8Array for binary)\n *\n * @example\n * ```typescript\n * const stream = await sandbox.readFileStream('/path/to/file.png');\n *\n * for await (const chunk of streamFile(stream)) {\n * if (chunk instanceof Uint8Array) {\n * // Binary chunk - already decoded from base64\n * console.log('Binary chunk:', chunk.byteLength, 'bytes');\n * } else {\n * // Text chunk\n * console.log('Text chunk:', chunk);\n * }\n * }\n *\n * // Access metadata\n * const iter = streamFile(stream);\n * for await (const chunk of iter) {\n * console.log('MIME type:', iter.metadata?.mimeType);\n * // process chunk...\n * }\n * ```\n */\nexport async function* streamFile(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal\n): AsyncGenerator<FileChunk, void, undefined> {\n let metadata: FileMetadata | undefined;\n\n try {\n for await (const event of parseSSEStream<FileStreamEvent>(stream, signal)) {\n switch (event.type) {\n case 'metadata':\n // Store metadata for access via iterator\n metadata = {\n mimeType: event.mimeType,\n size: event.size,\n isBinary: event.isBinary,\n encoding: event.encoding,\n };\n // Store on generator function for external access\n (streamFile as any).metadata = metadata;\n break;\n\n case 'chunk':\n // Auto-decode base64 for binary files\n if (metadata?.isBinary && metadata?.encoding === 'base64') {\n // Decode base64 to Uint8Array\n const binaryString = atob(event.data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n yield bytes;\n } else {\n // Text file - yield as-is\n yield event.data;\n }\n break;\n\n case 'complete':\n // Stream completed successfully\n console.log(`[streamFile] File streaming complete: ${event.bytesRead} bytes read`);\n return;\n\n case 'error':\n // Stream error\n throw new Error(`File streaming error: ${event.error}`);\n }\n }\n } catch (error) {\n console.error('[streamFile] Error streaming file:', error);\n throw error;\n }\n}\n\n/**\n * Helper to collect entire file from stream into memory\n * Useful for smaller files where you want the complete content at once\n *\n * @param stream - The SSE ReadableStream from readFileStream()\n * @param signal - Optional AbortSignal for cancellation\n * @returns Object with content (string or Uint8Array) and metadata\n *\n * @example\n * ```typescript\n * const stream = await sandbox.readFileStream('/path/to/image.png');\n * const { content, metadata } = await collectFile(stream);\n *\n * if (content instanceof Uint8Array) {\n * console.log('Binary file:', metadata.mimeType, content.byteLength, 'bytes');\n * } else {\n * console.log('Text file:', metadata.mimeType, content.length, 'chars');\n * }\n * ```\n */\nexport async function collectFile(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal\n): Promise<{ content: string | Uint8Array; metadata: FileMetadata }> {\n let metadata: FileMetadata | undefined;\n const chunks: FileChunk[] = [];\n\n for await (const chunk of streamFile(stream, signal)) {\n chunks.push(chunk);\n // Capture metadata from first iteration\n if (!metadata && (streamFile as any).metadata) {\n metadata = (streamFile as any).metadata;\n }\n }\n\n if (!metadata) {\n throw new Error('No metadata received from file stream');\n }\n\n // Combine chunks based on type\n if (chunks.length === 0) {\n // Empty file\n return {\n content: metadata.isBinary ? new Uint8Array(0) : '',\n metadata,\n };\n }\n\n // Check if binary or text based on first chunk\n if (chunks[0] instanceof Uint8Array) {\n // Binary file - concatenate Uint8Arrays\n const totalLength = chunks.reduce((sum, chunk) => {\n return sum + (chunk as Uint8Array).byteLength;\n }, 0);\n\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk as Uint8Array, offset);\n offset += (chunk as Uint8Array).byteLength;\n }\n\n return { content: result, metadata };\n } else {\n // Text file - concatenate strings\n return {\n content: chunks.join(''),\n metadata,\n };\n }\n}\n"],"mappings":";;;;;AAsCA,gBAAuB,WACrB,QACA,QAC4C;AAC5C,MAAI;AAEJ,MAAI;AACF,qBAAiB,SAAS,eAAgC,QAAQ,MAAM,GAAG;AACzE,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAEH,qBAAW;AAAA,YACT,UAAU,MAAM;AAAA,YAChB,MAAM,MAAM;AAAA,YACZ,UAAU,MAAM;AAAA,YAChB,UAAU,MAAM;AAAA,UAClB;AAEA,UAAC,WAAmB,WAAW;AAC/B;AAAA,QAEF,KAAK;AAEH,cAAI,UAAU,YAAY,UAAU,aAAa,UAAU;AAEzD,kBAAM,eAAe,KAAK,MAAM,IAAI;AACpC,kBAAM,QAAQ,IAAI,WAAW,aAAa,MAAM;AAChD,qBAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,oBAAM,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,YACtC;AACA,kBAAM;AAAA,UACR,OAAO;AAEL,kBAAM,MAAM;AAAA,UACd;AACA;AAAA,QAEF,KAAK;AAEH,kBAAQ,IAAI,yCAAyC,MAAM,SAAS,aAAa;AACjF;AAAA,QAEF,KAAK;AAEH,gBAAM,IAAI,MAAM,yBAAyB,MAAM,KAAK,EAAE;AAAA,MAC1D;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,sCAAsC,KAAK;AACzD,UAAM;AAAA,EACR;AACF;AAsBA,eAAsB,YACpB,QACA,QACmE;AACnE,MAAI;AACJ,QAAM,SAAsB,CAAC;AAE7B,mBAAiB,SAAS,WAAW,QAAQ,MAAM,GAAG;AACpD,WAAO,KAAK,KAAK;AAEjB,QAAI,CAAC,YAAa,WAAmB,UAAU;AAC7C,iBAAY,WAAmB;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAGA,MAAI,OAAO,WAAW,GAAG;AAEvB,WAAO;AAAA,MACL,SAAS,SAAS,WAAW,IAAI,WAAW,CAAC,IAAI;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,CAAC,aAAa,YAAY;AAEnC,UAAM,cAAc,OAAO,OAAO,CAAC,KAAK,UAAU;AAChD,aAAO,MAAO,MAAqB;AAAA,IACrC,GAAG,CAAC;AAEJ,UAAM,SAAS,IAAI,WAAW,WAAW;AACzC,QAAI,SAAS;AACb,eAAW,SAAS,QAAQ;AAC1B,aAAO,IAAI,OAAqB,MAAM;AACtC,gBAAW,MAAqB;AAAA,IAClC;AAEA,WAAO,EAAE,SAAS,QAAQ,SAAS;AAAA,EACrC,OAAO;AAEL,WAAO;AAAA,MACL,SAAS,OAAO,KAAK,EAAE;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
package/dist/chunk-D3U63BZP.js
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HttpClient
|
|
3
|
-
} from "./chunk-32UDXUPC.js";
|
|
4
|
-
import {
|
|
5
|
-
isRetryableError,
|
|
6
|
-
parseErrorResponse
|
|
7
|
-
} from "./chunk-FXYPFGOZ.js";
|
|
8
|
-
|
|
9
|
-
// src/interpreter-client.ts
|
|
10
|
-
var InterpreterClient = class extends HttpClient {
|
|
11
|
-
maxRetries = 3;
|
|
12
|
-
retryDelayMs = 1e3;
|
|
13
|
-
async createCodeContext(options = {}) {
|
|
14
|
-
return this.executeWithRetry(async () => {
|
|
15
|
-
const response = await this.doFetch("/api/contexts", {
|
|
16
|
-
method: "POST",
|
|
17
|
-
headers: { "Content-Type": "application/json" },
|
|
18
|
-
body: JSON.stringify({
|
|
19
|
-
language: options.language || "python",
|
|
20
|
-
cwd: options.cwd || "/workspace",
|
|
21
|
-
env_vars: options.envVars
|
|
22
|
-
})
|
|
23
|
-
});
|
|
24
|
-
if (!response.ok) {
|
|
25
|
-
throw await parseErrorResponse(response);
|
|
26
|
-
}
|
|
27
|
-
const data = await response.json();
|
|
28
|
-
return {
|
|
29
|
-
id: data.id,
|
|
30
|
-
language: data.language,
|
|
31
|
-
cwd: data.cwd,
|
|
32
|
-
createdAt: new Date(data.createdAt),
|
|
33
|
-
lastUsed: new Date(data.lastUsed)
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
async runCodeStream(contextId, code, language, callbacks) {
|
|
38
|
-
return this.executeWithRetry(async () => {
|
|
39
|
-
const response = await this.doFetch("/api/execute/code", {
|
|
40
|
-
method: "POST",
|
|
41
|
-
headers: {
|
|
42
|
-
"Content-Type": "application/json",
|
|
43
|
-
Accept: "text/event-stream"
|
|
44
|
-
},
|
|
45
|
-
body: JSON.stringify({
|
|
46
|
-
context_id: contextId,
|
|
47
|
-
code,
|
|
48
|
-
language
|
|
49
|
-
})
|
|
50
|
-
});
|
|
51
|
-
if (!response.ok) {
|
|
52
|
-
throw await parseErrorResponse(response);
|
|
53
|
-
}
|
|
54
|
-
if (!response.body) {
|
|
55
|
-
throw new Error("No response body for streaming execution");
|
|
56
|
-
}
|
|
57
|
-
for await (const chunk of this.readLines(response.body)) {
|
|
58
|
-
await this.parseExecutionResult(chunk, callbacks);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
async *readLines(stream) {
|
|
63
|
-
const reader = stream.getReader();
|
|
64
|
-
let buffer = "";
|
|
65
|
-
try {
|
|
66
|
-
while (true) {
|
|
67
|
-
const { done, value } = await reader.read();
|
|
68
|
-
if (value) {
|
|
69
|
-
buffer += new TextDecoder().decode(value);
|
|
70
|
-
}
|
|
71
|
-
if (done) break;
|
|
72
|
-
let newlineIdx = buffer.indexOf("\n");
|
|
73
|
-
while (newlineIdx !== -1) {
|
|
74
|
-
yield buffer.slice(0, newlineIdx);
|
|
75
|
-
buffer = buffer.slice(newlineIdx + 1);
|
|
76
|
-
newlineIdx = buffer.indexOf("\n");
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
if (buffer.length > 0) {
|
|
80
|
-
yield buffer;
|
|
81
|
-
}
|
|
82
|
-
} finally {
|
|
83
|
-
reader.releaseLock();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
async parseExecutionResult(line, callbacks) {
|
|
87
|
-
if (!line.trim()) return;
|
|
88
|
-
try {
|
|
89
|
-
const data = JSON.parse(line);
|
|
90
|
-
switch (data.type) {
|
|
91
|
-
case "stdout":
|
|
92
|
-
if (callbacks.onStdout && data.text) {
|
|
93
|
-
await callbacks.onStdout({
|
|
94
|
-
text: data.text,
|
|
95
|
-
timestamp: data.timestamp || Date.now()
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
break;
|
|
99
|
-
case "stderr":
|
|
100
|
-
if (callbacks.onStderr && data.text) {
|
|
101
|
-
await callbacks.onStderr({
|
|
102
|
-
text: data.text,
|
|
103
|
-
timestamp: data.timestamp || Date.now()
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
break;
|
|
107
|
-
case "result":
|
|
108
|
-
if (callbacks.onResult) {
|
|
109
|
-
const result = {
|
|
110
|
-
text: data.text,
|
|
111
|
-
html: data.html,
|
|
112
|
-
png: data.png,
|
|
113
|
-
jpeg: data.jpeg,
|
|
114
|
-
svg: data.svg,
|
|
115
|
-
latex: data.latex,
|
|
116
|
-
markdown: data.markdown,
|
|
117
|
-
javascript: data.javascript,
|
|
118
|
-
json: data.json,
|
|
119
|
-
chart: data.chart,
|
|
120
|
-
data: data.data,
|
|
121
|
-
formats: () => {
|
|
122
|
-
const formats = [];
|
|
123
|
-
if (data.text) formats.push("text");
|
|
124
|
-
if (data.html) formats.push("html");
|
|
125
|
-
if (data.png) formats.push("png");
|
|
126
|
-
if (data.jpeg) formats.push("jpeg");
|
|
127
|
-
if (data.svg) formats.push("svg");
|
|
128
|
-
if (data.latex) formats.push("latex");
|
|
129
|
-
if (data.markdown) formats.push("markdown");
|
|
130
|
-
if (data.javascript) formats.push("javascript");
|
|
131
|
-
if (data.json) formats.push("json");
|
|
132
|
-
if (data.chart) formats.push("chart");
|
|
133
|
-
return formats;
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
await callbacks.onResult(result);
|
|
137
|
-
}
|
|
138
|
-
break;
|
|
139
|
-
case "error":
|
|
140
|
-
if (callbacks.onError) {
|
|
141
|
-
await callbacks.onError({
|
|
142
|
-
name: data.ename || "Error",
|
|
143
|
-
value: data.evalue || data.text || "Unknown error",
|
|
144
|
-
traceback: data.traceback || [],
|
|
145
|
-
lineNumber: data.lineNumber
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
break;
|
|
149
|
-
case "execution_complete":
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
} catch (error) {
|
|
153
|
-
console.error(
|
|
154
|
-
"[InterpreterClient] Error parsing execution result:",
|
|
155
|
-
error
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
async listCodeContexts() {
|
|
160
|
-
return this.executeWithRetry(async () => {
|
|
161
|
-
const response = await this.doFetch("/api/contexts", {
|
|
162
|
-
method: "GET",
|
|
163
|
-
headers: { "Content-Type": "application/json" }
|
|
164
|
-
});
|
|
165
|
-
if (!response.ok) {
|
|
166
|
-
throw await parseErrorResponse(response);
|
|
167
|
-
}
|
|
168
|
-
const data = await response.json();
|
|
169
|
-
return data.contexts.map((ctx) => ({
|
|
170
|
-
id: ctx.id,
|
|
171
|
-
language: ctx.language,
|
|
172
|
-
cwd: ctx.cwd,
|
|
173
|
-
createdAt: new Date(ctx.createdAt),
|
|
174
|
-
lastUsed: new Date(ctx.lastUsed)
|
|
175
|
-
}));
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
async deleteCodeContext(contextId) {
|
|
179
|
-
return this.executeWithRetry(async () => {
|
|
180
|
-
const response = await this.doFetch(`/api/contexts/${contextId}`, {
|
|
181
|
-
method: "DELETE",
|
|
182
|
-
headers: { "Content-Type": "application/json" }
|
|
183
|
-
});
|
|
184
|
-
if (!response.ok) {
|
|
185
|
-
throw await parseErrorResponse(response);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
// Override parent doFetch to be public for this class
|
|
190
|
-
async doFetch(path, options) {
|
|
191
|
-
return super.doFetch(path, options);
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Execute an operation with automatic retry for transient errors
|
|
195
|
-
*/
|
|
196
|
-
async executeWithRetry(operation) {
|
|
197
|
-
let lastError;
|
|
198
|
-
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
|
199
|
-
try {
|
|
200
|
-
return await operation();
|
|
201
|
-
} catch (error) {
|
|
202
|
-
lastError = error;
|
|
203
|
-
if (this.isRetryableError(error)) {
|
|
204
|
-
if (attempt < this.maxRetries - 1) {
|
|
205
|
-
const delay = this.retryDelayMs * 2 ** attempt + Math.random() * 1e3;
|
|
206
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
throw error;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
if (lastError?.message.includes("Code execution")) {
|
|
214
|
-
throw lastError;
|
|
215
|
-
}
|
|
216
|
-
throw new Error("Unable to execute code at this time");
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Check if an error is retryable
|
|
220
|
-
*/
|
|
221
|
-
isRetryableError(error) {
|
|
222
|
-
if (isRetryableError(error)) {
|
|
223
|
-
return true;
|
|
224
|
-
}
|
|
225
|
-
if (error instanceof Error) {
|
|
226
|
-
if (error.message.includes("Circuit breaker is open")) {
|
|
227
|
-
return true;
|
|
228
|
-
}
|
|
229
|
-
if ("status" in error && error.status === "circuit_open") {
|
|
230
|
-
return true;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
return false;
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
export {
|
|
238
|
-
InterpreterClient
|
|
239
|
-
};
|
|
240
|
-
//# sourceMappingURL=chunk-D3U63BZP.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interpreter-client.ts"],"sourcesContent":["import { HttpClient } from \"./client.js\";\nimport { isRetryableError, parseErrorResponse } from \"./errors.js\";\nimport type {\n CodeContext,\n CreateContextOptions,\n ExecutionError,\n OutputMessage,\n Result,\n} from \"./interpreter-types.js\";\n\n// API Response types\ninterface ContextResponse {\n id: string;\n language: string;\n cwd: string;\n createdAt: string; // ISO date string from JSON\n lastUsed: string; // ISO date string from JSON\n}\n\ninterface ContextListResponse {\n contexts: ContextResponse[];\n}\n\n// Streaming execution data from the server\ninterface StreamingExecutionData {\n type: \"result\" | \"stdout\" | \"stderr\" | \"error\" | \"execution_complete\";\n text?: string;\n html?: string;\n png?: string; // base64\n jpeg?: string; // base64\n svg?: string;\n latex?: string;\n markdown?: string;\n javascript?: string;\n json?: unknown;\n chart?: {\n type:\n | \"line\"\n | \"bar\"\n | \"scatter\"\n | \"pie\"\n | \"histogram\"\n | \"heatmap\"\n | \"unknown\";\n data: unknown;\n options?: unknown;\n };\n data?: unknown;\n metadata?: Record<string, unknown>;\n execution_count?: number;\n ename?: string;\n evalue?: string;\n traceback?: string[];\n lineNumber?: number;\n timestamp?: number;\n}\n\nexport interface ExecutionCallbacks {\n onStdout?: (output: OutputMessage) => void | Promise<void>;\n onStderr?: (output: OutputMessage) => void | Promise<void>;\n onResult?: (result: Result) => void | Promise<void>;\n onError?: (error: ExecutionError) => void | Promise<void>;\n}\n\nexport class InterpreterClient extends HttpClient {\n private readonly maxRetries = 3;\n private readonly retryDelayMs = 1000;\n\n async createCodeContext(\n options: CreateContextOptions = {}\n ): Promise<CodeContext> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(\"/api/contexts\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n language: options.language || \"python\",\n cwd: options.cwd || \"/workspace\",\n env_vars: options.envVars,\n }),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n const data = (await response.json()) as ContextResponse;\n return {\n id: data.id,\n language: data.language,\n cwd: data.cwd,\n createdAt: new Date(data.createdAt),\n lastUsed: new Date(data.lastUsed),\n };\n });\n }\n\n async runCodeStream(\n contextId: string | undefined,\n code: string,\n language: string | undefined,\n callbacks: ExecutionCallbacks\n ): Promise<void> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(\"/api/execute/code\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify({\n context_id: contextId,\n code,\n language,\n }),\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming execution\");\n }\n\n // Process streaming response\n for await (const chunk of this.readLines(response.body)) {\n await this.parseExecutionResult(chunk, callbacks);\n }\n });\n }\n\n private async *readLines(\n stream: ReadableStream<Uint8Array>\n ): AsyncGenerator<string> {\n const reader = stream.getReader();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (value) {\n buffer += new TextDecoder().decode(value);\n }\n if (done) break;\n\n let newlineIdx = buffer.indexOf(\"\\n\");\n while (newlineIdx !== -1) {\n yield buffer.slice(0, newlineIdx);\n buffer = buffer.slice(newlineIdx + 1);\n newlineIdx = buffer.indexOf(\"\\n\");\n }\n }\n\n // Yield any remaining data\n if (buffer.length > 0) {\n yield buffer;\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n private async parseExecutionResult(\n line: string,\n callbacks: ExecutionCallbacks\n ) {\n if (!line.trim()) return;\n\n try {\n const data = JSON.parse(line) as StreamingExecutionData;\n\n switch (data.type) {\n case \"stdout\":\n if (callbacks.onStdout && data.text) {\n await callbacks.onStdout({\n text: data.text,\n timestamp: data.timestamp || Date.now(),\n });\n }\n break;\n\n case \"stderr\":\n if (callbacks.onStderr && data.text) {\n await callbacks.onStderr({\n text: data.text,\n timestamp: data.timestamp || Date.now(),\n });\n }\n break;\n\n case \"result\":\n if (callbacks.onResult) {\n // Convert raw result to Result interface\n const result: Result = {\n text: data.text,\n html: data.html,\n png: data.png,\n jpeg: data.jpeg,\n svg: data.svg,\n latex: data.latex,\n markdown: data.markdown,\n javascript: data.javascript,\n json: data.json,\n chart: data.chart,\n data: data.data,\n formats: () => {\n const formats: string[] = [];\n if (data.text) formats.push(\"text\");\n if (data.html) formats.push(\"html\");\n if (data.png) formats.push(\"png\");\n if (data.jpeg) formats.push(\"jpeg\");\n if (data.svg) formats.push(\"svg\");\n if (data.latex) formats.push(\"latex\");\n if (data.markdown) formats.push(\"markdown\");\n if (data.javascript) formats.push(\"javascript\");\n if (data.json) formats.push(\"json\");\n if (data.chart) formats.push(\"chart\");\n return formats;\n },\n };\n await callbacks.onResult(result);\n }\n break;\n\n case \"error\":\n if (callbacks.onError) {\n await callbacks.onError({\n name: data.ename || \"Error\",\n value: data.evalue || data.text || \"Unknown error\",\n traceback: data.traceback || [],\n lineNumber: data.lineNumber,\n });\n }\n break;\n\n case \"execution_complete\":\n // Execution completed successfully\n break;\n }\n } catch (error) {\n console.error(\n \"[InterpreterClient] Error parsing execution result:\",\n error\n );\n }\n }\n\n async listCodeContexts(): Promise<CodeContext[]> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(\"/api/contexts\", {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n const data = (await response.json()) as ContextListResponse;\n return data.contexts.map((ctx) => ({\n id: ctx.id,\n language: ctx.language,\n cwd: ctx.cwd,\n createdAt: new Date(ctx.createdAt),\n lastUsed: new Date(ctx.lastUsed),\n }));\n });\n }\n\n async deleteCodeContext(contextId: string): Promise<void> {\n return this.executeWithRetry(async () => {\n const response = await this.doFetch(`/api/contexts/${contextId}`, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n });\n }\n\n // Override parent doFetch to be public for this class\n public async doFetch(path: string, options?: RequestInit): Promise<Response> {\n return super.doFetch(path, options);\n }\n\n /**\n * Execute an operation with automatic retry for transient errors\n */\n private async executeWithRetry<T>(operation: () => Promise<T>): Promise<T> {\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < this.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error as Error;\n\n // Check if it's a retryable error (circuit breaker or interpreter not ready)\n if (this.isRetryableError(error)) {\n // Don't retry on the last attempt\n if (attempt < this.maxRetries - 1) {\n // Exponential backoff with jitter\n const delay =\n this.retryDelayMs * 2 ** attempt + Math.random() * 1000;\n await new Promise((resolve) => setTimeout(resolve, delay));\n continue;\n }\n }\n\n // Non-retryable error or last attempt - throw immediately\n throw error;\n }\n }\n\n // All retries exhausted - throw a clean error without implementation details\n if (lastError?.message.includes(\"Code execution\")) {\n // If the error already has a clean message about code execution, use it\n throw lastError;\n }\n\n // Otherwise, throw a generic but user-friendly error\n throw new Error(\"Unable to execute code at this time\");\n }\n\n /**\n * Check if an error is retryable\n */\n private isRetryableError(error: unknown): boolean {\n // Use the SDK's built-in retryable check\n if (isRetryableError(error)) {\n return true;\n }\n\n // Also check for circuit breaker specific errors\n if (error instanceof Error) {\n // Circuit breaker errors (from the container's response)\n if (error.message.includes(\"Circuit breaker is open\")) {\n return true;\n }\n\n // Check if error has a status property\n if (\"status\" in error && error.status === \"circuit_open\") {\n return true;\n }\n }\n\n return false;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/chunk-FXYPFGOZ.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
// src/errors.ts
|
|
2
|
-
var SandboxError = class extends Error {
|
|
3
|
-
constructor(message) {
|
|
4
|
-
super(message);
|
|
5
|
-
this.name = this.constructor.name;
|
|
6
|
-
if (Error.captureStackTrace) {
|
|
7
|
-
Error.captureStackTrace(this, this.constructor);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
var InterpreterNotReadyError = class extends SandboxError {
|
|
12
|
-
code = "INTERPRETER_NOT_READY";
|
|
13
|
-
retryAfter;
|
|
14
|
-
progress;
|
|
15
|
-
constructor(message, options) {
|
|
16
|
-
super(
|
|
17
|
-
message || "Interpreter is still initializing. Please retry in a few seconds."
|
|
18
|
-
);
|
|
19
|
-
this.retryAfter = options?.retryAfter || 5;
|
|
20
|
-
this.progress = options?.progress;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
var ContextNotFoundError = class extends SandboxError {
|
|
24
|
-
code = "CONTEXT_NOT_FOUND";
|
|
25
|
-
contextId;
|
|
26
|
-
constructor(contextId) {
|
|
27
|
-
super(`Context ${contextId} not found`);
|
|
28
|
-
this.contextId = contextId;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
var CodeExecutionError = class extends SandboxError {
|
|
32
|
-
code = "CODE_EXECUTION_ERROR";
|
|
33
|
-
executionError;
|
|
34
|
-
constructor(message, executionError) {
|
|
35
|
-
super(message);
|
|
36
|
-
this.executionError = executionError;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
var ContainerNotReadyError = class extends SandboxError {
|
|
40
|
-
code = "CONTAINER_NOT_READY";
|
|
41
|
-
constructor(message) {
|
|
42
|
-
super(
|
|
43
|
-
message || "Container is not ready. Please wait for initialization to complete."
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
var SandboxNetworkError = class extends SandboxError {
|
|
48
|
-
code = "NETWORK_ERROR";
|
|
49
|
-
statusCode;
|
|
50
|
-
statusText;
|
|
51
|
-
constructor(message, statusCode, statusText) {
|
|
52
|
-
super(message);
|
|
53
|
-
this.statusCode = statusCode;
|
|
54
|
-
this.statusText = statusText;
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
var ServiceUnavailableError = class extends SandboxError {
|
|
58
|
-
code = "SERVICE_UNAVAILABLE";
|
|
59
|
-
retryAfter;
|
|
60
|
-
constructor(message, retryAfter) {
|
|
61
|
-
super(message || "Service temporarily unavailable");
|
|
62
|
-
this.retryAfter = retryAfter;
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
function isInterpreterNotReadyError(error) {
|
|
66
|
-
return error instanceof InterpreterNotReadyError;
|
|
67
|
-
}
|
|
68
|
-
function isSandboxError(error) {
|
|
69
|
-
return error instanceof SandboxError;
|
|
70
|
-
}
|
|
71
|
-
function isRetryableError(error) {
|
|
72
|
-
if (error instanceof InterpreterNotReadyError || error instanceof ContainerNotReadyError || error instanceof ServiceUnavailableError) {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
if (error instanceof SandboxNetworkError) {
|
|
76
|
-
return error.statusCode ? [502, 503, 504].includes(error.statusCode) : false;
|
|
77
|
-
}
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
async function parseErrorResponse(response) {
|
|
81
|
-
let data;
|
|
82
|
-
try {
|
|
83
|
-
data = await response.json();
|
|
84
|
-
} catch {
|
|
85
|
-
return new SandboxNetworkError(
|
|
86
|
-
`Request failed with status ${response.status}`,
|
|
87
|
-
response.status,
|
|
88
|
-
response.statusText
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
if (response.status === 503) {
|
|
92
|
-
if (data.status === "circuit_open") {
|
|
93
|
-
return new ServiceUnavailableError(
|
|
94
|
-
"Service temporarily unavailable",
|
|
95
|
-
parseInt(response.headers.get("Retry-After") || "30")
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
if (data.status === "initializing") {
|
|
99
|
-
return new InterpreterNotReadyError(data.error, {
|
|
100
|
-
retryAfter: parseInt(response.headers.get("Retry-After") || "5"),
|
|
101
|
-
progress: data.progress
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (response.status === 404 && data.error?.includes("Context") && data.error?.includes("not found")) {
|
|
106
|
-
const contextId = data.error.match(/Context (\S+) not found/)?.[1] || "unknown";
|
|
107
|
-
return new ContextNotFoundError(contextId);
|
|
108
|
-
}
|
|
109
|
-
return new SandboxNetworkError(
|
|
110
|
-
data.error || `Request failed with status ${response.status}`,
|
|
111
|
-
response.status,
|
|
112
|
-
response.statusText
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export {
|
|
117
|
-
SandboxError,
|
|
118
|
-
InterpreterNotReadyError,
|
|
119
|
-
ContextNotFoundError,
|
|
120
|
-
CodeExecutionError,
|
|
121
|
-
ContainerNotReadyError,
|
|
122
|
-
SandboxNetworkError,
|
|
123
|
-
ServiceUnavailableError,
|
|
124
|
-
isInterpreterNotReadyError,
|
|
125
|
-
isSandboxError,
|
|
126
|
-
isRetryableError,
|
|
127
|
-
parseErrorResponse
|
|
128
|
-
};
|
|
129
|
-
//# sourceMappingURL=chunk-FXYPFGOZ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Standard error response from the sandbox API\n */\nexport interface SandboxErrorResponse {\n error?: string;\n status?: string;\n progress?: number;\n}\n\n/**\n * Base error class for all Sandbox-related errors\n */\nexport class SandboxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = this.constructor.name;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n}\n\n/**\n * Error thrown when interpreter functionality is requested but the service is still initializing.\n *\n * Note: With the current implementation, requests wait for interpreter to be ready.\n * This error is only thrown when:\n * 1. The request times out waiting for interpreter (default: 30 seconds)\n * 2. interpreter initialization actually fails\n *\n * Most requests will succeed after a delay, not throw this error.\n */\nexport class InterpreterNotReadyError extends SandboxError {\n public readonly code = \"INTERPRETER_NOT_READY\";\n public readonly retryAfter: number;\n public readonly progress?: number;\n\n constructor(\n message?: string,\n options?: { retryAfter?: number; progress?: number }\n ) {\n super(\n message ||\n \"Interpreter is still initializing. Please retry in a few seconds.\"\n );\n this.retryAfter = options?.retryAfter || 5;\n this.progress = options?.progress;\n }\n}\n\n/**\n * Error thrown when a context is not found\n */\nexport class ContextNotFoundError extends SandboxError {\n public readonly code = \"CONTEXT_NOT_FOUND\";\n public readonly contextId: string;\n\n constructor(contextId: string) {\n super(`Context ${contextId} not found`);\n this.contextId = contextId;\n }\n}\n\n/**\n * Error thrown when code execution fails\n */\nexport class CodeExecutionError extends SandboxError {\n public readonly code = \"CODE_EXECUTION_ERROR\";\n public readonly executionError?: {\n ename?: string;\n evalue?: string;\n traceback?: string[];\n };\n\n constructor(message: string, executionError?: any) {\n super(message);\n this.executionError = executionError;\n }\n}\n\n/**\n * Error thrown when the sandbox container is not ready\n */\nexport class ContainerNotReadyError extends SandboxError {\n public readonly code = \"CONTAINER_NOT_READY\";\n\n constructor(message?: string) {\n super(\n message ||\n \"Container is not ready. Please wait for initialization to complete.\"\n );\n }\n}\n\n/**\n * Error thrown when a network request to the sandbox fails\n */\nexport class SandboxNetworkError extends SandboxError {\n public readonly code = \"NETWORK_ERROR\";\n public readonly statusCode?: number;\n public readonly statusText?: string;\n\n constructor(message: string, statusCode?: number, statusText?: string) {\n super(message);\n this.statusCode = statusCode;\n this.statusText = statusText;\n }\n}\n\n/**\n * Error thrown when service is temporarily unavailable (e.g., circuit breaker open)\n */\nexport class ServiceUnavailableError extends SandboxError {\n public readonly code = \"SERVICE_UNAVAILABLE\";\n public readonly retryAfter?: number;\n\n constructor(message?: string, retryAfter?: number) {\n // Simple, user-friendly message without implementation details\n super(message || \"Service temporarily unavailable\");\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Type guard to check if an error is a InterpreterNotReadyError\n */\nexport function isInterpreterNotReadyError(\n error: unknown\n): error is InterpreterNotReadyError {\n return error instanceof InterpreterNotReadyError;\n}\n\n/**\n * Type guard to check if an error is any SandboxError\n */\nexport function isSandboxError(error: unknown): error is SandboxError {\n return error instanceof SandboxError;\n}\n\n/**\n * Helper to determine if an error is retryable\n */\nexport function isRetryableError(error: unknown): boolean {\n if (\n error instanceof InterpreterNotReadyError ||\n error instanceof ContainerNotReadyError ||\n error instanceof ServiceUnavailableError\n ) {\n return true;\n }\n\n if (error instanceof SandboxNetworkError) {\n // Retry on 502, 503, 504 (gateway/service unavailable errors)\n return error.statusCode\n ? [502, 503, 504].includes(error.statusCode)\n : false;\n }\n\n return false;\n}\n\n/**\n * Parse error response from the sandbox API and return appropriate error instance\n */\nexport async function parseErrorResponse(\n response: Response\n): Promise<SandboxError> {\n let data: SandboxErrorResponse;\n\n try {\n data = (await response.json()) as SandboxErrorResponse;\n } catch {\n // If JSON parsing fails, return a generic network error\n return new SandboxNetworkError(\n `Request failed with status ${response.status}`,\n response.status,\n response.statusText\n );\n }\n\n // Check for specific error types based on response\n if (response.status === 503) {\n // Circuit breaker error\n if (data.status === \"circuit_open\") {\n return new ServiceUnavailableError(\n \"Service temporarily unavailable\",\n parseInt(response.headers.get(\"Retry-After\") || \"30\")\n );\n }\n\n // Interpreter initialization error\n if (data.status === \"initializing\") {\n return new InterpreterNotReadyError(data.error, {\n retryAfter: parseInt(response.headers.get(\"Retry-After\") || \"5\"),\n progress: data.progress,\n });\n }\n }\n\n // Check for context not found\n if (\n response.status === 404 &&\n data.error?.includes(\"Context\") &&\n data.error?.includes(\"not found\")\n ) {\n const contextId =\n data.error.match(/Context (\\S+) not found/)?.[1] || \"unknown\";\n return new ContextNotFoundError(contextId);\n }\n\n // Default network error\n return new SandboxNetworkError(\n data.error || `Request failed with status ${response.status}`,\n response.status,\n response.statusText\n );\n}\n"],"mappings":"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","names":[]}
|