mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 19:05:18 +00:00
adding compute example
This commit is contained in:
parent
d67cc6edf4
commit
11950d2a39
7 changed files with 616 additions and 23 deletions
214
docs/deploy/computesdk.mdx
Normal file
214
docs/deploy/computesdk.mdx
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
---
|
||||
title: "ComputeSDK"
|
||||
description: "Deploy the daemon using ComputeSDK's provider-agnostic sandbox API."
|
||||
---
|
||||
|
||||
[ComputeSDK](https://computesdk.com) provides a unified interface for managing sandboxes across multiple providers. Write once, deploy anywhere—switch providers by changing environment variables.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- `COMPUTESDK_API_KEY` from [console.computesdk.com](https://console.computesdk.com)
|
||||
- Provider API key (one of: `E2B_API_KEY`, `DAYTONA_API_KEY`, `VERCEL_TOKEN`, `MODAL_TOKEN_ID` + `MODAL_TOKEN_SECRET`, `BLAXEL_API_KEY`, `CSB_API_KEY`)
|
||||
- `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` for the coding agents
|
||||
|
||||
## TypeScript Example
|
||||
|
||||
```typescript
|
||||
import {
|
||||
compute,
|
||||
detectProvider,
|
||||
getMissingEnvVars,
|
||||
getProviderConfigFromEnv,
|
||||
isProviderAuthComplete,
|
||||
isValidProvider,
|
||||
PROVIDER_NAMES,
|
||||
type ExplicitComputeConfig,
|
||||
type ProviderName,
|
||||
} from "computesdk";
|
||||
import { SandboxAgent } from "sandbox-agent";
|
||||
|
||||
const PORT = 3000;
|
||||
const REQUEST_TIMEOUT_MS =
|
||||
Number.parseInt(process.env.COMPUTESDK_TIMEOUT_MS || "", 10) || 120_000;
|
||||
|
||||
/**
|
||||
* Detects and validates the provider to use.
|
||||
* Priority: COMPUTESDK_PROVIDER env var > auto-detection from API keys
|
||||
*/
|
||||
function resolveProvider(): ProviderName {
|
||||
const providerOverride = process.env.COMPUTESDK_PROVIDER;
|
||||
|
||||
if (providerOverride) {
|
||||
if (!isValidProvider(providerOverride)) {
|
||||
throw new Error(
|
||||
`Unsupported provider "${providerOverride}". Supported: ${PROVIDER_NAMES.join(", ")}`
|
||||
);
|
||||
}
|
||||
if (!isProviderAuthComplete(providerOverride)) {
|
||||
const missing = getMissingEnvVars(providerOverride);
|
||||
throw new Error(
|
||||
`Missing credentials for "${providerOverride}". Set: ${missing.join(", ")}`
|
||||
);
|
||||
}
|
||||
return providerOverride as ProviderName;
|
||||
}
|
||||
|
||||
const detected = detectProvider();
|
||||
if (!detected) {
|
||||
throw new Error(
|
||||
`No provider credentials found. Set one of: ${PROVIDER_NAMES.map((p) => getMissingEnvVars(p).join(", ")).join(" | ")}`
|
||||
);
|
||||
}
|
||||
return detected as ProviderName;
|
||||
}
|
||||
|
||||
function configureComputeSDK(): void {
|
||||
const provider = resolveProvider();
|
||||
|
||||
const config: ExplicitComputeConfig = {
|
||||
provider,
|
||||
computesdkApiKey: process.env.COMPUTESDK_API_KEY,
|
||||
requestTimeoutMs: REQUEST_TIMEOUT_MS,
|
||||
};
|
||||
|
||||
// Add provider-specific config from environment
|
||||
const providerConfig = getProviderConfigFromEnv(provider);
|
||||
if (Object.keys(providerConfig).length > 0) {
|
||||
(config as any)[provider] = providerConfig;
|
||||
}
|
||||
|
||||
compute.setConfig(config);
|
||||
}
|
||||
|
||||
configureComputeSDK();
|
||||
|
||||
// Build environment variables to pass to sandbox
|
||||
const envs: Record<string, string> = {};
|
||||
if (process.env.ANTHROPIC_API_KEY) envs.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
|
||||
if (process.env.OPENAI_API_KEY) envs.OPENAI_API_KEY = process.env.OPENAI_API_KEY;
|
||||
|
||||
// Create sandbox
|
||||
const sandbox = await compute.sandbox.create({
|
||||
envs: Object.keys(envs).length > 0 ? envs : undefined,
|
||||
});
|
||||
|
||||
// Helper to run commands with error handling
|
||||
const run = async (cmd: string, options?: { background?: boolean }) => {
|
||||
const result = await sandbox.runCommand(cmd, options);
|
||||
if (typeof result?.exitCode === "number" && result.exitCode !== 0) {
|
||||
throw new Error(`Command failed: ${cmd} (exit ${result.exitCode})\n${result.stderr || ""}`);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Install sandbox-agent
|
||||
await run("curl -fsSL https://releases.rivet.dev/sandbox-agent/latest/install.sh | sh");
|
||||
|
||||
// Install agents conditionally based on available API keys
|
||||
if (envs.ANTHROPIC_API_KEY) {
|
||||
await run("sandbox-agent install-agent claude");
|
||||
}
|
||||
if (envs.OPENAI_API_KEY) {
|
||||
await run("sandbox-agent install-agent codex");
|
||||
}
|
||||
|
||||
// Start the server in the background
|
||||
await run(`sandbox-agent server --no-token --host 0.0.0.0 --port ${PORT}`, { background: true });
|
||||
|
||||
// Get the public URL for the sandbox
|
||||
const baseUrl = await sandbox.getUrl({ port: PORT });
|
||||
|
||||
// Wait for server to be ready
|
||||
const deadline = Date.now() + REQUEST_TIMEOUT_MS;
|
||||
while (Date.now() < deadline) {
|
||||
try {
|
||||
const response = await fetch(`${baseUrl}/v1/health`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data?.status === "ok") break;
|
||||
}
|
||||
} catch {
|
||||
// Server not ready yet
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, 500));
|
||||
}
|
||||
|
||||
// Connect to the server
|
||||
const client = await SandboxAgent.connect({ baseUrl });
|
||||
|
||||
// Detect which agent to use based on available API keys
|
||||
const agent = envs.ANTHROPIC_API_KEY ? "claude" : "codex";
|
||||
|
||||
// Create a session and start coding
|
||||
await client.createSession("my-session", { agent });
|
||||
|
||||
await client.postMessage("my-session", {
|
||||
message: "Summarize this repository",
|
||||
});
|
||||
|
||||
for await (const event of client.streamEvents("my-session")) {
|
||||
console.log(event.type, event.data);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
await sandbox.destroy();
|
||||
```
|
||||
|
||||
## Supported Providers
|
||||
|
||||
ComputeSDK auto-detects your provider from environment variables:
|
||||
|
||||
| Provider | Environment Variables |
|
||||
|----------|----------------------|
|
||||
| E2B | `E2B_API_KEY` |
|
||||
| Daytona | `DAYTONA_API_KEY` |
|
||||
| Vercel | `VERCEL_TOKEN` or `VERCEL_OIDC_TOKEN` |
|
||||
| Modal | `MODAL_TOKEN_ID` + `MODAL_TOKEN_SECRET` |
|
||||
| Blaxel | `BLAXEL_API_KEY` |
|
||||
| CodeSandbox | `CSB_API_KEY` |
|
||||
|
||||
## Notes
|
||||
|
||||
- **Provider resolution order**: `COMPUTESDK_PROVIDER` env var takes priority, otherwise auto-detection from API keys.
|
||||
- **Conditional agent installation**: Only agents with available API keys are installed, reducing setup time.
|
||||
- **Command error handling**: The example validates exit codes and throws on failures for easier debugging.
|
||||
- `sandbox.runCommand(..., { background: true })` keeps the server running while your app continues.
|
||||
- `sandbox.getUrl({ port })` returns a public URL for the sandbox port.
|
||||
- Always destroy the sandbox when you are done to avoid leaking resources.
|
||||
- If sandbox creation times out, set `COMPUTESDK_TIMEOUT_MS` to a higher value (default: 120000ms).
|
||||
|
||||
## Explicit Provider Selection
|
||||
|
||||
To force a specific provider instead of auto-detection, set the `COMPUTESDK_PROVIDER` environment variable:
|
||||
|
||||
```bash
|
||||
export COMPUTESDK_PROVIDER=e2b
|
||||
```
|
||||
|
||||
Or configure programmatically using `getProviderConfigFromEnv()`:
|
||||
|
||||
```typescript
|
||||
import { compute, getProviderConfigFromEnv, type ExplicitComputeConfig } from "computesdk";
|
||||
|
||||
const config: ExplicitComputeConfig = {
|
||||
provider: "e2b",
|
||||
computesdkApiKey: process.env.COMPUTESDK_API_KEY,
|
||||
requestTimeoutMs: 120_000,
|
||||
};
|
||||
|
||||
// Automatically populate provider-specific config from environment
|
||||
const providerConfig = getProviderConfigFromEnv("e2b");
|
||||
if (Object.keys(providerConfig).length > 0) {
|
||||
(config as any).e2b = providerConfig;
|
||||
}
|
||||
|
||||
compute.setConfig(config);
|
||||
```
|
||||
|
||||
## Direct Mode (No ComputeSDK API Key)
|
||||
|
||||
To bypass the ComputeSDK gateway and use provider SDKs directly, see the provider-specific examples:
|
||||
|
||||
- [E2B](/deploy/e2b)
|
||||
- [Daytona](/deploy/daytona)
|
||||
- [Vercel](/deploy/vercel)
|
||||
|
|
@ -57,6 +57,7 @@
|
|||
"icon": "server",
|
||||
"pages": [
|
||||
"deploy/local",
|
||||
"deploy/computesdk",
|
||||
"deploy/e2b",
|
||||
"deploy/daytona",
|
||||
"deploy/vercel",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue