Docs / runtime / architecture

Runtime Architecture

Runra Runtime architecture — layered design, agent orchestration, pluggable providers, event system, and how the open-source runtime works with Runra Sandbox

The Runra Runtime is the open-source orchestration layer that connects AI agents to sandbox infrastructure. It provides a unified interface for agents to create sandboxes, execute code, and receive structured observability events — regardless of which agent, LLM, or sandbox provider you use.

Design Philosophy

Runra Runtime is built on three principles:

  1. Agent-agnostic: Works with any AI coding agent (Claude Code, Codex, OpenCode, custom).
  2. Provider-pluggable: Swap sandbox providers, LLM backends, and observability exporters without changing agent code.
  3. Event-driven: All operations emit typed events that flow to your observability stack.

Architecture Layers

┌─────────────────────────────────────────┐
│          Your Application               │
│  (Next.js, Express, CLI tool, Worker)   │
└───────────────┬─────────────────────────┘

┌───────────────▼─────────────────────────┐
│         Agent Adapters                  │
│  Claude Code │ Codex │ OpenCode │ Custom│
└───────────────┬─────────────────────────┘

┌───────────────▼─────────────────────────┐
│          Runra Runtime                  │
│  ┌─────────────────────────────────────┐ │
│  │         Orchestrator                │ │
│  │  - Sandbox lifecycle management     │ │
│  │  - Tool execution dispatch          │ │
│  │  - Event bus                        │ │
│  └─────────────────────────────────────┘ │
│  ┌──────────────┬──────────────────────┐ │
│  │ Sandbox      │ Observability        │ │
│  │ Provider     │ Exporters            │ │
│  │ Interface    │ Interface            │ │
│  └──────────────┴──────────────────────┘ │
└───────────────┬─────────────────────────┘

┌───────────────▼─────────────────────────┐
│         Sandbox Providers               │
│  Runra Sandbox │ CubeSandbox │ Docker   │
│  E2B          │ Custom                  │
└─────────────────────────────────────────┘

App Layer

Your application code. This is where you instantiate the Runra runtime, configure providers, and start agents. The runtime exposes a simple top-level API:

import { Runra } from "@runra/runtime";

const runra = new Runra({
  sandbox: { provider: "runra-sandbox", apiKey: "..." },
  agent: { provider: "claude-code", model: "claude-sonnet-4-20250514" },
  observability: { provider: "axiom", token: "..." },
});

await runra.start({ prompt: "Build a React todo app" });

Agent Adapter Layer

Agent adapters translate between Runra's tool interface and each agent's native protocol. See Agent Adapters for details.

Orchestrator (Runtime Core)

The core runtime manages:

  • Sandbox lifecycle: Create, pause, resume, terminate sandboxes through the configured sandbox provider.
  • Tool dispatch: When an agent requests a tool (e.g., bash, edit, read), the orchestrator routes it to the sandbox.
  • Event bus: Every operation (sandbox created, command executed, file written) emits typed events.
  • Concurrency: Manages parallel sandbox operations with configurable limits.

Provider Interfaces

The runtime defines two key interfaces:

Sandbox Provider Interface

interface SandboxProvider {
  create(config: SandboxConfig): Promise<SandboxHandle>;
  get(id: string): Promise<SandboxHandle>;
  list(opts?: ListOptions): Promise<SandboxHandle[]>;
  pause(id: string): Promise<void>;
  resume(id: string): Promise<void>;
  terminate(id: string): Promise<void>;
  execute(id: string, command: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
  writeFile(id: string, path: string, content: string): Promise<void>;
  readFile(id: string, path: string): Promise<string>;
}

Observability Exporter Interface

interface ObservabilityExporter {
  export(events: RuntimeEvent[]): Promise<void>;
  flush(): Promise<void>;
}

Any implementation of these interfaces can plug into the runtime. See Sandbox Providers and Observability for built-in and custom implementations.

Event System

All runtime operations emit typed events. Events flow from the orchestrator to all configured observability exporters.

Event Schema

Every event has a common envelope:

interface RuntimeEvent {
  id: string;                // UUID
  timestamp: string;         // ISO 8601
  type: string;              // Event type discriminator
  sandboxId: string;         // Which sandbox
  runId: string;             // Which agent run
  data: Record<string, unknown>; // Type-specific payload
}

Event Types

Event TypeDescriptionKey Data Fields
sandbox.createdSandbox provisionedimage, resources
sandbox.pausedSandbox pausedruntimeDurationMs
sandbox.resumedSandbox resumedpausedDurationMs
sandbox.terminatedSandbox destroyedtotalRuntimeMs
exec.completedCommand finishedcommand, exitCode, stdout, stderr, durationMs
exec.streamedCommand output chunkstream, content
file.createdFile writtenpath, sizeBytes
file.readFile readpath
file.deletedFile removedpath
port.exposedPort exposedport, url
port.closedPort closedport
agent.thinkingAgent reasoningthought
agent.tool_callTool requesttool, args
agent.tool_resultTool responsetool, result
cost.runtimeResource usage costcost, durationMs

Pluggable Design

Every component is pluggable. See the dedicated pages:

Integration Flow

A typical agent run through the runtime:

1. Application calls runra.start({ prompt: "..." })
2. Orchestrator creates a sandbox via SandboxProvider
3. Agent adapter starts the agent with the prompt
4. Agent requests a tool (e.g., "run bash command")
5. Orchestrator dispatches to SandboxProvider.execute()
6. Result returned to agent
7. Agent processes output, requests next tool
8. Events emitted to ObservabilityExporters
9. Agent completes; sandbox paused or terminated

Next Steps