Skip to content

Architecture

Layer Structure

Robota SDK follows a strict bottom-up layered assembly model. Each layer builds on the layer below.

agent-cli                ← CLI entry point: argument parsing, provider wiring, TUI startup
agent-transport/tui      ← TUI layer: Ink/React terminal components, TuiTransport
agent-command            ← Consolidated slash command package — all 20 command modules in one import
agent-transport          ← Protocol transports (pure TS): headless, HTTP, WebSocket, MCP
  ↓ (command and transport packages consume)
agent-framework          ← Assembly layer: InteractiveSession, CommandRegistry,
  │                          config, context, createQuery(), skill/agent runtime APIs

agent-session     ← Session lifecycle: permissions, hooks, compaction, persistence, replay events
agent-executor    ← Background task and subagent lifecycle primitives
agent-tools       ← Tool infrastructure + 8 built-in CLI tools
agent-provider    ← AI provider implementations (Anthropic, OpenAI, DeepSeek, Gemini, Gemma, Qwen)

agent-core        ← Foundation: Robota engine, abstractions, DI, events, plugins

Package Roles

PackageRoleLayer
agent-coreRobota engine, execution loop, provider abstraction, permissions, hooks, plugin system, model definitions (SSOT)Foundation
agent-toolsToolRegistry, FunctionTool, createZodFunctionTool, 8 built-in CLI toolsGeneral
agent-sessionSession class with permission enforcement, context tracking, compactionGeneral
agent-executorBackground task state machines, subagent manager contracts, task snapshots, watchdogs, transcript referencesGeneral
agent-providerProvider packages for Anthropic, OpenAI, OpenAI-compatible primitives, DeepSeek, Gemini, Gemma, Qwen, and moreGeneral
agent-plugin8 official plugins: ConversationHistory, Logging, Usage, Limits, ErrorHandling, ExecutionAnalytics, Performance, WebhookGeneral
agent-commandConsolidated slash command package — all 20 command modules in a single importSDK-specific
agent-frameworkAssembly: InteractiveSession, CommandRegistry, BuiltinCommandSource, SkillCommandSource, config loading, context discovery, skill/agent runtime APIs, createQuery()SDK-specific
agent-transportProtocol transports (pure TS, zero React/Ink): headless (/headless), HTTP (/http), WebSocket (/ws), MCP (/mcp)Transport
agent-transport/tuiTUI rendering layer — all Ink/React terminal UI components, hooks, and TuiTransport adapter (subpath of agent-transport)Transport
agent-cliCLI entry point: argument parsing, provider factory, TUI startup; wires agent-transport/tui, agent-transport, agent-command, agent-frameworkCLI
agent-remote-clientHTTP client for calling a remote Robota agent exposed via agent-transport/httpClient
agent-web-uiBrowser React component library for monitoring a CLI session over WebSocketBrowser UI
agent-interface-transportTransport contract interfaces only (no implementation): ITransportAdapter, IConfigurableTransport, ITransportConfigContracts
agent-interface-tuiTUI interaction type contracts only: ITuiCommandInteraction, ITuiCliAdapter, ITerminalOutput — no runtime depsContracts

Dependency Flow

agent-cli              ─→ agent-framework, agent-transport/tui, agent-transport, agent-command
agent-transport/tui    ─→ agent-framework, agent-interface-tui, agent-interface-transport, agent-core
agent-transport        ─→ agent-interface-transport, agent-framework, agent-core
agent-command          ─→ agent-core, agent-framework
agent-remote-client                    (HTTP client, no agent-framework dependency)
agent-web-ui           ─→ agent-transport (ws types only)

React / Ink Policy

CategoryPackages allowedRule
React + Ink (TUI)agent-transport/tui onlyNever in protocol transport or SDK packages
React (browser)agent-playground, agent-web-uiBrowser app packages only
Pure TypeScriptEverything else (core, framework, transport, CLI)No React or Ink dependencies

Data Flow: IHistoryEntry[]

InteractiveSession maintains history as IHistoryEntry[] — a universal timeline that includes both chat messages (user/assistant turns) and session events (tool calls, system events, status changes). This is the single source of truth for display and persistence.

Background tasks are tracked alongside the session through runtime snapshots and append-only JSONL event/transcript streams. High-frequency streaming output is stored in logs/transcripts, while session JSON stores resumable task state and references.

User input
  → InteractiveSession.submit()
  → history appended: IHistoryEntry (kind: 'chat', role: 'user')
  → Session.run()
  → AI provider receives filtered view (chat-only IHistoryEntry[])
  → streaming response → text_delta / tool_start / tool_end events
  → history appended: IHistoryEntry (kind: 'chat', role: 'assistant')
  → event entries appended: IHistoryEntry (kind: 'event', ...)
  → thinking / context_update events emitted
  → clients (CLI, HTTP, MCP, WS, Headless) update their state from events

Key invariant: AI providers never receive event-kind entries. The session layer filters to chat-only entries before forwarding context to the provider.

Rules:

  • Dependencies are one-way. No cycles.
  • agent-core has zero workspace dependencies (foundation).
  • agent-session depends only on agent-core (generic — no tools or providers).
  • Assembly (wiring tools + provider + prompt) happens in agent-framework.
  • InteractiveSession (in agent-framework) is the gateway for all transport adapters. There is no separate IAgentGateway interface — transports consume InteractiveSession directly.
  • agent-cli and transport packages depend only on agent-framework; they do not access agent-session or agent-core directly.
  • agent-remote-client is a standalone HTTP client; it does not depend on agent-framework.

Design Patterns

PatternWherePurpose
FacadeRobota, Session, InteractiveSessionSingle entry point hiding internal complexity
DecoratorPermissionEnforcer.wrapTools()Wraps tools with permission checks
StrategyIAIProvider, ISessionLoggerSwappable implementations
FactoryInteractiveSession, createZodFunctionTool()Object creation
Null ObjectSilentLogger, DefaultEventServiceSafe no-op defaults
RegistryToolRegistry, CommandRegistryCentral management of tools and commands
CompositionInteractiveSessionSession; Session → sub-componentsDelegation over inheritance

Session Sub-Components

Session delegates to focused sub-components:

ComponentResponsibility
PermissionEnforcerTool wrapping, permission checks, hook execution, output truncation
ContextWindowTrackerToken usage tracking, auto-compact threshold
CompactionOrchestratorConversation summarization via LLM (PreCompact hook)

InteractiveSession

InteractiveSession (in agent-framework) wraps Session via composition to provide an event-driven API suitable for any interactive client. It is the single gateway used by all transport adapters — CLI, HTTP, MCP, WebSocket, and Headless.

Key responsibilities:

ConcernDetail
submit / abortsubmit(input) starts a run; abort() cancels the current run
cancelQueueCancels the pending queued prompt without aborting the in-flight run
Prompt queueQueues a new prompt submitted while a run is in progress
Event emissionEmits typed events (text_delta, tool_start, tool_end, thinking, context_update, error) consumed by clients
Universal historyMaintains IHistoryEntry[] — unified timeline of chat messages and session events; getFullHistory() returns the complete list
CommandRegistrySDK-owned utility used by clients to aggregate built-in, skill, plugin, and command-module sources for slash-command discovery

agent-transport/tui's useInteractiveSession hook subscribes to these events and translates them into React state via TuiStateManager. InteractiveSession itself has no React dependency.

Transport Layer

The transport layer exposes InteractiveSession over various protocols. Each transport is a thin adapter that bridges the protocol to the session's submit / abort / event API.

PackageProtocolRuntime
agent-transport/tuiTerminal (stdin, Ink TUI)Node.js (Ink + React)
agent-transport/httpHTTP / RESTCloudflare Workers, Node.js, AWS Lambda (Hono)
agent-transport/mcpMCPNode.js stdio / SSE (MCP SDK)
agent-transport/wsWebSocketAny WS library (framework-agnostic)
agent-transport/headlessstdin/stdout (non-interactive)Node.js — text/json/stream-json output

All adapters import InteractiveSession from agent-framework. None of them implement session logic — they only translate protocol messages into session calls and forward session events back to the caller.

All transport adapters implement IConfigurableTransport (defined in agent-interface-transport), which provides a uniform lifecycle: attach(session) to bind a session, start() to begin serving, and stop() to shut down.

agent-remote-client is a companion HTTP client that allows a remote process to call an agent exposed via agent-transport/http. It has no dependency on agent-framework.

Plugin Architecture

agent-core defines the AbstractPlugin base class. 8 plugin implementations are available in @robota-sdk/agent-plugin.

Plugins integrate with the agent lifecycle via hooks: beforeRun, afterRun, onError, onStreamChunk, beforeToolExecution, afterToolExecution.

Changes from v2.0.0

In v2.0.0, agent-core contained everything: tools, plugins, session management. In v3.0.0:

  • Tools moved to agent-tools (FunctionTool, ToolRegistry, built-in tools)
  • Plugins consolidated in @robota-sdk/agent-plugin
  • Session created as agent-session with permission and hook support
  • Background tasks handled by agent-executor
  • SDK assembly in agent-framework
  • CLI entry point is agent-cli
  • TUI (Ink/React) in agent-transport/tui subpath of agent-transport
  • Transport (protocol-only) in agent-transport
  • Permissions and Hooks added to agent-core as general-purpose infrastructure

Released under the MIT License.