mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-16 11:03:48 +00:00
docs: documentation overhaul and universal schema reference (#10)
* remove website .astro * fix default origin * docs: comprehensive documentation overhaul - Add quickstart with multi-platform examples (E2B, Daytona, Docker, local) - Add environment variables setup with platform-specific tabs - Add Python SDK page (coming soon) - Add local deployment guide - Update E2B/Daytona/Docker guides with TypeScript examples - Configure OpenAPI auto-generation for API reference - Add CORS configuration guide - Update manage-sessions with Rivet Actors examples - Fix SDK method names and URLs throughout - Add icons to main documentation pages - Remove outdated universal-api and http-api pages * docs: add universal schema and agent compatibility docs - Create universal-schema.mdx with full event/item schema reference - Create agent-compatibility.mdx mirroring README feature matrix - Rename glossary.md to universal-schema.mdx - Update CLAUDE.md with sync requirements for new docs - Add links in README to building-chat-ui, manage-sessions, universal-schema - Fix CLI docs link (rivet.dev -> sandboxagent.dev) * docs: add inspector page and daytona network limits warning
This commit is contained in:
parent
a6f77f3008
commit
08d299a3ef
40 changed files with 1996 additions and 1004 deletions
291
docs/universal-schema.mdx
Normal file
291
docs/universal-schema.mdx
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
---
|
||||
title: "Universal Schema"
|
||||
description: "Reference for the universal event and item schema."
|
||||
icon: "brackets-curly"
|
||||
---
|
||||
|
||||
The universal schema normalizes events from all supported agents (Claude Code, Codex, OpenCode, Amp) into a consistent format. This lets you build UIs and persistence layers that work with any agent without special-casing.
|
||||
|
||||
The schema is defined in [OpenAPI format](https://github.com/rivet-dev/sandbox-agent/blob/main/docs/openapi.json). See the [HTTP API Reference](/api-reference) for endpoint documentation.
|
||||
|
||||
## UniversalEvent
|
||||
|
||||
Every event from the API is wrapped in a `UniversalEvent` envelope.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `event_id` | string | Unique identifier for this event |
|
||||
| `sequence` | integer | Monotonic sequence number within the session (starts at 1) |
|
||||
| `time` | string | RFC3339 timestamp |
|
||||
| `session_id` | string | Daemon-generated session identifier |
|
||||
| `native_session_id` | string? | Provider-native session/thread identifier (e.g., Codex `threadId`, OpenCode `sessionID`) |
|
||||
| `source` | string | Event origin: `agent` (native) or `daemon` (synthetic) |
|
||||
| `synthetic` | boolean | Whether this event was generated by the daemon to fill gaps |
|
||||
| `type` | string | Event type (see [Event Types](#event-types)) |
|
||||
| `data` | object | Event-specific payload |
|
||||
| `raw` | any? | Original provider payload (only when `include_raw=true`) |
|
||||
|
||||
```json
|
||||
{
|
||||
"event_id": "evt_abc123",
|
||||
"sequence": 1,
|
||||
"time": "2025-01-28T12:00:00Z",
|
||||
"session_id": "my-session",
|
||||
"native_session_id": "thread_xyz",
|
||||
"source": "agent",
|
||||
"synthetic": false,
|
||||
"type": "item.completed",
|
||||
"data": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
## Event Types
|
||||
|
||||
### Session Lifecycle
|
||||
|
||||
| Type | Description | Data |
|
||||
|------|-------------|------|
|
||||
| `session.started` | Session has started | `{ metadata?: any }` |
|
||||
| `session.ended` | Session has ended | `{ reason, terminated_by }` |
|
||||
|
||||
**SessionEndedData**
|
||||
|
||||
| Field | Type | Values |
|
||||
|-------|------|--------|
|
||||
| `reason` | string | `completed`, `error`, `terminated` |
|
||||
| `terminated_by` | string | `agent`, `daemon` |
|
||||
|
||||
### Item Lifecycle
|
||||
|
||||
| Type | Description | Data |
|
||||
|------|-------------|------|
|
||||
| `item.started` | Item creation | `{ item }` |
|
||||
| `item.delta` | Streaming content delta | `{ item_id, native_item_id?, delta }` |
|
||||
| `item.completed` | Item finalized | `{ item }` |
|
||||
|
||||
Items follow a consistent lifecycle: `item.started` → `item.delta` (0 or more) → `item.completed`.
|
||||
|
||||
### HITL (Human-in-the-Loop)
|
||||
|
||||
| Type | Description | Data |
|
||||
|------|-------------|------|
|
||||
| `permission.requested` | Permission request pending | `{ permission_id, action, status, metadata? }` |
|
||||
| `permission.resolved` | Permission granted or denied | `{ permission_id, action, status, metadata? }` |
|
||||
| `question.requested` | Question pending user input | `{ question_id, prompt, options, status }` |
|
||||
| `question.resolved` | Question answered or rejected | `{ question_id, prompt, options, status, response? }` |
|
||||
|
||||
**PermissionEventData**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `permission_id` | string | Identifier for the permission request |
|
||||
| `action` | string | What the agent wants to do |
|
||||
| `status` | string | `requested`, `approved`, `denied` |
|
||||
| `metadata` | any? | Additional context |
|
||||
|
||||
**QuestionEventData**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `question_id` | string | Identifier for the question |
|
||||
| `prompt` | string | Question text |
|
||||
| `options` | string[] | Available answer options |
|
||||
| `status` | string | `requested`, `answered`, `rejected` |
|
||||
| `response` | string? | Selected answer (when resolved) |
|
||||
|
||||
### Errors
|
||||
|
||||
| Type | Description | Data |
|
||||
|------|-------------|------|
|
||||
| `error` | Runtime error | `{ message, code?, details? }` |
|
||||
| `agent.unparsed` | Parse failure | `{ error, location, raw_hash? }` |
|
||||
|
||||
The `agent.unparsed` event indicates the daemon failed to parse an agent payload. This should be treated as a bug.
|
||||
|
||||
## UniversalItem
|
||||
|
||||
Items represent discrete units of content within a session.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `item_id` | string | Daemon-generated identifier |
|
||||
| `native_item_id` | string? | Provider-native item/message identifier |
|
||||
| `parent_id` | string? | Parent item ID (e.g., tool call/result parented to a message) |
|
||||
| `kind` | string | Item category (see below) |
|
||||
| `role` | string? | Actor role for message items |
|
||||
| `status` | string | Lifecycle status |
|
||||
| `content` | ContentPart[] | Ordered list of content parts |
|
||||
|
||||
### ItemKind
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `message` | User or assistant message |
|
||||
| `tool_call` | Tool invocation |
|
||||
| `tool_result` | Tool execution result |
|
||||
| `system` | System message |
|
||||
| `status` | Status update |
|
||||
| `unknown` | Unrecognized item type |
|
||||
|
||||
### ItemRole
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `user` | User message |
|
||||
| `assistant` | Assistant response |
|
||||
| `system` | System prompt |
|
||||
| `tool` | Tool-related message |
|
||||
|
||||
### ItemStatus
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `in_progress` | Item is streaming or pending |
|
||||
| `completed` | Item is finalized |
|
||||
| `failed` | Item execution failed |
|
||||
|
||||
## Content Parts
|
||||
|
||||
The `content` array contains typed parts that make up an item's payload.
|
||||
|
||||
### text
|
||||
|
||||
Plain text content.
|
||||
|
||||
```json
|
||||
{ "type": "text", "text": "Hello, world!" }
|
||||
```
|
||||
|
||||
### json
|
||||
|
||||
Structured JSON content.
|
||||
|
||||
```json
|
||||
{ "type": "json", "json": { "key": "value" } }
|
||||
```
|
||||
|
||||
### tool_call
|
||||
|
||||
Tool invocation.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `name` | string | Tool name |
|
||||
| `arguments` | string | JSON-encoded arguments |
|
||||
| `call_id` | string | Unique call identifier |
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tool_call",
|
||||
"name": "read_file",
|
||||
"arguments": "{\"path\": \"/src/main.ts\"}",
|
||||
"call_id": "call_abc123"
|
||||
}
|
||||
```
|
||||
|
||||
### tool_result
|
||||
|
||||
Tool execution result.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `call_id` | string | Matching call identifier |
|
||||
| `output` | string | Tool output |
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tool_result",
|
||||
"call_id": "call_abc123",
|
||||
"output": "File contents here..."
|
||||
}
|
||||
```
|
||||
|
||||
### file_ref
|
||||
|
||||
File reference with optional diff.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `path` | string | File path |
|
||||
| `action` | string | `read`, `write`, `patch` |
|
||||
| `diff` | string? | Unified diff (for patches) |
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "file_ref",
|
||||
"path": "/src/main.ts",
|
||||
"action": "write",
|
||||
"diff": "@@ -1,3 +1,4 @@\n+import { foo } from 'bar';"
|
||||
}
|
||||
```
|
||||
|
||||
### image
|
||||
|
||||
Image reference.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `path` | string | Image file path |
|
||||
| `mime` | string? | MIME type |
|
||||
|
||||
```json
|
||||
{ "type": "image", "path": "/tmp/screenshot.png", "mime": "image/png" }
|
||||
```
|
||||
|
||||
### reasoning
|
||||
|
||||
Model reasoning/thinking content.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `text` | string | Reasoning text |
|
||||
| `visibility` | string | `public` or `private` |
|
||||
|
||||
```json
|
||||
{ "type": "reasoning", "text": "Let me think about this...", "visibility": "public" }
|
||||
```
|
||||
|
||||
### status
|
||||
|
||||
Status indicator.
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `label` | string | Status label |
|
||||
| `detail` | string? | Additional detail |
|
||||
|
||||
```json
|
||||
{ "type": "status", "label": "Running tests", "detail": "3 of 10 passed" }
|
||||
```
|
||||
|
||||
## Source & Synthetics
|
||||
|
||||
### EventSource
|
||||
|
||||
The `source` field indicates who emitted the event:
|
||||
|
||||
| Value | Description |
|
||||
|-------|-------------|
|
||||
| `agent` | Native event from the agent |
|
||||
| `daemon` | Synthetic event generated by the daemon |
|
||||
|
||||
### Synthetic Events
|
||||
|
||||
The daemon emits synthetic events (`synthetic: true`, `source: "daemon"`) to provide a consistent event stream across all agents. Common synthetics:
|
||||
|
||||
| Synthetic | When |
|
||||
|-----------|------|
|
||||
| `session.started` | Agent doesn't emit explicit session start |
|
||||
| `session.ended` | Agent doesn't emit explicit session end |
|
||||
| `item.started` | Agent doesn't emit item start events |
|
||||
| `item.delta` | Agent doesn't stream deltas natively |
|
||||
| `question.*` | Claude Code plan mode (from ExitPlanMode tool) |
|
||||
|
||||
### Raw Payloads
|
||||
|
||||
Pass `include_raw=true` to event endpoints to receive the original agent payload in the `raw` field. Useful for debugging or accessing agent-specific data not in the universal schema.
|
||||
|
||||
```typescript
|
||||
const events = await client.getEvents("my-session", { includeRaw: true });
|
||||
// events[0].raw contains the original agent payload
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue