DeepSeek-Reasonix Core Components: A Complete Architecture Guide

DeepSeek-Reasonix is a modular Go-based coding agent framework built around interchangeable providers, tools, plugins, and agents that enable safe, extensible LLM-driven automation.

The architecture of esengine/DeepSeek-Reasonix (commonly called Reasonix) deliberately separates concerns into thin, swappable layers. This design lets you add new language models, custom tools, or external plugins without modifying core logic. Below is a comprehensive breakdown of every component, how they interact, and how to extend them.

Provider: The LLM Abstraction Layer

The Provider component abstracts any LLM vendor behind a uniform interface. Whether you're connecting to OpenAI-compatible APIs, Anthropic Claude, or custom endpoints, the same Stream method handles token-delta delivery.

In internal/provider/provider.go, the interface looks like this:

type Provider interface {
    Name() string
    Stream(ctx context.Context, req Request) (<-chan Chunk, error)
}

Providers self-register via init() functions using provider.Register(kind, factory). This registry pattern lets you drop in new provider packages without touching existing code.

Built-in Provider Registration Example

// File: internal/provider/custom/custom.go
package custom

import (
    "context"
    "github.com/esengine/DeepSeek-Reasonix/internal/provider"
)

type SimpleProvider struct{ cfg provider.Config }

func (p *SimpleProvider) Name() string { return "custom" }

func (p *SimpleProvider) Stream(ctx context.Context, req provider.Request) (<-chan provider.Chunk, error) {
    // Implementation that streams from your model endpoint
    out := make(chan provider.Chunk)
    go func() {
        defer close(out)
        // ... token streaming logic ...
    }()
    return out, nil
}

func init() {
    provider.Register("custom", func(cfg provider.Config) (provider.Provider, error) {
        return &SimpleProvider{cfg: cfg}, nil
    })
}

The spec documents this pattern in SPEC §3.1.

Tool: Executable Actions for Agents

The Tool interface in internal/tool/tool.go encapsulates any callable action—from file I/O and shell commands to remote MCP tools. Every tool exposes four methods: Name, Description, Schema (JSON Schema for the LLM), and Execute.

Built-in tools live in internal/tool/builtin/. Here's how to register a simple greeting tool:

// File: internal/tool/builtin/hello.go
package builtin

import (
    "context"
    "encoding/json"
    "github.com/esengine/DeepSeek-Reasonix/internal/tool"
)

type helloTool struct{}

func (t *helloTool) Name() string        { return "hello" }
func (t *helloTool) Description() string { return "Greets the user." }
func (t *helloTool) Schema() json.RawMessage {
    return json.RawMessage(`{"type":"object","properties":{}}`)
}
func (t *helloTool) Execute(_ context.Context, _ json.RawMessage) (string, error) {
    return "Hello, Reasonix user!", nil
}

func init() { tool.RegisterBuiltin(&helloTool{}) }

This mirrors the tool.RegisterBuiltin pattern described in SPEC §3.2.

Plugin: Out-of-Process Extensions via MCP

The Plugin system enables external tools and prompts through the MCP (Model Context Protocol) using JSON-RPC. Implemented in internal/plugin/plugin.go, plugins support three transport types:

  • stdio – Local executable subprocess
  • http – HTTP POST endpoint
  • sse – Server-Sent Events stream

Plugins extend the agent's capabilities at runtime without recompilation, making Reasonix ideal for integrating specialized tools maintained by separate teams.

Agent: The Core Session Orchestrator

The Agent in internal/agent/agent.go drives a single LLM conversation. Its responsibilities include:

  1. Building the Request (conversation history + available tool schemas)
  2. Streaming responses via Provider.Stream
  3. Detecting ChunkToolCall deltas and dispatching to the appropriate tool
  4. Feeding tool results back as new messages
  5. Looping until completion or step limit reached

The agent also handles context compaction: when token usage nears the provider's context_window, it summarizes older turns while preserving recent facts (see SPEC §3.6).

Typical Agent Execution Flow

$ reasonix run "Write a Python function that computes Fibonacci numbers."

The CLI (cmd/reasonix/main.go) parses this, instantiates the configured provider, and hands control to Agent.Run, which streams output and automatically invokes tools like write_file or bash as needed.

Coordinator: Two-Model Collaboration

The Coordinator in internal/agent/coordinator.go implements an advanced pattern using two specialized models:

Model Role Tool Access
Planner Generates high-level plans from requirements Read-only tools only
Executor Executes the plan with full tool access All enabled tools

This separation keeps each model's prompt cache stable—the planner sees a consistent read-only view, while the executor handles mutation. When agent.planner_model is set in config, the coordinator spawns both agents and bridges their interaction.

Permission: Per-Tool Safety Gating

The Permission system in internal/permission/permission.go provides three-level gating for every tool:

  • allow – Execute automatically
  • ask – Prompt user for confirmation
  • deny – Block execution

Rules parse from TOML config and evaluate through the Gate.Decide method before any tool runs. This ensures safe autonomous operation even with powerful tools like bash or write_file.

Command: Slash-Command Interface

The Command handler in internal/command/command.go processes TUI inputs starting with /. Three sources populate the command registry:

  1. Built-ins: /new, /clear, /compact
  2. Custom markdown: Files in .reasonix/commands/*.md
  3. MCP prompts: Namespaced as /mcp__<server>__<prompt>

Commands can trigger agent actions, modify session state, or invoke plugin-provided functionality.

Configuration: TOML-Based Setup

Reasonix uses layered TOML configuration resolved in priority order:


CLI flags → project reasonix.toml → user config → defaults

The reasonix.example.toml demonstrates providers, tools, plugins, and permission rules. Key sections include:

  • [provider] – Model endpoints and API keys
  • [agent] – Model selection, planner configuration, step limits
  • [[tool]] – Built-in tool enablement
  • [[plugin]] – MCP server connections
  • [[permission]] – Tool-specific gating rules

Data Types: The Streaming Protocol

Core structures in internal/provider/provider.go drive the streaming protocol:

  • Message – Conversation turns with role and content
  • Chunk – Token deltas or tool call fragments from providers
  • Request – Complete payload sent to Provider.Stream
  • ChunkToolCall – Structured tool invocation from the LLM

These types ensure type-safe communication between agents and providers across the codebase.

CLI & Desktop: User-Facing Entry Points

The binary entry point at cmd/reasonix/main.go wires everything together:

  • Parses flags and subcommands via internal/cli/
  • Loads and merges configuration
  • Initializes the Bubble-Tea TUI
  • Dispatches to Agent.Run or Coordinator based on config

Users interact through either the TUI or direct command execution.

How Components Interact at Runtime

  1. Startup: CLI parses config, calls provider.Register and tool.RegisterBuiltin for all built-ins
  2. Session: internal/agent.NewRunner builds a *Registry (enabled tools + plugins) and Provider instance
  3. Request Loop: Agent.Run prepares Request, streams via Provider.Stream, consumes Chunks
  4. Tool Execution: On ChunkToolCall, agent registry-lookup → permission.Gate.Decide → Tool.Execute → result appended to messages
  5. Two-Model Mode: Coordinator spawns planner Agent (read-only), hands plan to executor Agent
  6. Compaction: Automatic summarization when nearing context_window

Summary

DeepSeek-Reasonix components form a plug-and-play architecture where each layer can be swapped independently:

  • Provider abstracts any LLM vendor behind a streaming interface
  • Tool encapsulates executable actions with JSON Schema contracts
  • Plugin extends capabilities via MCP without recompilation
  • Agent orchestrates single-model sessions with compaction
  • Coordinator enables efficient two-model planner/executor separation
  • Permission gates tool execution for safe autonomy
  • Command provides flexible TUI interaction
  • Configuration layers TOML settings with sensible defaults

Together these pieces let you customize models, add capabilities, and enforce policies without forking core code.

Frequently Asked Questions

What makes Reasonix different from other coding agents?

Reasonix distinguishes itself through vendor-agnostic providers and two-model coordination. Unlike agents tightly coupled to OpenAI or Claude, the Provider interface lets you swap models by changing config. The Coordinator pattern further optimizes cost and latency by using a lightweight planner model for reasoning and a capable executor for implementation.

How do I add a custom tool to Reasonix?

Implement the Tool interface with Name, Description, Schema, and Execute methods, then call tool.RegisterBuiltin in an init() function. Place your file in internal/tool/builtin/ or any package imported at runtime. No core changes required—the registry discovers your tool automatically.

Why does Reasonix use MCP for plugins instead of native Go plugins?

MCP (Model Context Protocol) via JSON-RPC provides language-agnostic, out-of-process isolation. Teams can write plugins in Python, TypeScript, or any language supporting JSON-RPC. This avoids Go plugin compatibility issues, enables separate versioning, and prevents plugin crashes from destabilizing the main agent.

What happens when a conversation exceeds the context window?

The Agent triggers compaction (SPEC §3.6). It summarizes older assistant and tool turns into compressed representations while preserving recent messages and critical state. This keeps the conversation within context_window limits without losing task continuity.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →