@computesdk/modal 1.4.8 → 1.6.0
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 +4 -4
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ const compute = createCompute({
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
// Create sandbox
|
|
40
|
-
const sandbox = await compute.sandbox.create(
|
|
40
|
+
const sandbox = await compute.sandbox.create();
|
|
41
41
|
|
|
42
42
|
// Execute Python code with GPU acceleration
|
|
43
43
|
const result = await sandbox.runCode(`
|
|
@@ -331,7 +331,7 @@ export async function POST(request: Request) {
|
|
|
331
331
|
### Machine Learning Pipeline
|
|
332
332
|
|
|
333
333
|
```typescript
|
|
334
|
-
const sandbox = await compute.sandbox.create(
|
|
334
|
+
const sandbox = await compute.sandbox.create();
|
|
335
335
|
|
|
336
336
|
// Create ML project structure
|
|
337
337
|
await sandbox.filesystem.mkdir('/ml-project');
|
|
@@ -404,7 +404,7 @@ console.log('Model saved:', modelExists);
|
|
|
404
404
|
### GPU-Accelerated Inference
|
|
405
405
|
|
|
406
406
|
```typescript
|
|
407
|
-
const sandbox = await compute.sandbox.create(
|
|
407
|
+
const sandbox = await compute.sandbox.create();
|
|
408
408
|
|
|
409
409
|
// GPU inference example
|
|
410
410
|
const result = await sandbox.runCode(`
|
|
@@ -469,7 +469,7 @@ const tasks = [
|
|
|
469
469
|
|
|
470
470
|
const results = await Promise.all(
|
|
471
471
|
tasks.map(async (taskFile) => {
|
|
472
|
-
const sandbox = await compute.sandbox.create(
|
|
472
|
+
const sandbox = await compute.sandbox.create();
|
|
473
473
|
|
|
474
474
|
return await sandbox.runCode(`
|
|
475
475
|
import json
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -155,12 +155,9 @@ var modal = (0, import_computesdk.createProvider)({
|
|
|
155
155
|
throw new Error(`Syntax error: ${stderr.trim()}`);
|
|
156
156
|
}
|
|
157
157
|
return {
|
|
158
|
-
|
|
159
|
-
stderr: stderr || "",
|
|
158
|
+
output: (stdout || "") + (stderr || ""),
|
|
160
159
|
exitCode: exitCode || 0,
|
|
161
|
-
|
|
162
|
-
sandboxId: modalSandbox.sandboxId,
|
|
163
|
-
provider: "modal"
|
|
160
|
+
language: detectedRuntime
|
|
164
161
|
};
|
|
165
162
|
} catch (error) {
|
|
166
163
|
if (error instanceof Error && error.message.includes("Syntax error")) {
|
|
@@ -187,18 +184,14 @@ var modal = (0, import_computesdk.createProvider)({
|
|
|
187
184
|
stdout: stdout || "",
|
|
188
185
|
stderr: stderr || "",
|
|
189
186
|
exitCode: exitCode || 0,
|
|
190
|
-
|
|
191
|
-
sandboxId: modalSandbox.sandboxId,
|
|
192
|
-
provider: "modal"
|
|
187
|
+
durationMs: Date.now() - startTime
|
|
193
188
|
};
|
|
194
189
|
} catch (error) {
|
|
195
190
|
return {
|
|
196
191
|
stdout: "",
|
|
197
192
|
stderr: error instanceof Error ? error.message : String(error),
|
|
198
193
|
exitCode: 127,
|
|
199
|
-
|
|
200
|
-
sandboxId: modalSandbox.sandboxId,
|
|
201
|
-
provider: "modal"
|
|
194
|
+
durationMs: Date.now() - startTime
|
|
202
195
|
};
|
|
203
196
|
}
|
|
204
197
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Modal Provider - Factory-based Implementation\n * \n * Full-featured provider with serverless sandbox execution using the factory pattern.\n * Leverages Modal's JavaScript SDK for real sandbox management.\n * \n * Note: Modal's JavaScript SDK is in alpha. This implementation provides a working\n * foundation but may need updates as the Modal API evolves.\n */\n\nimport { createProvider } from 'computesdk';\nimport type {\n ExecutionResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n// Import Modal SDK\nimport { App, Sandbox, initializeClient } from 'modal';\n\n/**\n * Modal-specific configuration options\n */\nexport interface ModalConfig {\n /** Modal API token ID - if not provided, will fallback to MODAL_TOKEN_ID environment variable */\n tokenId?: string;\n /** Modal API token secret - if not provided, will fallback to MODAL_TOKEN_SECRET environment variable */\n tokenSecret?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Modal environment (sandbox or main) */\n environment?: string;\n}\n\n/**\n * Modal sandbox interface - wraps Modal's Sandbox class\n */\ninterface ModalSandbox {\n sandbox: any; // Modal Sandbox instance (using any due to alpha SDK)\n sandboxId: string;\n}\n\n/**\n * Detect runtime from code content\n */\nfunction detectRuntime(code: string): Runtime {\n // Strong Node.js indicators\n if (code.includes('console.log') || \n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename') ||\n code.includes('throw new Error') || // JavaScript error throwing\n code.includes('new Error(')) {\n return 'node';\n }\n\n // Strong Python indicators\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n\n // Default to Node.js for Modal (now using Node.js base image)\n return 'node';\n}\n\n/**\n * Create a Modal provider instance using the factory pattern\n */\nexport const modal = createProvider<ModalSandbox, ModalConfig>({\n name: 'modal',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: ModalConfig, options?: CreateSandboxOptions) => {\n // Validate API credentials\n const tokenId = config.tokenId || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_ID) || '';\n const tokenSecret = config.tokenSecret || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_SECRET) || '';\n\n if (!tokenId || !tokenSecret) {\n throw new Error(\n `Missing Modal API credentials. Provide 'tokenId' and 'tokenSecret' in config or set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n\n try {\n // Initialize Modal client with credentials\n initializeClient({ tokenId, tokenSecret });\n\n let sandbox: any;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Modal sandbox\n sandbox = await Sandbox.fromId(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Modal sandbox with Node.js (more appropriate for a Node.js SDK)\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const image = await app.imageFromRegistry('node:20-alpine');\n sandbox = await app.createSandbox(image);\n sandboxId = sandbox.sandboxId;\n }\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('credentials')) {\n throw new Error(\n `Modal authentication failed. Please check your MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Modal quota exceeded. Please check your usage at https://modal.com/`\n );\n }\n }\n throw new Error(\n `Failed to create Modal sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: ModalConfig, sandboxId: string) => {\n const tokenId = config.tokenId || process.env.MODAL_TOKEN_ID!;\n const tokenSecret = config.tokenSecret || process.env.MODAL_TOKEN_SECRET!;\n\n try {\n initializeClient({ tokenId, tokenSecret });\n const sandbox = await Sandbox.fromId(sandboxId);\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: ModalConfig) => {\n throw new Error(\n `Modal provider does not support listing sandboxes. Modal sandboxes are managed individually through the Modal console. Use getById to reconnect to specific sandboxes by ID.`\n );\n },\n\n destroy: async (_config: ModalConfig, sandboxId: string) => {\n try {\n const sandbox = await Sandbox.fromId(sandboxId);\n if (sandbox && typeof sandbox.terminate === 'function') {\n await sandbox.terminate();\n }\n } catch (error) {\n // Sandbox might already be terminated or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (modalSandbox: ModalSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Auto-detect runtime from code if not specified\n const detectedRuntime = runtime || detectRuntime(code);\n\n // Create appropriate sandbox and command for the runtime\n let executionSandbox = modalSandbox.sandbox;\n let command: string[];\n let shouldCleanupSandbox = false;\n\n if (detectedRuntime === 'node') {\n // Use existing Node.js sandbox (now the default)\n command = ['node', '-e', code];\n } else {\n // For Python execution, create a Python sandbox dynamically\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const pythonImage = await app.imageFromRegistry('python:3.13-slim');\n executionSandbox = await app.createSandbox(pythonImage);\n command = ['python3', '-c', code];\n shouldCleanupSandbox = true; // Clean up temporary Python sandbox\n }\n\n const process = await executionSandbox.exec(command, {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n // Clean up temporary Python sandbox if created\n if (shouldCleanupSandbox && executionSandbox !== modalSandbox.sandbox) {\n try {\n await executionSandbox.terminate();\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n\n // Check for syntax errors in stderr\n if (exitCode !== 0 && stderr && (\n stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax')\n )) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n\n return {\n stdout: stdout || '',\n stderr: stderr || '',\n exitCode: exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: modalSandbox.sandboxId,\n provider: 'modal'\n };\n } catch (error) {\n // Handle syntax errors and runtime errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error; // Re-throw syntax errors\n }\n\n throw new Error(\n `Modal execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (modalSandbox: ModalSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Execute command using Modal's exec method with working pattern\n const process = await modalSandbox.sandbox.exec([command, ...args], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n return {\n stdout: stdout || '',\n stderr: stderr || '',\n exitCode: exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: modalSandbox.sandboxId,\n provider: 'modal'\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n executionTime: Date.now() - startTime,\n sandboxId: modalSandbox.sandboxId,\n provider: 'modal'\n };\n }\n },\n\n getInfo: async (modalSandbox: ModalSandbox): Promise<SandboxInfo> => {\n // Get actual sandbox status using Modal's poll method\n let status: 'running' | 'stopped' | 'error' = 'running';\n try {\n const pollResult = await modalSandbox.sandbox.poll();\n if (pollResult !== null) {\n // Sandbox has finished\n status = pollResult === 0 ? 'stopped' : 'error';\n }\n } catch (error) {\n // If polling fails, assume running\n status = 'running';\n }\n\n return {\n id: modalSandbox.sandboxId,\n provider: 'modal',\n runtime: 'node', // Modal default (now using Node.js)\n status,\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n modalSandboxId: modalSandbox.sandboxId,\n realModalImplementation: true\n }\n };\n },\n\n getUrl: async (modalSandbox: ModalSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Modal's built-in tunnels method to get tunnel information\n const tunnels = await modalSandbox.sandbox.tunnels();\n const tunnel = tunnels[options.port];\n \n if (!tunnel) {\n throw new Error(`No tunnel found for port ${options.port}. Available ports: ${Object.keys(tunnels).join(', ')}`);\n }\n \n let url = tunnel.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Modal tunnel URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - Modal supports filesystem operations\n filesystem: {\n readFile: async (modalSandbox: ModalSandbox, path: string): Promise<string> => {\n try {\n // Use Modal's file open API to read files\n const file = await modalSandbox.sandbox.open(path);\n \n // Read the entire file content\n let content = '';\n if (file && typeof file.read === 'function') {\n const data = await file.read();\n content = typeof data === 'string' ? data : new TextDecoder().decode(data);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n \n return content;\n } catch (error) {\n // Fallback to using cat command with working stream pattern\n try {\n const process = await modalSandbox.sandbox.exec(['cat', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [content, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`cat failed: ${stderr}`);\n }\n\n return content.trim(); // Remove extra newlines\n } catch (fallbackError) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n writeFile: async (modalSandbox: ModalSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use Modal's file open API to write files\n const file = await modalSandbox.sandbox.open(path);\n \n // Write content to the file\n if (file && typeof file.write === 'function') {\n await file.write(content);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n } catch (error) {\n // Fallback to using shell command with proper escaping\n try {\n const process = await modalSandbox.sandbox.exec(['sh', '-c', `printf '%s' \"${content.replace(/\"/g, '\\\\\"')}\" > \"${path}\"`], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`write failed: ${stderr}`);\n }\n } catch (fallbackError) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n mkdir: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['mkdir', '-p', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`mkdir failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (modalSandbox: ModalSandbox, path: string): Promise<FileEntry[]> => {\n try {\n // Use simple -l flag for BusyBox compatibility (Alpine/node:20-alpine uses BusyBox ls)\n const process = await modalSandbox.sandbox.exec(['ls', '-la', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [output, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`ls failed: ${stderr}`);\n }\n\n const lines = output.split('\\n').slice(1); // Skip header\n\n return lines\n .filter((line: string) => line.trim())\n .map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n path: `${path}/${name}`.replace('//', '/'),\n isDirectory: permissions.startsWith('d'),\n size,\n lastModified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (modalSandbox: ModalSandbox, path: string): Promise<boolean> => {\n try {\n const process = await modalSandbox.sandbox.exec(['test', '-e', path]);\n const exitCode = await process.wait();\n return exitCode === 0;\n } catch (error) {\n return false;\n }\n },\n\n remove: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['rm', '-rf', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`rm failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: ModalSandbox): ModalSandbox => {\n return sandbox;\n },\n\n }\n }\n});"],"mappings":"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","names":["process"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Modal Provider - Factory-based Implementation\n * \n * Full-featured provider with serverless sandbox execution using the factory pattern.\n * Leverages Modal's JavaScript SDK for real sandbox management.\n * \n * Note: Modal's JavaScript SDK is in alpha. This implementation provides a working\n * foundation but may need updates as the Modal API evolves.\n */\n\nimport { createProvider } from 'computesdk';\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n// Import Modal SDK\nimport { App, Sandbox, initializeClient } from 'modal';\n\n/**\n * Modal-specific configuration options\n */\nexport interface ModalConfig {\n /** Modal API token ID - if not provided, will fallback to MODAL_TOKEN_ID environment variable */\n tokenId?: string;\n /** Modal API token secret - if not provided, will fallback to MODAL_TOKEN_SECRET environment variable */\n tokenSecret?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Modal environment (sandbox or main) */\n environment?: string;\n /** Ports to expose */\n ports?: number[];\n}\n\n/**\n * Modal sandbox interface - wraps Modal's Sandbox class\n */\ninterface ModalSandbox {\n sandbox: any; // Modal Sandbox instance (using any due to alpha SDK)\n sandboxId: string;\n}\n\n/**\n * Detect runtime from code content\n */\nfunction detectRuntime(code: string): Runtime {\n // Strong Node.js indicators\n if (code.includes('console.log') || \n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename') ||\n code.includes('throw new Error') || // JavaScript error throwing\n code.includes('new Error(')) {\n return 'node';\n }\n\n // Strong Python indicators\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n\n // Default to Node.js for Modal (now using Node.js base image)\n return 'node';\n}\n\n/**\n * Create a Modal provider instance using the factory pattern\n */\nexport const modal = createProvider<ModalSandbox, ModalConfig>({\n name: 'modal',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: ModalConfig, options?: CreateSandboxOptions) => {\n // Validate API credentials\n const tokenId = config.tokenId || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_ID) || '';\n const tokenSecret = config.tokenSecret || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_SECRET) || '';\n\n if (!tokenId || !tokenSecret) {\n throw new Error(\n `Missing Modal API credentials. Provide 'tokenId' and 'tokenSecret' in config or set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n\n try {\n // Initialize Modal client with credentials\n initializeClient({ tokenId, tokenSecret });\n\n let sandbox: any;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Modal sandbox\n sandbox = await Sandbox.fromId(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Modal sandbox with Node.js (more appropriate for a Node.js SDK)\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const image = await app.imageFromRegistry('node:20-alpine');\n sandbox = await app.createSandbox(image);\n sandboxId = sandbox.sandboxId;\n }\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('credentials')) {\n throw new Error(\n `Modal authentication failed. Please check your MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Modal quota exceeded. Please check your usage at https://modal.com/`\n );\n }\n }\n throw new Error(\n `Failed to create Modal sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: ModalConfig, sandboxId: string) => {\n const tokenId = config.tokenId || process.env.MODAL_TOKEN_ID!;\n const tokenSecret = config.tokenSecret || process.env.MODAL_TOKEN_SECRET!;\n\n try {\n initializeClient({ tokenId, tokenSecret });\n const sandbox = await Sandbox.fromId(sandboxId);\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: ModalConfig) => {\n throw new Error(\n `Modal provider does not support listing sandboxes. Modal sandboxes are managed individually through the Modal console. Use getById to reconnect to specific sandboxes by ID.`\n );\n },\n\n destroy: async (_config: ModalConfig, sandboxId: string) => {\n try {\n const sandbox = await Sandbox.fromId(sandboxId);\n if (sandbox && typeof sandbox.terminate === 'function') {\n await sandbox.terminate();\n }\n } catch (error) {\n // Sandbox might already be terminated or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (modalSandbox: ModalSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n\n try {\n // Auto-detect runtime from code if not specified\n const detectedRuntime = runtime || detectRuntime(code);\n\n // Create appropriate sandbox and command for the runtime\n let executionSandbox = modalSandbox.sandbox;\n let command: string[];\n let shouldCleanupSandbox = false;\n\n if (detectedRuntime === 'node') {\n // Use existing Node.js sandbox (now the default)\n command = ['node', '-e', code];\n } else {\n // For Python execution, create a Python sandbox dynamically\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const pythonImage = await app.imageFromRegistry('python:3.13-slim');\n executionSandbox = await app.createSandbox(pythonImage);\n command = ['python3', '-c', code];\n shouldCleanupSandbox = true; // Clean up temporary Python sandbox\n }\n\n const process = await executionSandbox.exec(command, {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n // Clean up temporary Python sandbox if created\n if (shouldCleanupSandbox && executionSandbox !== modalSandbox.sandbox) {\n try {\n await executionSandbox.terminate();\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n\n // Check for syntax errors in stderr\n if (exitCode !== 0 && stderr && (\n stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax')\n )) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n\n return {\n output: (stdout || '') + (stderr || ''),\n exitCode: exitCode || 0,\n language: detectedRuntime,\n };\n } catch (error) {\n // Handle syntax errors and runtime errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error; // Re-throw syntax errors\n }\n\n throw new Error(\n `Modal execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (modalSandbox: ModalSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Execute command using Modal's exec method with working pattern\n const process = await modalSandbox.sandbox.exec([command, ...args], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n return {\n stdout: stdout || '',\n stderr: stderr || '',\n exitCode: exitCode || 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (modalSandbox: ModalSandbox): Promise<SandboxInfo> => {\n // Get actual sandbox status using Modal's poll method\n let status: 'running' | 'stopped' | 'error' = 'running';\n try {\n const pollResult = await modalSandbox.sandbox.poll();\n if (pollResult !== null) {\n // Sandbox has finished\n status = pollResult === 0 ? 'stopped' : 'error';\n }\n } catch (error) {\n // If polling fails, assume running\n status = 'running';\n }\n\n return {\n id: modalSandbox.sandboxId,\n provider: 'modal',\n runtime: 'node', // Modal default (now using Node.js)\n status,\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n modalSandboxId: modalSandbox.sandboxId,\n realModalImplementation: true\n }\n };\n },\n\n getUrl: async (modalSandbox: ModalSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Modal's built-in tunnels method to get tunnel information\n const tunnels = await modalSandbox.sandbox.tunnels();\n const tunnel = tunnels[options.port];\n \n if (!tunnel) {\n throw new Error(`No tunnel found for port ${options.port}. Available ports: ${Object.keys(tunnels).join(', ')}`);\n }\n \n let url = tunnel.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Modal tunnel URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - Modal supports filesystem operations\n filesystem: {\n readFile: async (modalSandbox: ModalSandbox, path: string): Promise<string> => {\n try {\n // Use Modal's file open API to read files\n const file = await modalSandbox.sandbox.open(path);\n \n // Read the entire file content\n let content = '';\n if (file && typeof file.read === 'function') {\n const data = await file.read();\n content = typeof data === 'string' ? data : new TextDecoder().decode(data);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n \n return content;\n } catch (error) {\n // Fallback to using cat command with working stream pattern\n try {\n const process = await modalSandbox.sandbox.exec(['cat', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [content, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`cat failed: ${stderr}`);\n }\n\n return content.trim(); // Remove extra newlines\n } catch (fallbackError) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n writeFile: async (modalSandbox: ModalSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use Modal's file open API to write files\n const file = await modalSandbox.sandbox.open(path);\n \n // Write content to the file\n if (file && typeof file.write === 'function') {\n await file.write(content);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n } catch (error) {\n // Fallback to using shell command with proper escaping\n try {\n const process = await modalSandbox.sandbox.exec(['sh', '-c', `printf '%s' \"${content.replace(/\"/g, '\\\\\"')}\" > \"${path}\"`], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`write failed: ${stderr}`);\n }\n } catch (fallbackError) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n mkdir: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['mkdir', '-p', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`mkdir failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (modalSandbox: ModalSandbox, path: string): Promise<FileEntry[]> => {\n try {\n // Use simple -l flag for BusyBox compatibility (Alpine/node:20-alpine uses BusyBox ls)\n const process = await modalSandbox.sandbox.exec(['ls', '-la', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [output, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`ls failed: ${stderr}`);\n }\n\n const lines = output.split('\\n').slice(1); // Skip header\n\n return lines\n .filter((line: string) => line.trim())\n .map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n path: `${path}/${name}`.replace('//', '/'),\n isDirectory: permissions.startsWith('d'),\n size,\n lastModified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (modalSandbox: ModalSandbox, path: string): Promise<boolean> => {\n try {\n const process = await modalSandbox.sandbox.exec(['test', '-e', path]);\n const exitCode = await process.wait();\n return exitCode === 0;\n } catch (error) {\n return false;\n }\n },\n\n remove: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['rm', '-rf', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`rm failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: ModalSandbox): ModalSandbox => {\n return sandbox;\n },\n\n }\n }\n});"],"mappings":"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","names":["process"]}
|
package/dist/index.mjs
CHANGED
|
@@ -131,12 +131,9 @@ var modal = createProvider({
|
|
|
131
131
|
throw new Error(`Syntax error: ${stderr.trim()}`);
|
|
132
132
|
}
|
|
133
133
|
return {
|
|
134
|
-
|
|
135
|
-
stderr: stderr || "",
|
|
134
|
+
output: (stdout || "") + (stderr || ""),
|
|
136
135
|
exitCode: exitCode || 0,
|
|
137
|
-
|
|
138
|
-
sandboxId: modalSandbox.sandboxId,
|
|
139
|
-
provider: "modal"
|
|
136
|
+
language: detectedRuntime
|
|
140
137
|
};
|
|
141
138
|
} catch (error) {
|
|
142
139
|
if (error instanceof Error && error.message.includes("Syntax error")) {
|
|
@@ -163,18 +160,14 @@ var modal = createProvider({
|
|
|
163
160
|
stdout: stdout || "",
|
|
164
161
|
stderr: stderr || "",
|
|
165
162
|
exitCode: exitCode || 0,
|
|
166
|
-
|
|
167
|
-
sandboxId: modalSandbox.sandboxId,
|
|
168
|
-
provider: "modal"
|
|
163
|
+
durationMs: Date.now() - startTime
|
|
169
164
|
};
|
|
170
165
|
} catch (error) {
|
|
171
166
|
return {
|
|
172
167
|
stdout: "",
|
|
173
168
|
stderr: error instanceof Error ? error.message : String(error),
|
|
174
169
|
exitCode: 127,
|
|
175
|
-
|
|
176
|
-
sandboxId: modalSandbox.sandboxId,
|
|
177
|
-
provider: "modal"
|
|
170
|
+
durationMs: Date.now() - startTime
|
|
178
171
|
};
|
|
179
172
|
}
|
|
180
173
|
},
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Modal Provider - Factory-based Implementation\n * \n * Full-featured provider with serverless sandbox execution using the factory pattern.\n * Leverages Modal's JavaScript SDK for real sandbox management.\n * \n * Note: Modal's JavaScript SDK is in alpha. This implementation provides a working\n * foundation but may need updates as the Modal API evolves.\n */\n\nimport { createProvider } from 'computesdk';\nimport type {\n ExecutionResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n// Import Modal SDK\nimport { App, Sandbox, initializeClient } from 'modal';\n\n/**\n * Modal-specific configuration options\n */\nexport interface ModalConfig {\n /** Modal API token ID - if not provided, will fallback to MODAL_TOKEN_ID environment variable */\n tokenId?: string;\n /** Modal API token secret - if not provided, will fallback to MODAL_TOKEN_SECRET environment variable */\n tokenSecret?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Modal environment (sandbox or main) */\n environment?: string;\n}\n\n/**\n * Modal sandbox interface - wraps Modal's Sandbox class\n */\ninterface ModalSandbox {\n sandbox: any; // Modal Sandbox instance (using any due to alpha SDK)\n sandboxId: string;\n}\n\n/**\n * Detect runtime from code content\n */\nfunction detectRuntime(code: string): Runtime {\n // Strong Node.js indicators\n if (code.includes('console.log') || \n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename') ||\n code.includes('throw new Error') || // JavaScript error throwing\n code.includes('new Error(')) {\n return 'node';\n }\n\n // Strong Python indicators\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n\n // Default to Node.js for Modal (now using Node.js base image)\n return 'node';\n}\n\n/**\n * Create a Modal provider instance using the factory pattern\n */\nexport const modal = createProvider<ModalSandbox, ModalConfig>({\n name: 'modal',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: ModalConfig, options?: CreateSandboxOptions) => {\n // Validate API credentials\n const tokenId = config.tokenId || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_ID) || '';\n const tokenSecret = config.tokenSecret || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_SECRET) || '';\n\n if (!tokenId || !tokenSecret) {\n throw new Error(\n `Missing Modal API credentials. Provide 'tokenId' and 'tokenSecret' in config or set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n\n try {\n // Initialize Modal client with credentials\n initializeClient({ tokenId, tokenSecret });\n\n let sandbox: any;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Modal sandbox\n sandbox = await Sandbox.fromId(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Modal sandbox with Node.js (more appropriate for a Node.js SDK)\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const image = await app.imageFromRegistry('node:20-alpine');\n sandbox = await app.createSandbox(image);\n sandboxId = sandbox.sandboxId;\n }\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('credentials')) {\n throw new Error(\n `Modal authentication failed. Please check your MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Modal quota exceeded. Please check your usage at https://modal.com/`\n );\n }\n }\n throw new Error(\n `Failed to create Modal sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: ModalConfig, sandboxId: string) => {\n const tokenId = config.tokenId || process.env.MODAL_TOKEN_ID!;\n const tokenSecret = config.tokenSecret || process.env.MODAL_TOKEN_SECRET!;\n\n try {\n initializeClient({ tokenId, tokenSecret });\n const sandbox = await Sandbox.fromId(sandboxId);\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: ModalConfig) => {\n throw new Error(\n `Modal provider does not support listing sandboxes. Modal sandboxes are managed individually through the Modal console. Use getById to reconnect to specific sandboxes by ID.`\n );\n },\n\n destroy: async (_config: ModalConfig, sandboxId: string) => {\n try {\n const sandbox = await Sandbox.fromId(sandboxId);\n if (sandbox && typeof sandbox.terminate === 'function') {\n await sandbox.terminate();\n }\n } catch (error) {\n // Sandbox might already be terminated or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (modalSandbox: ModalSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Auto-detect runtime from code if not specified\n const detectedRuntime = runtime || detectRuntime(code);\n\n // Create appropriate sandbox and command for the runtime\n let executionSandbox = modalSandbox.sandbox;\n let command: string[];\n let shouldCleanupSandbox = false;\n\n if (detectedRuntime === 'node') {\n // Use existing Node.js sandbox (now the default)\n command = ['node', '-e', code];\n } else {\n // For Python execution, create a Python sandbox dynamically\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const pythonImage = await app.imageFromRegistry('python:3.13-slim');\n executionSandbox = await app.createSandbox(pythonImage);\n command = ['python3', '-c', code];\n shouldCleanupSandbox = true; // Clean up temporary Python sandbox\n }\n\n const process = await executionSandbox.exec(command, {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n // Clean up temporary Python sandbox if created\n if (shouldCleanupSandbox && executionSandbox !== modalSandbox.sandbox) {\n try {\n await executionSandbox.terminate();\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n\n // Check for syntax errors in stderr\n if (exitCode !== 0 && stderr && (\n stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax')\n )) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n\n return {\n stdout: stdout || '',\n stderr: stderr || '',\n exitCode: exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: modalSandbox.sandboxId,\n provider: 'modal'\n };\n } catch (error) {\n // Handle syntax errors and runtime errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error; // Re-throw syntax errors\n }\n\n throw new Error(\n `Modal execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (modalSandbox: ModalSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Execute command using Modal's exec method with working pattern\n const process = await modalSandbox.sandbox.exec([command, ...args], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n return {\n stdout: stdout || '',\n stderr: stderr || '',\n exitCode: exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: modalSandbox.sandboxId,\n provider: 'modal'\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n executionTime: Date.now() - startTime,\n sandboxId: modalSandbox.sandboxId,\n provider: 'modal'\n };\n }\n },\n\n getInfo: async (modalSandbox: ModalSandbox): Promise<SandboxInfo> => {\n // Get actual sandbox status using Modal's poll method\n let status: 'running' | 'stopped' | 'error' = 'running';\n try {\n const pollResult = await modalSandbox.sandbox.poll();\n if (pollResult !== null) {\n // Sandbox has finished\n status = pollResult === 0 ? 'stopped' : 'error';\n }\n } catch (error) {\n // If polling fails, assume running\n status = 'running';\n }\n\n return {\n id: modalSandbox.sandboxId,\n provider: 'modal',\n runtime: 'node', // Modal default (now using Node.js)\n status,\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n modalSandboxId: modalSandbox.sandboxId,\n realModalImplementation: true\n }\n };\n },\n\n getUrl: async (modalSandbox: ModalSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Modal's built-in tunnels method to get tunnel information\n const tunnels = await modalSandbox.sandbox.tunnels();\n const tunnel = tunnels[options.port];\n \n if (!tunnel) {\n throw new Error(`No tunnel found for port ${options.port}. Available ports: ${Object.keys(tunnels).join(', ')}`);\n }\n \n let url = tunnel.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Modal tunnel URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - Modal supports filesystem operations\n filesystem: {\n readFile: async (modalSandbox: ModalSandbox, path: string): Promise<string> => {\n try {\n // Use Modal's file open API to read files\n const file = await modalSandbox.sandbox.open(path);\n \n // Read the entire file content\n let content = '';\n if (file && typeof file.read === 'function') {\n const data = await file.read();\n content = typeof data === 'string' ? data : new TextDecoder().decode(data);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n \n return content;\n } catch (error) {\n // Fallback to using cat command with working stream pattern\n try {\n const process = await modalSandbox.sandbox.exec(['cat', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [content, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`cat failed: ${stderr}`);\n }\n\n return content.trim(); // Remove extra newlines\n } catch (fallbackError) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n writeFile: async (modalSandbox: ModalSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use Modal's file open API to write files\n const file = await modalSandbox.sandbox.open(path);\n \n // Write content to the file\n if (file && typeof file.write === 'function') {\n await file.write(content);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n } catch (error) {\n // Fallback to using shell command with proper escaping\n try {\n const process = await modalSandbox.sandbox.exec(['sh', '-c', `printf '%s' \"${content.replace(/\"/g, '\\\\\"')}\" > \"${path}\"`], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`write failed: ${stderr}`);\n }\n } catch (fallbackError) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n mkdir: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['mkdir', '-p', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`mkdir failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (modalSandbox: ModalSandbox, path: string): Promise<FileEntry[]> => {\n try {\n // Use simple -l flag for BusyBox compatibility (Alpine/node:20-alpine uses BusyBox ls)\n const process = await modalSandbox.sandbox.exec(['ls', '-la', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [output, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`ls failed: ${stderr}`);\n }\n\n const lines = output.split('\\n').slice(1); // Skip header\n\n return lines\n .filter((line: string) => line.trim())\n .map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n path: `${path}/${name}`.replace('//', '/'),\n isDirectory: permissions.startsWith('d'),\n size,\n lastModified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (modalSandbox: ModalSandbox, path: string): Promise<boolean> => {\n try {\n const process = await modalSandbox.sandbox.exec(['test', '-e', path]);\n const exitCode = await process.wait();\n return exitCode === 0;\n } catch (error) {\n return false;\n }\n },\n\n remove: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['rm', '-rf', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`rm failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: ModalSandbox): ModalSandbox => {\n return sandbox;\n },\n\n }\n }\n});"],"mappings":"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","names":["process"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Modal Provider - Factory-based Implementation\n * \n * Full-featured provider with serverless sandbox execution using the factory pattern.\n * Leverages Modal's JavaScript SDK for real sandbox management.\n * \n * Note: Modal's JavaScript SDK is in alpha. This implementation provides a working\n * foundation but may need updates as the Modal API evolves.\n */\n\nimport { createProvider } from 'computesdk';\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry\n} from 'computesdk';\n\n// Import Modal SDK\nimport { App, Sandbox, initializeClient } from 'modal';\n\n/**\n * Modal-specific configuration options\n */\nexport interface ModalConfig {\n /** Modal API token ID - if not provided, will fallback to MODAL_TOKEN_ID environment variable */\n tokenId?: string;\n /** Modal API token secret - if not provided, will fallback to MODAL_TOKEN_SECRET environment variable */\n tokenSecret?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n /** Modal environment (sandbox or main) */\n environment?: string;\n /** Ports to expose */\n ports?: number[];\n}\n\n/**\n * Modal sandbox interface - wraps Modal's Sandbox class\n */\ninterface ModalSandbox {\n sandbox: any; // Modal Sandbox instance (using any due to alpha SDK)\n sandboxId: string;\n}\n\n/**\n * Detect runtime from code content\n */\nfunction detectRuntime(code: string): Runtime {\n // Strong Node.js indicators\n if (code.includes('console.log') || \n code.includes('process.') ||\n code.includes('require(') ||\n code.includes('module.exports') ||\n code.includes('__dirname') ||\n code.includes('__filename') ||\n code.includes('throw new Error') || // JavaScript error throwing\n code.includes('new Error(')) {\n return 'node';\n }\n\n // Strong Python indicators\n if (code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')) {\n return 'python';\n }\n\n // Default to Node.js for Modal (now using Node.js base image)\n return 'node';\n}\n\n/**\n * Create a Modal provider instance using the factory pattern\n */\nexport const modal = createProvider<ModalSandbox, ModalConfig>({\n name: 'modal',\n methods: {\n sandbox: {\n // Collection operations (map to compute.sandbox.*)\n create: async (config: ModalConfig, options?: CreateSandboxOptions) => {\n // Validate API credentials\n const tokenId = config.tokenId || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_ID) || '';\n const tokenSecret = config.tokenSecret || (typeof process !== 'undefined' && process.env?.MODAL_TOKEN_SECRET) || '';\n\n if (!tokenId || !tokenSecret) {\n throw new Error(\n `Missing Modal API credentials. Provide 'tokenId' and 'tokenSecret' in config or set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n\n try {\n // Initialize Modal client with credentials\n initializeClient({ tokenId, tokenSecret });\n\n let sandbox: any;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Modal sandbox\n sandbox = await Sandbox.fromId(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Modal sandbox with Node.js (more appropriate for a Node.js SDK)\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const image = await app.imageFromRegistry('node:20-alpine');\n sandbox = await app.createSandbox(image);\n sandboxId = sandbox.sandboxId;\n }\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('credentials')) {\n throw new Error(\n `Modal authentication failed. Please check your MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables. Get your credentials from https://modal.com/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Modal quota exceeded. Please check your usage at https://modal.com/`\n );\n }\n }\n throw new Error(\n `Failed to create Modal sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: ModalConfig, sandboxId: string) => {\n const tokenId = config.tokenId || process.env.MODAL_TOKEN_ID!;\n const tokenSecret = config.tokenSecret || process.env.MODAL_TOKEN_SECRET!;\n\n try {\n initializeClient({ tokenId, tokenSecret });\n const sandbox = await Sandbox.fromId(sandboxId);\n\n const modalSandbox: ModalSandbox = {\n sandbox,\n sandboxId\n };\n\n return {\n sandbox: modalSandbox,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (_config: ModalConfig) => {\n throw new Error(\n `Modal provider does not support listing sandboxes. Modal sandboxes are managed individually through the Modal console. Use getById to reconnect to specific sandboxes by ID.`\n );\n },\n\n destroy: async (_config: ModalConfig, sandboxId: string) => {\n try {\n const sandbox = await Sandbox.fromId(sandboxId);\n if (sandbox && typeof sandbox.terminate === 'function') {\n await sandbox.terminate();\n }\n } catch (error) {\n // Sandbox might already be terminated or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (map to individual Sandbox methods)\n runCode: async (modalSandbox: ModalSandbox, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const startTime = Date.now();\n\n try {\n // Auto-detect runtime from code if not specified\n const detectedRuntime = runtime || detectRuntime(code);\n\n // Create appropriate sandbox and command for the runtime\n let executionSandbox = modalSandbox.sandbox;\n let command: string[];\n let shouldCleanupSandbox = false;\n\n if (detectedRuntime === 'node') {\n // Use existing Node.js sandbox (now the default)\n command = ['node', '-e', code];\n } else {\n // For Python execution, create a Python sandbox dynamically\n const app = await App.lookup('computesdk-modal', { createIfMissing: true });\n const pythonImage = await app.imageFromRegistry('python:3.13-slim');\n executionSandbox = await app.createSandbox(pythonImage);\n command = ['python3', '-c', code];\n shouldCleanupSandbox = true; // Clean up temporary Python sandbox\n }\n\n const process = await executionSandbox.exec(command, {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n // Clean up temporary Python sandbox if created\n if (shouldCleanupSandbox && executionSandbox !== modalSandbox.sandbox) {\n try {\n await executionSandbox.terminate();\n } catch (e) {\n // Ignore cleanup errors\n }\n }\n\n // Check for syntax errors in stderr\n if (exitCode !== 0 && stderr && (\n stderr.includes('SyntaxError') ||\n stderr.includes('invalid syntax')\n )) {\n throw new Error(`Syntax error: ${stderr.trim()}`);\n }\n\n return {\n output: (stdout || '') + (stderr || ''),\n exitCode: exitCode || 0,\n language: detectedRuntime,\n };\n } catch (error) {\n // Handle syntax errors and runtime errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error; // Re-throw syntax errors\n }\n\n throw new Error(\n `Modal execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (modalSandbox: ModalSandbox, command: string, args: string[] = []): Promise<CommandResult> => {\n const startTime = Date.now();\n\n try {\n // Execute command using Modal's exec method with working pattern\n const process = await modalSandbox.sandbox.exec([command, ...args], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n // Use working stream reading pattern from debug\n const [stdout, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n return {\n stdout: stdout || '',\n stderr: stderr || '',\n exitCode: exitCode || 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n getInfo: async (modalSandbox: ModalSandbox): Promise<SandboxInfo> => {\n // Get actual sandbox status using Modal's poll method\n let status: 'running' | 'stopped' | 'error' = 'running';\n try {\n const pollResult = await modalSandbox.sandbox.poll();\n if (pollResult !== null) {\n // Sandbox has finished\n status = pollResult === 0 ? 'stopped' : 'error';\n }\n } catch (error) {\n // If polling fails, assume running\n status = 'running';\n }\n\n return {\n id: modalSandbox.sandboxId,\n provider: 'modal',\n runtime: 'node', // Modal default (now using Node.js)\n status,\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n modalSandboxId: modalSandbox.sandboxId,\n realModalImplementation: true\n }\n };\n },\n\n getUrl: async (modalSandbox: ModalSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n // Use Modal's built-in tunnels method to get tunnel information\n const tunnels = await modalSandbox.sandbox.tunnels();\n const tunnel = tunnels[options.port];\n \n if (!tunnel) {\n throw new Error(`No tunnel found for port ${options.port}. Available ports: ${Object.keys(tunnels).join(', ')}`);\n }\n \n let url = tunnel.url;\n \n // If a specific protocol is requested, replace the URL's protocol\n if (options.protocol) {\n const urlObj = new URL(url);\n urlObj.protocol = options.protocol + ':';\n url = urlObj.toString();\n }\n \n return url;\n } catch (error) {\n throw new Error(\n `Failed to get Modal tunnel URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n // Optional filesystem methods - Modal supports filesystem operations\n filesystem: {\n readFile: async (modalSandbox: ModalSandbox, path: string): Promise<string> => {\n try {\n // Use Modal's file open API to read files\n const file = await modalSandbox.sandbox.open(path);\n \n // Read the entire file content\n let content = '';\n if (file && typeof file.read === 'function') {\n const data = await file.read();\n content = typeof data === 'string' ? data : new TextDecoder().decode(data);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n \n return content;\n } catch (error) {\n // Fallback to using cat command with working stream pattern\n try {\n const process = await modalSandbox.sandbox.exec(['cat', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [content, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`cat failed: ${stderr}`);\n }\n\n return content.trim(); // Remove extra newlines\n } catch (fallbackError) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n writeFile: async (modalSandbox: ModalSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use Modal's file open API to write files\n const file = await modalSandbox.sandbox.open(path);\n \n // Write content to the file\n if (file && typeof file.write === 'function') {\n await file.write(content);\n }\n \n // Close the file if it has a close method\n if (file && typeof file.close === 'function') {\n await file.close();\n }\n } catch (error) {\n // Fallback to using shell command with proper escaping\n try {\n const process = await modalSandbox.sandbox.exec(['sh', '-c', `printf '%s' \"${content.replace(/\"/g, '\\\\\"')}\" > \"${path}\"`], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`write failed: ${stderr}`);\n }\n } catch (fallbackError) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n mkdir: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['mkdir', '-p', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`mkdir failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (modalSandbox: ModalSandbox, path: string): Promise<FileEntry[]> => {\n try {\n // Use simple -l flag for BusyBox compatibility (Alpine/node:20-alpine uses BusyBox ls)\n const process = await modalSandbox.sandbox.exec(['ls', '-la', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [output, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`ls failed: ${stderr}`);\n }\n\n const lines = output.split('\\n').slice(1); // Skip header\n\n return lines\n .filter((line: string) => line.trim())\n .map((line: string) => {\n const parts = line.trim().split(/\\s+/);\n const permissions = parts[0] || '';\n const size = parseInt(parts[4]) || 0;\n const dateStr = (parts[5] || '') + ' ' + (parts[6] || '');\n const date = dateStr.trim() ? new Date(dateStr) : new Date();\n const name = parts.slice(8).join(' ') || parts[parts.length - 1] || 'unknown';\n\n return {\n name,\n path: `${path}/${name}`.replace('//', '/'),\n isDirectory: permissions.startsWith('d'),\n size,\n lastModified: isNaN(date.getTime()) ? new Date() : date\n };\n });\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (modalSandbox: ModalSandbox, path: string): Promise<boolean> => {\n try {\n const process = await modalSandbox.sandbox.exec(['test', '-e', path]);\n const exitCode = await process.wait();\n return exitCode === 0;\n } catch (error) {\n return false;\n }\n },\n\n remove: async (modalSandbox: ModalSandbox, path: string): Promise<void> => {\n try {\n const process = await modalSandbox.sandbox.exec(['rm', '-rf', path], {\n stdout: 'pipe',\n stderr: 'pipe'\n });\n\n const [, stderr] = await Promise.all([\n process.stdout.readText(),\n process.stderr.readText()\n ]);\n\n const exitCode = await process.wait();\n\n if (exitCode !== 0) {\n throw new Error(`rm failed: ${stderr}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n },\n\n // Provider-specific typed getInstance method\n getInstance: (sandbox: ModalSandbox): ModalSandbox => {\n return sandbox;\n },\n\n }\n }\n});"],"mappings":"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","names":["process"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/modal",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Modal provider for ComputeSDK",
|
|
5
5
|
"author": "Garrison",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"modal": "^0.3.16",
|
|
22
|
-
"computesdk": "1.
|
|
22
|
+
"computesdk": "1.9.0"
|
|
23
23
|
},
|
|
24
24
|
"keywords": [
|
|
25
25
|
"modal",
|