# How Reasonix Integrates with OpenAI-Compatible Endpoints via Its Provider Registry

> Learn how Reasonix integrates with OpenAI compatible endpoints using its dynamic provider registry. Easily connect to any service with the /chat completions contract.

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

---

**Reasonix integrates with OpenAI-compatible endpoints through a pluggable provider registry that maps configuration `kind` strings to constructor functions, enabling dynamic instantiation of HTTP clients for any service following the `/chat/completions` contract.**

The DeepSeek-Reasonix project abstracts LLM interactions behind a unified provider interface defined in [`internal/provider/provider.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/provider.go). This architecture allows the system to treat diverse endpoints—including DeepSeek, MiniMax, and standard OpenAI services—as interchangeable backends through declarative configuration. Understanding how this registry resolves provider implementations and manages endpoint-specific quirks is essential for extending Reasonix to support custom OpenAI-compatible services.

## Understanding the Provider Registry Architecture

The provider registry operates as a compile-time plugin system that associates string identifiers with constructor functions capable of building concrete provider instances.

### The Registration Pattern

Provider implementations self-register during package initialization using the `provider.Register` function. In [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go), the registration occurs in an `init()` function that binds the `"openai"` kind string to the `New` constructor:

```go
// internal/provider/openai/openai.go
func init() {
    provider.Register("openai", New)
}

```

This pattern ensures that importing the package automatically populates the global registry map defined in [`internal/provider/provider.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/provider.go). The `anthropic` and other providers follow identical registration patterns in their respective files (e.g., [`internal/provider/anthropic/anthropic.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/anthropic/anthropic.go)), allowing the registry to aggregate all available backends without explicit imports in the main application code.

### Configuration Schema

The registry consumes configuration structures defined in [`internal/provider/provider.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/provider.go). Each provider entry in the TOML configuration maps to a `provider.Config` struct containing:

- **kind**: The registry lookup key (defaults to `"openai"` when omitted)
- **base_url**: The root endpoint for the OpenAI-compatible service
- **model**: The specific model identifier for API requests
- **api_key_env**: Environment variable name holding the authentication token
- **extras**: Provider-specific options including `effort`, `vision`, and `reasoning_protocol`

When Reasonix loads its configuration, the `NewFromConfig` helper function iterates through provider entries, resolves the `kind` against the registry, and invokes the corresponding constructor with the populated configuration.

## How OpenAI-Compatible Providers Work

The OpenAI provider implementation bridges the gap between Reasonix's generic request interface and the specific JSON schema required by `/chat/completions` endpoints.

### Constructor and Config Resolution

The `New` function in [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go) receives a `provider.Config` and initializes an HTTP client using `netclient.NewHTTPClient()`. This client handles connection pooling, proxy settings, and idle timeout management. The constructor extracts the `BaseURL` from configuration and validates that required fields—particularly `APIKey` (resolved from the environment variable specified by `api_key_env`) and `Model`—are present.

```go
// Conceptual implementation based on internal/provider/openai/openai.go
func New(cfg provider.Config) (provider.Provider, error) {
    client := netclient.NewHTTPClient()
    return &openAIProvider{
        baseURL: cfg.BaseURL,
        model:   cfg.Model,
        apiKey:  os.Getenv(cfg.APIKeyEnv),
        client:  client,
        extras:  cfg.Extras,
    }, nil
}

```

### Stream Method and HTTP Handling

The `Stream` method implements the core integration logic. It marshals Reasonix's internal message format into the JSON structure expected by OpenAI-compatible endpoints, including fields for `model`, `messages`, `stream: true`, and optional parameters like `reasoning_effort`. The method constructs an HTTP POST request to `${BaseURL}/chat/completions` with appropriate headers including `Authorization: Bearer ${APIKey}` and `Content-Type: application/json`.

The implementation returns a channel of `provider.Chunk` objects, allowing the caller to consume token streams asynchronously. Error handling differentiates between HTTP transport failures, JSON parsing errors, and API-specific error responses returned in the response body.

### Vendor-Specific Extensions

The provider handles vendor-specific deviations from the standard OpenAI schema through the `extras` configuration map. For DeepSeek endpoints, the implementation automatically sets `effort` to `"high"` when not explicitly configured, enabling the full reasoning mode. MiniMax support includes specialized handling for the `vision` parameter and `thinking.type` fields, demonstrating how the registry pattern accommodates endpoint-specific quirks while maintaining a unified interface.

## Practical Implementation Guide

Configuring an OpenAI-compatible endpoint requires defining a provider block in your configuration file and ensuring the corresponding environment variable is set.

### Configuring an OpenAI-Compatible Endpoint

Create or modify your [`reasonix.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/reasonix.toml) configuration to include a provider block targeting your endpoint:

```toml
default_model = "deepseek-flash"

[[providers]]
name        = "deepseek-flash"
kind        = "openai"
base_url    = "https://api.deepseek.com"
model       = "deepseek-v4-flash"
api_key_env = "DEEPSEEK_API_KEY"
effort      = "high"  # DeepSeek-specific extension

```

For standard OpenAI or compatible services like MiniMax, adjust the `base_url` and `model` fields accordingly. The `kind` field must remain `"openai"` to select the OpenAI-compatible implementation, even when targeting third-party services.

### Programmatic Integration

When building tools atop Reasonix, interact with the registry through the exported configuration API:

```go
package main

import (
    "context"
    "fmt"
    "log"
    
    "github.com/esengine/DeepSeek-Reasonix/internal/provider"
)

func main() {
    // Load configuration from TOML
    cfg, err := provider.LoadConfig("reasonix.toml")
    if err != nil {
        log.Fatal(err)
    }
    
    // Instantiate the first configured provider
    p, err := provider.NewFromConfig(cfg.Providers[0])
    if err != nil {
        log.Fatal(err)
    }
    
    // Create a request
    req := provider.Request{
        Model: cfg.Providers[0].Model,
        Messages: []provider.Message{
            {Role: provider.RoleUser, Content: "Explain recursion"},
        },
    }
    
    // Stream completion
    chunks, err := p.Stream(context.Background(), req)
    if err != nil {
        log.Fatal(err)
    }
    
    for chunk := range chunks {
        fmt.Print(chunk.Content)
    }
}

```

Key files involved in this integration include [`internal/provider/provider.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/provider.go) (interface definition), [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go) (implementation), and [`cmd/reasonix/main.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/cmd/reasonix/main.go) (CLI entry point that initializes the registry).

## Summary

- **Registry Pattern**: The `provider.Register` function in [`internal/provider/provider.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/provider.go) maintains a map connecting `kind` strings to constructor functions, populated during package initialization via `init()` functions in provider-specific files.
- **Configuration-Driven**: OpenAI-compatible endpoints are configured through TOML blocks specifying `kind="openai"`, `base_url`, `model`, and `api_key_env`, with the registry automatically selecting the appropriate implementation.
- **Unified Interface**: All providers implement the `Stream` method, which handles HTTP POST construction, authentication header injection, and token streaming from `/chat/completions` endpoints.
- **Extensibility**: Vendor-specific features like DeepSeek's `effort` parameter or MiniMax's vision support are handled within the provider implementation while exposing a consistent configuration schema to users.

## Frequently Asked Questions

### How does the provider registry select the correct implementation for an OpenAI-compatible endpoint?

The registry selects implementations based on the `kind` field in the provider configuration. When `kind` is set to `"openai"` (or defaults to it), the registry retrieves the constructor function registered under that key—typically defined in [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go) via the `init()` function's call to `provider.Register("openai", New)`. This constructor then builds the specific HTTP client configured for that endpoint's base URL and authentication credentials.

### What configuration fields are required to integrate a custom OpenAI-compatible endpoint?

At minimum, you must specify `base_url`, `model`, and `api_key_env` in the provider configuration block. The `base_url` should point to the service's API root (e.g., `https://api.deepseek.com`), while `api_key_env` names the environment variable containing your authentication token. Optional fields like `effort` or `vision` activate provider-specific features when supported by the underlying implementation in [`openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/openai.go).

### Can Reasonix simultaneously use multiple OpenAI-compatible providers from different vendors?

Yes. The configuration supports multiple `[[providers]]` blocks in a single TOML file, each with distinct `name`, `base_url`, and `model` values. As long as each entry specifies `kind = "openai"` (or relies on the default), the registry instantiate separate provider instances for each configuration. The CLI or programmatic API can then select between them using the provider name or by iterating through the configured providers list.

### How does Reasonix handle vendor-specific API extensions while maintaining OpenAI compatibility?

The provider implementation in [`internal/provider/openai/openai.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/provider/openai/openai.go) inspects the `extras` map within the configuration for non-standard fields. For example, when `effort` is set to `"high"`, the provider injects the corresponding `reasoning_effort` parameter into the JSON payload sent to DeepSeek endpoints. This approach isolates vendor-specific logic within the provider implementation while exposing a standardized configuration interface to the rest of the application.