@opencomputer/sdk
v0.12.4
Published
TypeScript SDK for OpenComputer - cloud sandbox platform
Downloads
10,999
Readme
@opencomputer/sdk
The official TypeScript SDK for OpenComputer: cloud sandboxes and Durable Agent Sessions (managed background agents).
This one package covers both surfaces — install
@opencomputer/sdk. (The older@opencomputer/agents-sdkis superseded; use this instead.)
Install
npm install @opencomputer/sdkQuick Start
import { Sandbox } from "@opencomputer/sdk";
const sandbox = await Sandbox.create({ template: "base" });
// Execute commands
const result = await sandbox.commands.run("echo hello");
console.log(result.stdout); // "hello\n"
// Read and write files
await sandbox.files.write("/tmp/test.txt", "Hello, world!");
const content = await sandbox.files.read("/tmp/test.txt");
// Clean up
await sandbox.kill();Durable Agent Sessions
Run a managed background agent: define an agent once, then create sessions that stream durable events and call back on completion.
import { OpenComputer, verifyWebhook } from "@opencomputer/sdk";
const oc = new OpenComputer({ apiKey: process.env.OPENCOMPUTER_API_KEY! });
// Bootstrap once — idempotent by name (safe on every deploy):
const agent = await oc.agents.create({
name: "reviewer",
runtime: "claude", // or "codex"
model: "anthropic/claude-opus-4-8",
prompt: "Review the diff. Run tests. Explain risks.",
credential: "managed", // run via OpenComputer, billed to credits — no key
// …or bring your own: key: process.env.ANTHROPIC_API_KEY! (sealed; never enters the sandbox)
});
// Per request — hand off durable work, route the callback via metadata:
const session = await oc.sessions.create({
agent: agent.id,
input: "Review PR #42",
metadata: { pullNumber: 42 }, // echoed back verbatim in the webhook
idempotencyKey: deliveryId, // retry-safe
});
// Register a SIGNED callback (inline create-time destinations can't carry a secret):
await session.destinations.create({ url: "https://app.example.com/oc-callback", secret: process.env.OC_WEBHOOK_SECRET! });
// In your webhook handler — verify the signature, then fetch the result:
const delivery = await verifyWebhook(rawBody, request.headers, process.env.OC_WEBHOOK_SECRET!);
if (delivery.type === "turn.completed") {
const session = await oc.sessions.get(delivery.sessionId!);
const { result } = await session.result();
}Create an agent from a repository
Repository creation is a two-phase review/import so a moving branch cannot change underneath the confirmation. Only an exact review is importable; invalid or unrecognized source should be fixed or reviewed at another root.
const review = await oc.agents.repository.review({
repo: "repo_...",
path: "agents/support",
productionRef: "main",
});
if (review.interpretation.disposition !== "exact") {
throw new Error(review.interpretation.summary);
}
const { agent, deployment } = await oc.agents.repository.import({
name: "Support triage",
credential: "managed",
idempotencyKey: crypto.randomUUID(),
source: {
type: "github",
repo: review.repository.id,
path: review.root,
productionRef: review.productionRef,
},
review: {
sha: review.sha,
sourceProfile: review.interpretation.sourceProfile,
fingerprint: review.reviewFingerprint,
},
});Credentials
Sessions run Managed (via OpenComputer, billed to your credits — credential: "managed", no key, the default for new orgs) or on your own model-provider key (Anthropic for claude, OpenAI for codex). An inline key stores one and attaches it to the agent; manage keys directly to reuse one across agents, set an org default, or rotate/remove:
await oc.credentials.create({ provider: "anthropic", key: process.env.ANTHROPIC_API_KEY!, name: "prod", isDefault: true });
const creds = await oc.credentials.list(); // metadata only — keys are write-only
await oc.credentials.setDefault({ credential: creds[0].id });
await oc.credentials.delete(creds[0].id);Or reference one by id when creating an agent: oc.agents.create({ …, credential: "cred_…" }). A key isn't required — credential: "managed" needs none; a session fails with 422 no_credential only when it resolves to neither Managed nor a usable key. Full guide: Credentials.
Sandbox webhooks (Preview)
Subscribe to sandbox lifecycle events (sandbox.ready, sandbox.stopped, …) — signed, retried, and redeliverable. The same verifyWebhook helper verifies both session and sandbox deliveries. Preview: newly available; the surface may change.
import { Webhooks, verifyWebhook, type SandboxLifecycleEvent } from "@opencomputer/sdk";
const webhooks = new Webhooks({ apiKey: process.env.OPENCOMPUTER_API_KEY! });
// `secret` (whsec_…) is returned ONCE on create — store it; you need it to verify.
const { secret } = await webhooks.create({
url: "https://app.example.com/oc-webhook",
eventTypes: ["sandbox.stopped"],
});
// In your handler — verify against the RAW body, then route:
const delivery = await verifyWebhook<SandboxLifecycleEvent>(rawBody, request.headers, secret);
if (delivery.type === "sandbox.stopped") {
console.log(delivery.sandboxId, delivery.event.data.reason);
}Configuration
Sandboxes (Sandbox):
| Option | Env Variable | Default |
|----------|------------------------|----------------------------------|
| apiUrl | OPENCOMPUTER_API_URL | https://app.opencomputer.dev |
| apiKey | OPENCOMPUTER_API_KEY | (none) |
Durable Agent Sessions (OpenComputer):
| Option | Env Variable | Default |
|-----------|------------------------|------------------------------------|
| baseUrl | — | https://api.opencomputer.dev/v3 |
| apiKey | OPENCOMPUTER_API_KEY | (none) |
Releasing
Bump the version in package.json (and package-lock.json) in any PR that changes the SDK. Publishing only fires on a version change — a change merged without a bump silently won't release. One bump per PR is enough.
License
MIT
