How to Integrate Reasonix with Editors via the ACP Protocol
Integrate Reasonix with editors by launching the reasonix acp command over standard input/output using NDJSON JSON-RPC 2.0 messages, negotiating capabilities via the initialize method, and managing AI coding sessions through the Agent Client Protocol (ACP) v1 lifecycle.
The DeepSeek-Reasonix repository provides a native ACP implementation that transforms the Reasonix AI coding agent into a long-running server for editor integrations. By treating Reasonix as an ACP host, editors can spawn the binary as a child process and communicate over structured JSON-RPC to create sessions, execute prompts, and handle file operations. This protocol enables real-time collaboration between the AI agent and the editor's UI, including mid-turn steering and hot-reloading of extensions.
Architecture Overview
Transport and Protocol
Reasonix implements ACP v1 over standard input/output using NDJSON (newline-delimited JSON) encoded as JSON-RPC 2.0 messages. The editor (client) launches the binary with the acp subcommand and must treat stdout as the exclusive protocol channel while reserving stderr for diagnostic logs. This design ensures that editors can spawn Reasonix as a sandboxed subprocess without network overhead, making it ideal for local AI-assisted development workflows.
Host Identification
The protocol identifies ACP-compatible hosts through the UIHostACP constant defined in the Go SDK and internal validation layers. According to the source code, this enum value is declared in [sdk/go/types_generated.go](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/sdk/go/types_generated.go) and enforced in [internal/extension/protocol/enums.go](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/internal/extension/protocol/enums.go), where it represents the editor integration surface alongside other host types like CLI and Desktop.
Launching the ACP Server
CLI Initialization
To start an ACP session, the editor spawns the binary with the acp subcommand and optional configuration flags. The command accepts --model to specify the default LLM (e.g., deepseek-pro) and --profile to load a predefined configuration set. These flags establish baseline capabilities, though the client can override them later via session/set_config_option during the session lifecycle.
# Start Reasonix with specific model and profile
reasonix acp --model deepseek-pro --profile delivery
The implementation validates these inputs against the protocol enums and runtime configuration, with comprehensive test coverage available in [internal/cli/acp_test.go](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/internal/cli/acp_test.go).
Capability Negotiation
The Initialize Method
Before creating sessions, the client must call the initialize method to negotiate capabilities. Reasonix responds with an agentCapabilities object that advertises supported session methods (list, resume, close, delete), prompt features like embeddedContext, and available transport shapes for the Model Context Protocol (MCP). The response also includes a _meta field containing vendor-specific extensions.
Vendor Extensions and Meta Fields
The _meta field in the initialize response exposes Reasonix-specific capabilities such as the steering method identifier (_reasonix.io/session/steer) and runtime reload endpoints. These extensions allow editors to discover dynamically whether mid-turn steering and extension hot-swapping are available for the current session. The protocol strictly requires that clients use the exact method names provided in the _meta object rather than hardcoding vendor prefixes.
Session Lifecycle Management
Creating and Managing Sessions
Each ACP session maintains its own workspace root, model configuration, work mode, and persisted transcript. The client initiates a session using session/new with an absolute cwd path, then controls the lifecycle through session/prompt for queries, session/cancel for aborting operations, and session/close or session/delete for cleanup. Session state persists across transport disconnections, enabling editors to resume work with session/resume using the previous session ID.
Mid-Turn Steering
Reasonix supports mid-turn steering, a vendor extension that allows the editor to influence an ongoing AI generation without canceling it. While a session/prompt is active, the client can send a _reasonix.io/session/steer request with additional text fragments (e.g., "Prefer a recursive solution"). The steering request is queued and applied to the current turn's context, providing real-time guidance as the model generates content.
Runtime Reload and Extension Surface
Two additional vendor methods enable advanced editor integrations: _reasonix.io/session/reloadExtensions triggers a hot reload of the session's runtime once the current turn completes, and extensionSurface provides structured UI payloads for consistent rendering across ACP, CLI, and Desktop surfaces. These capabilities ensure that editors can update plugins dynamically without restarting the AI agent.
Editor Integration Patterns
File System and Terminal Delegation
When the client advertises fs.readTextFile, fs.writeTextFile, or terminal capabilities in the initialize request, Reasonix routes file operations through the editor rather than accessing the disk directly. This "virtual filesystem" approach ensures that AI-generated edits appear immediately in the editor's buffer before saving, and that terminal commands execute within the editor's integrated terminal panel. The validation logic in [internal/extension/protocol/validate.go](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/internal/extension/protocol/validate.go) ensures that only whitelisted host types (including UIHostACP) can register these privileged capabilities.
Permission Handling
Reasonix may request user confirmation for sensitive operations via session/request_permission notifications. The editor must display these permission dialogs and respond with session/response_permission, passing the original requestId and a boolean allowed flag. This security layer ensures that file deletions, network requests, or shell executions require explicit user approval even when the AI agent initiates them.
Implementation Example
Node.js Integration
The following example demonstrates launching Reasonix from a Node.js editor extension and managing the protocol lifecycle:
const { spawn } = require('node:child_process');
// Spawn Reasonix with isolated stdio streams
const reasonix = spawn('reasonix', ['acp', '--model', 'deepseek-pro'], {
stdio: ['pipe', 'pipe', 'pipe'] // stdin, stdout (protocol), stderr (logs)
});
let rpcId = 1;
const send = (method, params) => {
const msg = JSON.stringify({ jsonrpc: '2.0', id: rpcId++, method, params });
reasonix.stdin.write(msg + '\n');
};
// 1. Initialize capability negotiation
send('initialize', {
clientCapabilities: {
fs: { readTextFile: true, writeTextFile: true },
terminal: true,
reasonix: { extensionSurface: true }
}
});
// 2. Create a new session with absolute workspace path
send('session/new', {
cwd: '/home/user/myproject'
});
// 3. Send a prompt to the AI
send('session/prompt', {
sessionId: 'sess_12345',
prompt: [{ type: 'text', text: 'Refactor the auth module to use async/await' }]
});
// 4. Apply mid-turn steering while generating
send('_reasonix.io/session/steer', {
sessionId: 'sess_12345',
prompt: [{ type: 'text', text: 'Ensure error handling uses try/catch blocks' }]
});
// 5. Cleanup when done
send('session/close', { sessionId: 'sess_12345' });
Handling Protocol Messages
Editors must parse NDJSON responses from stdout and handle server-to-client notifications:
const readline = require('node:readline');
const rl = readline.createInterface({ input: reasonix.stdout });
rl.on('line', (line) => {
const msg = JSON.parse(line);
if (msg.method === 'agent_message_chunk') {
// Stream AI output to the editor's UI
editor.appendText(msg.params.content);
}
else if (msg.method === 'session/request_permission') {
// Show permission dialog and respond
editor.showPermissionDialog(msg.params).then((allowed) => {
send('session/response_permission', {
requestId: msg.id,
allowed: allowed
});
});
}
else if (msg.method === 'fs/readTextFile') {
// Return file content from editor buffer
const content = editor.getBufferContent(msg.params.uri);
send('fs/readTextFile/response', { content, id: msg.id });
}
});
Summary
- Transport: Reasonix ACP uses NDJSON JSON-RPC 2.0 over stdio, requiring editors to parse
stdoutas the exclusive protocol channel. - Launch: Start the server with
reasonix acp [--model <name>] [--profile <name>]to establish baseline configuration. - Negotiation: Call
initializeto discover capabilities and vendor extensions via the_metafield before creating sessions. - Lifecycle: Manage AI interactions through
session/new,session/prompt, andsession/close, with optionalsession/resumefor reconnection. - Steering: Use
_reasonix.io/session/steerto influence ongoing generations without canceling them, discovered dynamically from_meta. - Integration: Delegate file and terminal operations to the editor by advertising
fsandterminalcapabilities in theinitializerequest.
Frequently Asked Questions
What transport protocol does Reasonix ACP use?
Reasonix ACP v1 communicates over standard input/output using NDJSON (newline-delimited JSON) formatted as JSON-RPC 2.0 messages. The editor must launch the reasonix acp process and treat stdout as the protocol stream while monitoring stderr for logs. This stdio-based approach eliminates network configuration and enables secure local sandboxing.
How do I enable mid-turn steering in my editor?
First, check the initialize response for _meta["reasonix.io"].sessionSteer.method, which provides the exact method name (typically _reasonix.io/session/steer). While a session/prompt is active, send a JSON-RPC request to that method with the sessionId and additional prompt fragments. The steering guidance enters a queue and influences the ongoing generation without aborting it.
What is the UIHostACP constant used for?
UIHostACP is an enumerated value defined in [internal/extension/protocol/enums.go](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/internal/extension/protocol/enums.go) and exposed in the Go SDK at [sdk/go/types_generated.go](https://github.com/esengine/DeepSeek-Reasonix/blob/main-v2/sdk/go/types_generated.go). It identifies the host type as an ACP-compatible editor during capability validation, ensuring that the protocol layer applies the correct security and transport policies for editor integrations.
How do I handle file operations through the editor instead of disk?
Advertise fs.readTextFile and fs.writeTextFile as true in the clientCapabilities object of your initialize request. When Reasonix needs file access, it will send fs/readTextFile or fs/writeTextFile requests to your client rather than accessing the filesystem directly. Respond with the buffer contents or write confirmation to ensure edits reflect immediately in the editor's UI before saving to disk.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →