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

OpenAIProvider

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

AnthropicProvider

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

GeminiProvider

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

MistralProvider

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

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

Plug In Your Own Provider

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

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 on any failure.

Provider Selection

Each provider receives its providers.<name> entry; the keys the plugin reads itself (completionModel, api, options, timeout) are not forwarded.

Retry Behavior

ProviderRetry
OpenAIProvider and subclassesBuilt-in retry wrapper – see details.
AnthropicProviderDelegated to the official anthropic-ai/sdk.

Every provider applies the per-provider timeout to its HTTP client, so a stalled connection fails rather than blocking. A failed request throws ProviderException with the upstream error attached as previous.