acontext-chatbot-integration
SKILL.md
Acontext Chatbot Integration
Integration patterns for building AI chatbots with Acontext SDK - session management, disk tools, sandbox execution, and artifact storage.
Architecture
Core Principle: One Session = One Conversation = One Disk (1:1:1)
┌─────────────────────────────────────────────────────┐
│ Your Chatbot │
├─────────────────────────────────────────────────────┤
│ LLM Client │ Tool Router │ Session Manager │
└──────┬───────┴───────┬───────┴────────┬─────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┤
│ Acontext SDK (Storage Layer) │
├─────────────────────────────────────────────────────┤
│ sessions.* disks.* sandboxes.* │
│ - storeMessage - create - create │
│ - getMessages - artifacts.* - execCommand │
│ - getTokenCounts - upsert - kill │
│ - delete - get │
└─────────────────────────────────────────────────────┘
Do NOT use database for messages! All messages via sessions.storeMessage() and sessions.getMessages().
Quick Start
import { AcontextClient, DISK_TOOLS, SANDBOX_TOOLS } from "@acontext/acontext";
// 1. Initialize
const client = new AcontextClient({ apiKey: process.env.ACONTEXT_API_KEY });
// 2. Create session + disk (1:1 binding)
const session = await client.sessions.create({ user: "user@example.com" });
const disk = await client.disks.create();
// 3. Store message (MUST include format option!)
await client.sessions.storeMessage(session.id, {
role: "user",
content: "Hello!"
}, { format: "openai" });
// 4. Load messages
const messages = await client.sessions.getMessages(session.id, { format: "openai" });
Reference Documentation
| Topic | File | When to Read |
|---|---|---|
| API Reference | api-reference.md | SDK methods, parameters, return types |
| Implementation | implementation.md | Full code examples, Next.js routes |
| Session Management | session-management.md | Lifecycle, 1:1 binding, list management |
| Context Compression | context-compression.md | Token monitoring, auto-compression |
| Disk Path Mapping | disk-path-mapping.md | disk:: protocol, URL expiration |
| Vision API | vision-api.md | Multimodal content, image processing |
| Streaming | streaming.md | SSE server and client implementation |
| Skill System | skill-system.md | Mount Acontext skills into sandboxes |
| Session Cleanup | session-cleanup.md | Delete sessions, batch cleanup |
| Error Handling | error-handling.md | API errors, retry strategies |
| Debugging | debugging.md | Logging format, common issues |
| Troubleshooting | troubleshooting.md | 404 errors, tool sequence errors |
Tool Categories
Disk Tools (DISK_TOOLS)
| Tool | Purpose |
|---|---|
write_file_disk |
Create/overwrite files |
read_file_disk |
Read file contents |
replace_string_disk |
Find and replace |
list_disk |
List directory |
grep_disk / glob_disk |
Search files |
download_file_disk |
Get public URL |
const ctx = DISK_TOOLS.format_context(client, diskId);
const result = await DISK_TOOLS.execute_tool(ctx, "write_file_disk", {
filename: "notes.txt",
content: "Hello",
file_path: "/"
});
Sandbox Tools (SANDBOX_TOOLS)
| Tool | Purpose |
|---|---|
bash_execution_sandbox |
Execute commands |
text_editor_sandbox |
Create/edit files |
export_file_sandbox |
Export to disk with URL |
const ctx = SANDBOX_TOOLS.format_context(client, sandboxId, diskId);
await SANDBOX_TOOLS.execute_tool(ctx, "text_editor_sandbox", {
command: "create",
path: "script.py",
file_text: "print('Hello')"
});
Critical Patterns
Message Sequence for Tool Calls
OpenAI API requires strict ordering: User → Assistant(tool_calls) → Tool Response
// 1. User message
await client.sessions.storeMessage(sessionId, { role: "user", content: "Draw" }, { format: "openai" });
// 2. Assistant with tool_calls (MUST save!)
await client.sessions.storeMessage(sessionId, {
role: "assistant",
content: "",
tool_calls: [{ id: "call_xxx", type: "function", function: {...} }]
}, { format: "openai" });
// 3. Tool response (MUST match tool_call_id!)
await client.sessions.storeMessage(sessionId, {
role: "tool",
tool_call_id: "call_xxx",
content: JSON.stringify({ result: "success" })
}, { format: "openai" });
Common Error: 400 An assistant message with 'tool_calls' must be followed by tool messages
Sandbox: No Heredoc Support
// WRONG - will hang!
command: "python - << 'EOF'\ncode\nEOF"
// CORRECT - create file first, then execute
await SANDBOX_TOOLS.execute_tool(ctx, "text_editor_sandbox", {
command: "create", path: "script.py", file_text: "..."
});
await SANDBOX_TOOLS.execute_tool(ctx, "bash_execution_sandbox", {
command: "python3 script.py"
});
Sandbox: Reuse sandbox_id
// CORRECT: Same sandbox_id across tool calls
let sandboxId: string | undefined;
const ctx1 = SANDBOX_TOOLS.format_context(client, sandboxId, diskId);
await SANDBOX_TOOLS.execute_tool(ctx1, "text_editor_sandbox", {...});
sandboxId = ctx1.sandbox_id; // Save for reuse!
const ctx2 = SANDBOX_TOOLS.format_context(client, sandboxId, diskId);
await SANDBOX_TOOLS.execute_tool(ctx2, "bash_execution_sandbox", {...});
// Now can find the file created earlier!
disk:: Protocol
Use disk:: for permanent image references (S3 URLs expire in ~1 hour):
// Tool returns
{ diskPath: "disk::artifacts/chart.png" }
// Frontend transforms for rendering

See disk-path-mapping.md for implementation.
Tool Routing Pattern
const DISK_TOOL_NAMES = ["write_file_disk", "read_file_disk", "list_disk", ...];
const SANDBOX_TOOL_NAMES = ["bash_execution_sandbox", "text_editor_sandbox", ...];
async function executeToolCall(toolCall, context) {
const { name } = toolCall.function;
const args = JSON.parse(toolCall.function.arguments || "{}");
if (DISK_TOOL_NAMES.includes(name)) {
const ctx = DISK_TOOLS.format_context(context.client, context.diskId);
return DISK_TOOLS.execute_tool(ctx, name, args);
}
if (SANDBOX_TOOL_NAMES.includes(name)) {
const ctx = SANDBOX_TOOLS.format_context(context.client, context.sandboxId, context.diskId);
return SANDBOX_TOOLS.execute_tool(ctx, name, args);
}
throw new Error(`Unknown tool: ${name}`);
}
// Register with LLM
const tools = [
...DISK_TOOLS.to_openai_tool_schema(),
...SANDBOX_TOOLS.to_openai_tool_schema(),
];
Integration Checklist
- Setup: Install
@acontext/acontext, configureACONTEXT_API_KEY - Sessions: Create on new chat, store every message with
{ format: "openai" } - Session + Disk: 1:1 binding, each session gets its own disk
- Message Sequence: Always save tool responses after tool_calls
- disk::: Tools return diskPath, frontend rewrites to API URL
- Compression: Monitor tokens, apply strategies when >80K
- Cleanup: Delete both Session AND Disk when deleting conversation
Common Mistakes
// WRONG: Store messages in database
await supabase.from('messages').insert({ content: "Hello" });
// CORRECT: Store messages in Acontext
await client.sessions.storeMessage(sessionId, { role: "user", content: "Hello" }, { format: "openai" });
// WRONG: Multiple sessions sharing one disk
const sharedDisk = await client.disks.create();
// Don't share this disk across sessions!
// CORRECT: Each session has its own disk
const session = await client.sessions.create({ user });
const disk = await client.disks.create(); // Exclusive to this session
Scripts
Copy these files to your project:
| File | Purpose |
|---|---|
scripts/types.ts |
Core type definitions |
scripts/config.ts |
Environment configuration |
scripts/acontext-client.ts |
SDK wrapper utilities |
scripts/disk-tools.ts |
Disk tool schemas and execution |
scripts/sandbox-tool.ts |
Python sandbox execution |
scripts/openai-client.ts |
OpenAI client with tool routing |
Weekly Installs
3
Repository
mbt1909432/acon…t-skillsFirst Seen
Feb 25, 2026
Security Audits
Installed on
opencode3
claude-code3
github-copilot3
codex3
kimi-cli3
gemini-cli3