Skip to content

esengine/DeepSeek-Reasonix

Repository files navigation

Reasonix

English  ·  简体中文  ·  Spec  ·  Website  ·  Discord

Important

Reasonix 1.0 is a ground-up rewrite in Go — this branch (main-v2) is the new default and where development happens now. The earlier 0.x TypeScript releases are legacy, living on the v1 branch (maintenance only). See the migration guide. npm i -g reasonix stays the install command — 1.0.0+ delivers the Go binary, 0.x is the legacy TS build. (Heads-up: 1.0.0 isn't on npm yet — build from source meanwhile.)

npm version CI license downloads GitHub stars AtomGit stars contributors Discussions Discord

oosmetrics — Top 2 in Agents by velocity oosmetrics — Top 3 in LLMs by velocity oosmetrics — Top 3 in CLI by velocity


A DeepSeek-native AI coding agent for your terminal.

A config- and plugin-driven harness — a single static Go binary, tuned around DeepSeek's prefix cache so token costs stay low across long sessions.


Important

Community · 加入社区 — bilingual Discord for setup help (#help / #求助), workflow showcases, and feature ideas. → https://discord.gg/XF78rEME2D


Features

  • Config-driven. Providers, the agent, enabled tools, and plugins are all declared in reasonix.toml. No hardcoded models.
  • Multi-model & composable. DeepSeek (flash/pro) and MiMo ship as presets; any OpenAI-compatible endpoint is a config entry, not new code. Optionally run two models together (executor + planner) in separate, cache-stable sessions.
  • Plugin-driven. External tools run as subprocesses over stdio JSON-RPC (MCP-compatible). Built-in tools self-register at compile time.
  • Zero-friction distribution. CGO_ENABLED=0 single binary; cross-compile to six targets with one command. The only dependency is a TOML parser.

Install / Build

make build      # -> bin/reasonix
make cross      # -> dist/ (darwin|linux|windows × amd64|arm64)

Quick start

reasonix setup                      # config wizard → ./reasonix.toml
export DEEPSEEK_API_KEY=sk-...  # or put it in .env (see .env.example)
reasonix chat                       # then run /init to generate AGENTS.md (project memory)
reasonix run "implement the TODOs in main.go"
reasonix run --model mimo-pro "add unit tests for this function"
echo "explain this code" | reasonix run

Configuration

Resolution order: flag > ./reasonix.toml > ~/.config/reasonix/config.toml > built-in defaults. Secrets come from the environment via api_key_env and are never stored in config files.

default_model = "deepseek-flash"   # executor; set [agent].planner_model to add a planner
# language    = "zh"               # ui language; empty = auto-detect from $LANG / $REASONIX_LANG

[agent]
# planner_model = "mimo-pro"          # optional low-frequency planner
# subagent_model = "deepseek-pro"     # optional default for runAs=subagent skills
# subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" }
auto_plan = "ask"                  # off|ask|on; complex chat tasks start in plan mode
# auto_plan_classifier = "deepseek-flash"   # optional; only borderline tasks call it

[[providers]]
name        = "deepseek-flash"
kind        = "openai"
base_url    = "https://api.deepseek.com"
model       = "deepseek-v4-flash"
api_key_env = "DEEPSEEK_API_KEY"
# also preset: deepseek-pro, mimo-pro (mimo-v2.5-pro), mimo-flash (mimo-v2-flash) @ api.xiaomimimo.com/v1

[tools]
enabled = []   # omit/empty = all built-ins

[permissions]
mode  = "ask"                                # writer fallback when no rule matches: ask|allow|deny
deny  = ["bash(rm -rf*)", "bash(git push*)"] # hard-blocked in every mode
allow = ["bash(go test*)"]                   # never prompted

[sandbox]
# workspace_root = ""          # file-writers confined here; empty = current dir
# allow_write    = ["/tmp"]    # extra dirs write_file/edit_file/multi_edit may touch

[[plugins]]
name    = "example"
command = "reasonix-plugin-example"

Permissions gate each tool call: deny > ask > allow > fallback (readers always allow; writers fall back to mode). reasonix chat prompts before writers (y once · a this session · n no); reasonix run stays autonomous but still honours deny. See docs/SPEC.md for the full schema and contract.

Permissions are policy (which calls to allow / prompt). The sandbox is enforcement: the file-writers (write_file / edit_file / multi_edit) refuse any path outside [sandbox] workspace_root (default: the current dir, so edits stay in the project), resolving symlinks and .. so a link can't tunnel out. Reads are unrestricted. bash is itself jailed on macOS by default ([sandbox] bash, Seatbelt): commands may write only those same roots (plus temp and toolchain caches) and reach the network only when [sandbox] network is set. Other platforms fall back to running unconfined for now (see docs/SPEC.md §9 for the escape-prompt and Linux support still to come).

Plugins (MCP)

Reasonix is an MCP client. A [[plugins]] entry's type selects the transport: stdio (default) launches a local subprocess (command/args/env); http (Streamable HTTP) connects to a remote url with optional static headers (${VAR} / ${VAR:-default} expanded from the environment, so tokens stay out of the file). Tools surface to the model as mcp__<server>__<tool>; a tool declaring MCP's readOnlyHint: true joins parallel dispatch and the permission reader-default.

A server's prompts surface as /mcp__<server>__<prompt> slash commands (positional args after the command); its resources are pulled in by writing @<server>:<uri> in a message; /mcp lists connected servers and what each exposes. make build also produces bin/reasonix-plugin-example — a runnable reference stdio server (echo, wordcount, a review prompt, a style-guide resource) you can copy.

[[plugins]]                       # local stdio server
name    = "example"
command = "reasonix-plugin-example"

[[plugins]]                       # remote server over Streamable HTTP
name    = "stripe"
type    = "http"
url     = "https://mcp.stripe.com"
headers = { Authorization = "Bearer ${STRIPE_KEY}" }

Already have an .mcp.json? Drop it in the project root and Reasonix reads it as-is — the mcpServers spec (command/args/env, type/url/ headers, ${VAR} expansion) maps field-for-field onto [[plugins]]. Both sources are merged; on a name collision reasonix.toml wins.

{
  "mcpServers": {
    "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"] },
    "stripe": { "type": "http", "url": "https://mcp.stripe.com", "headers": { "Authorization": "Bearer ${STRIPE_KEY}" } }
  }
}

Slash commands

In reasonix chat, built-in commands (/compact, /new, /rewind, /tree, /branch, /switch, /todo, /model, /mcp, /memory, /help) run locally. /tree shows saved conversation branches, /branch [name] forks the current conversation tip, /branch <turn> [name] forks from an earlier checkpointed turn, and /switch <id|name> loads another branch. Custom commands are Markdown files under .reasonix/commands/ (project) or ~/.config/reasonix/commands/ (user) — review.md becomes /review, a subdirectory namespaces it (git/commit.md/git:commit). The body is a prompt template; invoking the command sends it as a turn.

---
description: Review the staged diff
argument-hint: [focus-area]
---
Review the staged diff. Focus on $ARGUMENTS, list bugs with file:line.

$ARGUMENTS expands to all space-separated args, $1$N to positional ones. MCP prompts also appear here as /mcp__<server>__<prompt>.

@ references

Embed @ references in a message and Reasonix resolves them before sending, as tagged context blocks: @path/to/file (or @dir) injects a local file's contents (or a directory listing), and @<server>:<uri> injects an MCP resource. A local path is only treated as a reference when it actually exists, so ordinary @mentions stay literal. Typing / or @ opens an autocomplete menu — slash commands, or hierarchical file navigation (one directory level at a time, descend into folders) plus MCP resources.

Two-model collaboration (optional)

reasonix setup keeps first-run minimal: pick provider → keys (every SKU of a chosen provider is enabled). Running two models together (executor + planner, separate cache-stable sessions) is a one-line edit afterwards — set planner_model to any other enabled provider:

[agent]
planner_model = "deepseek-pro"   # used as the low-frequency planner

Subagent skills inherit the executor model by default. Set subagent_model to run them on another configured model, or use subagent_models to override only specific skills such as review or security_review.

For interactive frontends, agent.auto_plan = "ask" makes complex-looking tasks enter plan mode automatically: Reasonix first drafts a read-only plan, then waits for approval before editing or running side-effecting commands. auto_plan_classifier can name a cheap provider such as deepseek-flash; it is only called for borderline inputs and falls back to the heuristic if classification fails.

Architecture

Three tiers of extensibility, all behind registries the core resolves by name:

  1. RegistryProvider and Tool are interfaces; the core has no switch model.
  2. Compile-time built-ins — providers (provider/openai) and tools (tool/builtin) self-register via init(); main blank-imports them. Adding a built-in is one file plus one import.
  3. Runtime plugins — executables declared in config, spoken to over newline-delimited JSON-RPC 2.0 on stdin/stdout (the MCP stdio convention). Each remote tool is adapted to the Tool interface.

Status

Done: registry-based providers/tools, OpenAI-compatible streaming with tool calls (bounded retry on 429/5xx), built-in tools (read_file, write_file, edit_file, multi_edit, bash, ls, glob, grep, web_fetch, task, todo_write, ask), TOML config, an interactive reasonix setup wizard, two-model collaboration (executor + planner in separate, cache-stable sessions), low-frequency context compaction, sub-agents (task), a bubbletea chat TUI (markdown, plan mode with controller-driven approval, live token/activity readout, pinned task list, ask question chooser, /compact /new /tree /branch /switch /todo), session persistence + resume, per-call permissions (allow/ask/deny rules; chat prompts before writers, deny rules hard-block everywhere), a workspace sandbox confining file-writers to the project (symlink/..-safe), an MCP client — stdio + Streamable HTTP transports, tools (mcp__server__tool, readOnlyHint-aware), prompts (slash commands), resources (@-references), and /mcp, configured via [[plugins]] or a project .mcp.json — custom slash commands (.reasonix/commands/*.md), @file / @resource references, plus a runnable reference plugin (cmd/reasonix-plugin-example), the harness loop, and CLI. A Wails desktop client (desktop/) drives the same kernel. Next: an OS-level sandbox for bash (macOS Seatbelt / Linux bubblewrap), an Anthropic-native provider, MCP OAuth + legacy SSE. See docs/SPEC.md §9.


Star History

Star History Chart

Support

If Reasonix has been useful and you'd like to say thanks, you can. It stays a coffee, not a contract — donations don't buy feature priority or change how issues get triaged.

WeChat Pay QR code


Acknowledgments

A small list of folks whose work has shaped Reasonix the most — measured by both commit count and code volume. Listed alphabetically, no ordering of importance. The full contributor graph is on GitHub.

Also a separate thank-you to Bernardxu123 for designing the project logo, and to AIGC Link for promoting the project on XiaoHongShu.

Contributors to esengine/DeepSeek-Reasonix



MIT — see LICENSE
Built by the community at esengine/DeepSeek-Reasonix