@cloudflare/sandbox 0.3.1 → 0.3.3
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 +22 -24
- package/README.md +2 -2
- package/container_src/bun.lock +31 -77
- package/container_src/control-process.ts +1 -1
- package/container_src/index.ts +34 -43
- package/container_src/interpreter-service.ts +276 -0
- package/container_src/isolation.ts +1 -1
- package/container_src/mime-processor.ts +1 -1
- package/container_src/package.json +4 -4
- package/container_src/runtime/executors/javascript/node_executor.ts +123 -0
- package/container_src/runtime/executors/python/ipython_executor.py +338 -0
- package/container_src/runtime/executors/typescript/ts_executor.ts +138 -0
- package/container_src/runtime/process-pool.ts +464 -0
- package/container_src/startup.sh +6 -79
- package/dist/{chunk-LALY4SFU.js → chunk-FXYPFGOZ.js} +10 -10
- package/dist/chunk-FXYPFGOZ.js.map +1 -0
- package/dist/{chunk-LFLJGISB.js → chunk-H4PW2LGW.js} +6 -6
- package/dist/chunk-H4PW2LGW.js.map +1 -0
- package/dist/{chunk-FKBV7CZS.js → chunk-JTKON2SH.js} +9 -9
- package/dist/chunk-JTKON2SH.js.map +1 -0
- package/dist/{chunk-EGC5IYXA.js → chunk-W7TVRPBG.js} +2 -2
- package/dist/chunk-W7TVRPBG.js.map +1 -0
- package/dist/{chunk-BEQUGUY4.js → chunk-Z6OZPC6U.js} +9 -6
- package/dist/chunk-Z6OZPC6U.js.map +1 -0
- package/dist/{client-Dny_ro_v.d.ts → client-COGWU6bz.d.ts} +3 -3
- package/dist/client.d.ts +1 -1
- package/dist/errors.d.ts +9 -9
- package/dist/errors.js +5 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -11
- package/dist/interpreter-client.d.ts +4 -0
- package/dist/interpreter-client.js +9 -0
- package/dist/interpreter-types.d.ts +5 -5
- package/dist/interpreter-types.js +1 -1
- package/dist/interpreter.d.ts +2 -2
- package/dist/interpreter.js +2 -2
- package/dist/request-handler.d.ts +1 -1
- package/dist/request-handler.js +5 -5
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.js +5 -5
- package/package.json +2 -2
- package/src/errors.ts +15 -14
- package/src/index.ts +16 -5
- package/src/{jupyter-client.ts → interpreter-client.ts} +6 -3
- package/src/interpreter-types.ts +102 -95
- package/src/interpreter.ts +8 -8
- package/src/sandbox.ts +3 -3
- package/container_src/jupyter-server.ts +0 -579
- package/container_src/jupyter-service.ts +0 -461
- package/container_src/jupyter_config.py +0 -48
- package/dist/chunk-BEQUGUY4.js.map +0 -1
- package/dist/chunk-EGC5IYXA.js.map +0 -1
- package/dist/chunk-FKBV7CZS.js.map +0 -1
- package/dist/chunk-LALY4SFU.js.map +0 -1
- package/dist/chunk-LFLJGISB.js.map +0 -1
- package/dist/jupyter-client.d.ts +0 -4
- package/dist/jupyter-client.js +0 -9
- /package/dist/{jupyter-client.js.map → interpreter-client.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @cloudflare/sandbox
|
|
2
2
|
|
|
3
|
+
## 0.3.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#83](https://github.com/cloudflare/sandbox-sdk/pull/83) [`eec5bb6`](https://github.com/cloudflare/sandbox-sdk/commit/eec5bb6203dd5d775b4b54e91c26de25eeb767ce) Thanks [@mikenomitch](https://github.com/mikenomitch)! - Bump containers package version
|
|
8
|
+
|
|
9
|
+
## 0.3.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#76](https://github.com/cloudflare/sandbox-sdk/pull/76) [`ef9e320`](https://github.com/cloudflare/sandbox-sdk/commit/ef9e320dcef30e57797fef6ebd9a9383fa9720d9) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - Replace Jupyter with lightweight interpreters for >90% faster cold starts for `.runCode` calls, while maintaining full code execution capabilities and rich output support.
|
|
14
|
+
|
|
3
15
|
## 0.3.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/Dockerfile
CHANGED
|
@@ -51,24 +51,12 @@ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
|
|
51
51
|
COPY --from=bun-source /usr/local/bin/bun /usr/local/bin/bun
|
|
52
52
|
COPY --from=bun-source /usr/local/bin/bunx /usr/local/bin/bunx
|
|
53
53
|
|
|
54
|
-
# Install
|
|
55
|
-
RUN pip3 install --no-cache-dir \
|
|
56
|
-
jupyter-server \
|
|
57
|
-
jupyter-client \
|
|
58
|
-
ipykernel \
|
|
59
|
-
orjson \
|
|
60
|
-
&& python3 -m ipykernel install --user --name python3
|
|
61
|
-
|
|
62
|
-
# Install scientific packages
|
|
54
|
+
# Install essential Python packages for code execution
|
|
63
55
|
RUN pip3 install --no-cache-dir \
|
|
64
56
|
matplotlib \
|
|
65
57
|
numpy \
|
|
66
58
|
pandas \
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
# Install JavaScript kernel (ijavascript) - using E2B's fork
|
|
70
|
-
RUN npm install -g git+https://github.com/e2b-dev/ijavascript.git \
|
|
71
|
-
&& ijsinstall --install=global
|
|
59
|
+
ipython
|
|
72
60
|
|
|
73
61
|
# Set up container server directory
|
|
74
62
|
WORKDIR /container-server
|
|
@@ -77,9 +65,7 @@ WORKDIR /container-server
|
|
|
77
65
|
RUN python3 --version && \
|
|
78
66
|
node --version && \
|
|
79
67
|
npm --version && \
|
|
80
|
-
bun --version
|
|
81
|
-
jupyter --version && \
|
|
82
|
-
jupyter kernelspec list
|
|
68
|
+
bun --version
|
|
83
69
|
|
|
84
70
|
# Copy container source files to server directory
|
|
85
71
|
COPY container_src/package.json container_src/bun.lock ./
|
|
@@ -87,15 +73,27 @@ RUN bun install --frozen-lockfile
|
|
|
87
73
|
|
|
88
74
|
COPY container_src/ ./
|
|
89
75
|
|
|
90
|
-
# Compile TypeScript
|
|
91
|
-
|
|
92
|
-
RUN
|
|
93
|
-
|
|
94
|
-
|
|
76
|
+
# Compile TypeScript files using the locally installed TypeScript
|
|
77
|
+
RUN npx tsc control-process.ts --outDir . --module commonjs --target es2020 --esModuleInterop --skipLibCheck
|
|
78
|
+
RUN cd runtime/executors/javascript && npx tsc node_executor.ts --module commonjs --target es2020 --esModuleInterop --skipLibCheck
|
|
79
|
+
RUN cd runtime/executors/typescript && npx tsc ts_executor.ts --module commonjs --target es2020 --esModuleInterop --skipLibCheck
|
|
80
|
+
|
|
81
|
+
# Configure process pool sizes (can be overridden at runtime)
|
|
82
|
+
ENV PYTHON_POOL_MIN_SIZE=3
|
|
83
|
+
ENV PYTHON_POOL_MAX_SIZE=15
|
|
84
|
+
ENV JAVASCRIPT_POOL_MIN_SIZE=3
|
|
85
|
+
ENV JAVASCRIPT_POOL_MAX_SIZE=10
|
|
86
|
+
ENV TYPESCRIPT_POOL_MIN_SIZE=3
|
|
87
|
+
ENV TYPESCRIPT_POOL_MAX_SIZE=10
|
|
88
|
+
|
|
89
|
+
# Create clean workspace directory for user code
|
|
90
|
+
# Architecture:
|
|
91
|
+
# /container-server/ - SDK infrastructure (server, executors, dependencies)
|
|
92
|
+
# /workspace/ - User's clean workspace for their code
|
|
95
93
|
RUN mkdir -p /workspace
|
|
96
94
|
|
|
97
|
-
# Expose the application port (3000 for control
|
|
98
|
-
EXPOSE 3000
|
|
95
|
+
# Expose the application port (3000 for control)
|
|
96
|
+
EXPOSE 3000
|
|
99
97
|
|
|
100
98
|
# Make startup script executable
|
|
101
99
|
RUN chmod +x startup.sh
|
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ npm install @cloudflare/sandbox
|
|
|
72
72
|
1. **Create a Dockerfile** (temporary requirement, will be removed in future releases):
|
|
73
73
|
|
|
74
74
|
```dockerfile
|
|
75
|
-
FROM docker.io/cloudflare/sandbox:0.3.
|
|
75
|
+
FROM docker.io/cloudflare/sandbox:0.3.3
|
|
76
76
|
|
|
77
77
|
# Expose the ports you want to expose
|
|
78
78
|
EXPOSE 3000
|
|
@@ -89,7 +89,7 @@ EXPOSE 3000
|
|
|
89
89
|
{
|
|
90
90
|
"class_name": "Sandbox",
|
|
91
91
|
"image": "./Dockerfile",
|
|
92
|
-
"max_instances":
|
|
92
|
+
"max_instances": 20
|
|
93
93
|
}
|
|
94
94
|
],
|
|
95
95
|
"durable_objects": {
|
package/container_src/bun.lock
CHANGED
|
@@ -4,119 +4,73 @@
|
|
|
4
4
|
"": {
|
|
5
5
|
"name": "sandbox-server",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"
|
|
7
|
+
"esbuild": "^0.21.5",
|
|
8
8
|
"uuid": "^9.0.1",
|
|
9
|
-
"ws": "^8.16.0",
|
|
10
9
|
},
|
|
11
10
|
"devDependencies": {
|
|
11
|
+
"@types/node": "^20.0.0",
|
|
12
12
|
"@types/uuid": "^9.0.7",
|
|
13
|
-
"
|
|
13
|
+
"typescript": "^5.3.0",
|
|
14
14
|
},
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
"packages": {
|
|
18
|
-
"@
|
|
18
|
+
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
|
|
19
19
|
|
|
20
|
-
"@
|
|
20
|
+
"@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
|
|
21
21
|
|
|
22
|
-
"@
|
|
22
|
+
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
|
|
23
23
|
|
|
24
|
-
"@
|
|
24
|
+
"@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
|
|
25
25
|
|
|
26
|
-
"@
|
|
26
|
+
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
|
|
27
27
|
|
|
28
|
-
"@
|
|
28
|
+
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
|
|
29
29
|
|
|
30
|
-
"@
|
|
30
|
+
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
|
|
31
31
|
|
|
32
|
-
"@
|
|
32
|
+
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
|
|
33
33
|
|
|
34
|
-
"@
|
|
34
|
+
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
|
|
35
35
|
|
|
36
|
-
"@
|
|
36
|
+
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
|
|
37
37
|
|
|
38
|
-
"@
|
|
38
|
+
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
|
|
39
39
|
|
|
40
|
-
"@
|
|
40
|
+
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
|
|
41
41
|
|
|
42
|
-
"@
|
|
42
|
+
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
|
|
43
43
|
|
|
44
|
-
"@
|
|
44
|
+
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
|
|
45
45
|
|
|
46
|
-
"@
|
|
46
|
+
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
|
|
47
47
|
|
|
48
|
-
"@
|
|
48
|
+
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
|
|
49
49
|
|
|
50
|
-
"@
|
|
50
|
+
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
|
|
51
51
|
|
|
52
|
-
"@
|
|
52
|
+
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
|
|
53
53
|
|
|
54
|
-
"@
|
|
55
|
-
|
|
56
|
-
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
|
|
57
|
-
|
|
58
|
-
"ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
|
|
59
|
-
|
|
60
|
-
"compute-gcd": ["compute-gcd@1.2.1", "", { "dependencies": { "validate.io-array": "^1.0.3", "validate.io-function": "^1.0.2", "validate.io-integer-array": "^1.0.0" } }, "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg=="],
|
|
61
|
-
|
|
62
|
-
"compute-lcm": ["compute-lcm@1.1.2", "", { "dependencies": { "compute-gcd": "^1.2.1", "validate.io-array": "^1.0.3", "validate.io-function": "^1.0.2", "validate.io-integer-array": "^1.0.0" } }, "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ=="],
|
|
63
|
-
|
|
64
|
-
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
|
65
|
-
|
|
66
|
-
"fast-uri": ["fast-uri@3.0.6", "", {}, "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw=="],
|
|
67
|
-
|
|
68
|
-
"isomorphic.js": ["isomorphic.js@0.2.5", "", {}, "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw=="],
|
|
69
|
-
|
|
70
|
-
"json-schema-compare": ["json-schema-compare@0.2.2", "", { "dependencies": { "lodash": "^4.17.4" } }, "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ=="],
|
|
71
|
-
|
|
72
|
-
"json-schema-merge-allof": ["json-schema-merge-allof@0.8.1", "", { "dependencies": { "compute-lcm": "^1.1.2", "json-schema-compare": "^0.2.2", "lodash": "^4.17.20" } }, "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w=="],
|
|
73
|
-
|
|
74
|
-
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
|
75
|
-
|
|
76
|
-
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
|
77
|
-
|
|
78
|
-
"jsonpointer": ["jsonpointer@5.0.1", "", {}, "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ=="],
|
|
54
|
+
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
|
|
79
55
|
|
|
80
|
-
"
|
|
56
|
+
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
|
|
81
57
|
|
|
82
|
-
"
|
|
58
|
+
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
|
|
83
59
|
|
|
84
|
-
"
|
|
60
|
+
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
|
|
85
61
|
|
|
86
|
-
"
|
|
62
|
+
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
|
|
87
63
|
|
|
88
|
-
"
|
|
64
|
+
"@types/node": ["@types/node@20.19.16", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-VS6TTONVdgwJwtJr7U+ghEjpfmQdqehLLpg/iMYGOd1+ilaFjdBJwFuPggJ4EAYPDCzWfDUHoIxyVnu+tOWVuQ=="],
|
|
89
65
|
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
"react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="],
|
|
93
|
-
|
|
94
|
-
"react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
|
|
95
|
-
|
|
96
|
-
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
|
66
|
+
"@types/uuid": ["@types/uuid@9.0.8", "", {}, "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA=="],
|
|
97
67
|
|
|
98
|
-
"
|
|
68
|
+
"esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="],
|
|
99
69
|
|
|
100
|
-
"
|
|
70
|
+
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
|
|
101
71
|
|
|
102
|
-
"
|
|
72
|
+
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
|
103
73
|
|
|
104
74
|
"uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
|
|
105
|
-
|
|
106
|
-
"validate.io-array": ["validate.io-array@1.0.6", "", {}, "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg=="],
|
|
107
|
-
|
|
108
|
-
"validate.io-function": ["validate.io-function@1.0.2", "", {}, "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ=="],
|
|
109
|
-
|
|
110
|
-
"validate.io-integer": ["validate.io-integer@1.0.5", "", { "dependencies": { "validate.io-number": "^1.0.3" } }, "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ=="],
|
|
111
|
-
|
|
112
|
-
"validate.io-integer-array": ["validate.io-integer-array@1.0.0", "", { "dependencies": { "validate.io-array": "^1.0.3", "validate.io-integer": "^1.0.4" } }, "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA=="],
|
|
113
|
-
|
|
114
|
-
"validate.io-number": ["validate.io-number@1.0.3", "", {}, "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg=="],
|
|
115
|
-
|
|
116
|
-
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
|
|
117
|
-
|
|
118
|
-
"y-protocols": ["y-protocols@1.0.6", "", { "dependencies": { "lib0": "^0.2.85" }, "peerDependencies": { "yjs": "^13.0.0" } }, "sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q=="],
|
|
119
|
-
|
|
120
|
-
"yjs": ["yjs@13.6.27", "", { "dependencies": { "lib0": "^0.2.99" } }, "sha512-OIDwaflOaq4wC6YlPBy2L6ceKeKuF7DeTxx+jPzv1FHn9tCZ0ZwSRnUBxD05E3yed46fv/FWJbvR+Ud7x0L7zw=="],
|
|
121
75
|
}
|
|
122
76
|
}
|
|
@@ -654,7 +654,7 @@ async function handleControlMessage(msg: ControlMessage): Promise<void> {
|
|
|
654
654
|
*
|
|
655
655
|
* Creates either an isolated shell using 'unshare' or a regular bash shell.
|
|
656
656
|
* Isolation uses Linux namespaces (PID) to prevent the shell from:
|
|
657
|
-
* - Seeing control plane processes (
|
|
657
|
+
* - Seeing control plane processes (Bun server)
|
|
658
658
|
* - Accessing platform secrets in /proc/1/environ
|
|
659
659
|
* - Hijacking control plane ports
|
|
660
660
|
*/
|
package/container_src/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { serve } from "bun";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
handleExecuteRequest,
|
|
4
|
+
handleStreamingExecuteRequest,
|
|
5
|
+
} from "./handler/exec";
|
|
3
6
|
import {
|
|
4
7
|
handleDeleteFileRequest,
|
|
5
8
|
handleListFilesRequest,
|
|
@@ -26,9 +29,12 @@ import {
|
|
|
26
29
|
handleStreamProcessLogsRequest,
|
|
27
30
|
} from "./handler/process";
|
|
28
31
|
import { handleCreateSession, handleListSessions } from "./handler/session";
|
|
32
|
+
import type { CreateContextRequest } from "./interpreter-service";
|
|
33
|
+
import {
|
|
34
|
+
InterpreterNotReadyError,
|
|
35
|
+
InterpreterService,
|
|
36
|
+
} from "./interpreter-service";
|
|
29
37
|
import { hasNamespaceSupport, SessionManager } from "./isolation";
|
|
30
|
-
import type { CreateContextRequest } from "./jupyter-server";
|
|
31
|
-
import { JupyterNotReadyError, JupyterService } from "./jupyter-service";
|
|
32
38
|
|
|
33
39
|
// In-memory storage for exposed ports
|
|
34
40
|
const exposedPorts = new Map<number, { name?: string; exposedAt: Date }>();
|
|
@@ -72,28 +78,12 @@ process.on("uncaughtException", async (error) => {
|
|
|
72
78
|
process.exit(1);
|
|
73
79
|
});
|
|
74
80
|
|
|
75
|
-
// Initialize
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
// Start Jupyter initialization in background (non-blocking)
|
|
79
|
-
console.log("[Container] Starting Jupyter initialization in background...");
|
|
80
|
-
console.log(
|
|
81
|
-
"[Container] API endpoints are available immediately. Jupyter-dependent features will be available shortly."
|
|
82
|
-
);
|
|
81
|
+
// Initialize interpreter service
|
|
82
|
+
const interpreterService = new InterpreterService();
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
console.log(
|
|
88
|
-
"[Container] Jupyter fully initialized - all features available"
|
|
89
|
-
);
|
|
90
|
-
})
|
|
91
|
-
.catch((error) => {
|
|
92
|
-
console.error("[Container] Jupyter initialization failed:", error.message);
|
|
93
|
-
console.error(
|
|
94
|
-
"[Container] The API will continue in degraded mode without code execution capabilities"
|
|
95
|
-
);
|
|
96
|
-
});
|
|
84
|
+
// No initialization needed - service is ready immediately!
|
|
85
|
+
console.log("[Container] Interpreter service ready - no cold start!");
|
|
86
|
+
console.log("[Container] All API endpoints available immediately");
|
|
97
87
|
|
|
98
88
|
const server = serve({
|
|
99
89
|
async fetch(req: Request) {
|
|
@@ -144,26 +134,27 @@ const server = serve({
|
|
|
144
134
|
return handleExecuteRequest(req, corsHeaders, sessionManager);
|
|
145
135
|
}
|
|
146
136
|
break;
|
|
147
|
-
|
|
137
|
+
|
|
148
138
|
case "/api/execute/stream":
|
|
149
139
|
if (req.method === "POST") {
|
|
150
|
-
return handleStreamingExecuteRequest(
|
|
140
|
+
return handleStreamingExecuteRequest(
|
|
141
|
+
req,
|
|
142
|
+
sessionManager,
|
|
143
|
+
corsHeaders
|
|
144
|
+
);
|
|
151
145
|
}
|
|
152
146
|
break;
|
|
153
147
|
|
|
154
148
|
case "/api/ping":
|
|
155
149
|
if (req.method === "GET") {
|
|
156
|
-
const health = await
|
|
150
|
+
const health = await interpreterService.getHealthStatus();
|
|
157
151
|
return new Response(
|
|
158
152
|
JSON.stringify({
|
|
159
153
|
message: "pong",
|
|
160
154
|
timestamp: new Date().toISOString(),
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
? "initializing"
|
|
165
|
-
: "not ready",
|
|
166
|
-
jupyterHealth: health,
|
|
155
|
+
system: "interpreter (70x faster)",
|
|
156
|
+
status: health.ready ? "ready" : "initializing",
|
|
157
|
+
progress: health.progress,
|
|
167
158
|
}),
|
|
168
159
|
{
|
|
169
160
|
headers: {
|
|
@@ -267,7 +258,7 @@ const server = serve({
|
|
|
267
258
|
if (req.method === "POST") {
|
|
268
259
|
try {
|
|
269
260
|
const body = (await req.json()) as CreateContextRequest;
|
|
270
|
-
const context = await
|
|
261
|
+
const context = await interpreterService.createContext(body);
|
|
271
262
|
return new Response(
|
|
272
263
|
JSON.stringify({
|
|
273
264
|
id: context.id,
|
|
@@ -284,9 +275,9 @@ const server = serve({
|
|
|
284
275
|
}
|
|
285
276
|
);
|
|
286
277
|
} catch (error) {
|
|
287
|
-
if (error instanceof
|
|
278
|
+
if (error instanceof InterpreterNotReadyError) {
|
|
288
279
|
console.log(
|
|
289
|
-
`[Container] Request timed out waiting for
|
|
280
|
+
`[Container] Request timed out waiting for interpreter (${error.progress}% complete)`
|
|
290
281
|
);
|
|
291
282
|
return new Response(
|
|
292
283
|
JSON.stringify({
|
|
@@ -351,7 +342,7 @@ const server = serve({
|
|
|
351
342
|
);
|
|
352
343
|
}
|
|
353
344
|
} else if (req.method === "GET") {
|
|
354
|
-
const contexts = await
|
|
345
|
+
const contexts = await interpreterService.listContexts();
|
|
355
346
|
return new Response(JSON.stringify({ contexts }), {
|
|
356
347
|
headers: {
|
|
357
348
|
"Content-Type": "application/json",
|
|
@@ -369,7 +360,7 @@ const server = serve({
|
|
|
369
360
|
code: string;
|
|
370
361
|
language?: string;
|
|
371
362
|
};
|
|
372
|
-
return await
|
|
363
|
+
return await interpreterService.executeCode(
|
|
373
364
|
body.context_id,
|
|
374
365
|
body.code,
|
|
375
366
|
body.language
|
|
@@ -408,12 +399,12 @@ const server = serve({
|
|
|
408
399
|
error.message.includes("initializing")
|
|
409
400
|
) {
|
|
410
401
|
console.log(
|
|
411
|
-
"[Container] Code execution deferred -
|
|
402
|
+
"[Container] Code execution deferred - service still initializing"
|
|
412
403
|
);
|
|
413
404
|
} else {
|
|
414
405
|
console.error("[Container] Error executing code:", error);
|
|
415
406
|
}
|
|
416
|
-
// Error response is already handled by
|
|
407
|
+
// Error response is already handled by service.executeCode for not ready state
|
|
417
408
|
return new Response(
|
|
418
409
|
JSON.stringify({
|
|
419
410
|
error:
|
|
@@ -442,7 +433,7 @@ const server = serve({
|
|
|
442
433
|
const contextId = pathname.split("/")[3];
|
|
443
434
|
if (req.method === "DELETE") {
|
|
444
435
|
try {
|
|
445
|
-
await
|
|
436
|
+
await interpreterService.deleteContext(contextId);
|
|
446
437
|
return new Response(JSON.stringify({ success: true }), {
|
|
447
438
|
headers: {
|
|
448
439
|
"Content-Type": "application/json",
|
|
@@ -450,9 +441,9 @@ const server = serve({
|
|
|
450
441
|
},
|
|
451
442
|
});
|
|
452
443
|
} catch (error) {
|
|
453
|
-
if (error instanceof
|
|
444
|
+
if (error instanceof InterpreterNotReadyError) {
|
|
454
445
|
console.log(
|
|
455
|
-
`[Container] Request timed out waiting for
|
|
446
|
+
`[Container] Request timed out waiting for interpreter (${error.progress}% complete)`
|
|
456
447
|
);
|
|
457
448
|
return new Response(
|
|
458
449
|
JSON.stringify({
|