# Extension Protocol v1 for Sidecars in DeepSeek-Reasonix: Intercepting Runtime Events

> Explore Extension Protocol v1 for DeepSeek-Reasonix sidecars. Intercept and rewrite runtime events like user input before they reach the language model using this JSON-RPC 2.0 interface.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: api-reference
- Published: 2026-08-06

---

**Extension Protocol v1 defines a JSON-RPC 2.0 interface over STDIO that allows sidecar processes to intercept and rewrite runtime events—most notably user input via the `input.receive` event—before they reach the language model.**

DeepSeek-Reasonix implements **Extension Protocol v1** to communicate with out-of-process sidecars that extend the host's capabilities. This stable wire contract, defined in the `esengine/DeepSeek-Reasonix` repository, enables separate executables defined in a plugin's Manifest v1 `runtime` entry to intercept runtime events, modify requests, and inject custom behaviors while maintaining compatibility across Reasonix releases.

## Protocol Architecture and Transport

Extension Protocol v1 operates over **JSON-RPC 2.0** via standard input and output streams. When the Reasonix host initializes a session, it spawns the sidecar executable and establishes a bidirectional communication channel over STDIO, as implemented in [`sdk/go/sdk.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/sdk.go).

The protocol requires an explicit version handshake. According to [`internal/extension/protocol/schema.generated.json`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/extension/protocol/schema.generated.json), the `protocolVersion` field in `HostCapabilities` must be set to `"v1"` to indicate compliance with this specification.

### Sidecar Lifecycle and Initialization

Before processing any runtime events, the sidecar must complete an initialization sequence. As documented in [`sdk/go/sdk.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/sdk.go) lines 46-51, the sidecar receives `InitializeParams` and must respond with an initialization confirmation before the host sends any other callbacks. This ensures both processes agree on capabilities and event handlers before intercepting live traffic.

## Intercepting Runtime Events

The primary purpose of Extension Protocol v1 is to allow sidecars to intercept and potentially modify events flowing through the Reasonix host. The [`sdk/go/types_generated.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/types_generated.go) file (lines 82-107) defines the `EventParams` DTO, which includes several interceptable events:

- **`input.receive`**: Intercepts incoming user text before it reaches the model
- **`session.start`**: Hooks into session initialization
- **`session.end`**: Handles session cleanup
- **`provider.request`**: Intercepts or augments requests to model providers

### Rewriting User Input with input.receive

The most commonly intercepted event is `input.receive`, which allows sidecars to rewrite or augment user text in real-time. When a sidecar registers a handler for this event, it receives the raw input payload and can return a modified version with the `InterceptDecisionRewrite` decision before the host forwards it to the model.

## Implementing a Sidecar in Go

The DeepSeek-Reasonix SDK provides Go bindings that abstract the JSON-RPC wire protocol. Below are practical implementations demonstrating event interception.

### Starter Sidecar Example

The starter sidecar example in [`sdk/go/examples/starterextension/main_test.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/examples/starterextension/main_test.go) demonstrates a minimal implementation that intercepts inputs starting with `starter:` and rewrites them:

```go
// File: sdk/go/examples/starterextension/main_test.go
result, err := interceptInput(
    context.Background(),
    "input.receive",
    json.RawMessage(`{"text":"starter: explain sidecars"}`),
)
want := `{"text":"explain sidecars [rewritten by starter-extension]"}` // ✅ passes

```

This handler checks for the `starter:` prefix and transforms the payload by appending a suffix before returning the modified JSON.

### Full-Featured Sidecar Implementation

For more complex scenarios, the full sidecar example in [`sdk/go/examples/fullsidecar/main.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/examples/fullsidecar/main.go) shows how to register multiple intercept handlers and manage the sidecar lifecycle:

```go
// File: sdk/go/examples/fullsidecar/main.go
func main() {
    // …setup extension server…
    // Register intercept handler
    ext.OnIntercept("input.receive", func(ctx context.Context, p extension.InterceptParams) (extension.InterceptResult, error) {
        var in struct{ Text string `json:"text"` }
        json.Unmarshal(p.Payload, &in)
        if strings.HasPrefix(in.Text, "fullsidecar:") {
            in.Text = strings.TrimPrefix(in.Text, "fullsidecar:") + " [rewritten by fullsidecar]"
        }
        out, _ := json.Marshal(in)
        return extension.InterceptResult{Decision: extension.InterceptDecisionRewrite, Payload: out}, nil
    })
    // …run the sidecar…
}

```

When running this sidecar and sending `fullsidecar: hello`, the model receives `hello [rewritten by fullsidecar]`, demonstrating the end-to-end interception flow:

```text
> starter: explain sidecars

# The starter sidecar intercepts the input, rewrites it, and the model receives:

explain sidecars [rewritten by starter-extension]

```

## Protocol Stability and Versioning

Extension Protocol v1 guarantees backward compatibility through a frozen contract. According to [`internal/extension/protocolgen/sdkgo.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/extension/protocolgen/sdkgo.go) lines 160-165, method names and data structures are generated from the `internal/extension/protocol` definitions and are explicitly frozen for version v1.

This stability ensures that sidecars built against Protocol v1 continue functioning across Reasonix releases without recompilation, enabling reliable caching and safe hot-reloads of extensions.

## Key Source Files

Understanding the protocol implementation requires examining these specific files in the `esengine/DeepSeek-Reasonix` repository:

- **[`internal/extension/protocol/protocol.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/extension/protocol/protocol.go)**: Defines the core protocol messages and wire format
- **[`sdk/go/types_generated.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/types_generated.go)**: Contains generated DTOs and enums including `EventParams` and `InterceptResult`
- **[`sdk/go/sdk.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/sdk.go)**: Implements the Go SDK with STDIO transport and initialization handling
- **[`internal/extension/sidecar/doc.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/extension/sidecar/doc.go)**: Documents the host-side sidecar implementation
- **[`internal/extension/protocolgen/sdkgo.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/extension/protocolgen/sdkgo.go)**: Code generation logic that freezes v1 method signatures

## Summary

- **Extension Protocol v1** uses JSON-RPC 2.0 over STDIO to communicate with out-of-process sidecars
- Sidecars must complete initialization via `InitializeParams` before handling runtime events
- The **`input.receive`** event allows rewriting user input before it reaches the model
- Protocol contracts are frozen in v1, ensuring long-term compatibility across Reasonix versions
- Reference implementations in `sdk/go/examples/` demonstrate practical interception patterns

## Frequently Asked Questions

### What transport mechanism does Extension Protocol v1 use?

Extension Protocol v1 transmits messages via JSON-RPC 2.0 over standard input and output streams (STDIO). As implemented in [`sdk/go/sdk.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/sdk.go), the host spawns the sidecar process and establishes a bidirectional channel over STDIN/STDOUT, eliminating the need for network sockets or shared memory.

### Which runtime events can a sidecar intercept?

According to [`sdk/go/types_generated.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/sdk/go/types_generated.go), sidecars can intercept multiple events including `input.receive` for user text, `session.start` and `session.end` for lifecycle management, and `provider.request` for model provider calls. Each event passes structured data via the `EventParams` DTO.

### How does the protocol ensure version compatibility?

The protocol requires an explicit version handshake where `protocolVersion` in `HostCapabilities` must equal `"v1"`. Additionally, [`internal/extension/protocolgen/sdkgo.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/extension/protocolgen/sdkgo.go) generates frozen DTOs and method names that remain stable across releases, preventing breaking changes for compiled sidecars.

### Can sidecars modify user input before it reaches the model?

Yes. By registering a handler for the `input.receive` event, sidecars receive the raw input payload and return an `InterceptResult` with `Decision: InterceptDecisionRewrite` and modified payload data. Examples in both `starterextension` and `fullsidecar` demonstrate rewriting text by checking prefixes and transforming content.