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 Cloudflare Store Laravel Package

symfony/ai-cloudflare-store

Integrates Cloudflare Vectorize as a vector store for Symfony AI Store. Supports indexing and querying embeddings plus upserts and deletions via the Vectorize APIs, making it easy to connect Symfony AI apps to Cloudflare’s managed vector database.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install Dependencies:
    composer require symfony/ai symfony/ai-cloudflare-store
    
  2. Configure Cloudflare Credentials in .env:
    CLOUDFLARE_API_TOKEN=your_api_token_here
    CLOUDFLARE_VECTORIZE_INDEX=your_index_name
    
  3. Bind the Store in Laravel Service Provider:
    use Symfony\AI\CloudflareStore\CloudflareVectorizeStore;
    use Symfony\Component\AI\Store\StoreInterface;
    
    public function register()
    {
        $this->app->singleton(StoreInterface::class, function ($app) {
            return new CloudflareVectorizeStore(
                $app->make(\Symfony\Component\AI\Client::class),
                config('services.cloudflare.vectorize_index')
            );
        });
    }
    

First Use Case: Upserting Vectors

use Symfony\Component\AI\Store\StoreInterface;

public function storeEmbedding(StoreInterface $store, array $embedding, string $id)
{
    $store->upsert([$embedding], [$id]);
}

Implementation Patterns

Core Workflows

  1. Batch Upsert for Efficiency:

    $embeddings = [/* array of vectors */];
    $ids = [/* corresponding IDs */];
    $store->upsert($embeddings, $ids);
    
    • Use NDJSON format for large batches (handled internally by the package).
  2. Semantic Search Queries:

    $queryEmbedding = $embeddingService->embed("user query");
    $results = $store->query($queryEmbedding, 5); // Top 5 matches
    
  3. Metadata Filtering:

    $results = $store->query($queryEmbedding, 5, [
        'filter' => ['metadata_field' => 'value']
    ]);
    
  4. Bulk Deletion:

    $store->remove(['id1', 'id2', 'id3']);
    

Integration with Laravel Ecosystem

  • Queue Jobs for Async Upserts:

    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    
    class UpsertEmbeddingsJob implements ShouldQueue
    {
        use Queueable;
    
        public function handle(StoreInterface $store)
        {
            $store->upsert($this->embeddings, $this->ids);
        }
    }
    
  • Caching Layer:

    $cachedResults = Cache::remember("query_{$queryHash}", now()->addHours(1), function () use ($store, $queryEmbedding) {
        return $store->query($queryEmbedding, 5);
    });
    
  • Event-Driven Updates:

    event(new EmbeddingStored($embedding, $id));
    // Listen for updates and trigger re-indexing
    

Testing Patterns

  1. Mocking Cloudflare API:

    $mockStore = $this->createMock(StoreInterface::class);
    $mockStore->method('upsert')->willReturn(true);
    $mockStore->method('query')->willReturn([/* mock results */]);
    
    $this->app->instance(StoreInterface::class, $mockStore);
    
  2. Unit Testing Queries:

    public function testQueryReturnsTopMatches()
    {
        $store = $this->app->make(StoreInterface::class);
        $results = $store->query($testEmbedding, 3);
    
        $this->assertCount(3, $results);
        $this->assertEquals('expected_id', $results[0]['id']);
    }
    

Gotchas and Tips

Common Pitfalls

  1. API Rate Limits:

    • Cloudflare Vectorize enforces rate limits. Implement exponential backoff for retries:
      use Symfony\Component\AI\Exception\RateLimitExceededException;
      
      try {
          $store->query($embedding);
      } catch (RateLimitExceededException $e) {
          sleep(2 ** $attempt); // Exponential backoff
          retry();
      }
      
  2. ID Collisions:

    • Ensure IDs are unique across upserts. Use UUIDs or database-generated IDs:
      $id = Str::uuid()->toString();
      
  3. Metadata Filtering Quirks:

    • Cloudflare’s filter syntax may differ from expectations. Test with:
      $store->query($embedding, 5, [
          'filter' => ['category' => ['in' => ['books', 'movies']]]
      ]);
      
  4. Vector Dimension Mismatch:

    • Cloudflare requires consistent vector dimensions. Validate embeddings before upsert:
      $expectedDim = 768; // Example: text-embedding-ada-002
      if (count($embedding) !== $expectedDim) {
          throw new \InvalidArgumentException("Vector dimension mismatch");
      }
      

Debugging Tips

  1. Enable API Logging:

    // In CloudflareVectorizeStore constructor
    $client = new \Symfony\Component\AI\Client(
        $apiToken,
        ['debug' => true] // Enable debug logging
    );
    
  2. Validate NDJSON Payloads:

    • Use symfony/var-dumper to inspect payloads:
      dump($store->getLastPayload()); // If exposed via a method
      
  3. Check Index Configuration:

    • Verify your Vectorize index settings (dimension, distance metric) match your embeddings:
      curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/vectorize/indexes/{index_name}" \
           -H "Authorization: Bearer $API_TOKEN"
      

Extension Points

  1. Custom Distance Metrics:

    • Override the default cosine metric by extending CloudflareVectorizeStore:
      class CustomCloudflareStore extends CloudflareVectorizeStore
      {
          protected function getDistanceMetric(): string
          {
              return 'euclidean';
          }
      }
      
  2. Hybrid Search:

    • Combine with Laravel Scout for keyword + vector search:
      $hybridResults = collect($scoutResults)
          ->map(fn ($item) => [
              'id' => $item->id,
              'score' => $item->score + $vectorScore
          ])
          ->sortByDesc('score');
      
  3. Local Fallback:

    • Implement a decorator pattern for offline resilience:
      class FallbackCloudflareStore implements StoreInterface
      {
          public function __construct(
              private StoreInterface $cloudflareStore,
              private StoreInterface $localStore
          ) {}
      
          public function query($embedding, int $limit, array $options = []): array
          {
              try {
                  return $this->cloudflareStore->query($embedding, $limit, $options);
              } catch (\Exception $e) {
                  return $this->localStore->query($embedding, $limit, $options);
              }
          }
      }
      

Configuration Quirks

  1. Environment Variables:

    • Ensure .env variables are prefixed consistently:
      # Correct
      CLOUDFLARE_VECTORIZE_INDEX=my_index
      CLOUDFLARE_API_TOKEN=my_token
      
      # Avoid (unless documented otherwise)
      VECTORIZE_INDEX=my_index
      
  2. Index Creation:

    • The package assumes the index exists. Create it via API or CLI:
      curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/vectorize/indexes" \
           -H "Authorization: Bearer $API_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"name":"my_index","dimension":768,"metric":"cosine"}'
      
  3. PHP Version Warnings:

    • If using PHP < 8.1, ensure symfony/ai compatibility is maintained (may require polyfills).

Performance Optimization

  1. Batch Size Tuning:

    • Test batch sizes (e.g., 100–1000 vectors per upsert) for optimal throughput.
  2. Query Optimization:

    • Use limit and filter to reduce payload size:
      $store->query($embedding, 10, ['filter' => ['category' => 'books']]);
      
  3. Connection Pooling:

    • Reuse the Client instance across requests to avoid connection overhead.
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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