<!-- source: https://deepwiki.com/qhkm/zeptoclaw/10.6-provider-plugins -->

# Provider Plugins

- src/api/openai_types.rs
- src/api/routes/openai.rs
- src/cli/panel.rs
- src/providers/plugin.rs
- src/providers/retry.rs
- src/providers/types.rs

## Purpose and Scope

Provider Plugins enable integration of external LLM providers via JSON-RPC 2.0 over stdin/stdout communication. This mechanism allows ZeptoClaw to support arbitrary language models without requiring native Rust implementations for each provider's API.

This page covers the `ProviderPlugin` adapter class, the JSON-RPC 2.0 chat protocol, request/call wire formats, and execution lifecycle. For built-in provider implementations (Anthropic, OpenAI, etc.), see [Supported Providers](/qhkm/zeptoclaw/10.2-supported-providers). For provider selection and credential resolution, see [Provider Configuration](/qhkm/zeptoclaw/10.1-provider-configuration).

## Architecture Overview

Provider plugins follow a **process-per-request** model: each `chat()` call spawns the configured binary, writes a single JSON-RPC request to stdin, reads the response from stdout, and terminates the process. This stateless design simplifies plugin implementation and isolates failures.

### Component Diagram

The following diagram illustrates the flow from the core `AgentLoop` through the `ProviderPlugin` adapter to the external binary process.

```

```

**Sources:** [src/providers/plugin.rs1-124](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L1-L124) [src/providers/plugin.rs167-173](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L167-L173)

## JSON-RPC 2.0 Protocol

Provider plugins communicate via JSON-RPC 2.0 with a single `chat` method. The binary reads one request line from stdin, writes one response line to stdout, and exits.

### Request Format ( PluginChatRequest )

The request encapsulates the conversation history, available tools, and generation parameters. The `params` field contains the `PluginChatParams` structure [src/providers/plugin.rs46-52](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L46-L52)

```

```

### Response Format ( PluginChatResponse )

Success results include the generated text, any tool calls requested by the model, and token usage metrics. The structure `PluginChatResult` maps directly to the `LLMResponse` expected by the core system [src/providers/plugin.rs77-83](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L77-L83)

```

```

**Sources:** [src/providers/plugin.rs38-97](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L38-L97)

## Wire Type Mapping

The following table maps ZeptoClaw's internal types to JSON-RPC wire representations defined in `src/providers/plugin.rs`.

**Sources:** [src/providers/plugin.rs38-106](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L38-L106) [src/providers/types.rs1-100](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/types.rs#L1-L100)

## Execution Flow

The `ProviderPlugin::chat` implementation manages the lifecycle of the external process using `tokio::process::Command`.

```

```

### Key Functions

- ProviderPlugin::new : Initializes the adapter with the binary path and arguments src/providers/plugin.rs 149-156
- ProviderPlugin::chat : The primary entry point. It serializes the request, spawns the child process, and waits for completion src/providers/plugin.rs 167-173
- tokio::time::timeout : Ensures the external process does not hang indefinitely (default 120s) src/providers/plugin.rs 257-274

**Sources:** [src/providers/plugin.rs149-274](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L149-L274)

## ProviderPlugin Implementation Details

### Core Structure

The `ProviderPlugin` struct stores the configuration necessary to invoke the external binary [src/providers/plugin.rs125-130](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L125-L130)

```

```

### LLMProvider Trait Implementation

The `ProviderPlugin` implements the `LLMProvider` trait, allowing it to be used interchangeably with native providers. Note that `chat_stream` is not natively implemented by `ProviderPlugin` and falls back to the default `LLMProvider` implementation which wraps `chat()` and emits events sequentially [src/providers/types.rs121-142](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/types.rs#L121-L142)

**Sources:** [src/providers/plugin.rs125-163](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L125-L163) [src/providers/plugin.rs166-357](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L166-L357) [src/providers/types.rs121-142](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/types.rs#L121-L142)

## Error Handling and Diagnostics

### Error Mapping

The adapter translates process-level failures and JSON-RPC errors into `ZeptoError::Provider`.

```

```

### API Integration

Provider plugins can be exposed via the OpenAI-compatible gateway. When `POST /v1/chat/completions` is called, the `chat_completions` route handler uses the configured provider (which can be a `ProviderPlugin`) to fulfill the request [src/api/routes/openai.rs29-82](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/api/routes/openai.rs#L29-L82) If the provider fails, it returns a `StatusCode::INTERNAL_SERVER_ERROR` [src/api/routes/openai.rs97-105](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/api/routes/openai.rs#L97-L105)

**Sources:** [src/providers/plugin.rs234-347](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L234-L347) [src/api/routes/openai.rs29-82](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/api/routes/openai.rs#L29-L82) [src/api/routes/openai.rs97-105](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/api/routes/openai.rs#L97-L105)

## Relationship to Tool Plugins

ZeptoClaw utilizes a similar JSON-RPC 2.0 pattern for external tools via the `BinaryPluginTool`. While both use process-based isolation, they target different trait interfaces.

**Sources:** [src/providers/plugin.rs1-124](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L1-L124) [src/providers/plugin.rs154](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L154-L154)

## Future Enhancements

The codebase contains internal TODOs for extending the provider plugin protocol:

1. Streaming Support : Implementing chat_stream for real-time output.
2. Structured Output : Forwarding output_format (JSON mode) when it becomes a first-class feature src/providers/plugin.rs 62
3. Stop Sequences : Forwarding stop sequences from ChatOptions.stop src/providers/plugin.rs 63

**Sources:** [src/providers/plugin.rs62-63](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/providers/plugin.rs#L62-L63)
