# Architecture ## System Overview ```mermaid graph TB User((User)) SDK[SDK Client] subgraph Entry["Entry Points"] CLI[CLI] API[HTTP API] Console[React Console] end User --> CLI User --> Console SDK --> API CLI --> API Console --> API subgraph Core["Core Runtime"] Agents[Agent Loader] Sessions[Session Manager] Executor[Session Executor] Events[Event Logger] Compaction[Context Compactor] MCP[MCP Manager] Skills[Skill Loader] Templates[Template Loader] end API --> Agents API --> Sessions Sessions --> Executor Sessions --> Events Executor --> Compaction Executor --> MCP Executor --> Skills CLI --> Templates subgraph Providers["Provider Layer"] Models[Model Providers] Sandboxes[Sandbox Providers] Tools[Tool Sources] Strategies[Agent Strategies] end Executor --> Models Executor --> Sandboxes Executor --> Tools Executor --> Strategies subgraph Storage["Local Storage"] SQLite[(SQLite)] ProjectFiles[Project Files] Workspaces[Session Workspaces] end Events --> SQLite Sessions --> SQLite Agents --> ProjectFiles Skills --> ProjectFiles Sandboxes --> Workspaces ``` ## Four-Layer Runtime Model ```mermaid graph TD Agent["Agent
durable definition"] Environment["Environment
sandbox template"] Session["Session
control-plane state"] Sandbox["Sandbox
execution resource"] Agent --> Environment Agent --> Session Environment --> Session Session --> Sandbox ``` - Agent definitions are durable project configuration. - Environments describe how sandboxes are provisioned. - Sessions own state, metadata, and event history. - Sandboxes perform execution for one session at a time. ## Session State Machine ```mermaid stateDiagram-v2 [*] --> queued: create session queued --> running: user event running --> idle: turn complete running --> paused: interrupted running --> requires_action: user input needed running --> failed: unrecoverable error idle --> running: user event paused --> running: user event requires_action --> running: user response idle --> terminated: stop or delete paused --> terminated: stop or delete failed --> [*] terminated --> [*] ``` ## Session Turn Flow ```mermaid sequenceDiagram participant Client participant API participant Sessions as Session Manager participant Events as Event Logger participant Executor participant Strategy participant Model as Model Provider participant Tools participant SSE Client->>API: POST /v1/sessions/:id/messages API->>Sessions: send user message Sessions->>Events: append user.message Sessions->>SSE: broadcast user.message Sessions->>Executor: run turn Executor->>Strategy: execute context Strategy->>Model: request completion Model-->>Strategy: streamed response alt tool call Strategy->>Tools: execute tool Tools-->>Strategy: tool result Strategy->>Events: append tool events Strategy->>SSE: broadcast tool events else agent message Strategy->>Events: append agent.message Strategy->>SSE: broadcast agent.message end Strategy-->>Executor: turn finished Executor->>Sessions: update status Sessions->>SSE: broadcast status ``` ## Event Replay and Live Stream ```mermaid sequenceDiagram participant Client participant API participant Events as Event Logger participant Hub as SSE Hub Client->>API: GET /events/stream API->>Events: read persisted events after cursor Events-->>API: historical events API-->>Client: replay events API->>Hub: subscribe Hub-->>Client: live events ``` Persisted events have a positive sequence number. Transient live chunks use `seq = 0` and do not advance the replay cursor. ## Data Boundaries ```mermaid graph LR Config[Project Config] --> Loader[Runtime Loaders] Loader --> DB[(SQLite)] API[HTTP API] --> DB Sessions[Sessions] --> Workspace[Session Workspace] Sandbox[Sandbox] --> Workspace Workspace -. cleanup .-> Sessions ``` Workspace configuration and runtime state live under the workspace boundary. Runtime metadata belongs in SQLite at `/.managed-agents/data.db` by default. Uploaded bytes, logs, snapshots, and sandbox workspaces live under the same workspace state directory and should not be committed unless intentionally snapshotting local state. ## Workspace Boundary ```mermaid graph TB Workspace["Workspace
project boundary"] Config["Config
.managed-agents/config.yaml"] Agents["Agent Seeds
agents/*.yaml"] Skills["Skill Seeds
skills/*/SKILL.md"] RuntimeData["Runtime Data
.managed-agents/"] DB["SQLite
data.db"] Files["Blob Storage
files/ skills/ snapshots/"] Vaults["Credential Vaults"] Memory["Memory Stores"] Sessions["Sessions"] Sandboxes["Session Sandboxes"] Workspace --> Config Workspace --> Agents Workspace --> Skills Workspace -. owns slug .-> RuntimeData RuntimeData --> DB RuntimeData --> Files RuntimeData --> Vaults RuntimeData --> Memory RuntimeData --> Sessions Sessions --> Sandboxes ``` The Web Console currently exposes the active local workspace as a read-only runtime boundary. Desktop shells may add create, open, and switch workflows, but switching workspaces must restart or rebind runtime state so credentials, memory, session data, and sandbox paths remain scoped to the selected workspace. ## Provider Selection ```mermaid graph TD Agent[Agent Definition] --> EnvName[environment name] EnvName --> Env[Environment Config] Env --> Registry[Sandbox Provider Registry] Registry --> Local[Local Provider
child process] Registry --> Docker[Docker Provider
docker CLI] Registry --> Kubernetes[Kubernetes Provider
kubectl CLI] Registry --> SelfHosted[Self-Hosted Provider
work queue] Registry -. unregistered .-> Fail[Provision error
lists registered providers] ``` The executor resolves the sandbox provider from the selected environment before running a session turn. The registry is the only authority on which backends exist in a process. A backend is registered only when its transport is reachable at startup — no Docker daemon means no `docker`, no reachable cluster means no `kubernetes` — and an unresolvable request is an error rather than a substitution, so a session configured for an isolated backend can never quietly execute on the runtime host. Each provider also declares a capability set the runtime reads before acting: | Provider | isolatedExecution | hostFilesystem | resourceLimits | streamingExec | | --- | --- | --- | --- | --- | | local | No | Yes | No | No | | docker | Yes | No | Yes | No | | kubernetes | Yes | No | Yes | No | | self_hosted | Off-host | No | No | No | `hostFilesystem` gates workspace snapshots, which need a host-readable workspace. `resourceLimits` gates whether an Environment's `resources` values are enforced. A requested capability the backend lacks is logged against the session rather than dropped in silence. ## Deployment Modes ### Local Development ```text CLI or SDK -> local HTTP API -> SQLite + local sandbox ``` This is the default mode. ### Containerized Runtime ```text Client -> containerized HTTP API -> mounted config + persistent data volume ``` This mode keeps the same project files and API shape. ### Self-Hosted Worker ```text HTTP API -> work queue -> user-managed worker -> session event results ``` This mode lets users run execution on their own infrastructure while keeping the session control plane stable.