# The Multi-Provider Adapter Layer

> Exploration of the BYOC (Bring Your Own Client) architecture, supporting Google Gemini, OpenAI, Azure, OpenRouter, and local Ollama instances.

- Repository: AsyncFuncAI/deepwiki-open
- GitHub: https://github.com/AsyncFuncAI/deepwiki-open
- Human wiki: https://grok-wiki.com/public/wiki/asyncfuncai-deepwiki-open-4d1f22320747
- Complete Markdown: https://grok-wiki.com/public/wiki/asyncfuncai-deepwiki-open-4d1f22320747/llms-full.txt

## Source Files

- `api/openai_client.py`
- `api/google_embedder_client.py`
- `api/azureai_client.py`
- `api/bedrock_client.py`
- `api/openrouter_client.py`
- `api/dashscope_client.py`
- `api/ollama_patch.py`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [api/config.py](api/config.py)
- [api/openai_client.py](api/openai_client.py)
- [api/openrouter_client.py](api/openrouter_client.py)
- [api/azureai_client.py](api/azureai_client.py)
- [api/bedrock_client.py](api/bedrock_client.py)
- [api/google_embedder_client.py](api/google_embedder_client.py)
- [api/dashscope_client.py](api/dashscope_client.py)
- [api/ollama_patch.py](api/ollama_patch.py)
</details>

# The Multi-Provider Adapter Layer

The Multi-Provider Adapter Layer is a core architectural component of the repository, implementing a **Bring Your Own Client (BYOC)** strategy. This layer abstracts the complexities of interacting with various Large Language Model (LLM) and embedding providers, offering a unified interface for the rest of the application. by leveraging the Adapter design pattern, the system can seamlessly switch between cloud providers like Google Gemini, OpenAI, Azure, and OpenRouter, as well as local instances via Ollama.

This modular architecture ensures that the application remains provider-neutral, allowing developers to deploy the system in diverse environments without significant code changes. The integration is built upon the `adalflow` framework, extending its `ModelClient` base class to provide specialized functionality for each supported platform.

Sources: [api/openai_client.py:43]()

## Core Abstraction: The ModelClient Interface

The foundation of the adapter layer is the `ModelClient` class from the `adalflow` library. Every provider-specific adapter must implement this interface, which standardizes how chat completions and embeddings are requested and processed.

### Supported Adapters

| Client Class | Provider | Primary Use Case |
| :--- | :--- | :--- |
| `OpenAIClient` | OpenAI | Chat & Embeddings |
| `GoogleEmbedderClient` | Google Cloud | Specialized Embeddings |
| `AzureAIClient` | Microsoft Azure | Enterprise OpenAI Instances |
| `BedrockClient` | AWS Bedrock | Enterprise Model Hosting |
| `OpenRouterClient` | OpenRouter | Unified API Gateway |
| `DashscopeClient` | Alibaba Cloud | Dashscope Models |
| `OllamaClient` | Local (Ollama) | Local Inference |

Sources: [api/config.py:58-67](), [api/openai_client.py:120](), [api/openrouter_client.py:19]()

## Configuration and Dynamic Dispatch

The application uses `api/config.py` to manage the lifecycle and selection of these adapters. It maps configuration strings to actual Python classes and handles the resolution of environment variables.

### Client Mapping
The `CLIENT_CLASSES` dictionary serves as the central registry for all available adapters. When a provider is specified in the configuration files (e.g., `embedder.json` or `generator_config`), the system uses this map to instantiate the correct client.

```python
# api/config.py:58-67
CLIENT_CLASSES = {
    "GoogleGenAIClient": GoogleGenAIClient,
    "GoogleEmbedderClient": GoogleEmbedderClient,
    "OpenAIClient": OpenAIClient,
    "OpenRouterClient": OpenRouterClient,
    "OllamaClient": OllamaClient,
    "BedrockClient": BedrockClient,
    "AzureAIClient": AzureAIClient,
    "DashscopeClient": DashscopeClient
}
```

Sources: [api/config.py:58-67](), [api/config.py:359-412]()

## Provider-Specific Enhancements

While the `ModelClient` provides a standard interface, individual adapters often include logic to handle provider-specific features or limitations.

### Local Ollama Integration
Local model support is enhanced via `api/ollama_patch.py`. Because the native `OllamaClient` does not always support batch embedding for all document types, the `OllamaDocumentProcessor` ensures that documents are processed individually with consistent embedding sizes.

### AWS Bedrock and Azure OpenAI
The `BedrockClient` and `AzureAIClient` are designed for enterprise environments, supporting complex authentication flows including AWS IAM roles and Azure-specific endpoint configurations.

Sources: [api/ollama_patch.py:62-105](), [api/azureai_client.py:118](), [api/bedrock_client.py:20]()

## Architecture Diagram

The following diagram illustrates how the configuration layer interacts with the Multi-Provider Adapter Layer to deliver requests to external services.

```mermaid
graph TD
    subgraph "Application Core"
        Config[api/config.py]
        API[api/api.py]
    end

    subgraph "Adapter Layer (BYOC)"
        Base[ModelClient Interface]
        OAI[OpenAIClient]
        GGL[GoogleEmbedderClient]
        AZR[AzureAIClient]
        OLM[OllamaClient + Patch]
        BDR[BedrockClient]
    end

    subgraph "External Providers"
        OpenAI_API((OpenAI API))
        Google_API((Google Cloud))
        Azure_API((Azure OpenAI))
        Local_Ollama((Local Ollama))
        AWS_API((AWS Bedrock))
    end

    Config -->|Resolves| Base
    Base -.-> OAI
    Base -.-> GGL
    Base -.-> AZR
    Base -.-> OLM
    Base -.-> BDR

    OAI --> OpenAI_API
    GGL --> Google_API
    AZR --> Azure_API
    OLM --> Local_Ollama
    BDR --> AWS_API

    API -->|Uses| Config
```

## Implementation Notes

- **Environment Variable Substitution**: The system supports `${VAR}` placeholders in configuration files, which are recursively replaced at runtime to protect sensitive API keys.
- **Error Handling**: Adapters like `OpenRouterClient` include complex retry logic and error generators to handle the diverse failure modes of aggregate API providers.
- **Refactoring TODOs**: The `AzureAIClient` currently contains significant overlap with `OpenAIClient`, with internal notes suggesting a future refactor to use subclassing for better code reuse.

In summary, the Multi-Provider Adapter Layer provides the necessary abstraction to ensure that the repository is truly provider-agnostic, enabling high portability and support for both cloud-native and local-first LLM deployments.

Sources: [api/config.py:69-97](), [api/openrouter_client.py:19](), [api/azureai_client.py:71]()
