@watasu/sdk 0.1.30 → 0.1.50
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/README.md +13 -7
- package/dist/codeInterpreter.d.ts +141 -16
- package/dist/codeInterpreter.js +74 -19
- package/dist/commands.d.ts +16 -8
- package/dist/commands.js +17 -16
- package/dist/connectionConfig.d.ts +25 -0
- package/dist/connectionConfig.js +49 -2
- package/dist/errors.d.ts +21 -0
- package/dist/errors.js +54 -4
- package/dist/filesystem.d.ts +20 -20
- package/dist/filesystem.js +51 -12
- package/dist/git.d.ts +6 -4
- package/dist/git.js +7 -3
- package/dist/index.d.ts +22 -10
- package/dist/index.js +7 -5
- package/dist/process.d.ts +1 -1
- package/dist/process.js +11 -7
- package/dist/processSocket.d.ts +17 -4
- package/dist/processSocket.js +112 -8
- package/dist/pty.d.ts +3 -3
- package/dist/pty.js +10 -8
- package/dist/sandbox.d.ts +44 -30
- package/dist/sandbox.js +103 -59
- package/dist/template.d.ts +39 -9
- package/dist/template.js +117 -31
- package/dist/terminal.d.ts +3 -3
- package/dist/terminal.js +7 -4
- package/dist/transport.d.ts +2 -0
- package/dist/transport.js +23 -6
- package/dist/volume.d.ts +15 -8
- package/dist/volume.js +28 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Set `WATASU_API_KEY` before using the SDK.
|
|
|
16
16
|
import { Sandbox } from '@watasu/sdk'
|
|
17
17
|
|
|
18
18
|
const sbx = await Sandbox.create()
|
|
19
|
-
await sbx.
|
|
19
|
+
await sbx.files.write('/home/user/a.js', 'console.log(2 + 2)')
|
|
20
20
|
const result = await sbx.process.startAndWait('node /home/user/a.js')
|
|
21
21
|
console.log(result.stdout)
|
|
22
22
|
console.log(await sbx.isRunning())
|
|
@@ -71,7 +71,7 @@ await volume.destroy()
|
|
|
71
71
|
## Code Interpreter
|
|
72
72
|
|
|
73
73
|
```ts
|
|
74
|
-
import { Sandbox } from '@watasu/
|
|
74
|
+
import { Sandbox } from '@watasu/code-interpreter'
|
|
75
75
|
|
|
76
76
|
const sbx = await Sandbox.create()
|
|
77
77
|
const context = await sbx.createCodeContext()
|
|
@@ -85,7 +85,7 @@ await sbx.removeCodeContext(context)
|
|
|
85
85
|
await sbx.kill()
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
`@watasu/
|
|
88
|
+
`@watasu/code-interpreter` starts the `code-interpreter` template by default.
|
|
89
89
|
Code runs in persistent Python contexts and returns structured `results`, `logs`,
|
|
90
90
|
and `error` fields for each execution.
|
|
91
91
|
|
|
@@ -152,12 +152,12 @@ const remoteUrl = await sbx.git.remoteGet('/workspace/project', 'origin')
|
|
|
152
152
|
await sbx.git.restore('/workspace/project', { paths: ['README.md'] })
|
|
153
153
|
await sbx.git.reset('/workspace/project', { mode: 'hard', target: 'HEAD' })
|
|
154
154
|
|
|
155
|
-
await sbx.
|
|
155
|
+
await sbx.files.writeFiles([
|
|
156
156
|
{ path: '/workspace/project/a.txt', data: 'alpha' },
|
|
157
157
|
{ path: '/workspace/project/b.bin', data: new Uint8Array([0, 1, 2]) },
|
|
158
158
|
])
|
|
159
159
|
|
|
160
|
-
const watcher = sbx.
|
|
160
|
+
const watcher = sbx.files.watchDir('/workspace/project')
|
|
161
161
|
watcher.addEventListener((event) => {
|
|
162
162
|
console.log(event.type, event.path)
|
|
163
163
|
})
|
|
@@ -182,15 +182,21 @@ await sbx.kill()
|
|
|
182
182
|
```ts
|
|
183
183
|
const sbx = await Sandbox.create({
|
|
184
184
|
network: {
|
|
185
|
-
allowOut: ['pypi.org:443'],
|
|
185
|
+
allowOut: ({ rules }) => [...rules.keys(), 'pypi.org:443'],
|
|
186
186
|
denyOut: ['169.254.169.254'],
|
|
187
|
+
rules: {
|
|
188
|
+
'api.example.com': [
|
|
189
|
+
{ transform: { headers: { authorization: 'Bearer token' } } },
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
maskRequestHost: '${PORT}-sandbox.example.com',
|
|
187
193
|
},
|
|
188
194
|
})
|
|
189
195
|
|
|
190
196
|
await sbx.updateNetwork({
|
|
191
197
|
allowInternetAccess: false,
|
|
192
198
|
allowPackageRegistryAccess: true,
|
|
193
|
-
allowOut: ['
|
|
199
|
+
allowOut: ['registry.npmjs.org:443'],
|
|
194
200
|
})
|
|
195
201
|
```
|
|
196
202
|
|
|
@@ -1,21 +1,136 @@
|
|
|
1
1
|
import { Sandbox as BaseSandbox, SandboxConnectOpts, SandboxCreateOpts } from './sandbox.js';
|
|
2
|
-
export
|
|
2
|
+
export { ApiError, AuthenticationError, BuildError, ConflictError, FileNotFoundError, FileUploadError, GitAuthError, GitUpstreamError, InvalidArgumentError, NotEnoughSpaceError, NotFoundError, NotImplementedError, RateLimitError, SandboxError, SandboxNotFoundError, TemplateError, TimeoutError, VolumeError, } from './errors.js';
|
|
3
|
+
export { ConnectionConfig, KEEPALIVE_PING_INTERVAL_SEC } from './connectionConfig.js';
|
|
4
|
+
export type { ConnectionOpts, Username } from './connectionConfig.js';
|
|
5
|
+
export { ControlClient as ApiClient } from './transport.js';
|
|
6
|
+
export { ALL_TRAFFIC, SandboxPaginator, SnapshotPaginator, getSignature, } from './sandbox.js';
|
|
7
|
+
export type { CreateSnapshotOpts, FileUrlInfo, McpServer, McpServerName, RestoreSnapshotOpts, SandboxApiOpts, SandboxConnectOpts, SandboxCreateOpts, SandboxInfo, SandboxInfoLifecycle, SandboxLifecycle, SandboxListOpts, SandboxMetrics, SandboxMetricsOpts, SandboxNetworkInfo, SandboxNetworkOpts, SandboxNetworkRule, SandboxNetworkRuleInfo, SandboxNetworkRules, SandboxNetworkSelector, SandboxNetworkSelectorContext, SandboxNetworkTransform, SandboxNetworkUpdate, SandboxNetworkUpdateOpts, SandboxOpts, SandboxState, SandboxUrlOpts, SignatureOpts, SnapshotInfo, SnapshotListOpts, } from './sandbox.js';
|
|
8
|
+
export { CommandExitError, CommandHandle, Commands } from './commands.js';
|
|
9
|
+
export type { CommandConnectOpts, CommandRequestOpts, CommandResult, CommandStartOpts, ProcessInfo, PtyOutput, Stderr, Stdout, } from './commands.js';
|
|
10
|
+
export { Process, ProcessManager, ProcessMessage, ProcessOutput } from './process.js';
|
|
11
|
+
export type { ProcessOpts } from './process.js';
|
|
12
|
+
export { FileType, Filesystem, FilesystemEventType, FilesystemWatcher, WatchHandle, } from './filesystem.js';
|
|
13
|
+
export type { EntryInfo, FilesystemEvent, FilesystemReadOpts, FilesystemRequestOpts, FilesystemWriteOpts, WatchOpts, WriteData, WriteEntry, WriteInfo, } from './filesystem.js';
|
|
14
|
+
export { Git } from './git.js';
|
|
15
|
+
export type { GitAddOpts, GitAuthOpts, GitBranches, GitBranchOpts, GitCloneOpts, GitCommandResult, GitCommitOpts, GitConfigScope, GitConfigOpts, GitConfigureUserOpts, GitCredentialOpts, GitDangerouslyAuthenticateOpts, GitDeleteBranchOpts, GitFileStatus, GitInitOpts, GitPullOpts, GitPushOpts, GitRemoteAddOpts, GitResetMode, GitResetOpts, GitRestoreOpts, GitStatus, } from './git.js';
|
|
16
|
+
export { Pty } from './pty.js';
|
|
17
|
+
export type { PtyConnectOpts, PtyCreateOpts, PtySize } from './pty.js';
|
|
18
|
+
export { Terminal, TerminalManager, TerminalOutput } from './terminal.js';
|
|
19
|
+
export type { TerminalOpts } from './terminal.js';
|
|
20
|
+
export { Volume, VolumeConnectionConfig, VolumeFileType } from './volume.js';
|
|
21
|
+
export type { VolumeAndToken, VolumeApiParams, VolumeApiOpts, VolumeEntryStat, VolumeInfo, VolumeListFilesOpts, VolumeListOpts, VolumeMetadataOpts, VolumeMetadataOptions, VolumeReadFileOpts, VolumeReadFormat, VolumeWriteData, VolumeWriteFileOpts, VolumeWriteOptions, } from './volume.js';
|
|
22
|
+
export { ProcessSocket, base64DecodeBytes, base64DecodeText, base64Encode } from './processSocket.js';
|
|
23
|
+
export { ReadyCmd, Template, TemplateBase, LogEntry, LogEntryEnd, LogEntryStart, defaultBuildLogger, waitForFile, waitForPort, waitForProcess, waitForTimeout, waitForURL, } from './template.js';
|
|
24
|
+
export type { BuildInfo, BuildOptions, BuildStatusReason, CopyItem, GetBuildStatusOptions, LogEntryLevel, Logger, ReadyCommand, TemplateBuilder, TemplateBuildStatus, TemplateBuildStatusResponse, TemplateClass, TemplateFactory, TemplateFinal, TemplateFromImage, TemplateOptions, TemplateTag, TemplateTagInfo, } from './template.js';
|
|
25
|
+
export type { components, paths } from './index.js';
|
|
26
|
+
export type RunCodeLanguage = 'python' | 'javascript' | 'typescript' | 'r' | 'java' | 'bash' | (string & {});
|
|
27
|
+
type OutputHandler<T> = (output: T) => Promise<unknown> | unknown;
|
|
3
28
|
export interface RunCodeOpts {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
onResult?: (result: Result) => void;
|
|
9
|
-
onError?: (error: ExecutionError) => void;
|
|
29
|
+
onStdout?: OutputHandler<OutputMessage>;
|
|
30
|
+
onStderr?: OutputHandler<OutputMessage>;
|
|
31
|
+
onResult?: OutputHandler<Result>;
|
|
32
|
+
onError?: OutputHandler<ExecutionError>;
|
|
10
33
|
envs?: Record<string, string>;
|
|
11
|
-
|
|
34
|
+
timeoutMs?: number;
|
|
12
35
|
requestTimeoutMs?: number;
|
|
36
|
+
signal?: AbortSignal;
|
|
13
37
|
}
|
|
14
38
|
export interface CreateCodeContextOpts {
|
|
15
39
|
cwd?: string;
|
|
16
40
|
language?: RunCodeLanguage;
|
|
17
41
|
requestTimeoutMs?: number;
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
}
|
|
44
|
+
/** Chart types returned by code execution results. */
|
|
45
|
+
export declare enum ChartType {
|
|
46
|
+
LINE = "line",
|
|
47
|
+
SCATTER = "scatter",
|
|
48
|
+
BAR = "bar",
|
|
49
|
+
PIE = "pie",
|
|
50
|
+
BOX_AND_WHISKER = "box_and_whisker",
|
|
51
|
+
SUPERCHART = "superchart",
|
|
52
|
+
UNKNOWN = "unknown"
|
|
53
|
+
}
|
|
54
|
+
/** Axis scale types returned by chart results. */
|
|
55
|
+
export declare enum ScaleType {
|
|
56
|
+
LINEAR = "linear",
|
|
57
|
+
DATETIME = "datetime",
|
|
58
|
+
CATEGORICAL = "categorical",
|
|
59
|
+
LOG = "log",
|
|
60
|
+
SYMLOG = "symlog",
|
|
61
|
+
LOGIT = "logit",
|
|
62
|
+
FUNCTION = "function",
|
|
63
|
+
FUNCTIONLOG = "functionlog",
|
|
64
|
+
ASINH = "asinh"
|
|
18
65
|
}
|
|
66
|
+
export type Chart = {
|
|
67
|
+
type: ChartType;
|
|
68
|
+
title: string;
|
|
69
|
+
elements: unknown[];
|
|
70
|
+
};
|
|
71
|
+
export type Chart2D = Chart & {
|
|
72
|
+
x_label?: string;
|
|
73
|
+
y_label?: string;
|
|
74
|
+
x_unit?: string;
|
|
75
|
+
y_unit?: string;
|
|
76
|
+
};
|
|
77
|
+
export type PointData = {
|
|
78
|
+
label: string;
|
|
79
|
+
points: [number | string, number | string][];
|
|
80
|
+
};
|
|
81
|
+
export type PointChart = Chart2D & {
|
|
82
|
+
x_ticks: (number | string)[];
|
|
83
|
+
x_scale: ScaleType;
|
|
84
|
+
x_tick_labels: string[];
|
|
85
|
+
y_ticks: (number | string)[];
|
|
86
|
+
y_scale: ScaleType;
|
|
87
|
+
y_tick_labels: string[];
|
|
88
|
+
elements: PointData[];
|
|
89
|
+
};
|
|
90
|
+
export type LineChart = PointChart & {
|
|
91
|
+
type: ChartType.LINE;
|
|
92
|
+
};
|
|
93
|
+
export type ScatterChart = PointChart & {
|
|
94
|
+
type: ChartType.SCATTER;
|
|
95
|
+
};
|
|
96
|
+
export type BarData = {
|
|
97
|
+
label: string;
|
|
98
|
+
value: string;
|
|
99
|
+
group: string;
|
|
100
|
+
};
|
|
101
|
+
export type BarChart = Chart2D & {
|
|
102
|
+
type: ChartType.BAR;
|
|
103
|
+
elements: BarData[];
|
|
104
|
+
};
|
|
105
|
+
export type PieData = {
|
|
106
|
+
label: string;
|
|
107
|
+
angle: number;
|
|
108
|
+
radius: number;
|
|
109
|
+
};
|
|
110
|
+
export type PieChart = Chart & {
|
|
111
|
+
type: ChartType.PIE;
|
|
112
|
+
elements: PieData[];
|
|
113
|
+
};
|
|
114
|
+
export type BoxAndWhiskerData = {
|
|
115
|
+
label: string;
|
|
116
|
+
min: number;
|
|
117
|
+
first_quartile: number;
|
|
118
|
+
median: number;
|
|
119
|
+
third_quartile: number;
|
|
120
|
+
max: number;
|
|
121
|
+
outliers: number[];
|
|
122
|
+
};
|
|
123
|
+
export type BoxAndWhiskerChart = Chart2D & {
|
|
124
|
+
type: ChartType.BOX_AND_WHISKER;
|
|
125
|
+
elements: BoxAndWhiskerData[];
|
|
126
|
+
};
|
|
127
|
+
export type SuperChart = Chart & {
|
|
128
|
+
type: ChartType.SUPERCHART;
|
|
129
|
+
elements: Chart[];
|
|
130
|
+
};
|
|
131
|
+
export type ChartTypes = LineChart | ScatterChart | BarChart | PieChart | BoxAndWhiskerChart | SuperChart;
|
|
132
|
+
export type MIMEType = string;
|
|
133
|
+
export type RawData = Record<string, unknown>;
|
|
19
134
|
/** One stdout or stderr line emitted by code execution. */
|
|
20
135
|
export declare class OutputMessage {
|
|
21
136
|
readonly line: string;
|
|
@@ -35,6 +150,7 @@ export declare class ExecutionError {
|
|
|
35
150
|
}
|
|
36
151
|
/** Rich result produced by the last expression of a code execution. */
|
|
37
152
|
export declare class Result {
|
|
153
|
+
readonly raw: RawData;
|
|
38
154
|
readonly text?: string;
|
|
39
155
|
readonly html?: string;
|
|
40
156
|
readonly markdown?: string;
|
|
@@ -45,11 +161,11 @@ export declare class Result {
|
|
|
45
161
|
readonly latex?: string;
|
|
46
162
|
readonly json?: unknown;
|
|
47
163
|
readonly javascript?: string;
|
|
48
|
-
readonly data?: unknown
|
|
49
|
-
readonly chart?:
|
|
164
|
+
readonly data?: Record<string, unknown>;
|
|
165
|
+
readonly chart?: ChartTypes;
|
|
50
166
|
readonly extra: Record<string, unknown>;
|
|
51
167
|
readonly isMainResult: boolean;
|
|
52
|
-
constructor(payload?:
|
|
168
|
+
constructor(payload?: RawData, isMainResult?: boolean);
|
|
53
169
|
formats(): string[];
|
|
54
170
|
toJSON(): Record<string, unknown>;
|
|
55
171
|
}
|
|
@@ -70,9 +186,9 @@ export declare class Execution {
|
|
|
70
186
|
/** Code execution context metadata. */
|
|
71
187
|
export declare class Context {
|
|
72
188
|
readonly id: string;
|
|
73
|
-
readonly language
|
|
74
|
-
readonly cwd
|
|
75
|
-
constructor(id: string, language?: string
|
|
189
|
+
readonly language: string;
|
|
190
|
+
readonly cwd: string;
|
|
191
|
+
constructor(id: string, language?: string, cwd?: string);
|
|
76
192
|
toJSON(): Record<string, unknown>;
|
|
77
193
|
}
|
|
78
194
|
/** Sandbox specialized for running Python code. */
|
|
@@ -82,19 +198,28 @@ export declare class Sandbox extends BaseSandbox {
|
|
|
82
198
|
static create(template: string, opts?: SandboxCreateOpts): Promise<Sandbox>;
|
|
83
199
|
static connect(sandboxId: string, opts?: SandboxConnectOpts): Promise<Sandbox>;
|
|
84
200
|
/** Run Python code in the sandbox and return structured execution output. */
|
|
85
|
-
runCode(code: string, opts?: RunCodeOpts
|
|
201
|
+
runCode(code: string, opts?: RunCodeOpts & {
|
|
202
|
+
language?: RunCodeLanguage;
|
|
203
|
+
}): Promise<Execution>;
|
|
204
|
+
runCode(code: string, opts?: RunCodeOpts & {
|
|
205
|
+
context?: Context | string;
|
|
206
|
+
}): Promise<Execution>;
|
|
86
207
|
/** Create a persistent code context. */
|
|
87
|
-
createCodeContext(
|
|
208
|
+
createCodeContext(opts?: CreateCodeContextOpts): Promise<Context>;
|
|
88
209
|
/** Remove a persistent code context. */
|
|
89
210
|
removeCodeContext(context: Context | string, opts?: {
|
|
90
211
|
requestTimeoutMs?: number;
|
|
212
|
+
signal?: AbortSignal;
|
|
91
213
|
}): Promise<void>;
|
|
92
214
|
/** List persistent code contexts. */
|
|
93
215
|
listCodeContexts(opts?: {
|
|
94
216
|
requestTimeoutMs?: number;
|
|
217
|
+
signal?: AbortSignal;
|
|
95
218
|
}): Promise<Context[]>;
|
|
96
219
|
/** Restart a persistent code context. */
|
|
97
220
|
restartCodeContext(context: Context | string, opts?: {
|
|
98
221
|
requestTimeoutMs?: number;
|
|
222
|
+
signal?: AbortSignal;
|
|
99
223
|
}): Promise<void>;
|
|
100
224
|
}
|
|
225
|
+
export { Sandbox as default };
|
package/dist/codeInterpreter.js
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
import { InvalidArgumentError } from './errors.js';
|
|
2
2
|
import { Sandbox as BaseSandbox } from './sandbox.js';
|
|
3
|
+
export { ApiError, AuthenticationError, BuildError, ConflictError, FileNotFoundError, FileUploadError, GitAuthError, GitUpstreamError, InvalidArgumentError, NotEnoughSpaceError, NotFoundError, NotImplementedError, RateLimitError, SandboxError, SandboxNotFoundError, TemplateError, TimeoutError, VolumeError, } from './errors.js';
|
|
4
|
+
export { ConnectionConfig, KEEPALIVE_PING_INTERVAL_SEC } from './connectionConfig.js';
|
|
5
|
+
export { ControlClient as ApiClient } from './transport.js';
|
|
6
|
+
export { ALL_TRAFFIC, SandboxPaginator, SnapshotPaginator, getSignature, } from './sandbox.js';
|
|
7
|
+
export { CommandExitError, CommandHandle, Commands } from './commands.js';
|
|
8
|
+
export { Process, ProcessManager, ProcessMessage, ProcessOutput } from './process.js';
|
|
9
|
+
export { FileType, Filesystem, FilesystemEventType, FilesystemWatcher, WatchHandle, } from './filesystem.js';
|
|
10
|
+
export { Git } from './git.js';
|
|
11
|
+
export { Pty } from './pty.js';
|
|
12
|
+
export { Terminal, TerminalManager, TerminalOutput } from './terminal.js';
|
|
13
|
+
export { Volume, VolumeConnectionConfig, VolumeFileType } from './volume.js';
|
|
14
|
+
export { ProcessSocket, base64DecodeBytes, base64DecodeText, base64Encode } from './processSocket.js';
|
|
15
|
+
export { ReadyCmd, Template, TemplateBase, LogEntry, LogEntryEnd, LogEntryStart, defaultBuildLogger, waitForFile, waitForPort, waitForProcess, waitForTimeout, waitForURL, } from './template.js';
|
|
16
|
+
/** Chart types returned by code execution results. */
|
|
17
|
+
export var ChartType;
|
|
18
|
+
(function (ChartType) {
|
|
19
|
+
ChartType["LINE"] = "line";
|
|
20
|
+
ChartType["SCATTER"] = "scatter";
|
|
21
|
+
ChartType["BAR"] = "bar";
|
|
22
|
+
ChartType["PIE"] = "pie";
|
|
23
|
+
ChartType["BOX_AND_WHISKER"] = "box_and_whisker";
|
|
24
|
+
ChartType["SUPERCHART"] = "superchart";
|
|
25
|
+
ChartType["UNKNOWN"] = "unknown";
|
|
26
|
+
})(ChartType || (ChartType = {}));
|
|
27
|
+
/** Axis scale types returned by chart results. */
|
|
28
|
+
export var ScaleType;
|
|
29
|
+
(function (ScaleType) {
|
|
30
|
+
ScaleType["LINEAR"] = "linear";
|
|
31
|
+
ScaleType["DATETIME"] = "datetime";
|
|
32
|
+
ScaleType["CATEGORICAL"] = "categorical";
|
|
33
|
+
ScaleType["LOG"] = "log";
|
|
34
|
+
ScaleType["SYMLOG"] = "symlog";
|
|
35
|
+
ScaleType["LOGIT"] = "logit";
|
|
36
|
+
ScaleType["FUNCTION"] = "function";
|
|
37
|
+
ScaleType["FUNCTIONLOG"] = "functionlog";
|
|
38
|
+
ScaleType["ASINH"] = "asinh";
|
|
39
|
+
})(ScaleType || (ScaleType = {}));
|
|
3
40
|
/** One stdout or stderr line emitted by code execution. */
|
|
4
41
|
export class OutputMessage {
|
|
5
42
|
line;
|
|
@@ -41,6 +78,7 @@ export class ExecutionError {
|
|
|
41
78
|
}
|
|
42
79
|
/** Rich result produced by the last expression of a code execution. */
|
|
43
80
|
export class Result {
|
|
81
|
+
raw;
|
|
44
82
|
text;
|
|
45
83
|
html;
|
|
46
84
|
markdown;
|
|
@@ -55,7 +93,8 @@ export class Result {
|
|
|
55
93
|
chart;
|
|
56
94
|
extra;
|
|
57
95
|
isMainResult;
|
|
58
|
-
constructor(payload = {}) {
|
|
96
|
+
constructor(payload = {}, isMainResult) {
|
|
97
|
+
this.raw = payload;
|
|
59
98
|
this.text = stringValue(payload.text);
|
|
60
99
|
this.html = stringValue(payload.html);
|
|
61
100
|
this.markdown = stringValue(payload.markdown);
|
|
@@ -66,14 +105,16 @@ export class Result {
|
|
|
66
105
|
this.latex = stringValue(payload.latex);
|
|
67
106
|
this.json = payload.json;
|
|
68
107
|
this.javascript = stringValue(payload.javascript);
|
|
69
|
-
this.data = payload.data;
|
|
70
|
-
this.chart = payload.chart;
|
|
108
|
+
this.data = recordOrUndefined(payload.data);
|
|
109
|
+
this.chart = chartFromApi(payload.chart);
|
|
71
110
|
this.extra = record(payload.extra);
|
|
72
|
-
this.isMainResult = Boolean(payload.is_main_result ?? payload.isMainResult);
|
|
111
|
+
this.isMainResult = Boolean(isMainResult ?? payload.is_main_result ?? payload.isMainResult);
|
|
73
112
|
}
|
|
74
113
|
formats() {
|
|
75
114
|
const names = ['text', 'html', 'markdown', 'svg', 'png', 'jpeg', 'pdf', 'latex', 'json', 'javascript', 'data', 'chart'];
|
|
76
|
-
|
|
115
|
+
const formats = names.filter((name) => this[name] !== undefined);
|
|
116
|
+
formats.push(...Object.keys(this.extra));
|
|
117
|
+
return formats;
|
|
77
118
|
}
|
|
78
119
|
toJSON() {
|
|
79
120
|
return compactRecord({
|
|
@@ -127,7 +168,7 @@ export class Context {
|
|
|
127
168
|
id;
|
|
128
169
|
language;
|
|
129
170
|
cwd;
|
|
130
|
-
constructor(id, language, cwd) {
|
|
171
|
+
constructor(id, language = '', cwd = '') {
|
|
131
172
|
this.id = id;
|
|
132
173
|
this.language = language;
|
|
133
174
|
this.cwd = cwd;
|
|
@@ -149,7 +190,6 @@ export class Sandbox extends BaseSandbox {
|
|
|
149
190
|
static async connect(sandboxId, opts = {}) {
|
|
150
191
|
return await super.connect(sandboxId, opts);
|
|
151
192
|
}
|
|
152
|
-
/** Run Python code in the sandbox and return structured execution output. */
|
|
153
193
|
async runCode(code, opts = {}) {
|
|
154
194
|
if (typeof code !== 'string')
|
|
155
195
|
throw new InvalidArgumentError('code must be a string');
|
|
@@ -161,22 +201,24 @@ export class Sandbox extends BaseSandbox {
|
|
|
161
201
|
language: opts.language,
|
|
162
202
|
context_id: contextId(opts.context),
|
|
163
203
|
env_vars: opts.envs,
|
|
164
|
-
|
|
204
|
+
timeout_ms: opts.timeoutMs,
|
|
165
205
|
});
|
|
166
206
|
const response = await this.runtimePostJson('/runtime/v1/code/run', payload, {
|
|
167
207
|
requestTimeoutMs: opts.requestTimeoutMs,
|
|
208
|
+
signal: opts.signal,
|
|
168
209
|
});
|
|
169
210
|
const execution = executionFromApi(response);
|
|
170
|
-
emitCallbacks(execution, opts);
|
|
211
|
+
await emitCallbacks(execution, opts);
|
|
171
212
|
return execution;
|
|
172
213
|
}
|
|
173
214
|
/** Create a persistent code context. */
|
|
174
|
-
async createCodeContext(
|
|
215
|
+
async createCodeContext(opts = {}) {
|
|
175
216
|
const response = await this.runtimePostJson('/runtime/v1/code/contexts', compactRecord({
|
|
176
|
-
cwd:
|
|
177
|
-
language:
|
|
217
|
+
cwd: opts.cwd,
|
|
218
|
+
language: opts.language,
|
|
178
219
|
}), {
|
|
179
|
-
requestTimeoutMs:
|
|
220
|
+
requestTimeoutMs: opts.requestTimeoutMs,
|
|
221
|
+
signal: opts.signal,
|
|
180
222
|
});
|
|
181
223
|
return contextFromApi(response);
|
|
182
224
|
}
|
|
@@ -184,12 +226,14 @@ export class Sandbox extends BaseSandbox {
|
|
|
184
226
|
async removeCodeContext(context, opts = {}) {
|
|
185
227
|
await this.runtimeDeleteJson(`/runtime/v1/code/contexts/${encodeURIComponent(requireContextId(context))}`, {
|
|
186
228
|
requestTimeoutMs: opts.requestTimeoutMs,
|
|
229
|
+
signal: opts.signal,
|
|
187
230
|
});
|
|
188
231
|
}
|
|
189
232
|
/** List persistent code contexts. */
|
|
190
233
|
async listCodeContexts(opts = {}) {
|
|
191
234
|
const response = await this.runtimeGetJson('/runtime/v1/code/contexts', {
|
|
192
235
|
requestTimeoutMs: opts.requestTimeoutMs,
|
|
236
|
+
signal: opts.signal,
|
|
193
237
|
});
|
|
194
238
|
const contexts = Array.isArray(response) ? response : arrayOfUnknown(response.contexts);
|
|
195
239
|
return contexts.map((item) => contextFromApi(record(item)));
|
|
@@ -198,9 +242,11 @@ export class Sandbox extends BaseSandbox {
|
|
|
198
242
|
async restartCodeContext(context, opts = {}) {
|
|
199
243
|
await this.runtimePostJson(`/runtime/v1/code/contexts/${encodeURIComponent(requireContextId(context))}/restart`, {}, {
|
|
200
244
|
requestTimeoutMs: opts.requestTimeoutMs,
|
|
245
|
+
signal: opts.signal,
|
|
201
246
|
});
|
|
202
247
|
}
|
|
203
248
|
}
|
|
249
|
+
export { Sandbox as default };
|
|
204
250
|
function executionFromApi(payload) {
|
|
205
251
|
const execution = record(payload.execution ?? payload);
|
|
206
252
|
const logs = record(execution.logs);
|
|
@@ -222,15 +268,15 @@ function executionErrorFromApi(value) {
|
|
|
222
268
|
const item = value;
|
|
223
269
|
return new ExecutionError(String(item.name ?? ''), String(item.value ?? ''), String(item.traceback ?? ''));
|
|
224
270
|
}
|
|
225
|
-
function emitCallbacks(execution, opts) {
|
|
271
|
+
async function emitCallbacks(execution, opts) {
|
|
226
272
|
for (const message of execution.logs.stdout)
|
|
227
|
-
opts.onStdout?.(message);
|
|
273
|
+
await opts.onStdout?.(message);
|
|
228
274
|
for (const message of execution.logs.stderr)
|
|
229
|
-
opts.onStderr?.(message);
|
|
275
|
+
await opts.onStderr?.(message);
|
|
230
276
|
for (const result of execution.results)
|
|
231
|
-
opts.onResult?.(result);
|
|
277
|
+
await opts.onResult?.(result);
|
|
232
278
|
if (execution.error !== undefined)
|
|
233
|
-
opts.onError?.(execution.error);
|
|
279
|
+
await opts.onError?.(execution.error);
|
|
234
280
|
}
|
|
235
281
|
function contextId(context) {
|
|
236
282
|
if (context === undefined)
|
|
@@ -243,7 +289,7 @@ function requireContextId(context) {
|
|
|
243
289
|
return context.id;
|
|
244
290
|
}
|
|
245
291
|
function contextFromApi(payload) {
|
|
246
|
-
return new Context(String(payload.id ?? ''), stringValue(payload.language), stringValue(payload.cwd));
|
|
292
|
+
return new Context(String(payload.id ?? ''), stringValue(payload.language) ?? '', stringValue(payload.cwd) ?? '');
|
|
247
293
|
}
|
|
248
294
|
function compactRecord(payload) {
|
|
249
295
|
return Object.fromEntries(Object.entries(payload).filter(([, value]) => value !== undefined));
|
|
@@ -251,6 +297,15 @@ function compactRecord(payload) {
|
|
|
251
297
|
function record(value) {
|
|
252
298
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
253
299
|
}
|
|
300
|
+
function recordOrUndefined(value) {
|
|
301
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
|
|
302
|
+
}
|
|
303
|
+
function chartFromApi(value) {
|
|
304
|
+
const item = recordOrUndefined(value);
|
|
305
|
+
if (item === undefined)
|
|
306
|
+
return undefined;
|
|
307
|
+
return item;
|
|
308
|
+
}
|
|
254
309
|
function arrayOfRecords(value) {
|
|
255
310
|
return Array.isArray(value) ? value.map((item) => record(item)) : [];
|
|
256
311
|
}
|
package/dist/commands.d.ts
CHANGED
|
@@ -34,23 +34,27 @@ export interface CommandStartOpts {
|
|
|
34
34
|
/** Arguments for `cmd` when starting a direct executable. */
|
|
35
35
|
args?: string[];
|
|
36
36
|
cwd?: string;
|
|
37
|
-
/** Deprecated alias for `cwd`. */
|
|
38
|
-
rootDir?: string;
|
|
39
37
|
user?: string;
|
|
40
38
|
envs?: Record<string, string>;
|
|
41
|
-
/** Alias for `envs`. */
|
|
42
|
-
envVars?: Record<string, string>;
|
|
43
39
|
onStdout?: (data: string) => void | Promise<void>;
|
|
44
40
|
onStderr?: (data: string) => void | Promise<void>;
|
|
45
41
|
onPty?: (data: Uint8Array) => void | Promise<void>;
|
|
46
42
|
onExit?: (exitCode: number) => void | Promise<void>;
|
|
47
43
|
stdin?: boolean;
|
|
48
44
|
timeoutMs?: number;
|
|
49
|
-
/** Alias for `timeoutMs`. */
|
|
50
|
-
timeout?: number;
|
|
51
45
|
processID?: string;
|
|
52
46
|
requestTimeoutMs?: number;
|
|
47
|
+
signal?: AbortSignal;
|
|
53
48
|
}
|
|
49
|
+
export type CommandRequestOpts = Pick<CommandStartOpts, 'requestTimeoutMs' | 'signal'>;
|
|
50
|
+
export interface CommandConnectOpts extends CommandRequestOpts {
|
|
51
|
+
timeoutMs?: number;
|
|
52
|
+
onStdout?: (data: string) => void | Promise<void>;
|
|
53
|
+
onStderr?: (data: string) => void | Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
export type Stdout = string;
|
|
56
|
+
export type Stderr = string;
|
|
57
|
+
export type PtyOutput = Uint8Array;
|
|
54
58
|
/** Live handle for one sandbox process stream. */
|
|
55
59
|
export declare class CommandHandle implements Partial<CommandResult> {
|
|
56
60
|
readonly pid: number | string;
|
|
@@ -75,9 +79,9 @@ export declare class CommandHandle implements Partial<CommandResult> {
|
|
|
75
79
|
/** Kill the process. */
|
|
76
80
|
kill(): Promise<boolean>;
|
|
77
81
|
/** Send stdin bytes or text to the process. */
|
|
78
|
-
sendStdin(data: string | Uint8Array): Promise<void>;
|
|
82
|
+
sendStdin(data: string | Uint8Array, opts?: CommandRequestOpts): Promise<void>;
|
|
79
83
|
/** Close the stdin stream and signal EOF to the process. */
|
|
80
|
-
closeStdin(): Promise<void>;
|
|
84
|
+
closeStdin(opts?: CommandRequestOpts): Promise<void>;
|
|
81
85
|
/** Resize the attached PTY stream when this handle was created as a PTY. */
|
|
82
86
|
resize(size: {
|
|
83
87
|
cols: number;
|
|
@@ -98,18 +102,22 @@ export declare class Commands {
|
|
|
98
102
|
/** List processes currently known by the sandbox runtime. */
|
|
99
103
|
list(opts?: {
|
|
100
104
|
requestTimeoutMs?: number;
|
|
105
|
+
signal?: AbortSignal;
|
|
101
106
|
}): Promise<ProcessInfo[]>;
|
|
102
107
|
/** Send SIGKILL to a process by pid. */
|
|
103
108
|
kill(pid: number | string, opts?: {
|
|
104
109
|
requestTimeoutMs?: number;
|
|
110
|
+
signal?: AbortSignal;
|
|
105
111
|
}): Promise<boolean>;
|
|
106
112
|
/** Attach to a process and send stdin bytes or text. */
|
|
107
113
|
sendStdin(pid: number | string, data: string | Uint8Array, opts?: {
|
|
108
114
|
requestTimeoutMs?: number;
|
|
115
|
+
signal?: AbortSignal;
|
|
109
116
|
}): Promise<void>;
|
|
110
117
|
/** Attach to a process and close stdin, signalling EOF. */
|
|
111
118
|
closeStdin(pid: number | string, opts?: {
|
|
112
119
|
requestTimeoutMs?: number;
|
|
120
|
+
signal?: AbortSignal;
|
|
113
121
|
}): Promise<void>;
|
|
114
122
|
run(cmd: string, opts: CommandStartOpts & {
|
|
115
123
|
background: true;
|
package/dist/commands.js
CHANGED
|
@@ -56,16 +56,16 @@ export class CommandHandle {
|
|
|
56
56
|
return this.handleKill();
|
|
57
57
|
}
|
|
58
58
|
/** Send stdin bytes or text to the process. */
|
|
59
|
-
async sendStdin(data) {
|
|
60
|
-
this.socket.sendStdin(data);
|
|
59
|
+
async sendStdin(data, opts = {}) {
|
|
60
|
+
await this.socket.sendStdin(data, opts);
|
|
61
61
|
}
|
|
62
62
|
/** Close the stdin stream and signal EOF to the process. */
|
|
63
|
-
async closeStdin() {
|
|
64
|
-
this.socket.closeStdin();
|
|
63
|
+
async closeStdin(opts = {}) {
|
|
64
|
+
await this.socket.closeStdin(opts);
|
|
65
65
|
}
|
|
66
66
|
/** Resize the attached PTY stream when this handle was created as a PTY. */
|
|
67
67
|
async resize(size) {
|
|
68
|
-
this.socket.sendJson({ type: 'resize', cols: size.cols, rows: size.rows });
|
|
68
|
+
await this.socket.sendJson({ type: 'resize', cols: size.cols, rows: size.rows });
|
|
69
69
|
}
|
|
70
70
|
/** Detach the local stream without killing the process. */
|
|
71
71
|
async disconnect() {
|
|
@@ -146,7 +146,7 @@ export class Commands {
|
|
|
146
146
|
async sendStdin(pid, data, opts = {}) {
|
|
147
147
|
const handle = await this.connect(pid, opts);
|
|
148
148
|
try {
|
|
149
|
-
await handle.sendStdin(data);
|
|
149
|
+
await handle.sendStdin(data, opts);
|
|
150
150
|
}
|
|
151
151
|
finally {
|
|
152
152
|
await handle.disconnect();
|
|
@@ -156,7 +156,7 @@ export class Commands {
|
|
|
156
156
|
async closeStdin(pid, opts = {}) {
|
|
157
157
|
const handle = await this.connect(pid, opts);
|
|
158
158
|
try {
|
|
159
|
-
await handle.closeStdin();
|
|
159
|
+
await handle.closeStdin(opts);
|
|
160
160
|
}
|
|
161
161
|
finally {
|
|
162
162
|
await handle.disconnect();
|
|
@@ -167,31 +167,31 @@ export class Commands {
|
|
|
167
167
|
const handle = await this.start(cmd, opts);
|
|
168
168
|
if (opts.background)
|
|
169
169
|
return handle;
|
|
170
|
-
return handle.wait(opts.timeoutMs
|
|
170
|
+
return handle.wait(opts.timeoutMs);
|
|
171
171
|
}
|
|
172
172
|
/** Reconnect to a live process stream by pid. */
|
|
173
173
|
async connect(pid, opts = {}) {
|
|
174
|
-
const socket = await new ProcessSocket(this.dataPlane.baseUrl, this.dataPlane.token, `/runtime/v1/process/${pid}/connect?since=0`, opts.requestTimeoutMs ?? this.config.requestTimeoutMs).connect();
|
|
174
|
+
const socket = await new ProcessSocket(this.dataPlane.baseUrl, this.dataPlane.token, `/runtime/v1/process/${pid}/connect?since=0`, opts.requestTimeoutMs ?? this.config.requestTimeoutMs, this.config.headers).connect();
|
|
175
175
|
const first = await nextStarted(socket);
|
|
176
176
|
const actualPid = framePid(first) ?? pid;
|
|
177
177
|
return new CommandHandle(actualPid, socket, () => this.kill(actualPid), socket, opts.onStdout, opts.onStderr, opts.onPty);
|
|
178
178
|
}
|
|
179
179
|
/** Start a command and return a live handle immediately. */
|
|
180
180
|
async start(cmd, opts = {}) {
|
|
181
|
-
const socket = await new ProcessSocket(this.dataPlane.baseUrl, this.dataPlane.token, '/runtime/v1/process', opts.requestTimeoutMs ?? this.config.requestTimeoutMs).connect();
|
|
182
|
-
const environment = { ...this.sandboxEnvs, ...(opts.
|
|
181
|
+
const socket = await new ProcessSocket(this.dataPlane.baseUrl, this.dataPlane.token, '/runtime/v1/process', opts.requestTimeoutMs ?? this.config.requestTimeoutMs, this.config.headers).connect();
|
|
182
|
+
const environment = { ...this.sandboxEnvs, ...(opts.envs ?? {}) };
|
|
183
183
|
const processConfig = processStartConfig(cmd, opts);
|
|
184
|
-
socket.sendJson({
|
|
184
|
+
await socket.sendJson({
|
|
185
185
|
type: 'start',
|
|
186
186
|
id: opts.processID,
|
|
187
187
|
cmd: processConfig.cmd,
|
|
188
188
|
args: processConfig.args,
|
|
189
|
-
cwd: opts.cwd
|
|
189
|
+
cwd: opts.cwd,
|
|
190
190
|
user: opts.user,
|
|
191
191
|
environment,
|
|
192
192
|
envs: environment,
|
|
193
193
|
stdin: opts.stdin ?? false,
|
|
194
|
-
timeout_ms: opts.timeoutMs ??
|
|
194
|
+
timeout_ms: opts.timeoutMs ?? 60_000,
|
|
195
195
|
});
|
|
196
196
|
const first = await nextStarted(socket);
|
|
197
197
|
const pid = framePid(first);
|
|
@@ -233,10 +233,11 @@ function framePid(frame) {
|
|
|
233
233
|
function processInfo(value) {
|
|
234
234
|
const item = value && typeof value === 'object' ? value : {};
|
|
235
235
|
const process = item.process && typeof item.process === 'object' ? item.process : item;
|
|
236
|
+
const stablePid = typeof process.id === 'number' || typeof process.id === 'string' ? process.id : framePid(process);
|
|
236
237
|
return {
|
|
237
|
-
pid:
|
|
238
|
+
pid: stablePid ?? '',
|
|
238
239
|
tag: typeof process.tag === 'string' ? process.tag : undefined,
|
|
239
|
-
cmd: typeof process.cmd === 'string' ? process.cmd : undefined,
|
|
240
|
+
cmd: typeof process.cmd === 'string' ? process.cmd : typeof process.command === 'string' ? process.command : undefined,
|
|
240
241
|
args: Array.isArray(process.args) ? process.args.map(String) : [],
|
|
241
242
|
envs: recordOfStrings(process.envs ?? process.environment),
|
|
242
243
|
cwd: typeof process.cwd === 'string' ? process.cwd : undefined,
|