From 3bb8033c69d2b070f0c307e007eec5c819cb08f8 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Tue, 16 Dec 2025 12:00:22 +1000 Subject: [PATCH] chore: update dependencies and add unsandbox package --- packages/tools/unsandbox/README.md | 162 +++++++++++++++++ packages/tools/unsandbox/package.json | 230 +++++++++++++++++++++++++ packages/tools/unsandbox/src/index.ts | 20 +++ packages/tools/unsandbox/tsconfig.json | 12 ++ pnpm-lock.yaml | 25 +++ 5 files changed, 449 insertions(+) create mode 100644 packages/tools/unsandbox/README.md create mode 100644 packages/tools/unsandbox/package.json create mode 100644 packages/tools/unsandbox/src/index.ts create mode 100644 packages/tools/unsandbox/tsconfig.json diff --git a/packages/tools/unsandbox/README.md b/packages/tools/unsandbox/README.md new file mode 100644 index 0000000..5839b3f --- /dev/null +++ b/packages/tools/unsandbox/README.md @@ -0,0 +1,162 @@ +# @tpmjs/unsandbox + +AI SDK tools for secure code execution in 42+ programming languages via [unsandbox.com](https://unsandbox.com). + +## Installation + +```bash +npm install @tpmjs/unsandbox +# or +pnpm add @tpmjs/unsandbox +``` + +## Setup + +Get an API key at [unsandbox.com/api-keys](https://unsandbox.com/api-keys) and set it as an environment variable: + +```bash +export UNSANDBOX_API_KEY=your-api-key +``` + +## Usage + +```typescript +import { streamText } from 'ai'; +import { anthropic } from '@ai-sdk/anthropic'; +import { executeCode, listLanguages } from '@tpmjs/unsandbox'; + +const result = streamText({ + model: anthropic('claude-sonnet-4-20250514'), + tools: { + executeCode, + listLanguages, + }, + system: 'You can execute code in 42+ programming languages using a secure sandbox.', + prompt: 'Write and run a Python script that calculates the first 10 Fibonacci numbers', +}); +``` + +## Tools + +### executeCode + +Execute code synchronously in a secure sandbox. + +```typescript +import { executeCode } from '@tpmjs/unsandbox'; + +const result = await executeCode.execute({ + language: 'python', + code: 'print("Hello, World!")', +}); +// { stdout: "Hello, World!\n", stderr: "", exit_code: 0 } +``` + +**Parameters:** + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `language` | string | Yes | Programming language (python, javascript, go, rust, etc.) | +| `code` | string | Yes | Source code to execute | +| `input_files` | array | No | Files to make available in /tmp/input/ | +| `network_mode` | string | No | 'zerotrust' (default) or 'semitrusted' | +| `ttl` | number | No | Timeout in seconds (1-900, default 60) | +| `return_artifact` | boolean | No | Return compiled binary for compiled languages | +| `return_wasm_artifact` | boolean | No | Compile to WebAssembly (C, C++, Rust, Zig, Go) | + +### executeCodeAsync + +Execute code asynchronously, returning a job_id for tracking. + +```typescript +import { executeCodeAsync, getJob } from '@tpmjs/unsandbox'; + +const job = await executeCodeAsync.execute({ + language: 'rust', + code: 'fn main() { println!("Hello from Rust!"); }', +}); + +// Check status later +const result = await getJob.execute({ job_id: job.job_id }); +``` + +### runCode + +Execute code with automatic language detection from shebang. + +```typescript +import { runCode } from '@tpmjs/unsandbox'; + +const result = await runCode.execute({ + code: `#!/usr/bin/env python3 +print("Auto-detected Python!")`, +}); +``` + +### runCodeAsync + +Async version of runCode. + +### listJobs + +List all active jobs for your API key. + +```typescript +import { listJobs } from '@tpmjs/unsandbox'; + +const jobs = await listJobs.execute({}); +``` + +### getJob + +Get status and results of a specific async job. + +```typescript +import { getJob } from '@tpmjs/unsandbox'; + +const result = await getJob.execute({ job_id: 'abc123' }); +// { status: 'completed', stdout: '...', stderr: '...' } +``` + +### cancelJob + +Cancel a running or pending async job. + +```typescript +import { cancelJob } from '@tpmjs/unsandbox'; + +await cancelJob.execute({ job_id: 'abc123' }); +``` + +### listLanguages + +List all 42+ supported programming languages. + +```typescript +import { listLanguages } from '@tpmjs/unsandbox'; + +const languages = await listLanguages.execute({}); +``` + +## Supported Languages + +42+ languages including: + +- **Interpreted:** Python, JavaScript, TypeScript, Ruby, Perl, PHP, Lua, Bash, R, Elixir, Erlang, Tcl, Scheme, PowerShell, Clojure, Common Lisp, Crystal, Groovy, Deno, AWK, Raku +- **Compiled:** C, C++, Go, Rust, Java, Kotlin, COBOL, Fortran, D, Zig, Nim, V, Objective-C, Dart +- **Functional:** Julia, Haskell, OCaml, F#, C#, Prolog, Forth + +## Environment Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| `UNSANDBOX_API_KEY` | Yes | API key from unsandbox.com | + +## Related + +- [unsandbox.com](https://unsandbox.com) - Secure code execution API +- [TPMJS Registry](https://tpmjs.com) - Browse all available AI SDK tools + +## License + +MIT diff --git a/packages/tools/unsandbox/package.json b/packages/tools/unsandbox/package.json new file mode 100644 index 0000000..567a54d --- /dev/null +++ b/packages/tools/unsandbox/package.json @@ -0,0 +1,230 @@ +{ + "name": "@tpmjs/unsandbox", + "version": "0.0.1", + "description": "AI SDK tools for secure code execution in 42+ programming languages via unsandbox.com", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "dev": "tsc --watch", + "type-check": "tsc --noEmit" + }, + "keywords": ["tpmjs-tool", "ai-sdk", "code-execution", "sandbox", "unsandbox"], + "dependencies": { + "@thomasdavis/unsandbox": "^0.0.3" + }, + "devDependencies": { + "@tpmjs/tsconfig": "workspace:*", + "typescript": "^5.7.2" + }, + "files": ["dist", "README.md"], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/ajaxdavis/tpmjs.git", + "directory": "packages/tools/unsandbox" + }, + "homepage": "https://tpmjs.com", + "license": "MIT", + "tpmjs": { + "category": "ai-ml", + "frameworks": ["vercel-ai"], + "env": [ + { + "name": "UNSANDBOX_API_KEY", + "description": "API key for the Unsandbox code execution service (get one at https://unsandbox.com/api-keys)", + "required": true + } + ], + "tools": [ + { + "exportName": "executeCode", + "description": "Execute code synchronously in a secure sandbox. Supports 42+ languages including Python, JavaScript, TypeScript, Go, Rust, and more.", + "parameters": [ + { + "name": "language", + "type": "string", + "description": "Programming language to execute (python, javascript, typescript, go, rust, c, cpp, java, ruby, etc.)", + "required": true + }, + { + "name": "code", + "type": "string", + "description": "The source code to execute", + "required": true + }, + { + "name": "input_files", + "type": "array", + "description": "Optional array of input files to make available in /tmp/input/", + "required": false + }, + { + "name": "network_mode", + "type": "string", + "description": "Network isolation mode: 'zerotrust' (default, blocks all) or 'semitrusted' (allows outbound)", + "required": false + }, + { + "name": "ttl", + "type": "number", + "description": "Execution timeout in seconds (1-900, default 60)", + "required": false + } + ], + "returns": { + "type": "object", + "description": "Execution result with stdout, stderr, and exit code" + }, + "aiAgent": { + "useCase": "Use when you need to execute code in a secure sandbox environment. Great for running untrusted code, testing snippets, or executing code in languages not available locally.", + "examples": [ + "Execute Python code to analyze data", + "Run JavaScript to test a function", + "Compile and run Rust code" + ] + } + }, + { + "exportName": "executeCodeAsync", + "description": "Execute code asynchronously in a secure sandbox. Returns a job_id immediately for tracking.", + "parameters": [ + { + "name": "language", + "type": "string", + "description": "Programming language to execute", + "required": true + }, + { + "name": "code", + "type": "string", + "description": "The source code to execute", + "required": true + } + ], + "returns": { + "type": "object", + "description": "Job info with job_id for tracking" + }, + "aiAgent": { + "useCase": "Use for long-running code that may take time to complete. Check status with getJob.", + "examples": [ + "Run a long computation asynchronously", + "Execute code that may take several minutes" + ] + } + }, + { + "exportName": "runCode", + "description": "Execute code with automatic language detection from shebang line (e.g., #!/usr/bin/env python3).", + "parameters": [ + { + "name": "code", + "type": "string", + "description": "Source code with shebang line for language detection", + "required": true + } + ], + "returns": { + "type": "object", + "description": "Execution result with stdout, stderr, and detected language" + }, + "aiAgent": { + "useCase": "Simpler alternative to executeCode when your code has a shebang line.", + "examples": [ + "Run a script with #!/usr/bin/env python3", + "Execute bash script with #!/bin/bash" + ] + } + }, + { + "exportName": "runCodeAsync", + "description": "Execute code asynchronously with automatic language detection from shebang.", + "parameters": [ + { + "name": "code", + "type": "string", + "description": "Source code with shebang line", + "required": true + } + ], + "returns": { + "type": "object", + "description": "Job info with job_id" + }, + "aiAgent": { + "useCase": "Async version of runCode for long-running scripts.", + "examples": ["Run a long Python script asynchronously"] + } + }, + { + "exportName": "listJobs", + "description": "List all active jobs for your API key. Jobs are retained for 3 minutes after completion.", + "parameters": [], + "returns": { + "type": "object", + "description": "List of jobs with IDs, statuses, and timestamps" + }, + "aiAgent": { + "useCase": "Check what async jobs are currently running or recently completed.", + "examples": ["List all my running code executions"] + } + }, + { + "exportName": "getJob", + "description": "Get status and results of a specific async job.", + "parameters": [ + { + "name": "job_id", + "type": "string", + "description": "The job ID from executeCodeAsync or runCodeAsync", + "required": true + } + ], + "returns": { + "type": "object", + "description": "Job status (pending, running, completed, cancelled, timeout) with stdout/stderr" + }, + "aiAgent": { + "useCase": "Check if an async job has completed and get its output.", + "examples": ["Get results of job abc123"] + } + }, + { + "exportName": "cancelJob", + "description": "Cancel a running or pending async job.", + "parameters": [ + { + "name": "job_id", + "type": "string", + "description": "The job ID to cancel", + "required": true + } + ], + "returns": { + "type": "object", + "description": "Cancellation confirmation with partial output collected" + }, + "aiAgent": { + "useCase": "Stop a long-running job that's no longer needed.", + "examples": ["Cancel job abc123"] + } + }, + { + "exportName": "listLanguages", + "description": "List all 42+ supported programming languages and their aliases.", + "parameters": [], + "returns": { + "type": "object", + "description": "List of supported languages with aliases" + }, + "aiAgent": { + "useCase": "Discover what languages are available before executing code.", + "examples": ["What languages can I execute?"] + } + } + ] + } +} diff --git a/packages/tools/unsandbox/src/index.ts b/packages/tools/unsandbox/src/index.ts new file mode 100644 index 0000000..9e04429 --- /dev/null +++ b/packages/tools/unsandbox/src/index.ts @@ -0,0 +1,20 @@ +/** + * @tpmjs/unsandbox + * + * AI SDK tools for secure code execution in 42+ programming languages. + * Wraps @thomasdavis/unsandbox for use with the TPMJS registry. + * + * Requires UNSANDBOX_API_KEY environment variable. + * Get an API key at https://unsandbox.com/api-keys + */ + +export { + executeCode, + executeCodeAsync, + runCode, + runCodeAsync, + listJobs, + getJob, + cancelJob, + listLanguages, +} from '@thomasdavis/unsandbox'; diff --git a/packages/tools/unsandbox/tsconfig.json b/packages/tools/unsandbox/tsconfig.json new file mode 100644 index 0000000..eb15958 --- /dev/null +++ b/packages/tools/unsandbox/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@tpmjs/tsconfig/base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fa3013..78c9268 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -648,6 +648,19 @@ importers: specifier: ^5.7.2 version: 5.9.3 + packages/tools/unsandbox: + dependencies: + '@thomasdavis/unsandbox': + specifier: ^0.0.3 + version: 0.0.3(zod@4.1.13) + devDependencies: + '@tpmjs/tsconfig': + specifier: workspace:* + version: link:../../config/tsconfig + typescript: + specifier: ^5.7.2 + version: 5.9.3 + packages/types: dependencies: zod: @@ -2416,6 +2429,9 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@thomasdavis/unsandbox@0.0.3': + resolution: {integrity: sha512-7Bmql6ykkpd+S3foMKGjnnNQhfh0iUriE0f9YAhyx7C+4qicsb5oGJ0rkOBI8Pk5VXx/PPUm36+VNNKqqPzozg==} + '@total-typescript/ts-reset@0.6.1': resolution: {integrity: sha512-cka47fVSo6lfQDIATYqb/vO1nvFfbPw7uWLayIXIhGETj0wcOOlrlkobOMDNQOFr9QOafegUPq13V2+6vtD7yg==} @@ -7903,6 +7919,15 @@ snapshots: dependencies: '@testing-library/dom': 10.4.0 + '@thomasdavis/unsandbox@0.0.3(zod@4.1.13)': + dependencies: + ai: 6.0.0-beta.131(effect@3.18.4)(zod@4.1.13) + transitivePeerDependencies: + - '@valibot/to-json-schema' + - arktype + - effect + - zod + '@total-typescript/ts-reset@0.6.1': {} '@tybys/wasm-util@0.10.1':