# esengine/DeepSeek-Reasonix

> Single-binary Go coding agent built around prefix-cache-stable prompts, an optional planner/executor split, OS sandboxing and per-turn rewind.

- Category: [Open-source coding agents](https://llms-technical-reviews.com/coding-agents/)
- Repository: https://github.com/esengine/DeepSeek-Reasonix (reviewed at commit `7f30fcbdb371585cd684947723097ec67ba4cf4f`, 2026-10-06)
- Stars: 35741 · Language: Go · License: MIT
- Canonical page: https://llms-technical-reviews.com/p/deepseek-reasonix/

## Overview

Reasonix began as a DeepSeek-focused agent and is now a general coding agent written from scratch in Go. It is not a fork of another CLI. The pinned commit is on the `studio` branch, "Reasonix 2.x", which the README calls the active line. The 1.x line lives on another branch in maintenance mode. One `reasonix` binary serves four front ends: a terminal UI, a browser UI (`web`/`serve`), an Electron desktop app under `desktop/`, and editors over ACP.

The design is shaped by one constraint: provider prefix caching, which makes DeepSeek in particular very cheap on cache hits. Comments throughout the loop protect a byte-stable prompt prefix. Tool schemas are frozen once per sampling attempt. Context-pressure notices are appended to the tail and never rewrite the prefix. Project instructions (`REASONIX.md`/`AGENTS.md`/`CLAUDE.md`) are delivered inside a `<project-instructions>` block in the conversation rather than in the system prompt, because their project-specific text would change the prefix from its first byte ([policies.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/contract/config/policies.go#L14-L18)). The plan-mode marker also rides the user turn "so plan toggles preserve cache shape" ([planmode/policy.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/contract/planmode/policy.go#L9-L11)). Compaction is described as a "low-frequency cache-reset point" ([compact.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/compact.go#L18-L25)). Around that core sits a large amount of defensive engineering: stream recovery, perseveration detection, stale-anchor guards, write receipts, permission rules, an OS sandbox and git-free per-turn checkpoints.

## Architecture

```mermaid
flowchart LR
  FE["TUI / web / desktop / ACP"] --> CTRL["session control (Controller)"]
  CTRL --> COORD["Coordinator (optional planner)"]
  COORD --> EXE["Executor Agent"]
  CTRL --> EXE
  EXE --> LOOP["runToolLoop"]
  LOOP --> PROV["provider: openai / anthropic / responses"]
  LOOP --> ONE["executeOne: parse, policy, prepare, finish"]
  ONE --> PERM["permission Gate + approvals"]
  ONE --> TOOLS["builtin tools / MCP / extensions"]
  TOOLS --> SBX["sandbox: bwrap / Seatbelt"]
  TOOLS --> CKPT["checkpoint store (rewind)"]
  LOOP --> CMP["compaction checkpoint"]
```

| Component | Path | Role |
|---|---|---|
| Entry | `cmd/reasonix/main.go`, `internal/frontend/cli/cli.go` | Blank-imports providers and tools; dispatches `run`, `tui`, `serve`, `web`, `acp`, `mcp`, … |
| Front ends | `internal/frontend/{tui,serve,acp}`, `desktop/` | Terminal, HTTP/browser, ACP and Electron surfaces over one engine |
| Session control | `internal/session/control/` | Approvals, attachments, branches, rewind, memory commands |
| Agent loop | `internal/runtime/agent/` | `runToolLoop`, sampling recovery, tool rounds, compaction, sub-agents |
| Coordinator | `internal/runtime/coordinator/` | Planner model → `submit_plan` → executor model |
| Providers | `internal/model/{openai,anthropic,responses}` | Self-registering provider kinds with per-vendor reasoning knobs |
| Built-in tools | `internal/tools/builtin/` | `read_file`, `edit_file`, `multi_edit`, `write_file`, `grep`, `glob`, `bash`, `code_index`, `web_fetch`, … |
| Safety | `internal/safety/{permission,sandbox,egress}` | Allow/ask/deny rules, OS jail for shell, egress proxy |
| Checkpoints | `internal/state/checkpoint/` | Pre-edit snapshots per user turn for rewind |
| Extensions | `internal/ext/`, `sdk/go/` | MCP, hooks, skills, plugin packages, Extension Protocol v2 |

## How a request flows

1. **Entry.** `main` blank-imports the `anthropic`, `openai` and `responses` providers and the built-in tools, so they register themselves. Then it hands off to `cli.RunWithBuildInfo` ([main.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/cmd/reasonix/main.go#L1-L58)), which dispatches on the subcommand ([cli.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/frontend/cli/cli.go#L85-L100)).
2. **Optional planning.** When a planner model is configured, `Coordinator.Run` asks the planner policy for a route. `executor_only` skips planning. Otherwise the planner researches with read-only tools and must deliver a structured plan through `submit_plan`. A planner failure falls back to running the executor alone, except in plan-only or plan-for-approval routes, which fail closed ([coordinator.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/coordinator/coordinator.go#L309-L372)).
3. **Tool loop.** `runToolLoop` iterates up to the step budget. Each step lands any queued steer message, appends context-budget notices at the tail, captures the frozen tool schemas and prefix shape, and calls `streamWithSamplingRecovery` ([run_loop.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/run_loop.go#L257-L300)). Interrupted streams are retried, up to six sampling attempts in total.
4. **Branch.** A response without tool calls goes to `handleFinalResponse`. Otherwise `handleToolRound` runs the calls. When the budget runs out, a grace round or a pause takes over ([run_loop.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/run_loop.go#L300-L380)).
5. **Execute one call.** `executeOne` is pure with respect to events, so calls can run in parallel. It runs four stages: parse (resolve the tool, reject unknown or ambiguous names, apply repeat-success and stale-anchor guards), extension `tool.before` intercepts, policy (the permission gate), prepare (sandbox, checkpoint capture), and finish ([execute_one.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/execute_one.go#L92-L145)).
6. **Edit.** `edit_file` confines the path to the write roots, requires `old_string` to match exactly once (a fuzzy match is allowed and reported), writes, updates the file view and appends a bounded post-write receipt showing what landed ([editfile.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/editfile.go#L30-L88)).
7. **Loop.** Tool results join the conversation and the next step samples again. Past 85% of the window, compaction installs a summary checkpoint before continuing.

## Key components

### Providers

There are three provider kinds. `openai` covers any `/chat/completions` endpoint and picks the reasoning wire shape from the base URL: DeepSeek `thinking` plus `reasoning_effort`, MiniMax `adaptive|disabled`, Zhipu GLM, LongCat, Ollama Cloud, and Kimi K3's `max_completion_tokens` ([openai.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/model/openai/openai.go#L1-L22)). `anthropic` speaks `/v1/messages` and replays signed thinking blocks. `responses` (also registered as `dashscope-responses`) targets the OpenAI Responses API ([responses.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/model/responses/responses.go#L25-L40)). Providers are config instances in `reasonix.toml`, not code. There is no bundled local-inference path. A local server is used as an OpenAI-compatible endpoint.

### Context and compaction

Repository context is pulled on demand: `read_file` with paging, `grep` (ripgrep), `glob`, and a tree-sitter `code_index` for outlines and symbol search in Go, JS/TS, Python and Rust. There is no embedding index. Compaction triggers at 85% of the window and keeps a stable prefix, one structured digest of at most 16K tokens produced at low effort, and a verbatim recent tail of 10% of the window, clamped to 32K–96K tokens ([compact.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/compact.go#L18-L40)). Instruction files `REASONIX.md`, `AGENTS.md` and `CLAUDE.md`, plus `*.local.md` variants, are resolved at user, ancestor, project and local scope, with `@path` imports up to five levels deep ([resolver.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/state/instruction/resolver.go#L17-L30)). `#<note>` appends a note to them.

### Safety

Permission modes are `read-only`, `ask`/`manual`, `acceptEdits`, `auto`, `dontAsk`, `plan` and `bypassPermissions`. The 1.x names `workspace-write` and `danger-full-access` still parse ([cli.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/frontend/cli/cli.go#L232-L256)). Rules evaluate to allow, ask or deny. `Ask` defers to an interactive approver, or resolves to allow when there is none ([permission.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/safety/permission/permission.go#L1-L40)). Under the rules, `bash` runs in an OS jail: Seatbelt on macOS, bubblewrap on Linux. The host is mounted read-only, with writable roots, optional forbid-read roots, a network flag and host-authority grants. When enforcement is requested but no backend exists (Windows today), the tool fails closed ([sandbox.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/safety/sandbox/sandbox.go#L1-L60)). The file-writing built-ins confine themselves in-process.

### Checkpoints

Before a writer tool changes a file, its pre-edit content is stored under the current user turn. A front end can then rewind the workspace, and the conversation, to an earlier turn. Checkpoints never touch git. Shell side effects are not captured, because only tools that can preview their change are hooked ([checkpoint.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/state/checkpoint/checkpoint.go#L1-L13)).

## Extending it

- **MCP.** `[mcp_servers]` in config, with stdio and SSE, OAuth, a registry browser, and a per-server sandbox spec.
- **Hooks.** Claude-Code-style events (`PreToolUse`, `PostToolUse`, `PermissionRequest`, `UserPromptSubmit`, `Stop`, `SessionStart/End`, `SubagentStart/Stop`, `PreCompact`, plus `PostLLMCall`) ([hook.go](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/ext/hook/hook.go#L44-L67)).
- **Skills and slash commands.** Built-in and filesystem skills that can be invoked as slash commands.
- **Extensions.** Sidecar processes speaking Extension Protocol v2 over stdio can intercept tool calls, observe events, host provider streams and add UI surfaces. `sdk/go` is a dependency-free Go SDK for writing them ([sdk/go README](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/sdk/go/README.md#L1-L20)).

## Running it

- Install a 2.x "Studio" release (the 1.x line ships on npm as `reasonix`). Run `reasonix setup`, then `reasonix` or `reasonix tui` in a repository, or `reasonix run "<task>"` headless.
- Configure providers, models, permissions, sandbox and MCP in `reasonix.toml` (`reasonix.example.toml` is the reference).
- `reasonix serve` or `web` starts the browser UI. `reasonix acp` serves editors. The desktop app wraps the same engine.
- Shell sandboxing needs `bwrap` on Linux. On macOS it uses the built-in `sandbox-exec`.

## Strengths and caveats

- **Strength: cost-aware loop design.** Frozen schemas, append-only context notices and rare compaction keep cache hit rates high. On DeepSeek-class pricing that is the biggest cost lever.
- **Strength: defence in depth.** Permission rules, an OS jail that fails closed, in-process write confinement, stale-write detection and per-turn rewind together make long autonomous runs recoverable.
- **Strength: honest planner fallback.** The two-model mode degrades to single-model on planner failure but never skips an approval boundary.
- **Caveat: rewind does not cover the shell.** Checkpoints capture edit-tool writes only. Anything `bash` changes is outside the undo.
- **Caveat: no Windows shell sandbox.** Enforcement is unavailable there, so `bash` runs only with the sandbox turned off.
- **Caveat: a fast-moving 2.x.** The README itself steers users who want stability to 1.x. The agent package alone has hundreds of files, so internals change often.

*Sources: code at 7f30fcb, deepwiki-open wiki (11 pages), verified Q&A.*

## How esengine/DeepSeek-Reasonix answers the Open-source coding agents questions

### How is the agent loop implemented? (answered)

The agent loop is a tool-round loop inside `Agent.runToolLoop` (`internal/runtime/agent/run_loop.go:261`). There is no separate planner model by default — the single model both plans and executes. An optional two-model `Coordinator` (`internal/runtime/coordinator/coordinator.go:97`) runs a planner model first (via `submit_plan`, planner tools are read-only), then hands its plan to an executor Agent. The loop in `runToolLoop` iterates steps up to `maxSteps` (default from config). Each step: (a) freezes the provider request via `prepareSamplingRequest` — tool schemas are captured once (`ProviderSchemas`), prefix shape recorded; (b) streams the model response with `streamWithSamplingRecovery` (`run_loop.go:407`), which retries up to maxSamplingAttempts=6 on interruption or context overflow; (c) classifies the response boundary via `classifyResponseBoundary` (`response_boundary.go:27`) to drop half-written tool calls; (d) commits assistant message to conversation; (e) for tool calls, runs `handleToolRound` → `executeOne` (`execute_one.go:95`), which resolves the tool (parse, policy, permission gate, sandbox extend, execute, post-write receipt); (f) loops back for another step. Stop conditions: no tool calls → final response handled by `handleFinalResponse`; max steps reached → `armFinalizationRound`/`gracePause` (`finalization.go:40,55`); task budget exhausted → `taskBudgetPause`; perseveration detected → cut-and-retry with nudge (`settlePerseveration`). Sub-agents are spawned via `RunSubAgentWithSession` (`child_run.go:36`), each getting its own Agent instance, session, event sink, and session-private temp directory.


Citations: [internal/runtime/agent/run_loop.go:261-380](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/run_loop.go#L261-L380) · [internal/runtime/agent/run_loop.go:407-460](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/run_loop.go#L407-L460) · [internal/runtime/coordinator/coordinator.go:1-100](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/coordinator/coordinator.go#L1-L100) · [internal/runtime/agent/execute_one.go:95-145](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/execute_one.go#L95-L145) · [internal/runtime/agent/finalization.go:40-60](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/finalization.go#L40-L60) · [internal/runtime/agent/child_run.go:36-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/child_run.go#L36-L80)

### How is repository context gathered and kept within the context window? (answered)

Repository context is gathered through compile-time-builtin tools, not embeddings or a repo-map pass. The primary tools are: `read_file` (`internal/tools/builtin/readfile.go:52`) reads files with offset/limit paging and reports total-length/pagination trailer; `grep` (`internal/tools/builtin/grep.go:30`) runs ripgrep underneath, capped at 200 results and 300s timeout; `glob` finds files by glob pattern; `code_index` (`internal/tools/builtin/codeindex.go:51`) provides outline/search for Go/JS/Python/Rust/TypeScript via tree-sitter AST parsing without a language server. The model selectively invokes these on demand — there is no automatic repository indexing. Context window management is handled by `windowState` (`internal/runtime/agent/context_window.go:13`) with a compaction system (`internal/runtime/agent/compact.go:20`). At 85% capacity (`defaultCompactRatio`), the agent installs a summary checkpoint: earlier conversation is replaced by a structured brief under headings (Standing facts, Goal, Decisions, Files, Commands, Errors, Pending) generated by the model itself with a low-effort summarizer prompt (`compact.go:57`). The recent tail (at least 10% of window, 32K–96K tokens) and a small number of verbatim user turns are preserved. Compaction is one-shot per maintenance boundary; the model sees a `<compaction-summary>...</compaction-summary>` block. The workspace scan (`workspace_scan.go:22`) walks the workspace tree (skipping VCS dirs, symlinks) in parallel (16 readers) up to 50K files, used for delivery-verification scans rather than continuous context. There is no embedding-based retrieval or RAG system.


Citations: [internal/tools/builtin/readfile.go:27-60](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/readfile.go#L27-L60) · [internal/tools/builtin/grep.go:29-60](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/grep.go#L29-L60) · [internal/runtime/agent/context_window.go:13-46](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/context_window.go#L13-L46) · [internal/runtime/agent/compact.go:20-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/compact.go#L20-L80) · [internal/runtime/agent/workspace_scan.go:22-56](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/runtime/agent/workspace_scan.go#L22-L56) · [internal/tools/builtin/codeindex.go:24-58](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/codeindex.go#L24-L58)

### How are code edits applied? (answered)

Edits are applied through three compile-time-builtin tools. `write_file` (`internal/tools/builtin/writefile.go:43`) replaces an entire file; it detects no-op writes (same content) and reports them, and creates parent directories. `edit_file` (`internal/tools/builtin/editfile.go:30`) does a search-and-replace: `old_string` must match exactly once in the file, `new_string` replaces it. A fuzzy-match fallback is available (whitespace-tolerant). `multi_edit` (`internal/tools/builtin/multiedit.go:43`) applies a batch of edits atomically to one file — each step runs against the result of the previous one in memory, and the file is only rewritten if every edit succeeds. Each edit tool has a `Preview` method (`internal/tools/builtin/preview.go:25,50`) that computes the diff without executing; preview_test.go asserts `Preview` matches `Execute` exactly. After every write, a bounded "post-write receipt" (`post_write_receipt.go:20`) is appended to the conversation — it shows the matched and replacement spans (capped at ~2KB total) so the model can confirm what landed. The `FileViews` mechanism (`internal/tools/builtin/fileviews.go:23`) tracks SHA-256 hashes of files the agent read or wrote; `write_file` checks that the file hasn't changed since the agent last saw it, refusing the overwrite (`ErrFileChangedSinceSeen`) to prevent clobbering simultaneous edits. There is no lint or test validation between edits and the model's reasoning — that is left to the model's own judgement and the subsequent tool round. Git integration is available via platform/gitcmd for commits and status queries, but edits themselves do not auto-commit; the bash tool can be used to run lint/test commands. All write tools pass through `confineWrite` which checks write roots, session-data guards, and managed config path protections.


Citations: [internal/tools/builtin/editfile.go:18-88](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/editfile.go#L18-L88) · [internal/tools/builtin/multiedit.go:15-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/multiedit.go#L15-L80) · [internal/tools/builtin/writefile.go:22-100](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/writefile.go#L22-L100) · [internal/tools/builtin/preview.go:25-60](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/preview.go#L25-L60) · [internal/tools/builtin/fileviews.go:17-60](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/fileviews.go#L17-L60) · [internal/tools/builtin/post_write_receipt.go:9-60](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/post_write_receipt.go#L9-L60)

### How are shell commands and file writes kept safe? (answered)

Shell commands and file writes have three independent layers of protection. **Permission policy** (`internal/safety/permission/permission.go:1`): each tool call is evaluated against a `Policy` of rules (allow/ask/deny). Rules are configured as `[permission]` entries in `reasonix.toml` (e.g. `allow = ["Bash:git*"]`, `deny = ["Bash:rm -rf /"]`). A `Gate` wraps the policy with an interactive `Approver` that lets the user allow/deny/always-allow on each call. The default is Ask (prompt user). Read-only mode denies all writers with a clear refusal code (`RefusalReadOnly`). **OS sandbox** (`internal/safety/sandbox/sandbox.go:1`): on Linux, bash commands run under bubblewrap; on macOS, under sandbox-exec/Seatbelt. The `Spec` declares write roots (workspace + configured extras), forbid-read roots, a Network boolean, HostAuthorities for SSH/Docker/Podman, an Egress proxy route for external HTTP, and MinimalWrites for MCP processes. On Windows, OS-level bash sandboxing is not available and enforced sandbox fails closed (`UnavailableMessage`). **Path confinement** (`internal/tools/builtin/confine.go:29`): `ConfineBash` binds the bash tool to the sandbox spec; `BindSessionTemp` attaches session-private temp dirs. The write tools (write_file, edit_file, multi_edit, move_file, delete operations) apply `confineWrite` to ensure the target path falls within allowed write roots and outside protected Reasonix data directories (`SessionDataGuard`). Network access for tool calls is further governed by the egress policy (`internal/safety/egress/policy.go`) which routes external HTTP through a proxy. The sandbox enforces three dimensions independently: Integrity (write roots), Confidentiality (forbid-read roots), and Authority (host services). Checkpoints (session snapshots) are stored separately in the session store for rewind, not used for sandbox isolation.


Citations: [internal/safety/sandbox/sandbox.go:1-83](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/safety/sandbox/sandbox.go#L1-L83) · [internal/safety/permission/permission.go:1-100](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/safety/permission/permission.go#L1-L100) · [internal/safety/permission/verdict.go:10-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/safety/permission/verdict.go#L10-L80) · [internal/tools/builtin/confine.go:20-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/tools/builtin/confine.go#L20-L80) · [internal/safety/sandbox/prepare.go:1-45](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/safety/sandbox/prepare.go#L1-L45)

### Which models are supported and how are they called? (answered)

Models are supported through two provider implementations registered in a `provider.Registry`. **OpenAI-compatible** (`internal/model/openai/openai.go:1`): registered as kind `"openai"`, calls `/chat/completions` with SSE streaming. Per-vendor wire-shape detection selects different reasoning parameters: `api.deepseek.com` uses `thinking.type=enabled` with `reasoning_effort`; `api.minimaxi.com` uses `thinking.type=adaptive|disabled` (M3's binary knob); `open.bigmodel.cn` / `api.z.ai` (Zhipu GLM) have documented depth fields; `api.longcat.chat` uses `thinking.type=enabled|disabled` without effort scale; `ollama.com` accepts hosted Ollama Cloud's effort scale including `max`; Kimi K3 preserves complete messages and uses `max_completion_tokens`. Everything else uses vanilla `reasoning_effort`. **Anthropic** (`internal/model/anthropic/anthropic.go:1`): registered as kind `"anthropic"`, calls POST `/v1/messages` with SSE streaming. Supports extended thinking via signed reasoning blocks that are replayed on multi-turn. No temperature/top_p (Claude rejects sampling params). DeepSeek's compatible Anthropic endpoint uses unsigned thinking blocks with binary enabled|disabled and output_config.effort. Configuration is via `reasonix.toml` `[provider]` blocks with `kind`, `base_url`, `model`, `api_key`, and kind-specific extras. Providers resolve via `config.go` (`internal/contract/provider/config.go:6`) and the provider broker serves them. `local.go` (`internal/model/providerbroker/local.go`) provides no local-model fallback; there is no Ollama-hosted local inference path — the Ollama integration reaches hosted cloud API. Cost tracking uses `pricing.rates.go` (`internal/contract/pricing/rates.go:36`) with official rates for DeepSeek, Anthropic Claude, OpenAI GPT, MiniMax, LongCat, Moonshot (Kimi), and others, stored as oldest-first generations per vendor. `make pricecheck` reads vendor pages to verify rates.

> **Editor's note.** Correction: there are three provider kinds, not two; `responses` (also `dashscope-responses`, internal/model/responses/responses.go) targets the OpenAI Responses API alongside `openai` and `anthropic`.

Citations: [internal/model/openai/openai.go:1-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/model/openai/openai.go#L1-L80) · [internal/model/anthropic/anthropic.go:1-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/model/anthropic/anthropic.go#L1-L80) · [internal/contract/provider/vendor.go:1-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/contract/provider/vendor.go#L1-L80) · [internal/contract/pricing/rates.go:1-80](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/contract/pricing/rates.go#L1-L80)

### How can it be extended and customised? (answered)

Reasonix provides two extension systems. **MCP (Model Context Protocol)** servers (`internal/ext/plugin/plugin.go`): configured via `[mcp_servers]` in `reasonix.toml`, supports stdio and SSE transports, OAuth, URI handlers, prompt templates, and resource listing. MCP servers are launched and managed by `mcplaunch`/`plugin` packages, with per-server sandbox specs (write roots, network, egress). The MCP registry client (`internal/ext/mcpregistry/registry.go:33`) provides browse/install from the official registry. MCP tool results can include images (toolresult_image.go). **Extension packages** (`internal/ext/extension/`): a protocol for runtime-loadable packages that can register new providers, tools, themes, skills, and frontend hooks through a JSON-wire RPC mechanism (packages like `internal/ext/extension/protocol`, `dispatch`, `providerext`). The `extensioncontract` package defines the contract between host and extension. **Skills** (`internal/ext/skill/`): slash-command invocable workflows registered from filesystem or built-in content; resolved by the `skill` package and routed by `slash.go`/`slash_catalog.go`. **Hooks** (`internal/ext/hook/`): lifecycle hooks that fire on session events (start, turn begin/end). **Instruction/rule files**: multi-file loading from `REASONIX.md`, `AGENTS.md`, `CLAUDE.md`, personal `*.local.md` variants, and ancestor-directory search. `@path` imports and `#<note>` quick-add are supported. **Plugin packaging** (`internal/ext/pluginpkg/`): package/unpackage MCP servers into redistributable archives with declared metadata. There is no SDK or headless-agent library exposed to external Go consumers — the `sdk/` directory at the repo root contains stubs only. The desktop frontend (`desktop/`) is a separate Electron app that drives the same Controller.

> **Editor's note.** Correction: `sdk/go` is not a stub; it is a dependency-free Go SDK for writing Extension Protocol v2 sidecars that intercept tool calls, observe events, host provider streams and add UI surfaces.

Citations: [internal/ext/plugin/plugin.go:1-10](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/ext/plugin/plugin.go#L1-L10) · [internal/ext/mcpregistry/registry.go:1-60](https://github.com/esengine/DeepSeek-Reasonix/blob/7f30fcbdb371585cd684947723097ec67ba4cf4f/internal/ext/mcpregistry/registry.go#L1-L60)
