# How to Integrate Reasonix with Editors via the ACP Protocol

> Integrate Reasonix with editors using the ACP protocol. Launch the reasonix acp command and manage AI coding sessions via NDJSON JSON-RPC 2.0 messages for seamless development.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: how-to-guide
- Published: 2026-08-08

---

**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](https://github.com/esengine/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/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/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.

```bash

# 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/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/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:

```javascript
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:

```javascript
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 `stdout` as the exclusive protocol channel.
- **Launch**: Start the server with `reasonix acp [--model <name>] [--profile <name>]` to establish baseline configuration.
- **Negotiation**: Call `initialize` to discover capabilities and vendor extensions via the `_meta` field before creating sessions.
- **Lifecycle**: Manage AI interactions through `session/new`, `session/prompt`, and `session/close`, with optional `session/resume` for reconnection.
- **Steering**: Use `_reasonix.io/session/steer` to influence ongoing generations without canceling them, discovered dynamically from `_meta`.
- **Integration**: Delegate file and terminal operations to the editor by advertising `fs` and `terminal` capabilities in the `initialize` request.

## 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/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/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.