Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ai Albert Platform Laravel Package

symfony/ai-albert-platform

Symfony AI bridge for the French government’s Albert Platform (OpenGateLLM). Connect Symfony apps to Albert’s OpenAI-compatible chat and embeddings endpoints, with links to the API reference, supported models, and upstream sources.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require symfony/ai-albert-platform
    
  2. Configure the provider in config/ai.php:
    'providers' => [
        'albert' => [
            'api_key' => env('ALBERT_API_KEY'),
            'base_uri' => 'https://albert.api.etalab.gouv.fr',
        ],
    ],
    
  3. First use case: Replace an OpenAI chat completion call:
    use Symfony\Component\Ai\Provider\AlbertProvider;
    
    public function __construct(private AlbertProvider $albert) {}
    
    public function generateResponse(string $prompt): string
    {
        $response = $this->albert->complete([
            'model' => 'mistral-7b',
            'prompt' => $prompt,
        ]);
        return $response->choices[0]->text;
    }
    

Where to Look First


Implementation Patterns

Core Workflows

1. Provider-Based Integration

Leverage Symfony AI’s provider abstraction to route requests dynamically:

// config/ai.php
'providers' => [
    'primary' => 'albert',
    'fallback' => 'openai',
],
// In service
public function __construct(private AiClient $aiClient) {}

public function generateWithFallback(string $prompt): string
{
    try {
        return $this->aiClient->complete([
            'provider' => 'albert',
            'model' => 'mistral-7b',
            'prompt' => $prompt,
        ]);
    } catch (Exception $e) {
        return $this->aiClient->complete([
            'provider' => 'openai',
            'model' => 'gpt-3.5-turbo',
            'prompt' => $prompt,
        ]);
    }
}

2. Embeddings for Vector Search

Use Albert’s embeddings with Laravel Scout or custom vector DBs:

public function generateEmbedding(string $text): array
{
    $response = $this->albert->embed([
        'model' => 'all-minilm',
        'input' => $text,
    ]);
    return $response->data[0]->embedding;
}

Store embeddings in a vector database (e.g., Meilisearch):

$client = new MeilisearchClient(env('MEILI_URL'), env('MEILI_API_KEY'));
$client->index('documents')->addDocuments([
    'id' => 1,
    'embedding' => $embedding,
    'content' => $text,
]);

3. Async Processing with Queues

Offload AI calls to queues to avoid blocking requests:

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;

class GenerateAiResponse implements ShouldQueue
{
    use Queueable;

    public function __construct(
        public string $prompt,
        public string $model = 'mistral-7b'
    ) {}

    public function handle(AiClient $aiClient)
    {
        $response = $aiClient->complete([
            'provider' => 'albert',
            'model' => $this->model,
            'prompt' => $this->prompt,
        ]);
        // Store or broadcast response
    }
}

Dispatch from a controller:

GenerateAiResponse::dispatch($userInput)->onQueue('ai');

4. Model Routing Logic

Route prompts to optimal models based on context:

public function selectModel(string $prompt): string
{
    if (str_contains(strtolower($prompt), 'france') || str_contains(strtolower($prompt), 'français')) {
        return 'mistral-7b'; // French-optimized
    }
    return 'llama-2'; // General-purpose
}

public function generateResponse(string $prompt): string
{
    $model = $this->selectModel($prompt);
    $response = $this->albert->complete([
        'model' => $model,
        'prompt' => $prompt,
    ]);
    return $response->choices[0]->text;
}

Integration Tips

  • Laravel Service Container: Bind the Albert provider as a singleton for global access:
    $this->app->singleton(AiClient::class, function ($app) {
        return new AiClient([
            'providers' => [
                'albert' => [
                    'api_key' => env('ALBERT_API_KEY'),
                    'base_uri' => 'https://albert.api.etalab.gouv.fr',
                ],
            ],
        ]);
    });
    
  • Environment Variables: Use Laravel’s .env for API keys and endpoints:
    ALBERT_API_KEY=your_api_key_here
    ALBERT_BASE_URI=https://albert.api.etalab.gouv.fr
    
  • Testing: Mock the Albert provider in tests:
    $this->app->instance(AiClient::class, Mockery::mock(AiClient::class));
    

Gotchas and Tips

Pitfalls

  1. API Rate Limits

    • Albert may enforce stricter rate limits than OpenAI. Implement exponential backoff for retries:
      use Symfony\Component\Ai\Exception\AiException;
      use Symfony\Component\Ai\Retry\RetryStrategy;
      
      try {
          return $this->albert->complete($request);
      } catch (AiException $e) {
          return (new RetryStrategy())->retry(
              fn() => $this->albert->complete($request),
              3, // Max retries
              1000 // Delay ms
          );
      }
      
    • Tip: Monitor usage via Albert’s API docs and log requests.
  2. Model Availability

    • Not all OpenAI-compatible models are available on Albert. Verify supported models in:
  3. Response Format Quirks

    • Albert’s responses may differ slightly from OpenAI (e.g., finish_reason values). Normalize responses:
      $response = $this->albert->complete($request);
      $text = $response->choices[0]->text ?? '';
      $finishReason = $response->choices[0]->finish_reason ?? 'stop';
      
    • Tip: Use a response DTO to handle variations:
      class AlbertResponse {
          public function __construct(
              public string $text,
              public string $finishReason,
              public int $tokenUsage
          ) {}
      }
      
  4. Embedding Dimensions

    • Albert’s embeddings may have different dimensions than OpenAI. Validate before storage:
      $embedding = $this->albert->embed($request);
      if (count($embedding->data[0]->embedding) !== 384) { // Example: all-minilm
          throw new \RuntimeException('Unexpected embedding dimension');
      }
      
  5. CORS/Proxy Issues

    • If Albert’s API is behind a proxy or CORS-restricted, configure Laravel’s HTTP client:
      $client = new Client([
          'base_uri' => 'https://albert.api.etalab.gouv.fr',
          'headers' => [
              'Authorization' => 'Bearer ' . env('ALBERT_API_KEY'),
              'Accept' => 'application/json',
          ],
          'timeout' => 30,
      ]);
      

Debugging

  • Enable Debugging: Add debug headers to Albert requests:
    $response = $this->albert->complete($request, [
        'debug' => true,
    ]);
    
  • Log Raw Responses: Inspect raw API responses for errors:
    \Log::debug('Albert API Response', [
        'status' => $response->getStatusCode(),
        'body' => $response->getContent(),
    ]);
    
  • Common Errors:
    • 429 Too Many Requests: Implement rate limiting (e.g., symfony/rate-limiter).
    • 401 Unauthorized: Verify ALBERT_API_KEY in .env.
    • 400 Bad Request: Check model names and input formats against ReDoc.

Extension Points

  1. Custom Providers Extend the AlbertProvider to add Albert-specific features:
    namespace App\Providers;
    
    use Symfony\Component\Ai\Provider\AlbertProvider as BaseAlbertProvider;
    
    class CustomAlbertProvider extends BaseAlbertProvider {
        public function generateWithCustomParams(array $params): mixed {
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope