---
title: "Overview"
description: "Switch between OpenAI, Anthropic, Gemini, or Mistral – or plug in your own provider – without changing your call sites."
canonical_url: "https://kirby.tools/docs/copilot/php-classes/providers"
---

# Overview

> Switch between OpenAI, Anthropic, Gemini, or Mistral – or plug in your own provider – without changing your call sites.

A provider is the transport that talks to one AI vendor. The `Client` resolves which one to use from `johannschopplich.copilot.provider` and forwards every request unchanged – your call sites never know the difference.

## Built-in Implementations

<card-group>
<card icon="i-simple-icons-openai" title="OpenAIProvider" to="/docs/copilot/php-classes/providers/openai">

The base. Doubles as the transport for any OpenAI-compatible endpoint (Mistral, Gemini's `/v1beta/openai`, OpenRouter, Ollama).

</card>

<card icon="i-simple-icons-anthropic" title="AnthropicProvider" to="/docs/copilot/php-classes/providers/anthropic">

Native Anthropic SDK. Wire-format-specific. Structured output via forced `tool_use`.

</card>

<card icon="i-simple-icons-google" title="GeminiProvider" to="/docs/copilot/php-classes/providers/gemini">

Extends `OpenAIProvider`. Targets Google's OpenAI-compat endpoint at `generativelanguage.googleapis.com/v1beta/openai`.

</card>

<card icon="i-simple-icons-mistralai" title="MistralProvider" to="/docs/copilot/php-classes/providers/mistral">

Extends `OpenAIProvider`. Targets `api.mistral.ai/v1`.

</card>
</card-group>

<note>

All four classes are marked `@internal`. Use them through `Client` for stable behavior. Direct instantiation works but constructor signatures may shift between minor versions.

</note>

## Plug In Your Own Provider

Implement the `Provider` interface to add support for any AI service.

```php
namespace JohannSchopplich\Copilot\AI\Providers;

interface Provider
{
    /**
     * @param list<array{role: string, content: string}> $messages
     * @param array<string, mixed> $schema
     * @return array<string, mixed>
     *
     * @throws ProviderException
     */
    public function generateObject(array $messages, array $schema): array;

    /**
     * @param list<array{role: string, content: string}> $messages
     *
     * @throws ProviderException
     */
    public function generateText(array $messages): string;
}
```

Both methods throw [`ProviderException`](/docs/copilot/php-classes/exceptions) on any failure.

## Provider Selection

`Client` selects a provider via `match` on the resolved `ProviderName` enum. Each receives a `ProviderConfig` with `apiKey`, `model`, `baseUrl`, and an `options` bag forwarded to the upstream request. The Panel-only keys `completionModel` and `api` are dropped rather than forwarded.

## Retry Behavior

<table>
<thead>
  <tr>
    <th>
      Provider
    </th>
    
    <th>
      Retry
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        OpenAIProvider
      </code>
      
       and subclasses
    </td>
    
    <td>
      Built-in retry wrapper – see <a href="/docs/copilot/php-classes/providers/openai#retry-behavior">
        details
      </a>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AnthropicProvider
      </code>
    </td>
    
    <td>
      Delegated to the official <code>
        anthropic-ai/sdk
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

A failed retry chain throws `ProviderException` with the upstream error attached as `previous` and the response body as `responseExcerpt`.

---

Every page of this site as Markdown: <https://kirby.tools/sitemap.md>
