Skip to content

AI Provider System

When to Use

Use this guide when calling a specific provider, building a custom provider plugin, or working with the provider/model selection form. Use Operation Types for the typed Input/Output classes.

Decision

Situation Choose Why
Provider with unique API AiProviderClientBase Full flexibility to implement any API
Provider with OpenAI-compatible API OpenAiBasedProviderClientBase Gets chat, embeddings, TTS, STT, T2I for free
List models for a form getSimpleProviderModelOptions() Returns formatted provider__model => label array
Check if operation is available hasProvidersForOperationType() Boolean check before calling
Upload file to provider ai.file_manager service Lifecycle management; don't call provider file methods directly

Pattern

$providerManager = \Drupal::service('ai.provider');

// Get default provider for an operation type.
$defaults = $providerManager->getDefaultProviderForOperationType('chat');

// Create a provider instance (returns ProviderProxy).
$provider = $providerManager->createInstance('anthropic');

// Check availability before calling.
if (!$provider->isUsable('chat')) {
  return;
}

// Get models for a select element.
$options = $providerManager->getSimpleProviderModelOptions('chat');
// Returns: ['anthropic__claude-3-sonnet' => 'Anthropic: Claude 3 Sonnet', ...]

Building a Custom Provider

use Drupal\ai\Attribute\AiProvider;
use Drupal\ai\Base\AiProviderClientBase;

#[AiProvider(
  id: 'my_provider',
  label: new TranslatableMarkup('My Provider'),
)]
class MyProvider extends AiProviderClientBase implements ChatInterface {

  public function isUsable(?string $operation_type = NULL): bool {
    return !empty($this->getApiKey());
  }

  public function getSupportedOperationTypes(): array {
    return ['chat'];
  }

  public function getConfiguredModels(string $operation_type): array {
    return ['my-model-v1' => 'My Model v1'];
  }

  public function chat(ChatInput $input, string $model_id, array $tags = []): ChatOutput {
    // Call API, normalize response.
    return new ChatOutput($input, $normalizedMessages, $rawResponse, []);
  }
}

Provider File Handling (New in 1.4.2)

Providers that support a remote Files API implement AiFileProviderInterface (Drupal\ai\AiFileProviderInterface):

Method Purpose
uploadFile(AiFileInterface $ai_file, mixed $file): AiFileInterface Upload binary/stream; MUST set remote ID on entity
deleteFile(AiFileInterface $ai_file): bool Delete remote file by stored remote ID
downloadFile(AiFileInterface $ai_file, ?string $destination = NULL): string Download to path, or return raw contents when no destination given
supportsMimeType(string $mime_type, string $purpose): bool Whether MIME type is allowed for the purpose

OpenAI-compatible providers get this via FileApiTrait (Drupal\ai\Traits\OpenAi\FileApiTrait), which maps to the OpenAI files() endpoint. Don't call provider file methods directly — use ai.file_manager. See Operation Types for the AiFileManager API.

Scaffolding (New in 1.4)

drush generate plugin:ai:provider       # alias: ai-provider
drush generate plugin:ai:guardrail      # alias: ai-guardrail
drush generate plugin:ai:automator-type # alias: ai-automator-type

Provider Matrix

Provider Chat Embeddings Moderation TTS STT T2I Translation
Anthropic Yes
OpenAI Yes Yes Yes Yes Yes Yes
Google/Gemini Yes
Ollama Yes Yes
AWS Bedrock Yes Yes Yes
Azure Yes Yes Yes Yes Yes Yes
LiteLLM Yes Yes Yes Yes Yes Yes
DeepL Yes
Vertex AI Yes Yes Yes

Base Classes

Class Use When
AiProviderClientBase Custom provider with unique API
OpenAiBasedProviderClientBase Provider with OpenAI-compatible API (e.g., Ollama, LiteLLM)

OpenAiBasedProviderClientBase implements ChatInterface, ModerationInterface, EmbeddingsInterface, TextToSpeechInterface, SpeechToTextInterface, and TextToImageInterface out of the box. It handles streaming, token usage extraction into TokenUsageDto, rate limit parsing into ChatProviderLimitsDto, and standard error mapping. Only loadClient() needs to be provided.

Key AiProviderInterface Methods

Method Purpose
getAvailableConfiguration($op, $model) Returns configurable parameters for model config UI
getDefaultConfigurationValues($op, $model) Default parameter values
setAuthentication($auth) Override authentication at runtime
getSupportedCapabilities() Returns AiModelCapability[] or AiProviderCapability[] the provider supports
getSetupData() Returns key_config_name (Key module) + default_models
setTag($tag) / getTags() Tag management for logging/filtering
setDebugData($key, $value) / getDebugData() Attach debug metadata to requests

Common Mistakes

  • Wrong: Using createInstance() without checking isUsable()Right: Provider may lack API key — check first
  • Wrong: Not implementing getAvailableConfiguration()Right: Breaks the form helper's model configuration UI
  • Wrong: Missing loadClient()Right: Base class expects this for lazy client initialization
  • Wrong: Calling provider file methods directly → Right: Always use ai.file_manager service for file lifecycle management

See Also

  • Core Architecture
  • Operation Types
  • Reference: web/modules/contrib/ai/src/Base/AiProviderClientBase.php
  • Reference: web/modules/contrib/ai/src/Base/OpenAiBasedProviderClientBase.php
  • Reference: web/modules/contrib/ai/src/AiFileProviderInterface.php