Reyn

Architecture

How Reyn works.

A bird's-eye view of the components that make up Reyn, and how they coordinate to execute a single request.

01 At a glance

The whole system,
on one page.

Reyn is built from a small set of components. Agents hold long-lived conversations and route each decision through a RouterLoop. Skills are instructions the model reads on demand, not phase graphs the OS executes. Every LLM decision becomes a typed Control IR op, validated and dispatched under a permission gate. Workspace and Events make every step inspectable and replayable.

flowchart TB U(["User / External System"]) subgraph I01["01 · Interface"] direction LR CLI["CLI"] ~~~ TUI["Inline CUI (terminal)"] ~~~ WEB["Web UI (FastAPI + WebSocket)"] end subgraph I02["02 · Agent Registry"] direction LR AM["manages named agents"] ~~~ TG["Topology gate — network · team · pipeline"] end subgraph I03["03 · Agent = ChatSession"] direction LR RL["RouterLoop (LLM-driven dispatch)"] ~~~ PL["Planner (optional · plan mode)"] ~~~ MEM["memory scope · skill allowlist"] end subgraph I04["04 · OS — the constant"] direction LR CB["Context Build"] ~~~ LC["LLM Call"] ~~~ VA["Output Validation"] ~~~ EE["Event Emit"] end subgraph I05["05 · Skill"] direction LR L1["L1 · menu entry"] ~~~ L2["L2 · on-demand read"] ~~~ L3["L3 · bundled assets"] end subgraph I06["06 · Control IR"] direction LR OPV["Schema-validated op"] ~~~ PG2["Permission gate"] ~~~ DISP["Dispatch to tool/skill/pipeline/agent"] end subgraph I07["07 · Persistence"] direction LR WS["Workspace (artifacts · files)"] ~~~ EV["Events (append-only log)"] end U --> I01 --> I02 --> I03 --> I04 --> I05 --> I06 --> I07
02 The pieces

Five components.
Sharp boundaries.

Each component has one job. Agents don't know how a Skill's instructions are written. The OS is the only layer that touches all of them — and it never embeds skill-specific logic.

Agent

A long-lived ChatSession. RouterLoop dispatches messages to Skills, an optional Planner decomposes complex goals, memory scope and skill allowlist define what the agent can see and do.

Skill

Layered-disclosure instructions the model chooses to read — a one-line menu entry, an on-demand full read, and bundled assets. Not a program the OS executes.

Control IR

The typed contract. Every LLM decision — a tool call, a skill read, a delegation — becomes a schema-validated op before it touches the world. No side effect ever rides a free-form string.

OS

The runtime engine. Builds context, validates LLM output against schemas, executes ops under permission gates, emits an event for every state change. Constant; never embeds skill specifics.

State

Workspace is the single source of truth for inter-phase data. Events is an append-only log of every transition, op call, and decision. Together they make crash recovery and replay possible.

03 A request, end to end

From message
to reply.

sequenceDiagram participant U as User participant A as Agent (ChatSession) participant PL as Planner (optional) participant RL as RouterLoop participant OS as OS (context · LLM · validation) participant WS as Workspace + Events U->>A: message alt Complex multi-step request A->>PL: plan_task(goal) PL-->>A: Plan { steps: [S1, S2, ...] } Note over A: each step → an action below else Simple request Note over A: RouterLoop decides directly end A->>RL: dispatch turn loop Bounded by force-close RL->>OS: build context (incl. Skill instructions on demand) OS->>OS: call LLM (closed candidate set) OS->>OS: validate response as typed Control IR op OS->>WS: dispatch op under permission gate · emit event OS-->>RL: op result alt decision = continue Note over RL: pick next action — tool · skill read · delegate · pipeline else decision = finish RL-->>A: final reply end end A-->>U: reply

A user message arrives at an Agent. The RouterLoop decides what to do — call a tool, read a Skill's instructions, or delegate to another agent. The OS builds context, calls the LLM with a closed candidate set, and validates the response as a typed Control IR op. The op dispatches under a permission gate and writes to the Workspace; an event records each step. The loop continues, bounded by force-close, until the RouterLoop decides the turn is done, and the reply travels back to the user.

04 Beyond a single agent

Reyn talks out.
Reyn is talked to.

Agents reach other Agents through a topology gate — network, team, or pipeline — permission-scoped the same way any other capability is. From outside, Reyn exposes itself as an MCP server: Claude Code, Cursor, and any MCP-aware client can call list_agents() and send_to_agent(). Inside Phases, Control IR ops can call external MCP servers as well — third-party tools come under the same permission gate and event log as everything else.

Multi-hop agent-to-agent relay retired with delegate_to_agent; the current interface addresses a single (agent, session). Whether a join concept returns is an open design question.

flowchart LR subgraph SRV["MCP Server — implemented (reyn mcp serve)"] direction TB EXT["External LLM Client\nClaude Code · Cursor · OpenAI SDK"] STDIO["stdio / JSON-RPC 2.0"] TOOLS["list_agents() · send_to_agent()"] AR["AgentRegistry → ChatSession"] EXT --> STDIO --> TOOLS --> AR end subgraph CLI2["MCP Client — implemented (stdio · HTTP)"] direction TB CTRL["Control IR (mcp op)"] MCIROP["MCPIROp kind: mcp"] MCLIENT["MCPClient\nstdio / HTTP transport"] EXTMCP["External MCP Server"] CTRL --> MCIROP --> MCLIENT --> EXTMCP end

Go deeper in the docs.

The concepts section covers each component in detail — with design rationale, edge cases, and links to the implementation.