@blaxel/core 0.2.49-dev.213 → 0.2.49-dev1
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/dist/agents/index.d.ts +15 -0
- package/dist/agents/index.js +109 -0
- package/dist/authentication/apikey.d.ts +10 -0
- package/dist/authentication/apikey.js +24 -0
- package/dist/authentication/clientcredentials.d.ts +17 -0
- package/dist/authentication/clientcredentials.js +85 -0
- package/dist/authentication/credentials.d.ts +6 -0
- package/dist/authentication/credentials.js +17 -0
- package/dist/authentication/deviceMode.d.ts +15 -0
- package/dist/authentication/deviceMode.js +70 -0
- package/dist/authentication/index.d.ts +3 -0
- package/dist/authentication/index.js +62 -0
- package/dist/authentication/types.d.ts +9 -0
- package/dist/authentication/types.js +2 -0
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.js +26 -0
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/agents/index.js +2 -2
- package/dist/cjs/authentication/clientcredentials.js +1 -4
- package/dist/cjs/client/responseInterceptor.js +53 -0
- package/dist/cjs/client/sdk.gen.js +143 -3
- package/dist/cjs/common/autoload.js +7 -0
- package/dist/cjs/common/env.js +3 -0
- package/dist/cjs/common/internal.js +0 -40
- package/dist/cjs/common/settings.js +2 -5
- package/dist/cjs/common/version.js +6 -0
- package/dist/cjs/common/webhook.js +101 -0
- package/dist/cjs/jobs/executions.js +119 -0
- package/dist/cjs/jobs/jobs.js +2 -2
- package/dist/cjs/sandbox/action.js +2 -1
- package/dist/cjs/sandbox/index.js +1 -0
- package/dist/cjs/sandbox/interpreter.js +400 -0
- package/dist/cjs/sandbox/sandbox.js +10 -67
- package/dist/cjs/tools/mcpTool.js +2 -6
- package/dist/cjs/types/client/responseInterceptor.d.ts +12 -0
- package/dist/cjs/types/client/sdk.gen.d.ts +41 -1
- package/dist/cjs/types/client/types.gen.d.ts +599 -16
- package/dist/cjs/types/common/internal.d.ts +0 -2
- package/dist/cjs/types/common/settings.d.ts +0 -1
- package/dist/cjs/types/common/version.d.ts +2 -0
- package/dist/cjs/types/common/webhook.d.ts +89 -0
- package/dist/cjs/types/jobs/executions.d.ts +42 -0
- package/dist/cjs/types/sandbox/client/sdk.gen.d.ts +1 -1
- package/dist/cjs/types/sandbox/index.d.ts +1 -0
- package/dist/cjs/types/sandbox/interpreter.d.ts +71 -0
- package/dist/cjs/types/sandbox/sandbox.d.ts +6 -12
- package/dist/cjs/types/sandbox/types.d.ts +0 -3
- package/dist/cjs-browser/.tsbuildinfo +1 -1
- package/dist/cjs-browser/agents/index.js +2 -2
- package/dist/cjs-browser/authentication/clientcredentials.js +1 -4
- package/dist/cjs-browser/client/responseInterceptor.js +53 -0
- package/dist/cjs-browser/client/sdk.gen.js +143 -3
- package/dist/cjs-browser/common/autoload.js +7 -0
- package/dist/cjs-browser/common/env.js +3 -0
- package/dist/cjs-browser/common/internal.js +0 -40
- package/dist/cjs-browser/common/settings.js +2 -5
- package/dist/cjs-browser/common/version.js +6 -0
- package/dist/cjs-browser/common/webhook.js +101 -0
- package/dist/cjs-browser/jobs/executions.js +119 -0
- package/dist/cjs-browser/jobs/jobs.js +2 -2
- package/dist/cjs-browser/sandbox/action.js +2 -1
- package/dist/cjs-browser/sandbox/index.js +1 -0
- package/dist/cjs-browser/sandbox/interpreter.js +400 -0
- package/dist/cjs-browser/sandbox/sandbox.js +10 -67
- package/dist/cjs-browser/tools/mcpTool.js +2 -6
- package/dist/cjs-browser/types/client/responseInterceptor.d.ts +12 -0
- package/dist/cjs-browser/types/client/sdk.gen.d.ts +41 -1
- package/dist/cjs-browser/types/client/types.gen.d.ts +599 -16
- package/dist/cjs-browser/types/common/internal.d.ts +0 -2
- package/dist/cjs-browser/types/common/settings.d.ts +0 -1
- package/dist/cjs-browser/types/common/version.d.ts +2 -0
- package/dist/cjs-browser/types/common/webhook.d.ts +89 -0
- package/dist/cjs-browser/types/jobs/executions.d.ts +42 -0
- package/dist/cjs-browser/types/sandbox/client/sdk.gen.d.ts +1 -1
- package/dist/cjs-browser/types/sandbox/index.d.ts +1 -0
- package/dist/cjs-browser/types/sandbox/interpreter.d.ts +71 -0
- package/dist/cjs-browser/types/sandbox/sandbox.d.ts +6 -12
- package/dist/cjs-browser/types/sandbox/types.d.ts +0 -3
- package/dist/client/authentication.d.ts +25 -0
- package/dist/client/authentication.js +15 -0
- package/dist/client/client.d.ts +2 -0
- package/dist/client/client.gen.d.ts +12 -0
- package/dist/client/client.gen.js +8 -0
- package/dist/{cjs/sandbox/websocket/index.js → client/client.js} +1 -1
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +19 -0
- package/dist/client/interceptors.d.ts +3 -0
- package/dist/client/interceptors.js +17 -0
- package/dist/client/sdk.gen.d.ts +499 -0
- package/dist/client/sdk.gen.js +1751 -0
- package/dist/client/types.gen.d.ts +4546 -0
- package/dist/client/types.gen.js +4 -0
- package/dist/common/autoload.d.ts +3 -0
- package/dist/common/autoload.js +27 -0
- package/dist/common/env.d.ts +5 -0
- package/dist/common/env.js +42 -0
- package/dist/common/errors.d.ts +1 -0
- package/dist/common/errors.js +17 -0
- package/dist/common/internal.d.ts +4 -0
- package/dist/common/internal.js +188 -0
- package/dist/common/internal.test.d.ts +1 -0
- package/dist/common/internal.test.js +39 -0
- package/dist/common/logger.d.ts +25 -0
- package/dist/common/logger.js +69 -0
- package/dist/common/node.d.ts +5 -0
- package/dist/common/node.js +26 -0
- package/dist/common/settings.d.ts +31 -0
- package/dist/common/settings.js +170 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/agents/index.js +3 -3
- package/dist/esm/authentication/clientcredentials.js +1 -4
- package/dist/esm/client/responseInterceptor.js +49 -0
- package/dist/esm/client/sdk.gen.js +132 -0
- package/dist/esm/common/autoload.js +7 -0
- package/dist/esm/common/env.js +3 -0
- package/dist/esm/common/internal.js +0 -38
- package/dist/esm/common/settings.js +2 -5
- package/dist/esm/common/version.js +3 -0
- package/dist/esm/common/webhook.js +97 -0
- package/dist/esm/jobs/executions.js +114 -0
- package/dist/esm/jobs/jobs.js +3 -3
- package/dist/esm/sandbox/action.js +3 -2
- package/dist/esm/sandbox/index.js +1 -0
- package/dist/esm/sandbox/interpreter.js +396 -0
- package/dist/esm/sandbox/sandbox.js +10 -67
- package/dist/esm/tools/mcpTool.js +3 -7
- package/dist/esm-browser/.tsbuildinfo +1 -1
- package/dist/esm-browser/agents/index.js +3 -3
- package/dist/esm-browser/authentication/clientcredentials.js +1 -4
- package/dist/esm-browser/client/responseInterceptor.js +49 -0
- package/dist/esm-browser/client/sdk.gen.js +132 -0
- package/dist/esm-browser/common/autoload.js +7 -0
- package/dist/esm-browser/common/env.js +3 -0
- package/dist/esm-browser/common/internal.js +0 -38
- package/dist/esm-browser/common/settings.js +2 -5
- package/dist/esm-browser/common/version.js +3 -0
- package/dist/esm-browser/common/webhook.js +97 -0
- package/dist/esm-browser/jobs/executions.js +114 -0
- package/dist/esm-browser/jobs/jobs.js +3 -3
- package/dist/esm-browser/sandbox/action.js +3 -2
- package/dist/esm-browser/sandbox/index.js +1 -0
- package/dist/esm-browser/sandbox/interpreter.js +396 -0
- package/dist/esm-browser/sandbox/sandbox.js +10 -67
- package/dist/esm-browser/tools/mcpTool.js +3 -7
- package/dist/index.browser.test.d.ts +1 -0
- package/dist/index.browser.test.js +45 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +33 -0
- package/dist/jobs/index.d.ts +3 -0
- package/dist/jobs/index.js +19 -0
- package/dist/jobs/jobs.d.ts +13 -0
- package/dist/jobs/jobs.js +90 -0
- package/dist/jobs/start.d.ts +1 -0
- package/dist/jobs/start.js +66 -0
- package/dist/jobs/types.d.ts +3 -0
- package/dist/jobs/types.js +2 -0
- package/dist/mcp/client.d.ts +28 -0
- package/dist/mcp/client.js +247 -0
- package/dist/{cjs-browser/types/sandbox/websocket → mcp}/index.d.ts +1 -0
- package/dist/{cjs-browser/sandbox/websocket → mcp}/index.js +1 -0
- package/dist/mcp/server.d.ts +24 -0
- package/dist/mcp/server.js +213 -0
- package/dist/models/index.d.ts +8 -0
- package/dist/models/index.js +31 -0
- package/dist/sandbox/action.d.ts +19 -0
- package/dist/sandbox/action.js +84 -0
- package/dist/sandbox/client/client.gen.d.ts +12 -0
- package/dist/sandbox/client/client.gen.js +6 -0
- package/dist/sandbox/client/index.d.ts +2 -0
- package/dist/sandbox/client/index.js +19 -0
- package/dist/sandbox/client/sdk.gen.d.ts +101 -0
- package/dist/sandbox/client/sdk.gen.js +289 -0
- package/dist/sandbox/client/types.gen.d.ts +578 -0
- package/dist/sandbox/client/types.gen.js +3 -0
- package/dist/{cjs/types/sandbox/filesystem/filesystem-ws.d.ts → sandbox/filesystem/filesystem.d.ts} +6 -18
- package/dist/sandbox/filesystem/filesystem.js +276 -0
- package/dist/sandbox/filesystem/index.d.ts +2 -0
- package/dist/sandbox/filesystem/index.js +18 -0
- package/dist/sandbox/filesystem/types.d.ts +15 -0
- package/dist/sandbox/filesystem/types.js +2 -0
- package/dist/sandbox/index.d.ts +4 -0
- package/dist/sandbox/index.js +36 -0
- package/dist/sandbox/network/index.d.ts +1 -0
- package/dist/sandbox/network/index.js +17 -0
- package/dist/sandbox/network/network.d.ts +5 -0
- package/dist/sandbox/network/network.js +10 -0
- package/dist/sandbox/preview.d.ts +37 -0
- package/dist/sandbox/preview.js +148 -0
- package/dist/sandbox/process/index.d.ts +1 -0
- package/dist/sandbox/process/index.js +17 -0
- package/dist/sandbox/process/process.d.ts +24 -0
- package/dist/sandbox/process/process.js +189 -0
- package/dist/sandbox/sandbox.d.ts +33 -0
- package/dist/sandbox/sandbox.js +178 -0
- package/dist/sandbox/session.d.ts +27 -0
- package/dist/sandbox/session.js +123 -0
- package/dist/sandbox/types.d.ts +51 -0
- package/dist/sandbox/types.js +81 -0
- package/dist/telemetry/telemetry.d.ts +62 -0
- package/dist/telemetry/telemetry.js +80 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/mcpTool.d.ts +28 -0
- package/dist/tools/mcpTool.js +218 -0
- package/dist/tools/types.d.ts +8 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/zodSchema.d.ts +9 -0
- package/dist/tools/zodSchema.js +50 -0
- package/dist/volume/index.d.ts +23 -0
- package/dist/volume/index.js +113 -0
- package/package.json +2 -2
- package/dist/cjs/sandbox/codegen/codegen-ws.js +0 -30
- package/dist/cjs/sandbox/filesystem/filesystem-ws.js +0 -106
- package/dist/cjs/sandbox/network/network-ws.js +0 -12
- package/dist/cjs/sandbox/process/process-ws.js +0 -139
- package/dist/cjs/sandbox/websocket/client.js +0 -269
- package/dist/cjs/types/sandbox/codegen/codegen-ws.d.ts +0 -10
- package/dist/cjs/types/sandbox/network/network-ws.d.ts +0 -7
- package/dist/cjs/types/sandbox/process/process-ws.d.ts +0 -27
- package/dist/cjs/types/sandbox/websocket/client.d.ts +0 -48
- package/dist/cjs/types/sandbox/websocket/index.d.ts +0 -1
- package/dist/cjs-browser/sandbox/codegen/codegen-ws.js +0 -30
- package/dist/cjs-browser/sandbox/filesystem/filesystem-ws.js +0 -106
- package/dist/cjs-browser/sandbox/network/network-ws.js +0 -12
- package/dist/cjs-browser/sandbox/process/process-ws.js +0 -139
- package/dist/cjs-browser/sandbox/websocket/client.js +0 -269
- package/dist/cjs-browser/types/sandbox/codegen/codegen-ws.d.ts +0 -10
- package/dist/cjs-browser/types/sandbox/filesystem/filesystem-ws.d.ts +0 -35
- package/dist/cjs-browser/types/sandbox/network/network-ws.d.ts +0 -7
- package/dist/cjs-browser/types/sandbox/process/process-ws.d.ts +0 -27
- package/dist/cjs-browser/types/sandbox/websocket/client.d.ts +0 -48
- package/dist/esm/sandbox/codegen/codegen-ws.js +0 -26
- package/dist/esm/sandbox/filesystem/filesystem-ws.js +0 -102
- package/dist/esm/sandbox/network/network-ws.js +0 -8
- package/dist/esm/sandbox/process/process-ws.js +0 -135
- package/dist/esm/sandbox/websocket/client.js +0 -265
- package/dist/esm/sandbox/websocket/index.js +0 -1
- package/dist/esm-browser/sandbox/codegen/codegen-ws.js +0 -26
- package/dist/esm-browser/sandbox/filesystem/filesystem-ws.js +0 -102
- package/dist/esm-browser/sandbox/network/network-ws.js +0 -8
- package/dist/esm-browser/sandbox/process/process-ws.js +0 -135
- package/dist/esm-browser/sandbox/websocket/client.js +0 -265
- package/dist/esm-browser/sandbox/websocket/index.js +0 -1
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import { logger } from "../common/logger.js";
|
|
2
|
+
import { settings } from "../common/settings.js";
|
|
3
|
+
import { SandboxInstance } from "./sandbox.js";
|
|
4
|
+
export class CodeInterpreter extends SandboxInstance {
|
|
5
|
+
static DEFAULT_IMAGE = "blaxel/jupyter-server";
|
|
6
|
+
static DEFAULT_PORTS = [
|
|
7
|
+
{ name: "jupyter", target: 8888, protocol: "HTTP" },
|
|
8
|
+
];
|
|
9
|
+
static DEFAULT_LIFECYCLE = {
|
|
10
|
+
expirationPolicies: [{ type: "ttl-idle", value: "30m", action: "delete" }],
|
|
11
|
+
};
|
|
12
|
+
_sandboxConfig;
|
|
13
|
+
constructor(sandbox) {
|
|
14
|
+
super(sandbox);
|
|
15
|
+
this._sandboxConfig = sandbox;
|
|
16
|
+
}
|
|
17
|
+
static async get(sandboxName) {
|
|
18
|
+
const base = await SandboxInstance.get(sandboxName);
|
|
19
|
+
// Create a minimal config - the base instance already has the sandbox data
|
|
20
|
+
// We'll rely on the process property for URL/headers access
|
|
21
|
+
const config = {
|
|
22
|
+
metadata: base.metadata,
|
|
23
|
+
spec: base.spec,
|
|
24
|
+
status: base.status,
|
|
25
|
+
events: base.events,
|
|
26
|
+
};
|
|
27
|
+
return new CodeInterpreter(config);
|
|
28
|
+
}
|
|
29
|
+
static async create(sandbox, { safe = true } = {}) {
|
|
30
|
+
const payload = {
|
|
31
|
+
image: CodeInterpreter.DEFAULT_IMAGE,
|
|
32
|
+
ports: CodeInterpreter.DEFAULT_PORTS,
|
|
33
|
+
lifecycle: CodeInterpreter.DEFAULT_LIFECYCLE,
|
|
34
|
+
};
|
|
35
|
+
const allowedCopyKeys = new Set(["name", "envs", "memory", "region", "headers"]);
|
|
36
|
+
if (sandbox && typeof sandbox === "object") {
|
|
37
|
+
if (Array.isArray(sandbox)) {
|
|
38
|
+
// Skip arrays
|
|
39
|
+
}
|
|
40
|
+
else if ("metadata" in sandbox || "spec" in sandbox) {
|
|
41
|
+
// It's a Sandbox object
|
|
42
|
+
const sandboxObj = sandbox;
|
|
43
|
+
if (sandboxObj.metadata?.name) {
|
|
44
|
+
payload["name"] = sandboxObj.metadata.name;
|
|
45
|
+
}
|
|
46
|
+
if (sandboxObj.spec?.runtime) {
|
|
47
|
+
if (sandboxObj.spec.runtime.envs) {
|
|
48
|
+
payload["envs"] = sandboxObj.spec.runtime.envs;
|
|
49
|
+
}
|
|
50
|
+
if (sandboxObj.spec.runtime.memory) {
|
|
51
|
+
payload["memory"] = sandboxObj.spec.runtime.memory;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (sandboxObj.spec?.region) {
|
|
55
|
+
payload["region"] = sandboxObj.spec.region;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if ("name" in sandbox || "image" in sandbox || "memory" in sandbox) {
|
|
59
|
+
// It's a SandboxCreateConfiguration or dict-like object
|
|
60
|
+
const sandboxDict = sandbox;
|
|
61
|
+
for (const k of allowedCopyKeys) {
|
|
62
|
+
const value = sandboxDict[k];
|
|
63
|
+
if (value !== null && value !== undefined) {
|
|
64
|
+
payload[k] = value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const baseInstance = await SandboxInstance.create(payload, { safe });
|
|
70
|
+
// Create config from the instance - preserve any forceUrl/headers if provided in input
|
|
71
|
+
const config = {
|
|
72
|
+
metadata: baseInstance.metadata,
|
|
73
|
+
spec: baseInstance.spec,
|
|
74
|
+
status: baseInstance.status,
|
|
75
|
+
events: baseInstance.events,
|
|
76
|
+
};
|
|
77
|
+
// Preserve forceUrl and headers from input if it was a dict-like object
|
|
78
|
+
if (sandbox && typeof sandbox === "object" && !Array.isArray(sandbox)) {
|
|
79
|
+
if ("forceUrl" in sandbox && typeof sandbox.forceUrl === "string") {
|
|
80
|
+
config.forceUrl = sandbox.forceUrl;
|
|
81
|
+
}
|
|
82
|
+
if ("headers" in sandbox && typeof sandbox.headers === "object") {
|
|
83
|
+
config.headers = sandbox.headers;
|
|
84
|
+
}
|
|
85
|
+
if ("params" in sandbox && typeof sandbox.params === "object") {
|
|
86
|
+
config.params = sandbox.params;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return new CodeInterpreter(config);
|
|
90
|
+
}
|
|
91
|
+
get _jupyterUrl() {
|
|
92
|
+
return this.process.url;
|
|
93
|
+
}
|
|
94
|
+
static OutputMessage = class {
|
|
95
|
+
text;
|
|
96
|
+
timestamp;
|
|
97
|
+
isStderr;
|
|
98
|
+
constructor(text, timestamp, isStderr) {
|
|
99
|
+
this.text = text;
|
|
100
|
+
this.timestamp = timestamp;
|
|
101
|
+
this.isStderr = isStderr;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
static Result = class {
|
|
105
|
+
constructor(kwargs = {}) {
|
|
106
|
+
for (const [k, v] of Object.entries(kwargs)) {
|
|
107
|
+
this[k] = v;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
static ExecutionError = class {
|
|
112
|
+
name;
|
|
113
|
+
value;
|
|
114
|
+
traceback;
|
|
115
|
+
constructor(name, value, traceback) {
|
|
116
|
+
this.name = name;
|
|
117
|
+
this.value = value;
|
|
118
|
+
this.traceback = traceback;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
static Logs = class {
|
|
122
|
+
stdout = [];
|
|
123
|
+
stderr = [];
|
|
124
|
+
};
|
|
125
|
+
static Execution = class {
|
|
126
|
+
results = [];
|
|
127
|
+
logs = new CodeInterpreter.Logs();
|
|
128
|
+
error = null;
|
|
129
|
+
executionCount = null;
|
|
130
|
+
};
|
|
131
|
+
static Context = class {
|
|
132
|
+
id;
|
|
133
|
+
constructor(id) {
|
|
134
|
+
this.id = id;
|
|
135
|
+
}
|
|
136
|
+
static fromJson(data) {
|
|
137
|
+
return new CodeInterpreter.Context(String(data.id || data.context_id || ""));
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
_parseOutput(execution, output, onStdout, onStderr, onResult, onError) {
|
|
141
|
+
let data;
|
|
142
|
+
try {
|
|
143
|
+
data = JSON.parse(output);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Fallback: treat as stdout text-only message
|
|
147
|
+
execution.logs.stdout.push(output);
|
|
148
|
+
if (onStdout) {
|
|
149
|
+
return onStdout(new CodeInterpreter.OutputMessage(output, null, false));
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
let dataType = "";
|
|
154
|
+
if (typeof data.type === "string") {
|
|
155
|
+
dataType = data.type;
|
|
156
|
+
}
|
|
157
|
+
else if (data.type !== null &&
|
|
158
|
+
data.type !== undefined &&
|
|
159
|
+
typeof data.type !== "object") {
|
|
160
|
+
const typeValue = data.type;
|
|
161
|
+
dataType = String(typeValue);
|
|
162
|
+
}
|
|
163
|
+
const restData = { ...data };
|
|
164
|
+
delete restData.type;
|
|
165
|
+
if (dataType === "result") {
|
|
166
|
+
const result = new CodeInterpreter.Result(restData);
|
|
167
|
+
execution.results.push(result);
|
|
168
|
+
if (onResult) {
|
|
169
|
+
return onResult(result);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else if (dataType === "stdout") {
|
|
173
|
+
let text = "";
|
|
174
|
+
if (typeof data.text === "string") {
|
|
175
|
+
text = data.text;
|
|
176
|
+
}
|
|
177
|
+
else if (data.text !== null &&
|
|
178
|
+
data.text !== undefined &&
|
|
179
|
+
typeof data.text !== "object") {
|
|
180
|
+
const textValue = data.text;
|
|
181
|
+
text = String(textValue);
|
|
182
|
+
}
|
|
183
|
+
execution.logs.stdout.push(text);
|
|
184
|
+
if (onStdout) {
|
|
185
|
+
return onStdout(new CodeInterpreter.OutputMessage(text, typeof data.timestamp === "number" ? data.timestamp : null, false));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (dataType === "stderr") {
|
|
189
|
+
let text = "";
|
|
190
|
+
if (typeof data.text === "string") {
|
|
191
|
+
text = data.text;
|
|
192
|
+
}
|
|
193
|
+
else if (data.text !== null &&
|
|
194
|
+
data.text !== undefined &&
|
|
195
|
+
typeof data.text !== "object") {
|
|
196
|
+
const textValue = data.text;
|
|
197
|
+
text = String(textValue);
|
|
198
|
+
}
|
|
199
|
+
execution.logs.stderr.push(text);
|
|
200
|
+
if (onStderr) {
|
|
201
|
+
return onStderr(new CodeInterpreter.OutputMessage(text, typeof data.timestamp === "number" ? data.timestamp : null, true));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else if (dataType === "error") {
|
|
205
|
+
let errorName = "";
|
|
206
|
+
if (typeof data.name === "string") {
|
|
207
|
+
errorName = data.name;
|
|
208
|
+
}
|
|
209
|
+
else if (data.name !== null &&
|
|
210
|
+
data.name !== undefined &&
|
|
211
|
+
typeof data.name !== "object") {
|
|
212
|
+
const nameValue = data.name;
|
|
213
|
+
errorName = String(nameValue);
|
|
214
|
+
}
|
|
215
|
+
execution.error = new CodeInterpreter.ExecutionError(errorName, data.value, data.traceback);
|
|
216
|
+
if (onError) {
|
|
217
|
+
return onError(execution.error);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if (dataType === "number_of_executions") {
|
|
221
|
+
execution.executionCount =
|
|
222
|
+
typeof data.execution_count === "number" ? data.execution_count : null;
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
async runCode(code, options = {}) {
|
|
227
|
+
const { language = null, context = null, onStdout, onStderr, onResult, onError, envs = null, timeout = null, } = options;
|
|
228
|
+
const DEFAULT_TIMEOUT = 60.0;
|
|
229
|
+
if (language && context) {
|
|
230
|
+
throw new Error("You can provide context or language, but not both at the same time.");
|
|
231
|
+
}
|
|
232
|
+
const readTimeout = timeout === 0 ? null : timeout ?? DEFAULT_TIMEOUT;
|
|
233
|
+
const contextId = context?.id ?? null;
|
|
234
|
+
const body = {
|
|
235
|
+
code,
|
|
236
|
+
context_id: contextId,
|
|
237
|
+
language,
|
|
238
|
+
env_vars: envs,
|
|
239
|
+
};
|
|
240
|
+
const execution = new CodeInterpreter.Execution();
|
|
241
|
+
const headers = this._sandboxConfig.forceUrl
|
|
242
|
+
? this._sandboxConfig.headers
|
|
243
|
+
: settings.headers;
|
|
244
|
+
const controller = new AbortController();
|
|
245
|
+
let timeoutId = null;
|
|
246
|
+
// Set up timeout
|
|
247
|
+
if (readTimeout !== null) {
|
|
248
|
+
timeoutId = setTimeout(() => {
|
|
249
|
+
controller.abort();
|
|
250
|
+
}, readTimeout * 1000);
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
const response = await fetch(`${this._jupyterUrl}/port/8888/execute`, {
|
|
254
|
+
method: "POST",
|
|
255
|
+
headers: {
|
|
256
|
+
...headers,
|
|
257
|
+
"Content-Type": "application/json",
|
|
258
|
+
},
|
|
259
|
+
body: JSON.stringify(body),
|
|
260
|
+
signal: controller.signal,
|
|
261
|
+
});
|
|
262
|
+
if (response.status >= 400) {
|
|
263
|
+
let bodyText = "<unavailable>";
|
|
264
|
+
try {
|
|
265
|
+
bodyText = await response.text();
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Ignore errors
|
|
269
|
+
}
|
|
270
|
+
const method = "POST";
|
|
271
|
+
const url = `${this._jupyterUrl}/port/8888/execute`;
|
|
272
|
+
const reason = response.statusText;
|
|
273
|
+
const details = "Execution failed\n" +
|
|
274
|
+
`- method: ${method}\n- url: ${url}\n- status: ${response.status} ${reason}\n` +
|
|
275
|
+
`- response-headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}\n- body:\n${bodyText}`;
|
|
276
|
+
logger.debug(details);
|
|
277
|
+
throw new Error(details);
|
|
278
|
+
}
|
|
279
|
+
if (!response.body) {
|
|
280
|
+
throw new Error("No response body");
|
|
281
|
+
}
|
|
282
|
+
const reader = response.body.getReader();
|
|
283
|
+
const decoder = new TextDecoder();
|
|
284
|
+
let buffer = "";
|
|
285
|
+
try {
|
|
286
|
+
while (true) {
|
|
287
|
+
const result = await reader.read();
|
|
288
|
+
if (result.done)
|
|
289
|
+
break;
|
|
290
|
+
const value = result.value;
|
|
291
|
+
if (value instanceof Uint8Array) {
|
|
292
|
+
buffer += decoder.decode(value, { stream: true });
|
|
293
|
+
const lines = buffer.split(/\r?\n/);
|
|
294
|
+
buffer = lines.pop() || "";
|
|
295
|
+
for (const line of lines) {
|
|
296
|
+
if (!line)
|
|
297
|
+
continue;
|
|
298
|
+
try {
|
|
299
|
+
this._parseOutput(execution, line, onStdout, onStderr, onResult, onError);
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
// Fallback: treat as stdout text-only message
|
|
303
|
+
execution.logs.stdout.push(line);
|
|
304
|
+
if (onStdout) {
|
|
305
|
+
onStdout(new CodeInterpreter.OutputMessage(line, null, false));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
finally {
|
|
313
|
+
reader.releaseLock();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (error &&
|
|
318
|
+
typeof error === "object" &&
|
|
319
|
+
"name" in error &&
|
|
320
|
+
error.name === "AbortError") {
|
|
321
|
+
throw new Error("Request timeout");
|
|
322
|
+
}
|
|
323
|
+
throw error;
|
|
324
|
+
}
|
|
325
|
+
finally {
|
|
326
|
+
if (timeoutId) {
|
|
327
|
+
clearTimeout(timeoutId);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return execution;
|
|
331
|
+
}
|
|
332
|
+
async createCodeContext(options = {}) {
|
|
333
|
+
const { cwd = null, language = null, requestTimeout = null } = options;
|
|
334
|
+
const data = {};
|
|
335
|
+
if (language) {
|
|
336
|
+
data.language = language;
|
|
337
|
+
}
|
|
338
|
+
if (cwd) {
|
|
339
|
+
data.cwd = cwd;
|
|
340
|
+
}
|
|
341
|
+
const headers = this._sandboxConfig.forceUrl
|
|
342
|
+
? this._sandboxConfig.headers
|
|
343
|
+
: settings.headers;
|
|
344
|
+
const controller = new AbortController();
|
|
345
|
+
let timeoutId = null;
|
|
346
|
+
if (requestTimeout !== null) {
|
|
347
|
+
timeoutId = setTimeout(() => {
|
|
348
|
+
controller.abort();
|
|
349
|
+
}, requestTimeout * 1000);
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
const response = await fetch(`${this._jupyterUrl}/port/8888/contexts`, {
|
|
353
|
+
method: "POST",
|
|
354
|
+
headers: {
|
|
355
|
+
...headers,
|
|
356
|
+
"Content-Type": "application/json",
|
|
357
|
+
},
|
|
358
|
+
body: JSON.stringify(data),
|
|
359
|
+
signal: controller.signal,
|
|
360
|
+
});
|
|
361
|
+
if (response.status >= 400) {
|
|
362
|
+
let bodyText = "<unavailable>";
|
|
363
|
+
try {
|
|
364
|
+
bodyText = await response.text();
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
// Ignore errors
|
|
368
|
+
}
|
|
369
|
+
const method = "POST";
|
|
370
|
+
const url = `${this._jupyterUrl}/port/8888/contexts`;
|
|
371
|
+
const reason = response.statusText;
|
|
372
|
+
const details = "Create context failed\n" +
|
|
373
|
+
`- method: ${method}\n- url: ${url}\n- status: ${response.status} ${reason}\n` +
|
|
374
|
+
`- response-headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}\n- body:\n${bodyText}`;
|
|
375
|
+
logger.debug(details);
|
|
376
|
+
throw new Error(details);
|
|
377
|
+
}
|
|
378
|
+
const responseData = (await response.json());
|
|
379
|
+
return CodeInterpreter.Context.fromJson(responseData);
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
if (error &&
|
|
383
|
+
typeof error === "object" &&
|
|
384
|
+
"name" in error &&
|
|
385
|
+
error.name === "AbortError") {
|
|
386
|
+
throw new Error("Request timeout");
|
|
387
|
+
}
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
finally {
|
|
391
|
+
if (timeoutId) {
|
|
392
|
+
clearTimeout(timeoutId);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
@@ -2,16 +2,11 @@ import { v4 as uuidv4 } from "uuid";
|
|
|
2
2
|
import { createSandbox, deleteSandbox, getSandbox, listSandboxes, updateSandbox } from "../client/index.js";
|
|
3
3
|
import { logger } from "../common/logger.js";
|
|
4
4
|
import { SandboxFileSystem } from "./filesystem/index.js";
|
|
5
|
-
import { SandboxFileSystemWebSocket } from "./filesystem/filesystem-ws.js";
|
|
6
5
|
import { SandboxNetwork } from "./network/index.js";
|
|
7
|
-
import { SandboxNetworkWebSocket } from "./network/network-ws.js";
|
|
8
6
|
import { SandboxPreviews } from "./preview.js";
|
|
9
7
|
import { SandboxProcess } from "./process/index.js";
|
|
10
|
-
import { SandboxProcessWebSocket } from "./process/process-ws.js";
|
|
11
8
|
import { SandboxCodegen } from "./codegen/index.js";
|
|
12
|
-
import { SandboxCodegenWebSocket } from "./codegen/codegen-ws.js";
|
|
13
9
|
import { SandboxSessions } from "./session.js";
|
|
14
|
-
import { WebSocketClient } from "./websocket/index.js";
|
|
15
10
|
import { normalizeEnvs, normalizePorts, normalizeVolumes } from "./types.js";
|
|
16
11
|
export class SandboxInstance {
|
|
17
12
|
sandbox;
|
|
@@ -21,32 +16,14 @@ export class SandboxInstance {
|
|
|
21
16
|
previews;
|
|
22
17
|
sessions;
|
|
23
18
|
codegen;
|
|
24
|
-
wsClient;
|
|
25
19
|
constructor(sandbox) {
|
|
26
20
|
this.sandbox = sandbox;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.wsClient = new WebSocketClient({
|
|
31
|
-
url,
|
|
32
|
-
headers: sandbox.headers,
|
|
33
|
-
});
|
|
34
|
-
// Initialize WebSocket-based action handlers
|
|
35
|
-
this.process = new SandboxProcessWebSocket(sandbox, this.wsClient);
|
|
36
|
-
this.fs = new SandboxFileSystemWebSocket(sandbox, this.process, this.wsClient);
|
|
37
|
-
this.network = new SandboxNetworkWebSocket(sandbox, this.wsClient);
|
|
38
|
-
this.codegen = new SandboxCodegenWebSocket(sandbox, this.wsClient);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
// Default to HTTP-based action handlers
|
|
42
|
-
this.process = new SandboxProcess(sandbox);
|
|
43
|
-
this.fs = new SandboxFileSystem(sandbox, this.process);
|
|
44
|
-
this.network = new SandboxNetwork(sandbox);
|
|
45
|
-
this.codegen = new SandboxCodegen(sandbox);
|
|
46
|
-
}
|
|
47
|
-
// These are always HTTP-based
|
|
21
|
+
this.process = new SandboxProcess(sandbox);
|
|
22
|
+
this.fs = new SandboxFileSystem(sandbox, this.process);
|
|
23
|
+
this.network = new SandboxNetwork(sandbox);
|
|
48
24
|
this.previews = new SandboxPreviews(sandbox);
|
|
49
25
|
this.sessions = new SandboxSessions(sandbox);
|
|
26
|
+
this.codegen = new SandboxCodegen(sandbox);
|
|
50
27
|
}
|
|
51
28
|
get metadata() {
|
|
52
29
|
return this.sandbox.metadata;
|
|
@@ -65,17 +42,10 @@ export class SandboxInstance {
|
|
|
65
42
|
logger.warn("⚠️ Warning: sandbox.wait() is deprecated. You don't need to wait for the sandbox to be deployed anymore.");
|
|
66
43
|
return this;
|
|
67
44
|
}
|
|
68
|
-
closeConnection() {
|
|
69
|
-
if (this.wsClient) {
|
|
70
|
-
this.wsClient.close();
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
45
|
static async create(sandbox, { safe = true } = {}) {
|
|
74
46
|
const defaultName = `sandbox-${uuidv4().replace(/-/g, '').substring(0, 8)}`;
|
|
75
47
|
const defaultImage = `blaxel/base-image:latest`;
|
|
76
48
|
const defaultMemory = 4096;
|
|
77
|
-
// Store connection type if provided
|
|
78
|
-
let connectionType;
|
|
79
49
|
// Handle SandboxCreateConfiguration or simple dict with name/image/memory/ports/envs/volumes keys
|
|
80
50
|
if (!sandbox ||
|
|
81
51
|
'name' in sandbox ||
|
|
@@ -85,8 +55,7 @@ export class SandboxInstance {
|
|
|
85
55
|
'envs' in sandbox ||
|
|
86
56
|
'volumes' in sandbox ||
|
|
87
57
|
'lifecycle' in sandbox ||
|
|
88
|
-
'snapshotEnabled' in sandbox
|
|
89
|
-
'connectionType' in sandbox) {
|
|
58
|
+
'snapshotEnabled' in sandbox) {
|
|
90
59
|
if (!sandbox)
|
|
91
60
|
sandbox = {};
|
|
92
61
|
if (!sandbox.name)
|
|
@@ -95,7 +64,6 @@ export class SandboxInstance {
|
|
|
95
64
|
sandbox.image = defaultImage;
|
|
96
65
|
if (!sandbox.memory)
|
|
97
66
|
sandbox.memory = defaultMemory;
|
|
98
|
-
connectionType = sandbox.connectionType;
|
|
99
67
|
const ports = normalizePorts(sandbox.ports);
|
|
100
68
|
const envs = normalizeEnvs(sandbox.envs);
|
|
101
69
|
const volumes = normalizeVolumes(sandbox.volumes);
|
|
@@ -144,16 +112,7 @@ export class SandboxInstance {
|
|
|
144
112
|
body: sandbox,
|
|
145
113
|
throwOnError: true,
|
|
146
114
|
});
|
|
147
|
-
|
|
148
|
-
const config = {
|
|
149
|
-
...data,
|
|
150
|
-
connectionType: connectionType || "http",
|
|
151
|
-
};
|
|
152
|
-
const instance = new SandboxInstance(config);
|
|
153
|
-
// Connect WebSocket if needed
|
|
154
|
-
if (connectionType === "websocket" && instance.wsClient) {
|
|
155
|
-
await instance.wsClient.connect();
|
|
156
|
-
}
|
|
115
|
+
const instance = new SandboxInstance(data);
|
|
157
116
|
// TODO remove this part once we have a better way to handle this
|
|
158
117
|
if (safe) {
|
|
159
118
|
try {
|
|
@@ -163,34 +122,20 @@ export class SandboxInstance {
|
|
|
163
122
|
}
|
|
164
123
|
return instance;
|
|
165
124
|
}
|
|
166
|
-
static async get(sandboxName
|
|
125
|
+
static async get(sandboxName) {
|
|
167
126
|
const { data } = await getSandbox({
|
|
168
127
|
path: {
|
|
169
128
|
sandboxName,
|
|
170
129
|
},
|
|
171
130
|
throwOnError: true,
|
|
172
131
|
});
|
|
173
|
-
|
|
174
|
-
const config = {
|
|
175
|
-
...data,
|
|
176
|
-
connectionType: connectionType || "http",
|
|
177
|
-
};
|
|
178
|
-
const instance = new SandboxInstance(config);
|
|
179
|
-
// Connect WebSocket if needed
|
|
180
|
-
if (connectionType === "websocket" && instance.wsClient) {
|
|
181
|
-
await instance.wsClient.connect();
|
|
182
|
-
}
|
|
183
|
-
return instance;
|
|
132
|
+
return new SandboxInstance(data);
|
|
184
133
|
}
|
|
185
134
|
static async list() {
|
|
186
135
|
const { data } = await listSandboxes({ throwOnError: true });
|
|
187
136
|
return data.map((sandbox) => new SandboxInstance(sandbox));
|
|
188
137
|
}
|
|
189
|
-
static async delete(sandboxName
|
|
190
|
-
// Close WebSocket connection if instance is provided
|
|
191
|
-
if (instance && instance.wsClient) {
|
|
192
|
-
instance.closeConnection();
|
|
193
|
-
}
|
|
138
|
+
static async delete(sandboxName) {
|
|
194
139
|
const { data } = await deleteSandbox({
|
|
195
140
|
path: {
|
|
196
141
|
sandboxName,
|
|
@@ -220,10 +165,8 @@ export class SandboxInstance {
|
|
|
220
165
|
if (!name) {
|
|
221
166
|
throw new Error("Sandbox name is required");
|
|
222
167
|
}
|
|
223
|
-
// Get connection type if specified
|
|
224
|
-
const connectionType = 'connectionType' in sandbox ? sandbox.connectionType : undefined;
|
|
225
168
|
// Get the existing sandbox to check its status
|
|
226
|
-
const sandboxInstance = await SandboxInstance.get(name
|
|
169
|
+
const sandboxInstance = await SandboxInstance.get(name);
|
|
227
170
|
// If the sandbox is TERMINATED, treat it as not existing
|
|
228
171
|
if (sandboxInstance.status === "TERMINATED") {
|
|
229
172
|
// Create a new sandbox - backend will handle cleanup of the terminated one
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Client as ModelContextProtocolClient } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
2
|
import { env } from "../common/env.js";
|
|
3
|
-
import {
|
|
3
|
+
import { getForcedUrl, getGlobalUniqueHash } from "../common/internal.js";
|
|
4
4
|
import { logger } from "../common/logger.js";
|
|
5
5
|
import { settings } from "../common/settings.js";
|
|
6
6
|
import { authenticate } from "../index.js";
|
|
@@ -39,10 +39,6 @@ export class McpTool {
|
|
|
39
39
|
this.client = new ModelContextProtocolClient({
|
|
40
40
|
name: this.name,
|
|
41
41
|
version: "1.0.0",
|
|
42
|
-
}, {
|
|
43
|
-
capabilities: {
|
|
44
|
-
tools: {},
|
|
45
|
-
},
|
|
46
42
|
});
|
|
47
43
|
}
|
|
48
44
|
get fallbackUrl() {
|
|
@@ -55,8 +51,8 @@ export class McpTool {
|
|
|
55
51
|
return new URL(`${settings.runUrl}/${settings.workspace}/${this.pluralType}/${this.name}`);
|
|
56
52
|
}
|
|
57
53
|
get internalUrl() {
|
|
58
|
-
const
|
|
59
|
-
return new URL(
|
|
54
|
+
const hash = getGlobalUniqueHash(settings.workspace, this.type, this.name);
|
|
55
|
+
return new URL(`${settings.runInternalProtocol}://bl-${settings.env}-${hash}.${settings.runInternalHostname}`);
|
|
60
56
|
}
|
|
61
57
|
get forcedUrl() {
|
|
62
58
|
return getForcedUrl(this.type, this.name);
|