@sandagent/sdk
v0.9.14
Published
SandAgent SDK - AI Provider and React hooks for building AI agents
Downloads
6,284
Readme
Why @sandagent/sdk?
Coding Agents (Claude Code, Codex CLI, Gemini CLI, OpenCode …) already have:
- ✅ Sophisticated memory & context management
- ✅ Battle-tested tool use (bash, file I/O, web search)
- ✅ MCP server ecosystem
- ✅ Refined prompts from millions of interactions
@sandagent/sdk lets you harness all of that inside your own product — as a standard AI SDK model, with zero prompt engineering.
Your App → @sandagent/sdk → Coding Agent (Claude / Codex / …)
↕
Sandbox (Local or Cloud)Features
| Feature | Description |
|---------|-------------|
| 🔌 AI SDK Provider | createSandAgent() returns a model you pass to streamText / generateText |
| ⚛️ React Hooks | useSandAgentChat, useArtifacts, useWriteTool, useAskUserQuestion |
| 🖥️ Local Mode | Built-in LocalSandbox — run on your machine for Desktop apps & debugging |
| ☁️ Cloud Sandboxes | Plug in Sandock, E2B, or Daytona for isolated cloud execution |
| 🎨 Agent Templates | Markdown-based templates turn a generic agent into a domain expert |
| 🔄 Multi-turn Sessions | Resume conversations with full filesystem continuity |
Quick Start
1. Install
npm install @sandagent/sdk ai2. Backend — Create an API Route (Next.js)
// app/api/ai/route.ts
import { createSandAgent, LocalSandbox } from "@sandagent/sdk";
import {
convertToModelMessages,
createUIMessageStream,
createUIMessageStreamResponse,
streamText,
} from "ai";
export async function POST(request: Request) {
const { messages } = await request.json();
const sandbox = new LocalSandbox({
workdir: process.cwd(),
templatesPath: process.cwd(),
runnerCommand: ["npx", "-y", "@sandagent/runner-cli@latest", "run"],
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
const sandagent = createSandAgent({
sandbox,
cwd: sandbox.getWorkdir(),
});
const stream = createUIMessageStream({
execute: async ({ writer }) => {
const result = streamText({
model: sandagent("sonnet"),
messages: await convertToModelMessages(messages),
abortSignal: request.signal,
});
writer.merge(result.toUIMessageStream());
},
});
return createUIMessageStreamResponse({ stream });
}3. Frontend — Chat UI
"use client";
import { useSandAgentChat } from "@sandagent/sdk/react";
export default function Chat() {
const { messages, isLoading, sendMessage } = useSandAgentChat({
apiEndpoint: "/api/ai",
});
return (
<div>
{messages.map((m) => (
<div key={m.id}>
{m.parts.map((p, i) => p.type === "text" && <span key={i}>{p.text}</span>)}
</div>
))}
<form onSubmit={(e) => { e.preventDefault(); sendMessage(e.currentTarget.input.value); }}>
<input name="input" placeholder="Ask anything…" />
<button disabled={isLoading}>Send</button>
</form>
</div>
);
}4. Run
export ANTHROPIC_API_KEY=sk-ant-xxx
npm run devThat's it — you now have a full Coding Agent streaming into your app.
Local vs Cloud Sandbox
Local Mode (Desktop apps & debugging)
LocalSandbox is built-in — no extra packages needed. The agent runs directly on your machine's filesystem.
import { createSandAgent, LocalSandbox } from "@sandagent/sdk";
const sandbox = new LocalSandbox({
workdir: "/path/to/project",
templatesPath: "./my-agent-template",
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
const sandagent = createSandAgent({ sandbox, cwd: sandbox.getWorkdir() });Best for: Electron/Tauri desktop apps, local development, debugging.
Cloud Mode — Sandock (Recommended)
Sandock provides Docker-based cloud sandboxes with persistent volumes.
Why Sandock? Coding Agents rely on filesystem
appendand other POSIX semantics. Sandock is the only cloud sandbox with 100% POSIX-compatible filesystems, ensuring agents run without FS failures. Volumes are persistent and shareable across sandboxes.
npm install @sandagent/sandbox-sandockimport { createSandAgent } from "@sandagent/sdk";
import { SandockSandbox } from "@sandagent/sandbox-sandock";
const sandbox = new SandockSandbox({
apiKey: process.env.SANDOCK_API_KEY, // Get yours at https://sandock.ai
image: "ghcr.io/vikadata/sandagent:latest", // Pre-built image (fast startup)
skipBootstrap: true,
workdir: "/workspace",
env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
// Optional: persistent volumes
volumes: [
{ volumeName: "my-workspace", volumeMountPath: "/workspace" },
],
});
const sandagent = createSandAgent({ sandbox, cwd: sandbox.getWorkdir() });| Sandock Option | Description |
|----------------|-------------|
| apiKey | Your Sandock API key (sandock.ai) |
| image | Docker image — use ghcr.io/vikadata/sandagent:latest for pre-built, or sandockai/sandock-code:latest |
| skipBootstrap | true when using pre-built image (skips npm install inside sandbox) |
| volumes | Named volumes for persistent workspace & session storage |
| keep | true (default) keeps sandbox alive ~30 min after execution |
| memoryLimitMb | Memory limit in MB |
Other Cloud Sandboxes
npm install @sandagent/sandbox-e2b # E2B cloud sandbox
npm install @sandagent/sandbox-daytona # Daytona workspaceimport { E2BSandbox } from "@sandagent/sandbox-e2b";
const sandbox = new E2BSandbox({ apiKey: process.env.E2B_API_KEY });
import { DaytonaSandbox } from "@sandagent/sandbox-daytona";
const sandbox = new DaytonaSandbox({ apiKey: process.env.DAYTONA_API_KEY });Agent Templates
Templates customize what the agent knows and how it behaves — pure Markdown, no code.
my-agent/
├── CLAUDE.md # System instructions
├── skills/
│ └── sql-expert/
│ └── SKILL.md # Modular capability
└── .claude/
└── mcp.json # MCP server integrationsconst sandbox = new LocalSandbox({
workdir: process.cwd(),
templatesPath: "./templates/analyst", // Point to your template
});Built-in templates: default, coder, analyst, researcher, seo-agent.
React Hooks
All hooks are available from @sandagent/sdk/react:
import {
useSandAgentChat, // Full chat with streaming
useArtifacts, // Display agent-generated files (reports, charts)
useWriteTool, // Handle file write tool calls
useAskUserQuestion, // Handle interactive questions from the agent
} from "@sandagent/sdk/react";API Reference
Provider
createSandAgent — sandbox transport (cloud / local filesystem)
import { createSandAgent, LocalSandbox } from "@sandagent/sdk";
const sandagent = createSandAgent({
sandbox: SandboxAdapter, // LocalSandbox, SandockSandbox, E2BSandbox, etc.
cwd?: string, // Working directory inside sandbox
env?: Record<string, string>, // Environment variables
template?: string, // Template name
resume?: string, // Session ID for multi-turn
verbose?: boolean, // Debug logging
});
const model = sandagent("claude-sonnet-4-20250514");Daemon HTTP transport (same provider)
With any sandbox adapter (E2B, Sandock, LocalSandbox, etc.): pass sandbox + daemonUrl. The URL is resolved inside the sandbox (the vikadata/sandagent image starts sandagent-daemon on port 3080). The SDK streams via streamCodingRunFromSandbox (curl -N in the sandbox, including LocalSandbox), not fetch from your server. It does not call /healthz for you — use isSandagentDaemonHealthy from @sandagent/sdk when you want a probe before setting daemonUrl (e.g. to fall back to the CLI runner).
import { createSandAgent, DEFAULT_SANDAGENT_DAEMON_URL } from "@sandagent/sdk";
const sandagent = createSandAgent({
sandbox: mySandboxAdapter,
daemonUrl: DEFAULT_SANDAGENT_DAEMON_URL, // http://127.0.0.1:3080 inside the container
runnerType: "claude",
cwd: "/workspace",
});Omit daemonUrl to use the CLI runner in the same sandbox. createSandAgent always requires a sandbox adapter.
Exports
| Entry Point | Exports |
|-------------|---------|
| @sandagent/sdk | createSandAgent, LocalSandbox, SandAgentLanguageModel, submitAnswer, DEFAULT_SANDAGENT_DAEMON_URL (re-exported from @sandagent/manager) |
| @sandagent/sdk/react | useSandAgentChat, useArtifacts, useWriteTool, useAskUserQuestion, DEFAULT_SANDAGENT_DAEMON_URL (re-exported from @sandagent/manager) |
Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| ANTHROPIC_API_KEY | Yes | Anthropic API key |
| SANDOCK_API_KEY | For Sandock | sandock.ai API key |
| E2B_API_KEY | For E2B | E2B API key |
| DAYTONA_API_KEY | For Daytona | Daytona API key |
Documentation
📖 Full docs: sandagent.dev/docs
License
Apache-2.0
