Skip to content

Commit bf55426

Browse files
committed
feat(sdks): javascript sdk
1 parent e537ca9 commit bf55426

64 files changed

Lines changed: 9025 additions & 7 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/real-e2e.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,57 @@ jobs:
114114
name: java-test-report
115115
path: tests/java/build/reports/tests/test/
116116
retention-days: 5
117+
118+
javascript-e2e:
119+
name: JavaScript E2E (docker bridge)
120+
runs-on: ubuntu-latest
121+
steps:
122+
- name: Checkout code
123+
uses: actions/checkout@v4
124+
125+
- name: Set up Node
126+
uses: actions/setup-node@v4
127+
with:
128+
node-version: "20"
129+
130+
- name: Set up Python
131+
uses: actions/setup-python@v5
132+
with:
133+
python-version: "3.10"
134+
135+
- name: Install uv
136+
run: pip install uv
137+
138+
- name: Run tests
139+
env:
140+
TAG: latest
141+
run: |
142+
set -e
143+
144+
# Create config file (match other E2E jobs)
145+
cat <<EOF > ~/.sandbox.toml
146+
[server]
147+
host = "127.0.0.1"
148+
port = 8080
149+
log_level = "INFO"
150+
api_key = ""
151+
[runtime]
152+
type = "docker"
153+
execd_image = "opensandbox/execd:${TAG}"
154+
[docker]
155+
network_mode = "bridge"
156+
EOF
157+
158+
bash ./scripts/javascript-e2e.sh
159+
160+
- name: Eval logs
161+
if: ${{ always() }}
162+
run: cat server/server.log
163+
164+
- name: Upload Test Report
165+
if: always()
166+
uses: actions/upload-artifact@v4
167+
with:
168+
name: javascript-test-report
169+
path: tests/javascript/build/test-results/junit.xml
170+
retention-days: 5

scripts/add-license.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ style_for_file() {
143143

144144
case "$ext" in
145145
sh|py|toml|tf|sql) echo "line:#"; return ;;
146-
go|java|kt|kts|ts|tsx|js|jsx) echo "line://"; return ;;
146+
go|java|kt|kts|ts|tsx|js|jsx|mjs|cjs|mts|cts) echo "line://"; return ;;
147147
css) echo "block:css"; return ;;
148148
html) echo "block:html"; return ;;
149149
esac
@@ -207,7 +207,11 @@ process_file() {
207207

208208
main() {
209209
local files
210-
IFS=$'\n' read -r -d '' -a files < <(git ls-files && printf '\0')
210+
if [[ "$#" -gt 0 ]]; then
211+
IFS=$'\n' read -r -d '' -a files < <(git ls-files -- "$@" && printf '\0')
212+
else
213+
IFS=$'\n' read -r -d '' -a files < <(git ls-files && printf '\0')
214+
fi
211215
for f in "${files[@]}"; do
212216
process_file "$f"
213217
done

scripts/javascript-e2e.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/bash
2+
# Copyright 2025 Alibaba Group Holding Ltd.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
set -euxo pipefail
17+
18+
# prepare required images
19+
TAG=${TAG:-latest}
20+
docker pull "opensandbox/execd:${TAG}"
21+
docker pull "opensandbox/code-interpreter:${TAG}"
22+
23+
# setup server
24+
cd server
25+
uv sync && uv run python -m src.main > server.log 2>&1 &
26+
cd ..
27+
28+
# wait for server
29+
sleep 10
30+
31+
# run JavaScript/TypeScript e2e (SDK builds are handled by the test script)
32+
cd tests/javascript
33+
34+
# Pin pnpm via corepack (repo expects [email protected])
35+
corepack enable
36+
corepack prepare [email protected] --activate
37+
38+
pnpm install
39+
40+
# Ensure SDK workspace deps exist before running build steps (CI does not have prebuilt node_modules).
41+
pnpm -C ../../sdks/sandbox/javascript install --prefer-offline
42+
pnpm -C ../../sdks/code-interpreter/javascript install --prefer-offline
43+
44+
# Align with other E2E jobs: local server does not require API key by default.
45+
# Ensure tests do not send an auth header.
46+
export OPENSANDBOX_TEST_API_KEY=""
47+
export OPENSANDBOX_SANDBOX_DEFAULT_IMAGE="opensandbox/code-interpreter:${TAG}"
48+
49+
pnpm test:ci
50+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
20
2+
3+
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Alibaba Code Interpreter SDK for JavaScript/TypeScript
2+
3+
English | [中文](README_zh.md)
4+
5+
A TypeScript/JavaScript SDK for executing code in secure, isolated sandboxes. It provides a high-level API for running Python, Java, Go, TypeScript, and other languages safely, with support for code execution contexts.
6+
7+
## Prerequisites
8+
9+
This SDK requires a Docker image containing the Code Interpreter runtime environment. You must use the `opensandbox/code-interpreter` image (or a derivative) which includes pre-installed runtimes for Python, Java, Go, Node.js, etc.
10+
11+
For detailed information about supported languages and versions, please refer to the [Environment Documentation](../../../sandboxes/code-interpreter/README.md).
12+
13+
## Installation
14+
15+
### npm
16+
17+
```bash
18+
npm install @alibaba/opensandbox-code-interpreter
19+
```
20+
21+
### pnpm
22+
23+
```bash
24+
pnpm add @alibaba/opensandbox-code-interpreter
25+
```
26+
27+
### yarn
28+
29+
```bash
30+
yarn add @alibaba/opensandbox-code-interpreter
31+
```
32+
33+
## Quick Start
34+
35+
The following example demonstrates how to create a sandbox with a specific runtime configuration and execute a simple script.
36+
37+
> **Note**: Before running this example, ensure the OpenSandbox service is running. See the root [README.md](../../../README.md) for startup instructions.
38+
39+
```ts
40+
import { ConnectionConfig, Sandbox } from "@alibaba/opensandbox";
41+
import { CodeInterpreter, SupportedLanguages } from "@alibaba/opensandbox-code-interpreter";
42+
43+
// 1. Configure connection
44+
const config = new ConnectionConfig({
45+
domain: "api.opensandbox.io",
46+
apiKey: "your-api-key",
47+
});
48+
49+
// 2. Create a Sandbox with the code-interpreter image + runtime versions
50+
const sandbox = await Sandbox.create({
51+
connectionConfig: config,
52+
image: "opensandbox/code-interpreter:latest",
53+
entrypoint: ["/opt/opensandbox/code-interpreter.sh"],
54+
env: {
55+
PYTHON_VERSION: "3.11",
56+
JAVA_VERSION: "17",
57+
NODE_VERSION: "20",
58+
GO_VERSION: "1.24",
59+
},
60+
timeoutSeconds: 15 * 60,
61+
});
62+
63+
// 3. Create CodeInterpreter wrapper
64+
const ci = await CodeInterpreter.create(sandbox);
65+
66+
// 4. Create an execution context (Python)
67+
const ctx = await ci.codes.createContext(SupportedLanguages.PYTHON);
68+
69+
// 5. Run code
70+
const result = await ci.codes.run("import sys\nprint(sys.version)\nresult = 2 + 2\nresult", {
71+
context: ctx,
72+
});
73+
74+
// 6. Print output
75+
console.log(result.result[0]?.text);
76+
77+
// 7. Cleanup remote instance (optional but recommended)
78+
await sandbox.kill();
79+
```
80+
81+
## Runtime Configuration
82+
83+
### Docker Image
84+
85+
The Code Interpreter SDK relies on a specialized environment. Ensure your sandbox provider has the `opensandbox/code-interpreter` image available.
86+
87+
### Language Version Selection
88+
89+
You can specify the desired version of a programming language by setting the corresponding environment variable when creating the `Sandbox`.
90+
91+
| Language | Environment Variable | Example Value | Default (if unset) |
92+
| --- | --- | --- | --- |
93+
| Python | `PYTHON_VERSION` | `3.11` | Image default |
94+
| Java | `JAVA_VERSION` | `17` | Image default |
95+
| Node.js | `NODE_VERSION` | `20` | Image default |
96+
| Go | `GO_VERSION` | `1.24` | Image default |
97+
98+
```ts
99+
const sandbox = await Sandbox.create({
100+
connectionConfig: config,
101+
image: "opensandbox/code-interpreter:latest",
102+
entrypoint: ["/opt/opensandbox/code-interpreter.sh"],
103+
env: {
104+
JAVA_VERSION: "17",
105+
GO_VERSION: "1.24",
106+
},
107+
});
108+
```
109+
110+
## Usage Examples
111+
112+
### 0. Run with `language` (default language context)
113+
114+
If you don't need to manage explicit context IDs, you can run code by specifying only `language`.
115+
When `context.id` is omitted, execd can create/reuse a default session for that language, so state can persist across runs.
116+
117+
```ts
118+
import { SupportedLanguages } from "@alibaba/opensandbox-code-interpreter";
119+
120+
await ci.codes.run("x = 42", { language: SupportedLanguages.PYTHON });
121+
const execution = await ci.codes.run("result = x\nresult", { language: SupportedLanguages.PYTHON });
122+
console.log(execution.result[0]?.text); // "42"
123+
```
124+
125+
### 1. Java Code Execution
126+
127+
```ts
128+
import { SupportedLanguages } from "@alibaba/opensandbox-code-interpreter";
129+
130+
const javaCtx = await ci.codes.createContext(SupportedLanguages.JAVA);
131+
const execution = await ci.codes.run(
132+
[
133+
'System.out.println("Calculating sum...");',
134+
"int a = 10;",
135+
"int b = 20;",
136+
"int sum = a + b;",
137+
'System.out.println("Sum: " + sum);',
138+
"sum",
139+
].join("\n"),
140+
{ context: javaCtx },
141+
);
142+
console.log(execution.logs.stdout.map((m) => m.text));
143+
```
144+
145+
### 2. Streaming Output Handling
146+
147+
Handle stdout/stderr and execution events in real-time.
148+
149+
```ts
150+
import type { ExecutionHandlers } from "@alibaba/opensandbox";
151+
import { SupportedLanguages } from "@alibaba/opensandbox-code-interpreter";
152+
153+
const handlers: ExecutionHandlers = {
154+
onStdout: (m) => console.log("STDOUT:", m.text),
155+
onStderr: (m) => console.error("STDERR:", m.text),
156+
onResult: (r) => console.log("RESULT:", r.text),
157+
};
158+
159+
const pyCtx = await ci.codes.createContext(SupportedLanguages.PYTHON);
160+
await ci.codes.run("import time\nfor i in range(5):\n print(i)\n time.sleep(0.2)", {
161+
context: pyCtx,
162+
handlers,
163+
});
164+
```
165+
166+
## Notes
167+
168+
- **Lifecycle**: `CodeInterpreter` wraps an existing `Sandbox` instance and reuses its connection configuration.
169+
- **Default context**: `codes.run(..., { language })` uses a language default context (state can persist across runs).
170+

0 commit comments

Comments
 (0)