@langchain/modal 0.0.1
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 +344 -0
- package/dist/index.cjs +636 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +514 -0
- package/dist/index.d.ts +514 -0
- package/dist/index.js +633 -0
- package/dist/index.js.map +1 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
import { ModalClient, Sandbox, SandboxCreateParams } from "modal";
|
|
2
|
+
import { BaseSandbox, ExecuteResponse, FileDownloadResponse, FileUploadResponse } from "deepagents";
|
|
3
|
+
|
|
4
|
+
//#region src/types.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Fields from SandboxCreateParams that we wrap with a different API:
|
|
7
|
+
* - `volumes` -> we accept volume names (strings), SDK needs Volume objects
|
|
8
|
+
* - `secrets` -> we accept secret names (strings), SDK needs Secret objects
|
|
9
|
+
*
|
|
10
|
+
* Fields not exposed yet:
|
|
11
|
+
* - `cloudBucketMounts`, `proxy`, `experimentalOptions`, `customDomain`
|
|
12
|
+
* - `command`, `pty`, `encryptedPorts`, `h2Ports`, `unencryptedPorts`, `cloud`
|
|
13
|
+
*/
|
|
14
|
+
type WrappedSdkFields = "secrets" | "volumes" | "cloudBucketMounts" | "proxy" | "experimentalOptions" | "customDomain" | "command" | "pty" | "encryptedPorts" | "h2Ports" | "unencryptedPorts" | "cloud";
|
|
15
|
+
/**
|
|
16
|
+
* SDK options that pass through directly.
|
|
17
|
+
*/
|
|
18
|
+
type BaseSdkOptions = Omit<SandboxCreateParams, WrappedSdkFields>;
|
|
19
|
+
/**
|
|
20
|
+
* Configuration options for creating a Modal Sandbox.
|
|
21
|
+
*
|
|
22
|
+
* Extends the Modal SDK's SandboxCreateParams with additional options
|
|
23
|
+
* for app/image configuration and a simplified volumes/secrets API.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const options: ModalSandboxOptions = {
|
|
28
|
+
* appName: "my-sandbox-app",
|
|
29
|
+
* imageName: "python:3.12-slim",
|
|
30
|
+
* timeoutMs: 600_000, // 10 minutes
|
|
31
|
+
* memoryMiB: 2048, // 2GB
|
|
32
|
+
* initialFiles: {
|
|
33
|
+
* "/app/index.js": "console.log('Hello')",
|
|
34
|
+
* },
|
|
35
|
+
* };
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
interface ModalSandboxOptions extends BaseSdkOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Name of the Modal App to associate the sandbox with.
|
|
41
|
+
* If not provided, a default app name will be used.
|
|
42
|
+
* The app will be created if it doesn't exist.
|
|
43
|
+
*
|
|
44
|
+
* @default "deepagents-sandbox"
|
|
45
|
+
*/
|
|
46
|
+
appName?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Docker image to use for the sandbox container.
|
|
49
|
+
* Can be any public Docker image or a Modal Image reference.
|
|
50
|
+
*
|
|
51
|
+
* @default "alpine:3.21"
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* // Use Python image
|
|
56
|
+
* imageName: "python:3.12-slim"
|
|
57
|
+
*
|
|
58
|
+
* // Use Node.js image
|
|
59
|
+
* imageName: "node:20-slim"
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
imageName?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Modal Volume names to mount, mapped to their mount paths.
|
|
65
|
+
* Volumes must be created beforehand in Modal.
|
|
66
|
+
*
|
|
67
|
+
* Unlike the SDK which requires Volume objects, we accept volume names
|
|
68
|
+
* and look them up automatically.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* volumes: {
|
|
73
|
+
* "/data": "my-data-volume",
|
|
74
|
+
* "/cache": "my-cache-volume"
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
volumes?: Record<string, string>;
|
|
79
|
+
/**
|
|
80
|
+
* Modal Secret names to inject into the sandbox environment.
|
|
81
|
+
* Secrets must be created beforehand in Modal.
|
|
82
|
+
*
|
|
83
|
+
* Unlike the SDK which requires Secret objects, we accept secret names
|
|
84
|
+
* and look them up automatically.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* secrets: ["my-api-keys", "database-credentials"]
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
secrets?: string[];
|
|
92
|
+
/**
|
|
93
|
+
* Initial files to populate the sandbox with.
|
|
94
|
+
*
|
|
95
|
+
* Keys are file paths (relative to the working directory), values are file contents.
|
|
96
|
+
* Parent directories will be created automatically if they don't exist.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* initialFiles: {
|
|
101
|
+
* "/src/index.js": "console.log('Hello')",
|
|
102
|
+
* "/package.json": '{"name": "my-app"}',
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
initialFiles?: Record<string, string | Uint8Array>;
|
|
107
|
+
/**
|
|
108
|
+
* Authentication configuration for Modal API.
|
|
109
|
+
*
|
|
110
|
+
* ### Environment Variable Setup
|
|
111
|
+
*
|
|
112
|
+
* ```bash
|
|
113
|
+
* # Create a token at https://modal.com/settings/tokens
|
|
114
|
+
* export MODAL_TOKEN_ID=your_token_id
|
|
115
|
+
* export MODAL_TOKEN_SECRET=your_token_secret
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* Or pass the credentials directly in this auth configuration.
|
|
119
|
+
*/
|
|
120
|
+
auth?: {
|
|
121
|
+
/**
|
|
122
|
+
* Modal token ID.
|
|
123
|
+
* If not provided, reads from `MODAL_TOKEN_ID` environment variable.
|
|
124
|
+
*/
|
|
125
|
+
tokenId?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Modal token secret.
|
|
128
|
+
* If not provided, reads from `MODAL_TOKEN_SECRET` environment variable.
|
|
129
|
+
*/
|
|
130
|
+
tokenSecret?: string;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Error codes for Modal Sandbox operations.
|
|
135
|
+
*
|
|
136
|
+
* Used to identify specific error conditions and handle them appropriately.
|
|
137
|
+
*/
|
|
138
|
+
type ModalSandboxErrorCode = /** Sandbox has not been initialized - call initialize() first */"NOT_INITIALIZED" /** Sandbox is already initialized - cannot initialize twice */ | "ALREADY_INITIALIZED" /** Authentication failed - check token configuration */ | "AUTHENTICATION_FAILED" /** Failed to create sandbox - check options and quotas */ | "SANDBOX_CREATION_FAILED" /** Sandbox not found - may have been stopped or expired */ | "SANDBOX_NOT_FOUND" /** Command execution timed out */ | "COMMAND_TIMEOUT" /** Command execution failed */ | "COMMAND_FAILED" /** File operation (read/write) failed */ | "FILE_OPERATION_FAILED" /** Resource limits exceeded (CPU, memory, storage) */ | "RESOURCE_LIMIT_EXCEEDED" /** Volume operation failed */ | "VOLUME_ERROR";
|
|
139
|
+
declare const MODAL_SANDBOX_ERROR_SYMBOL: unique symbol;
|
|
140
|
+
/**
|
|
141
|
+
* Custom error class for Modal Sandbox operations.
|
|
142
|
+
*
|
|
143
|
+
* Provides structured error information including:
|
|
144
|
+
* - Human-readable message
|
|
145
|
+
* - Error code for programmatic handling
|
|
146
|
+
* - Original cause for debugging
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* try {
|
|
151
|
+
* await sandbox.execute("some command");
|
|
152
|
+
* } catch (error) {
|
|
153
|
+
* if (error instanceof ModalSandboxError) {
|
|
154
|
+
* switch (error.code) {
|
|
155
|
+
* case "NOT_INITIALIZED":
|
|
156
|
+
* await sandbox.initialize();
|
|
157
|
+
* break;
|
|
158
|
+
* case "COMMAND_TIMEOUT":
|
|
159
|
+
* console.error("Command took too long");
|
|
160
|
+
* break;
|
|
161
|
+
* default:
|
|
162
|
+
* throw error;
|
|
163
|
+
* }
|
|
164
|
+
* }
|
|
165
|
+
* }
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
declare class ModalSandboxError extends Error {
|
|
169
|
+
readonly code: ModalSandboxErrorCode;
|
|
170
|
+
readonly cause?: Error | undefined;
|
|
171
|
+
[MODAL_SANDBOX_ERROR_SYMBOL]: true;
|
|
172
|
+
/** Error name for instanceof checks and logging */
|
|
173
|
+
readonly name = "ModalSandboxError";
|
|
174
|
+
/**
|
|
175
|
+
* Creates a new ModalSandboxError.
|
|
176
|
+
*
|
|
177
|
+
* @param message - Human-readable error description
|
|
178
|
+
* @param code - Structured error code for programmatic handling
|
|
179
|
+
* @param cause - Original error that caused this error (for debugging)
|
|
180
|
+
*/
|
|
181
|
+
constructor(message: string, code: ModalSandboxErrorCode, cause?: Error | undefined);
|
|
182
|
+
/**
|
|
183
|
+
* Checks if the error is an instance of ModalSandboxError.
|
|
184
|
+
*
|
|
185
|
+
* @param error - The error to check
|
|
186
|
+
* @returns True if the error is an instance of ModalSandboxError, false otherwise
|
|
187
|
+
*/
|
|
188
|
+
static isInstance(error: unknown): error is ModalSandboxError;
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/sandbox.d.ts
|
|
192
|
+
/**
|
|
193
|
+
* Modal Sandbox backend for deepagents.
|
|
194
|
+
*
|
|
195
|
+
* Extends `BaseSandbox` to provide command execution, file operations, and
|
|
196
|
+
* sandbox lifecycle management using Modal's serverless infrastructure.
|
|
197
|
+
*
|
|
198
|
+
* ## Basic Usage
|
|
199
|
+
*
|
|
200
|
+
* ```typescript
|
|
201
|
+
* import { ModalSandbox } from "@langchain/modal";
|
|
202
|
+
*
|
|
203
|
+
* // Create and initialize a sandbox
|
|
204
|
+
* const sandbox = await ModalSandbox.create({
|
|
205
|
+
* imageName: "python:3.12-slim",
|
|
206
|
+
* timeout: 600,
|
|
207
|
+
* });
|
|
208
|
+
*
|
|
209
|
+
* try {
|
|
210
|
+
* // Execute commands
|
|
211
|
+
* const result = await sandbox.execute("python --version");
|
|
212
|
+
* console.log(result.output);
|
|
213
|
+
* } finally {
|
|
214
|
+
* // Always cleanup
|
|
215
|
+
* await sandbox.close();
|
|
216
|
+
* }
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* ## Using with DeepAgent
|
|
220
|
+
*
|
|
221
|
+
* ```typescript
|
|
222
|
+
* import { createDeepAgent } from "deepagents";
|
|
223
|
+
* import { ModalSandbox } from "@langchain/modal";
|
|
224
|
+
*
|
|
225
|
+
* const sandbox = await ModalSandbox.create();
|
|
226
|
+
*
|
|
227
|
+
* const agent = createDeepAgent({
|
|
228
|
+
* model: new ChatAnthropic({ model: "claude-sonnet-4-20250514" }),
|
|
229
|
+
* systemPrompt: "You are a coding assistant with sandbox access.",
|
|
230
|
+
* backend: sandbox,
|
|
231
|
+
* });
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
declare class ModalSandbox extends BaseSandbox {
|
|
235
|
+
#private;
|
|
236
|
+
/**
|
|
237
|
+
* Get the unique identifier for this sandbox.
|
|
238
|
+
*
|
|
239
|
+
* Before initialization, returns a temporary ID.
|
|
240
|
+
* After initialization, returns the actual Modal sandbox ID.
|
|
241
|
+
*/
|
|
242
|
+
get id(): string;
|
|
243
|
+
/**
|
|
244
|
+
* Get the underlying Modal Sandbox instance.
|
|
245
|
+
*
|
|
246
|
+
* @throws {ModalSandboxError} If the sandbox is not initialized
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```typescript
|
|
250
|
+
* const sandbox = await ModalSandbox.create();
|
|
251
|
+
* const modalInstance = sandbox.instance; // Access the raw Modal Sandbox
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
get instance(): Sandbox;
|
|
255
|
+
/**
|
|
256
|
+
* Get the underlying Modal client instance.
|
|
257
|
+
*
|
|
258
|
+
* @throws {ModalSandboxError} If the sandbox is not initialized
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* const sandbox = await ModalSandbox.create();
|
|
263
|
+
* const modalClient = sandbox.client; // Access the raw Modal client
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
get client(): ModalClient;
|
|
267
|
+
/**
|
|
268
|
+
* Check if the sandbox is initialized and running.
|
|
269
|
+
*/
|
|
270
|
+
get isRunning(): boolean;
|
|
271
|
+
/**
|
|
272
|
+
* Create a new ModalSandbox instance.
|
|
273
|
+
*
|
|
274
|
+
* Note: This only creates the instance. Call `initialize()` to actually
|
|
275
|
+
* create the Modal Sandbox, or use the static `ModalSandbox.create()` method.
|
|
276
|
+
*
|
|
277
|
+
* @param options - Configuration options for the sandbox
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```typescript
|
|
281
|
+
* // Two-step initialization
|
|
282
|
+
* const sandbox = new ModalSandbox({ imageName: "python:3.12-slim" });
|
|
283
|
+
* await sandbox.initialize();
|
|
284
|
+
*
|
|
285
|
+
* // Or use the factory method
|
|
286
|
+
* const sandbox = await ModalSandbox.create({ imageName: "python:3.12-slim" });
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
constructor(options?: ModalSandboxOptions);
|
|
290
|
+
/**
|
|
291
|
+
* Initialize the sandbox by creating a new Modal Sandbox instance.
|
|
292
|
+
*
|
|
293
|
+
* This method authenticates with Modal and provisions a new sandbox container.
|
|
294
|
+
* After initialization, the `id` property will reflect the actual Modal sandbox ID.
|
|
295
|
+
*
|
|
296
|
+
* @throws {ModalSandboxError} If already initialized (`ALREADY_INITIALIZED`)
|
|
297
|
+
* @throws {ModalSandboxError} If authentication fails (`AUTHENTICATION_FAILED`)
|
|
298
|
+
* @throws {ModalSandboxError} If sandbox creation fails (`SANDBOX_CREATION_FAILED`)
|
|
299
|
+
*
|
|
300
|
+
* @example
|
|
301
|
+
* ```typescript
|
|
302
|
+
* const sandbox = new ModalSandbox();
|
|
303
|
+
* await sandbox.initialize();
|
|
304
|
+
* console.log(`Sandbox ID: ${sandbox.id}`);
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
initialize(): Promise<void>;
|
|
308
|
+
/**
|
|
309
|
+
* Execute a command in the sandbox.
|
|
310
|
+
*
|
|
311
|
+
* Commands are run using bash -c to execute the command string.
|
|
312
|
+
*
|
|
313
|
+
* @param command - The shell command to execute
|
|
314
|
+
* @returns Execution result with output, exit code, and truncation flag
|
|
315
|
+
* @throws {ModalSandboxError} If the sandbox is not initialized
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* const result = await sandbox.execute("echo 'Hello World'");
|
|
320
|
+
* console.log(result.output); // "Hello World\n"
|
|
321
|
+
* console.log(result.exitCode); // 0
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
execute(command: string): Promise<ExecuteResponse>;
|
|
325
|
+
/**
|
|
326
|
+
* Upload files to the sandbox.
|
|
327
|
+
*
|
|
328
|
+
* Files are written to the sandbox filesystem using Modal's file API.
|
|
329
|
+
* Parent directories are created automatically if they don't exist.
|
|
330
|
+
*
|
|
331
|
+
* @param files - Array of [path, content] tuples to upload
|
|
332
|
+
* @returns Upload result for each file, with success or error status
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```typescript
|
|
336
|
+
* const encoder = new TextEncoder();
|
|
337
|
+
* const results = await sandbox.uploadFiles([
|
|
338
|
+
* ["src/index.js", encoder.encode("console.log('Hello')")],
|
|
339
|
+
* ["package.json", encoder.encode('{"name": "test"}')],
|
|
340
|
+
* ]);
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
uploadFiles(files: Array<[string, Uint8Array]>): Promise<FileUploadResponse[]>;
|
|
344
|
+
/**
|
|
345
|
+
* Download files from the sandbox.
|
|
346
|
+
*
|
|
347
|
+
* Each file is read individually using Modal's file API, allowing
|
|
348
|
+
* partial success when some files exist and others don't.
|
|
349
|
+
*
|
|
350
|
+
* @param paths - Array of file paths to download
|
|
351
|
+
* @returns Download result for each file, with content or error
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```typescript
|
|
355
|
+
* const results = await sandbox.downloadFiles(["src/index.js", "missing.txt"]);
|
|
356
|
+
* for (const result of results) {
|
|
357
|
+
* if (result.content) {
|
|
358
|
+
* console.log(new TextDecoder().decode(result.content));
|
|
359
|
+
* } else {
|
|
360
|
+
* console.error(`Error: ${result.error}`);
|
|
361
|
+
* }
|
|
362
|
+
* }
|
|
363
|
+
* ```
|
|
364
|
+
*/
|
|
365
|
+
downloadFiles(paths: string[]): Promise<FileDownloadResponse[]>;
|
|
366
|
+
/**
|
|
367
|
+
* Close the sandbox and release all resources.
|
|
368
|
+
*
|
|
369
|
+
* After closing, the sandbox cannot be used again. This terminates
|
|
370
|
+
* the sandbox container on Modal.
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```typescript
|
|
374
|
+
* try {
|
|
375
|
+
* await sandbox.execute("npm run build");
|
|
376
|
+
* } finally {
|
|
377
|
+
* await sandbox.close();
|
|
378
|
+
* }
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
close(): Promise<void>;
|
|
382
|
+
/**
|
|
383
|
+
* Terminate the sandbox.
|
|
384
|
+
*
|
|
385
|
+
* Alias for close() for Modal SDK compatibility.
|
|
386
|
+
*
|
|
387
|
+
* @example
|
|
388
|
+
* ```typescript
|
|
389
|
+
* await sandbox.terminate();
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
terminate(): Promise<void>;
|
|
393
|
+
/**
|
|
394
|
+
* Alias for close() to maintain compatibility with other sandbox implementations.
|
|
395
|
+
*/
|
|
396
|
+
stop(): Promise<void>;
|
|
397
|
+
/**
|
|
398
|
+
* Poll the sandbox status to check if it has finished running.
|
|
399
|
+
*
|
|
400
|
+
* @returns The exit code if the sandbox has finished, or null if still running
|
|
401
|
+
*/
|
|
402
|
+
poll(): Promise<number | null>;
|
|
403
|
+
/**
|
|
404
|
+
* Wait for the sandbox to finish running.
|
|
405
|
+
*
|
|
406
|
+
* @returns The exit code of the sandbox
|
|
407
|
+
* @throws {ModalSandboxError} If the sandbox is not initialized
|
|
408
|
+
*/
|
|
409
|
+
wait(): Promise<number>;
|
|
410
|
+
/**
|
|
411
|
+
* Create and initialize a new ModalSandbox in one step.
|
|
412
|
+
*
|
|
413
|
+
* This is the recommended way to create a sandbox. It combines
|
|
414
|
+
* construction and initialization into a single async operation.
|
|
415
|
+
*
|
|
416
|
+
* @param options - Configuration options for the sandbox
|
|
417
|
+
* @returns An initialized and ready-to-use sandbox
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```typescript
|
|
421
|
+
* const sandbox = await ModalSandbox.create({
|
|
422
|
+
* imageName: "python:3.12-slim",
|
|
423
|
+
* timeout: 600,
|
|
424
|
+
* memory: 2048,
|
|
425
|
+
* });
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
static create(options?: ModalSandboxOptions): Promise<ModalSandbox>;
|
|
429
|
+
/**
|
|
430
|
+
* Reconnect to an existing sandbox by ID.
|
|
431
|
+
*
|
|
432
|
+
* This allows you to resume working with a sandbox that was created
|
|
433
|
+
* earlier and is still running.
|
|
434
|
+
*
|
|
435
|
+
* @param sandboxId - The ID of the sandbox to reconnect to
|
|
436
|
+
* @param options - Optional auth configuration
|
|
437
|
+
* @returns A connected sandbox instance
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* ```typescript
|
|
441
|
+
* // Resume a sandbox from a stored ID
|
|
442
|
+
* const sandbox = await ModalSandbox.fromId("sb-abc123");
|
|
443
|
+
* const result = await sandbox.execute("ls -la");
|
|
444
|
+
* ```
|
|
445
|
+
*/
|
|
446
|
+
static fromId(sandboxId: string, options?: Pick<ModalSandboxOptions, "auth">): Promise<ModalSandbox>;
|
|
447
|
+
/**
|
|
448
|
+
* Get a running sandbox by name from a deployed app.
|
|
449
|
+
*
|
|
450
|
+
* @param appName - The name of the Modal app
|
|
451
|
+
* @param sandboxName - The name of the sandbox
|
|
452
|
+
* @param options - Optional auth configuration
|
|
453
|
+
* @returns A connected sandbox instance
|
|
454
|
+
*
|
|
455
|
+
* @example
|
|
456
|
+
* ```typescript
|
|
457
|
+
* const sandbox = await ModalSandbox.fromName("my-app", "my-sandbox");
|
|
458
|
+
* const result = await sandbox.execute("ls -la");
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
static fromName(appName: string, sandboxName: string, options?: Pick<ModalSandboxOptions, "auth">): Promise<ModalSandbox>;
|
|
462
|
+
}
|
|
463
|
+
//#endregion
|
|
464
|
+
//#region src/auth.d.ts
|
|
465
|
+
/**
|
|
466
|
+
* Authentication credentials for Modal API.
|
|
467
|
+
*/
|
|
468
|
+
interface ModalCredentials {
|
|
469
|
+
/** Modal token ID */
|
|
470
|
+
tokenId: string;
|
|
471
|
+
/** Modal token secret */
|
|
472
|
+
tokenSecret: string;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Get authentication credentials for Modal API.
|
|
476
|
+
*
|
|
477
|
+
* Credentials are resolved in the following priority order:
|
|
478
|
+
*
|
|
479
|
+
* 1. **Explicit options**: If `options.tokenId` and/or `options.tokenSecret` are provided,
|
|
480
|
+
* they are used directly.
|
|
481
|
+
* 2. **Environment variables**: `MODAL_TOKEN_ID` and `MODAL_TOKEN_SECRET` are used as fallbacks.
|
|
482
|
+
*
|
|
483
|
+
* ## Environment Variable Setup
|
|
484
|
+
*
|
|
485
|
+
* ```bash
|
|
486
|
+
* # Go to https://modal.com/settings/tokens
|
|
487
|
+
* # Create a new token and set the environment variables
|
|
488
|
+
* export MODAL_TOKEN_ID=your_token_id
|
|
489
|
+
* export MODAL_TOKEN_SECRET=your_token_secret
|
|
490
|
+
* ```
|
|
491
|
+
*
|
|
492
|
+
* @param options - Optional authentication configuration from ModalSandboxOptions
|
|
493
|
+
* @returns Complete authentication credentials
|
|
494
|
+
* @throws {Error} If any credentials are missing
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```typescript
|
|
498
|
+
* // With explicit credentials
|
|
499
|
+
* const creds = getAuthCredentials({ tokenId: "...", tokenSecret: "..." });
|
|
500
|
+
*
|
|
501
|
+
* // Using environment variables (auto-detected)
|
|
502
|
+
* const creds = getAuthCredentials();
|
|
503
|
+
*
|
|
504
|
+
* // From ModalSandboxOptions
|
|
505
|
+
* const options: ModalSandboxOptions = {
|
|
506
|
+
* auth: { tokenId: "...", tokenSecret: "..." }
|
|
507
|
+
* };
|
|
508
|
+
* const creds = getAuthCredentials(options.auth);
|
|
509
|
+
* ```
|
|
510
|
+
*/
|
|
511
|
+
declare function getAuthCredentials(options?: ModalSandboxOptions["auth"]): ModalCredentials;
|
|
512
|
+
//#endregion
|
|
513
|
+
export { type ModalCredentials, ModalSandbox, ModalSandboxError, type ModalSandboxErrorCode, type ModalSandboxOptions, getAuthCredentials };
|
|
514
|
+
//# sourceMappingURL=index.d.ts.map
|