@cloudflare/sandbox 0.2.0 → 0.2.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/CHANGELOG.md +12 -0
- package/Dockerfile +31 -7
- package/README.md +226 -2
- package/container_src/bun.lock +122 -0
- package/container_src/circuit-breaker.ts +121 -0
- package/container_src/index.ts +305 -10
- package/container_src/jupyter-server.ts +579 -0
- package/container_src/jupyter-service.ts +448 -0
- package/container_src/mime-processor.ts +255 -0
- package/container_src/package.json +9 -0
- package/container_src/startup.sh +83 -0
- package/dist/{chunk-YVZ3K26G.js → chunk-CUHYLCMT.js} +9 -21
- package/dist/chunk-CUHYLCMT.js.map +1 -0
- package/dist/chunk-EGC5IYXA.js +108 -0
- package/dist/chunk-EGC5IYXA.js.map +1 -0
- package/dist/chunk-FKBV7CZS.js +113 -0
- package/dist/chunk-FKBV7CZS.js.map +1 -0
- package/dist/chunk-LALY4SFU.js +129 -0
- package/dist/chunk-LALY4SFU.js.map +1 -0
- package/dist/{chunk-6THNBO4S.js → chunk-S5FFBU4Y.js} +1 -1
- package/dist/{chunk-6THNBO4S.js.map → chunk-S5FFBU4Y.js.map} +1 -1
- package/dist/chunk-VTKZL632.js +237 -0
- package/dist/chunk-VTKZL632.js.map +1 -0
- package/dist/{chunk-ZJN2PQOS.js → chunk-ZMPO44U4.js} +171 -72
- package/dist/chunk-ZMPO44U4.js.map +1 -0
- package/dist/{client-BXYlxy-j.d.ts → client-bzEV222a.d.ts} +52 -4
- package/dist/client.d.ts +2 -1
- package/dist/client.js +1 -1
- package/dist/errors.d.ts +95 -0
- package/dist/errors.js +27 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +33 -3
- package/dist/interpreter-types.d.ts +259 -0
- package/dist/interpreter-types.js +9 -0
- package/dist/interpreter-types.js.map +1 -0
- package/dist/interpreter.d.ts +33 -0
- package/dist/interpreter.js +8 -0
- package/dist/interpreter.js.map +1 -0
- package/dist/jupyter-client.d.ts +4 -0
- package/dist/jupyter-client.js +9 -0
- package/dist/jupyter-client.js.map +1 -0
- package/dist/request-handler.d.ts +2 -1
- package/dist/request-handler.js +8 -3
- package/dist/sandbox.d.ts +2 -1
- package/dist/sandbox.js +8 -3
- package/dist/types.d.ts +8 -0
- package/dist/types.js +1 -1
- package/package.json +1 -1
- package/src/client.ts +37 -54
- package/src/errors.ts +218 -0
- package/src/index.ts +44 -10
- package/src/interpreter-types.ts +383 -0
- package/src/interpreter.ts +150 -0
- package/src/jupyter-client.ts +349 -0
- package/src/sandbox.ts +281 -153
- package/src/types.ts +15 -0
- package/dist/chunk-YVZ3K26G.js.map +0 -1
- package/dist/chunk-ZJN2PQOS.js.map +0 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Function to check if Jupyter is ready
|
|
4
|
+
check_jupyter_ready() {
|
|
5
|
+
curl -s http://localhost:8888/api > /dev/null 2>&1
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
# Function to notify Bun server that Jupyter is ready
|
|
9
|
+
notify_jupyter_ready() {
|
|
10
|
+
# Create a marker file that the Bun server can check
|
|
11
|
+
touch /tmp/jupyter-ready
|
|
12
|
+
echo "[Startup] Jupyter is ready, notified Bun server"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
# Start Jupyter notebook server in background
|
|
16
|
+
echo "[Startup] Starting Jupyter server..."
|
|
17
|
+
jupyter notebook \
|
|
18
|
+
--ip=0.0.0.0 \
|
|
19
|
+
--port=8888 \
|
|
20
|
+
--no-browser \
|
|
21
|
+
--allow-root \
|
|
22
|
+
--NotebookApp.token='' \
|
|
23
|
+
--NotebookApp.password='' \
|
|
24
|
+
--NotebookApp.allow_origin='*' \
|
|
25
|
+
--NotebookApp.disable_check_xsrf=True \
|
|
26
|
+
--NotebookApp.allow_remote_access=True \
|
|
27
|
+
--NotebookApp.allow_credentials=True \
|
|
28
|
+
> /tmp/jupyter.log 2>&1 &
|
|
29
|
+
|
|
30
|
+
JUPYTER_PID=$!
|
|
31
|
+
|
|
32
|
+
# Start Bun server immediately (parallel startup)
|
|
33
|
+
echo "[Startup] Starting Bun server..."
|
|
34
|
+
bun index.ts &
|
|
35
|
+
BUN_PID=$!
|
|
36
|
+
|
|
37
|
+
# Monitor Jupyter readiness in background
|
|
38
|
+
(
|
|
39
|
+
echo "[Startup] Monitoring Jupyter readiness in background..."
|
|
40
|
+
MAX_ATTEMPTS=30
|
|
41
|
+
ATTEMPT=0
|
|
42
|
+
DELAY=0.5
|
|
43
|
+
MAX_DELAY=5
|
|
44
|
+
|
|
45
|
+
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
|
|
46
|
+
if check_jupyter_ready; then
|
|
47
|
+
notify_jupyter_ready
|
|
48
|
+
echo "[Startup] Jupyter server is ready after $ATTEMPT attempts"
|
|
49
|
+
break
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Check if Jupyter process is still running
|
|
53
|
+
if ! kill -0 $JUPYTER_PID 2>/dev/null; then
|
|
54
|
+
echo "[Startup] WARNING: Jupyter process died. Check /tmp/jupyter.log for details"
|
|
55
|
+
cat /tmp/jupyter.log
|
|
56
|
+
# Don't exit - let Bun server continue running in degraded mode
|
|
57
|
+
break
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
ATTEMPT=$((ATTEMPT + 1))
|
|
61
|
+
echo "[Startup] Jupyter not ready yet (attempt $ATTEMPT/$MAX_ATTEMPTS, delay ${DELAY}s)"
|
|
62
|
+
|
|
63
|
+
# Sleep with exponential backoff
|
|
64
|
+
sleep $DELAY
|
|
65
|
+
|
|
66
|
+
# Increase delay exponentially with jitter, cap at MAX_DELAY
|
|
67
|
+
DELAY=$(awk "BEGIN {printf \"%.2f\", $DELAY * 1.5 + (rand() * 0.5)}")
|
|
68
|
+
# Use awk for comparison since bc might not be available
|
|
69
|
+
if [ $(awk "BEGIN {print ($DELAY > $MAX_DELAY)}") -eq 1 ]; then
|
|
70
|
+
DELAY=$MAX_DELAY
|
|
71
|
+
fi
|
|
72
|
+
done
|
|
73
|
+
|
|
74
|
+
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
|
|
75
|
+
echo "[Startup] WARNING: Jupyter failed to become ready within attempts"
|
|
76
|
+
echo "[Startup] Jupyter logs:"
|
|
77
|
+
cat /tmp/jupyter.log
|
|
78
|
+
# Don't exit - let Bun server continue in degraded mode
|
|
79
|
+
fi
|
|
80
|
+
) &
|
|
81
|
+
|
|
82
|
+
# Wait for Bun server (main process)
|
|
83
|
+
wait $BUN_PID
|
|
@@ -91,7 +91,7 @@ var HttpClient = class {
|
|
|
91
91
|
}),
|
|
92
92
|
headers: {
|
|
93
93
|
"Content-Type": "application/json",
|
|
94
|
-
|
|
94
|
+
Accept: "text/event-stream"
|
|
95
95
|
},
|
|
96
96
|
method: "POST"
|
|
97
97
|
});
|
|
@@ -104,9 +104,7 @@ var HttpClient = class {
|
|
|
104
104
|
if (!response.body) {
|
|
105
105
|
throw new Error("No response body for streaming request");
|
|
106
106
|
}
|
|
107
|
-
console.log(
|
|
108
|
-
`[HTTP Client] Started command stream: ${command}`
|
|
109
|
-
);
|
|
107
|
+
console.log(`[HTTP Client] Started command stream: ${command}`);
|
|
110
108
|
return response.body;
|
|
111
109
|
} catch (error) {
|
|
112
110
|
console.error("[HTTP Client] Error in command stream:", error);
|
|
@@ -395,9 +393,7 @@ var HttpClient = class {
|
|
|
395
393
|
);
|
|
396
394
|
}
|
|
397
395
|
const data = await response.json();
|
|
398
|
-
console.log(
|
|
399
|
-
`[HTTP Client] Got ${data.count} exposed ports`
|
|
400
|
-
);
|
|
396
|
+
console.log(`[HTTP Client] Got ${data.count} exposed ports`);
|
|
401
397
|
return data;
|
|
402
398
|
} catch (error) {
|
|
403
399
|
console.error("[HTTP Client] Error getting exposed ports:", error);
|
|
@@ -501,9 +497,7 @@ var HttpClient = class {
|
|
|
501
497
|
);
|
|
502
498
|
}
|
|
503
499
|
const data = await response.json();
|
|
504
|
-
console.log(
|
|
505
|
-
`[HTTP Client] Listed ${data.processes.length} processes`
|
|
506
|
-
);
|
|
500
|
+
console.log(`[HTTP Client] Listed ${data.processes.length} processes`);
|
|
507
501
|
return data;
|
|
508
502
|
} catch (error) {
|
|
509
503
|
console.error("[HTTP Client] Error listing processes:", error);
|
|
@@ -549,9 +543,7 @@ var HttpClient = class {
|
|
|
549
543
|
);
|
|
550
544
|
}
|
|
551
545
|
const data = await response.json();
|
|
552
|
-
console.log(
|
|
553
|
-
`[HTTP Client] Killed process ${processId}`
|
|
554
|
-
);
|
|
546
|
+
console.log(`[HTTP Client] Killed process ${processId}`);
|
|
555
547
|
return data;
|
|
556
548
|
} catch (error) {
|
|
557
549
|
console.error("[HTTP Client] Error killing process:", error);
|
|
@@ -573,9 +565,7 @@ var HttpClient = class {
|
|
|
573
565
|
);
|
|
574
566
|
}
|
|
575
567
|
const data = await response.json();
|
|
576
|
-
console.log(
|
|
577
|
-
`[HTTP Client] Killed ${data.killedCount} processes`
|
|
578
|
-
);
|
|
568
|
+
console.log(`[HTTP Client] Killed ${data.killedCount} processes`);
|
|
579
569
|
return data;
|
|
580
570
|
} catch (error) {
|
|
581
571
|
console.error("[HTTP Client] Error killing all processes:", error);
|
|
@@ -597,9 +587,7 @@ var HttpClient = class {
|
|
|
597
587
|
);
|
|
598
588
|
}
|
|
599
589
|
const data = await response.json();
|
|
600
|
-
console.log(
|
|
601
|
-
`[HTTP Client] Got logs for process ${processId}`
|
|
602
|
-
);
|
|
590
|
+
console.log(`[HTTP Client] Got logs for process ${processId}`);
|
|
603
591
|
return data;
|
|
604
592
|
} catch (error) {
|
|
605
593
|
console.error("[HTTP Client] Error getting process logs:", error);
|
|
@@ -610,7 +598,7 @@ var HttpClient = class {
|
|
|
610
598
|
try {
|
|
611
599
|
const response = await this.doFetch(`/api/process/${processId}/stream`, {
|
|
612
600
|
headers: {
|
|
613
|
-
|
|
601
|
+
Accept: "text/event-stream",
|
|
614
602
|
"Cache-Control": "no-cache"
|
|
615
603
|
},
|
|
616
604
|
method: "GET"
|
|
@@ -638,4 +626,4 @@ var HttpClient = class {
|
|
|
638
626
|
export {
|
|
639
627
|
HttpClient
|
|
640
628
|
};
|
|
641
|
-
//# sourceMappingURL=chunk-
|
|
629
|
+
//# sourceMappingURL=chunk-CUHYLCMT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 GetProcessLogsResponse,\n GetProcessResponse,\n ListProcessesResponse,\n StartProcessRequest,\n StartProcessResponse,\n} from \"./types\";\n\nexport interface ExecuteResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n command: string;\n timestamp: string;\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\nexport interface GitCheckoutResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n repoUrl: string;\n branch: string;\n targetDir: string;\n timestamp: string;\n}\n\ninterface MkdirRequest {\n path: string;\n recursive?: boolean;\n sessionId?: string;\n}\n\nexport interface MkdirResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n path: string;\n recursive: boolean;\n timestamp: string;\n}\n\ninterface WriteFileRequest {\n path: string;\n content: string;\n encoding?: string;\n sessionId?: string;\n}\n\nexport interface WriteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\ninterface ReadFileRequest {\n path: string;\n encoding?: string;\n sessionId?: string;\n}\n\nexport interface ReadFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n content: string;\n timestamp: string;\n}\n\ninterface DeleteFileRequest {\n path: string;\n sessionId?: string;\n}\n\nexport interface DeleteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\ninterface RenameFileRequest {\n oldPath: string;\n newPath: string;\n sessionId?: string;\n}\n\nexport interface RenameFileResponse {\n success: boolean;\n exitCode: number;\n oldPath: string;\n newPath: string;\n timestamp: string;\n}\n\ninterface MoveFileRequest {\n sourcePath: string;\n destinationPath: string;\n sessionId?: string;\n}\n\nexport interface MoveFileResponse {\n success: boolean;\n exitCode: number;\n sourcePath: string;\n destinationPath: string;\n timestamp: string;\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 private sessionId: string | null = null;\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 execute(\n command: string,\n options: Pick<BaseExecOptions, \"sessionId\" | \"cwd\" | \"env\">\n ): Promise<ExecuteResponse> {\n try {\n const targetSessionId = options.sessionId || this.sessionId;\n const executeRequest = {\n command,\n sessionId: targetSessionId,\n cwd: options.cwd,\n env: options.env,\n } satisfies ExecuteRequest;\n\n const response = await this.doFetch(`/api/execute`, {\n body: JSON.stringify(executeRequest),\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: ExecuteResponse = await response.json();\n console.log(\n `[HTTP Client] Command executed: ${command}, Success: ${data.success}`\n );\n\n // Call the callback if provided\n this.options.onCommandComplete?.(\n data.success,\n data.exitCode,\n data.stdout,\n data.stderr,\n data.command\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error executing command:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n command\n );\n throw error;\n }\n }\n\n async executeCommandStream(\n command: string,\n sessionId?: string\n ): Promise<ReadableStream<Uint8Array>> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/execute/stream`, {\n body: JSON.stringify({\n command,\n sessionId: targetSessionId,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\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 if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n console.log(`[HTTP Client] Started command stream: ${command}`);\n\n return response.body;\n } catch (error) {\n console.error(\"[HTTP Client] Error in command stream:\", error);\n throw error;\n }\n }\n\n async gitCheckout(\n repoUrl: string,\n branch: string = \"main\",\n targetDir?: string,\n sessionId?: string\n ): Promise<GitCheckoutResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/git/checkout`, {\n body: JSON.stringify({\n branch,\n repoUrl,\n sessionId: targetSessionId,\n targetDir,\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 targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/mkdir`, {\n body: JSON.stringify({\n path,\n recursive,\n sessionId: targetSessionId,\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}`\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 targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/write`, {\n body: JSON.stringify({\n content,\n encoding,\n path,\n sessionId: targetSessionId,\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}`\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 targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/read`, {\n body: JSON.stringify({\n encoding,\n path,\n sessionId: targetSessionId,\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}`\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 deleteFile(\n path: string,\n sessionId?: string\n ): Promise<DeleteFileResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/delete`, {\n body: JSON.stringify({\n path,\n sessionId: targetSessionId,\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}`\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 targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/rename`, {\n body: JSON.stringify({\n newPath,\n oldPath,\n sessionId: targetSessionId,\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}`\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 targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/move`, {\n body: JSON.stringify({\n destinationPath,\n sessionId: targetSessionId,\n sourcePath,\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}`\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 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 async getCommands(): Promise<string[]> {\n try {\n const response = await fetch(`${this.baseUrl}/api/commands`, {\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: CommandsResponse = await response.json();\n console.log(\n `[HTTP Client] Available commands: ${data.availableCommands.length}`\n );\n return data.availableCommands;\n } catch (error) {\n console.error(\"[HTTP Client] Error getting commands:\", error);\n throw error;\n }\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n setSessionId(sessionId: string): void {\n this.sessionId = sessionId;\n }\n\n clearSession(): void {\n this.sessionId = null;\n }\n\n // Process management methods\n async startProcess(\n command: string,\n options?: {\n processId?: string;\n sessionId?: 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 targetSessionId = options?.sessionId || this.sessionId;\n\n const response = await this.doFetch(\"/api/process/start\", {\n body: JSON.stringify({\n command,\n options: {\n ...options,\n sessionId: targetSessionId,\n },\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(): Promise<ListProcessesResponse> {\n try {\n const response = await this.doFetch(\"/api/process/list\", {\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(): Promise<{\n success: boolean;\n killedCount: number;\n message: string;\n }> {\n try {\n const response = await this.doFetch(\"/api/process/kill-all\", {\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 ): 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 });\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":[]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// src/interpreter-types.ts
|
|
2
|
+
var Execution = class {
|
|
3
|
+
constructor(code, context) {
|
|
4
|
+
this.code = code;
|
|
5
|
+
this.context = context;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* All results from the execution
|
|
9
|
+
*/
|
|
10
|
+
results = [];
|
|
11
|
+
/**
|
|
12
|
+
* Accumulated stdout and stderr
|
|
13
|
+
*/
|
|
14
|
+
logs = {
|
|
15
|
+
stdout: [],
|
|
16
|
+
stderr: []
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Execution error if any
|
|
20
|
+
*/
|
|
21
|
+
error;
|
|
22
|
+
/**
|
|
23
|
+
* Execution count (for Jupyter)
|
|
24
|
+
*/
|
|
25
|
+
executionCount;
|
|
26
|
+
/**
|
|
27
|
+
* Convert to a plain object for serialization
|
|
28
|
+
*/
|
|
29
|
+
toJSON() {
|
|
30
|
+
return {
|
|
31
|
+
code: this.code,
|
|
32
|
+
logs: this.logs,
|
|
33
|
+
error: this.error,
|
|
34
|
+
executionCount: this.executionCount,
|
|
35
|
+
results: this.results.map((result) => ({
|
|
36
|
+
text: result.text,
|
|
37
|
+
html: result.html,
|
|
38
|
+
png: result.png,
|
|
39
|
+
jpeg: result.jpeg,
|
|
40
|
+
svg: result.svg,
|
|
41
|
+
latex: result.latex,
|
|
42
|
+
markdown: result.markdown,
|
|
43
|
+
javascript: result.javascript,
|
|
44
|
+
json: result.json,
|
|
45
|
+
chart: result.chart,
|
|
46
|
+
data: result.data
|
|
47
|
+
}))
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var ResultImpl = class {
|
|
52
|
+
constructor(raw) {
|
|
53
|
+
this.raw = raw;
|
|
54
|
+
}
|
|
55
|
+
get text() {
|
|
56
|
+
return this.raw.text || this.raw.data?.["text/plain"];
|
|
57
|
+
}
|
|
58
|
+
get html() {
|
|
59
|
+
return this.raw.html || this.raw.data?.["text/html"];
|
|
60
|
+
}
|
|
61
|
+
get png() {
|
|
62
|
+
return this.raw.png || this.raw.data?.["image/png"];
|
|
63
|
+
}
|
|
64
|
+
get jpeg() {
|
|
65
|
+
return this.raw.jpeg || this.raw.data?.["image/jpeg"];
|
|
66
|
+
}
|
|
67
|
+
get svg() {
|
|
68
|
+
return this.raw.svg || this.raw.data?.["image/svg+xml"];
|
|
69
|
+
}
|
|
70
|
+
get latex() {
|
|
71
|
+
return this.raw.latex || this.raw.data?.["text/latex"];
|
|
72
|
+
}
|
|
73
|
+
get markdown() {
|
|
74
|
+
return this.raw.markdown || this.raw.data?.["text/markdown"];
|
|
75
|
+
}
|
|
76
|
+
get javascript() {
|
|
77
|
+
return this.raw.javascript || this.raw.data?.["application/javascript"];
|
|
78
|
+
}
|
|
79
|
+
get json() {
|
|
80
|
+
return this.raw.json || this.raw.data?.["application/json"];
|
|
81
|
+
}
|
|
82
|
+
get chart() {
|
|
83
|
+
return this.raw.chart;
|
|
84
|
+
}
|
|
85
|
+
get data() {
|
|
86
|
+
return this.raw.data;
|
|
87
|
+
}
|
|
88
|
+
formats() {
|
|
89
|
+
const formats = [];
|
|
90
|
+
if (this.text) formats.push("text");
|
|
91
|
+
if (this.html) formats.push("html");
|
|
92
|
+
if (this.png) formats.push("png");
|
|
93
|
+
if (this.jpeg) formats.push("jpeg");
|
|
94
|
+
if (this.svg) formats.push("svg");
|
|
95
|
+
if (this.latex) formats.push("latex");
|
|
96
|
+
if (this.markdown) formats.push("markdown");
|
|
97
|
+
if (this.javascript) formats.push("javascript");
|
|
98
|
+
if (this.json) formats.push("json");
|
|
99
|
+
if (this.chart) formats.push("chart");
|
|
100
|
+
return formats;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export {
|
|
105
|
+
Execution,
|
|
106
|
+
ResultImpl
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=chunk-EGC5IYXA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/interpreter-types.ts"],"sourcesContent":["// Context Management\nexport interface CreateContextOptions {\n /**\n * Programming language for the context\n * @default 'python'\n */\n language?: 'python' | 'javascript' | 'typescript';\n \n /**\n * Working directory for the context\n * @default '/workspace'\n */\n cwd?: string;\n \n /**\n * Environment variables for the context\n */\n envVars?: Record<string, string>;\n \n /**\n * Request timeout in milliseconds\n * @default 30000\n */\n timeout?: number;\n}\n\nexport interface CodeContext {\n /**\n * Unique identifier for the context\n */\n readonly id: string;\n \n /**\n * Programming language of the context\n */\n readonly language: string;\n \n /**\n * Current working directory\n */\n readonly cwd: string;\n \n /**\n * When the context was created\n */\n readonly createdAt: Date;\n \n /**\n * When the context was last used\n */\n readonly lastUsed: Date;\n}\n\n// Execution Options\nexport interface RunCodeOptions {\n /**\n * Context to run the code in. If not provided, uses default context for the language\n */\n context?: CodeContext;\n \n /**\n * Language to use if context is not provided\n * @default 'python'\n */\n language?: 'python' | 'javascript' | 'typescript';\n \n /**\n * Environment variables for this execution\n */\n envVars?: Record<string, string>;\n \n /**\n * Execution timeout in milliseconds\n * @default 60000\n */\n timeout?: number;\n \n /**\n * AbortSignal for cancelling execution\n */\n signal?: AbortSignal;\n \n /**\n * Callback for stdout output\n */\n onStdout?: (output: OutputMessage) => void | Promise<void>;\n \n /**\n * Callback for stderr output\n */\n onStderr?: (output: OutputMessage) => void | Promise<void>;\n \n /**\n * Callback for execution results (charts, tables, etc)\n */\n onResult?: (result: Result) => void | Promise<void>;\n \n /**\n * Callback for execution errors\n */\n onError?: (error: ExecutionError) => void | Promise<void>;\n}\n\n// Output Messages\nexport interface OutputMessage {\n /**\n * The output text\n */\n text: string;\n \n /**\n * Timestamp of the output\n */\n timestamp: number;\n}\n\n// Execution Results\nexport interface Result {\n /**\n * Plain text representation\n */\n text?: string;\n \n /**\n * HTML representation (tables, formatted output)\n */\n html?: string;\n \n /**\n * PNG image data (base64 encoded)\n */\n png?: string;\n \n /**\n * JPEG image data (base64 encoded)\n */\n jpeg?: string;\n \n /**\n * SVG image data\n */\n svg?: string;\n \n /**\n * LaTeX representation\n */\n latex?: string;\n \n /**\n * Markdown representation\n */\n markdown?: string;\n \n /**\n * JavaScript code to execute\n */\n javascript?: string;\n \n /**\n * JSON data\n */\n json?: any;\n \n /**\n * Chart data if the result is a visualization\n */\n chart?: ChartData;\n \n /**\n * Raw data object\n */\n data?: any;\n \n /**\n * Available output formats\n */\n formats(): string[];\n}\n\n// Chart Data\nexport interface ChartData {\n /**\n * Type of chart\n */\n type: 'line' | 'bar' | 'scatter' | 'pie' | 'histogram' | 'heatmap' | 'unknown';\n \n /**\n * Chart title\n */\n title?: string;\n \n /**\n * Chart data (format depends on library)\n */\n data: any;\n \n /**\n * Chart layout/configuration\n */\n layout?: any;\n \n /**\n * Additional configuration\n */\n config?: any;\n \n /**\n * Library that generated the chart\n */\n library?: 'matplotlib' | 'plotly' | 'altair' | 'seaborn' | 'unknown';\n \n /**\n * Base64 encoded image if available\n */\n image?: string;\n}\n\n// Execution Error\nexport interface ExecutionError {\n /**\n * Error name/type (e.g., 'NameError', 'SyntaxError')\n */\n name: string;\n \n /**\n * Error message\n */\n value: string;\n \n /**\n * Stack trace\n */\n traceback: string[];\n \n /**\n * Line number where error occurred\n */\n lineNumber?: number;\n}\n\n// Serializable execution result\nexport interface ExecutionResult {\n code: string;\n logs: {\n stdout: string[];\n stderr: string[];\n };\n error?: ExecutionError;\n executionCount?: number;\n results: Array<{\n text?: string;\n html?: string;\n png?: string;\n jpeg?: string;\n svg?: string;\n latex?: string;\n markdown?: string;\n javascript?: string;\n json?: any;\n chart?: ChartData;\n data?: any;\n }>;\n}\n\n// Execution Result Container\nexport class Execution {\n /**\n * All results from the execution\n */\n public results: Result[] = [];\n \n /**\n * Accumulated stdout and stderr\n */\n public logs = {\n stdout: [] as string[],\n stderr: [] as string[]\n };\n \n /**\n * Execution error if any\n */\n public error?: ExecutionError;\n \n /**\n * Execution count (for Jupyter)\n */\n public executionCount?: number;\n \n constructor(\n public readonly code: string,\n public readonly context: CodeContext\n ) {}\n \n /**\n * Convert to a plain object for serialization\n */\n toJSON(): ExecutionResult {\n return {\n code: this.code,\n logs: this.logs,\n error: this.error,\n executionCount: this.executionCount,\n results: this.results.map(result => ({\n text: result.text,\n html: result.html,\n png: result.png,\n jpeg: result.jpeg,\n svg: result.svg,\n latex: result.latex,\n markdown: result.markdown,\n javascript: result.javascript,\n json: result.json,\n chart: result.chart,\n data: result.data\n }))\n };\n }\n}\n\n// Implementation of Result\nexport class ResultImpl implements Result {\n constructor(private raw: any) {}\n \n get text(): string | undefined { \n return this.raw.text || this.raw.data?.['text/plain']; \n }\n \n get html(): string | undefined { \n return this.raw.html || this.raw.data?.['text/html']; \n }\n \n get png(): string | undefined { \n return this.raw.png || this.raw.data?.['image/png']; \n }\n \n get jpeg(): string | undefined { \n return this.raw.jpeg || this.raw.data?.['image/jpeg']; \n }\n \n get svg(): string | undefined { \n return this.raw.svg || this.raw.data?.['image/svg+xml']; \n }\n \n get latex(): string | undefined { \n return this.raw.latex || this.raw.data?.['text/latex']; \n }\n \n get markdown(): string | undefined { \n return this.raw.markdown || this.raw.data?.['text/markdown']; \n }\n \n get javascript(): string | undefined { \n return this.raw.javascript || this.raw.data?.['application/javascript']; \n }\n \n get json(): any { \n return this.raw.json || this.raw.data?.['application/json']; \n }\n \n get chart(): ChartData | undefined { \n return this.raw.chart; \n }\n \n get data(): any { \n return this.raw.data; \n }\n \n formats(): string[] {\n const formats: string[] = [];\n if (this.text) formats.push('text');\n if (this.html) formats.push('html');\n if (this.png) formats.push('png');\n if (this.jpeg) formats.push('jpeg');\n if (this.svg) formats.push('svg');\n if (this.latex) formats.push('latex');\n if (this.markdown) formats.push('markdown');\n if (this.javascript) formats.push('javascript');\n if (this.json) formats.push('json');\n if (this.chart) formats.push('chart');\n return formats;\n }\n}"],"mappings":";AAyQO,IAAM,YAAN,MAAgB;AAAA,EAwBrB,YACkB,MACA,SAChB;AAFgB;AACA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAvBI,UAAoB,CAAC;AAAA;AAAA;AAAA;AAAA,EAKrB,OAAO;AAAA,IACZ,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKO;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAUP,SAA0B;AACxB,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,gBAAgB,KAAK;AAAA,MACrB,SAAS,KAAK,QAAQ,IAAI,aAAW;AAAA,QACnC,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,KAAK,OAAO;AAAA,QACZ,MAAM,OAAO;AAAA,QACb,KAAK,OAAO;AAAA,QACZ,OAAO,OAAO;AAAA,QACd,UAAU,OAAO;AAAA,QACjB,YAAY,OAAO;AAAA,QACnB,MAAM,OAAO;AAAA,QACb,OAAO,OAAO;AAAA,QACd,MAAM,OAAO;AAAA,MACf,EAAE;AAAA,IACJ;AAAA,EACF;AACF;AAGO,IAAM,aAAN,MAAmC;AAAA,EACxC,YAAoB,KAAU;AAAV;AAAA,EAAW;AAAA,EAE/B,IAAI,OAA2B;AAC7B,WAAO,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,YAAY;AAAA,EACtD;AAAA,EAEA,IAAI,OAA2B;AAC7B,WAAO,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,WAAW;AAAA,EACrD;AAAA,EAEA,IAAI,MAA0B;AAC5B,WAAO,KAAK,IAAI,OAAO,KAAK,IAAI,OAAO,WAAW;AAAA,EACpD;AAAA,EAEA,IAAI,OAA2B;AAC7B,WAAO,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,YAAY;AAAA,EACtD;AAAA,EAEA,IAAI,MAA0B;AAC5B,WAAO,KAAK,IAAI,OAAO,KAAK,IAAI,OAAO,eAAe;AAAA,EACxD;AAAA,EAEA,IAAI,QAA4B;AAC9B,WAAO,KAAK,IAAI,SAAS,KAAK,IAAI,OAAO,YAAY;AAAA,EACvD;AAAA,EAEA,IAAI,WAA+B;AACjC,WAAO,KAAK,IAAI,YAAY,KAAK,IAAI,OAAO,eAAe;AAAA,EAC7D;AAAA,EAEA,IAAI,aAAiC;AACnC,WAAO,KAAK,IAAI,cAAc,KAAK,IAAI,OAAO,wBAAwB;AAAA,EACxE;AAAA,EAEA,IAAI,OAAY;AACd,WAAO,KAAK,IAAI,QAAQ,KAAK,IAAI,OAAO,kBAAkB;AAAA,EAC5D;AAAA,EAEA,IAAI,QAA+B;AACjC,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA,EAEA,IAAI,OAAY;AACd,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA,EAEA,UAAoB;AAClB,UAAM,UAAoB,CAAC;AAC3B,QAAI,KAAK,KAAM,SAAQ,KAAK,MAAM;AAClC,QAAI,KAAK,KAAM,SAAQ,KAAK,MAAM;AAClC,QAAI,KAAK,IAAK,SAAQ,KAAK,KAAK;AAChC,QAAI,KAAK,KAAM,SAAQ,KAAK,MAAM;AAClC,QAAI,KAAK,IAAK,SAAQ,KAAK,KAAK;AAChC,QAAI,KAAK,MAAO,SAAQ,KAAK,OAAO;AACpC,QAAI,KAAK,SAAU,SAAQ,KAAK,UAAU;AAC1C,QAAI,KAAK,WAAY,SAAQ,KAAK,YAAY;AAC9C,QAAI,KAAK,KAAM,SAAQ,KAAK,MAAM;AAClC,QAAI,KAAK,MAAO,SAAQ,KAAK,OAAO;AACpC,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Execution,
|
|
3
|
+
ResultImpl
|
|
4
|
+
} from "./chunk-EGC5IYXA.js";
|
|
5
|
+
|
|
6
|
+
// src/interpreter.ts
|
|
7
|
+
var CodeInterpreter = class {
|
|
8
|
+
jupyterClient;
|
|
9
|
+
contexts = /* @__PURE__ */ new Map();
|
|
10
|
+
constructor(sandbox) {
|
|
11
|
+
this.jupyterClient = sandbox.client;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create a new code execution context
|
|
15
|
+
*/
|
|
16
|
+
async createCodeContext(options = {}) {
|
|
17
|
+
const context = await this.jupyterClient.createCodeContext(options);
|
|
18
|
+
this.contexts.set(context.id, context);
|
|
19
|
+
return context;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Run code with optional context
|
|
23
|
+
*/
|
|
24
|
+
async runCode(code, options = {}) {
|
|
25
|
+
let context = options.context;
|
|
26
|
+
if (!context) {
|
|
27
|
+
const language = options.language || "python";
|
|
28
|
+
context = await this.getOrCreateDefaultContext(language);
|
|
29
|
+
}
|
|
30
|
+
const execution = new Execution(code, context);
|
|
31
|
+
await this.jupyterClient.runCodeStream(context.id, code, options.language, {
|
|
32
|
+
onStdout: (output) => {
|
|
33
|
+
execution.logs.stdout.push(output.text);
|
|
34
|
+
if (options.onStdout) return options.onStdout(output);
|
|
35
|
+
},
|
|
36
|
+
onStderr: (output) => {
|
|
37
|
+
execution.logs.stderr.push(output.text);
|
|
38
|
+
if (options.onStderr) return options.onStderr(output);
|
|
39
|
+
},
|
|
40
|
+
onResult: async (result) => {
|
|
41
|
+
execution.results.push(new ResultImpl(result));
|
|
42
|
+
if (options.onResult) return options.onResult(result);
|
|
43
|
+
},
|
|
44
|
+
onError: (error) => {
|
|
45
|
+
execution.error = error;
|
|
46
|
+
if (options.onError) return options.onError(error);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return execution;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Run code and return a streaming response
|
|
53
|
+
*/
|
|
54
|
+
async runCodeStream(code, options = {}) {
|
|
55
|
+
let context = options.context;
|
|
56
|
+
if (!context) {
|
|
57
|
+
const language = options.language || "python";
|
|
58
|
+
context = await this.getOrCreateDefaultContext(language);
|
|
59
|
+
}
|
|
60
|
+
const response = await this.jupyterClient.doFetch("/api/execute/code", {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": "application/json",
|
|
64
|
+
Accept: "text/event-stream"
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({
|
|
67
|
+
context_id: context.id,
|
|
68
|
+
code,
|
|
69
|
+
language: options.language
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
74
|
+
throw new Error(
|
|
75
|
+
errorData.error || `Failed to execute code: ${response.status}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
if (!response.body) {
|
|
79
|
+
throw new Error("No response body for streaming execution");
|
|
80
|
+
}
|
|
81
|
+
return response.body;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* List all code contexts
|
|
85
|
+
*/
|
|
86
|
+
async listCodeContexts() {
|
|
87
|
+
const contexts = await this.jupyterClient.listCodeContexts();
|
|
88
|
+
for (const context of contexts) {
|
|
89
|
+
this.contexts.set(context.id, context);
|
|
90
|
+
}
|
|
91
|
+
return contexts;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Delete a code context
|
|
95
|
+
*/
|
|
96
|
+
async deleteCodeContext(contextId) {
|
|
97
|
+
await this.jupyterClient.deleteCodeContext(contextId);
|
|
98
|
+
this.contexts.delete(contextId);
|
|
99
|
+
}
|
|
100
|
+
async getOrCreateDefaultContext(language) {
|
|
101
|
+
for (const context of this.contexts.values()) {
|
|
102
|
+
if (context.language === language) {
|
|
103
|
+
return context;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return this.createCodeContext({ language });
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export {
|
|
111
|
+
CodeInterpreter
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=chunk-FKBV7CZS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/interpreter.ts"],"sourcesContent":["import {\n type CodeContext,\n type CreateContextOptions,\n Execution,\n ResultImpl,\n type RunCodeOptions,\n} from \"./interpreter-types.js\";\nimport type { JupyterClient } from \"./jupyter-client.js\";\nimport type { Sandbox } from \"./sandbox.js\";\n\nexport class CodeInterpreter {\n private jupyterClient: JupyterClient;\n private contexts = new Map<string, CodeContext>();\n\n constructor(sandbox: Sandbox) {\n this.jupyterClient = sandbox.client as JupyterClient;\n }\n\n /**\n * Create a new code execution context\n */\n async createCodeContext(\n options: CreateContextOptions = {}\n ): Promise<CodeContext> {\n const context = await this.jupyterClient.createCodeContext(options);\n this.contexts.set(context.id, context);\n return context;\n }\n\n /**\n * Run code with optional context\n */\n async runCode(\n code: string,\n options: RunCodeOptions = {}\n ): Promise<Execution> {\n // Get or create context\n let context = options.context;\n if (!context) {\n // Try to find or create a default context for the language\n const language = options.language || \"python\";\n context = await this.getOrCreateDefaultContext(language);\n }\n\n // Create execution object to collect results\n const execution = new Execution(code, context);\n\n // Stream execution\n await this.jupyterClient.runCodeStream(context.id, code, options.language, {\n onStdout: (output) => {\n execution.logs.stdout.push(output.text);\n if (options.onStdout) return options.onStdout(output);\n },\n onStderr: (output) => {\n execution.logs.stderr.push(output.text);\n if (options.onStderr) return options.onStderr(output);\n },\n onResult: async (result) => {\n execution.results.push(new ResultImpl(result) as any);\n if (options.onResult) return options.onResult(result);\n },\n onError: (error) => {\n execution.error = error;\n if (options.onError) return options.onError(error);\n },\n });\n\n return execution;\n }\n\n /**\n * Run code and return a streaming response\n */\n async runCodeStream(\n code: string,\n options: RunCodeOptions = {}\n ): Promise<ReadableStream> {\n // Get or create context\n let context = options.context;\n if (!context) {\n const language = options.language || \"python\";\n context = await this.getOrCreateDefaultContext(language);\n }\n\n // Create streaming response\n const response = await this.jupyterClient.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: context.id,\n code,\n language: options.language,\n }),\n });\n\n if (!response.ok) {\n const errorData = (await response\n .json()\n .catch(() => ({ error: \"Unknown error\" }))) as { error?: string };\n throw new Error(\n errorData.error || `Failed to execute code: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming execution\");\n }\n\n return response.body;\n }\n\n /**\n * List all code contexts\n */\n async listCodeContexts(): Promise<CodeContext[]> {\n const contexts = await this.jupyterClient.listCodeContexts();\n\n // Update local cache\n for (const context of contexts) {\n this.contexts.set(context.id, context);\n }\n\n return contexts;\n }\n\n /**\n * Delete a code context\n */\n async deleteCodeContext(contextId: string): Promise<void> {\n await this.jupyterClient.deleteCodeContext(contextId);\n this.contexts.delete(contextId);\n }\n\n private async getOrCreateDefaultContext(\n language: \"python\" | \"javascript\" | \"typescript\"\n ): Promise<CodeContext> {\n // Check if we have a cached context for this language\n for (const context of this.contexts.values()) {\n if (context.language === language) {\n return context;\n }\n }\n\n // Create new default context\n return this.createCodeContext({ language });\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,129 @@
|
|
|
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 JupyterNotReadyError = class extends SandboxError {
|
|
12
|
+
code = "JUPYTER_NOT_READY";
|
|
13
|
+
retryAfter;
|
|
14
|
+
progress;
|
|
15
|
+
constructor(message, options) {
|
|
16
|
+
super(
|
|
17
|
+
message || "Jupyter 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 isJupyterNotReadyError(error) {
|
|
66
|
+
return error instanceof JupyterNotReadyError;
|
|
67
|
+
}
|
|
68
|
+
function isSandboxError(error) {
|
|
69
|
+
return error instanceof SandboxError;
|
|
70
|
+
}
|
|
71
|
+
function isRetryableError(error) {
|
|
72
|
+
if (error instanceof JupyterNotReadyError || 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 JupyterNotReadyError(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
|
+
JupyterNotReadyError,
|
|
119
|
+
ContextNotFoundError,
|
|
120
|
+
CodeExecutionError,
|
|
121
|
+
ContainerNotReadyError,
|
|
122
|
+
SandboxNetworkError,
|
|
123
|
+
ServiceUnavailableError,
|
|
124
|
+
isJupyterNotReadyError,
|
|
125
|
+
isSandboxError,
|
|
126
|
+
isRetryableError,
|
|
127
|
+
parseErrorResponse
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=chunk-LALY4SFU.js.map
|