From 17eaefb768e014a63ccd119a187cb6a6d859fee9 Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Fri, 20 Mar 2026 13:58:41 +0100 Subject: [PATCH] Fix outdated code references across documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix class names: CachedPlatform→CachePlatform, OllamaApiCatalog→ModelCatalog, Indexer→DocumentIndexer/SourceIndexer, Store\Vector→Platform\Vector\Vector - Fix namespaces: TokenUsage, MemoryInputProcessor, ConfiguredSourceIndexer, SourceIndexer, DocumentIndexer, StructuredOutputSerializer - Fix method calls: asText()→getContent(), private property access→getters - Fix API signatures: StoreInterface::query() now requires QueryInterface, ChromaDb\Store constructor updated, Ollama PlatformFactory simplified - Remove unused imports: Gpt, Embeddings, VertexAi Model - Fix incorrect file reference: _model-listing.php→_model.php - Fix incorrect link target: Crawler Tool→firecrawl-crawl.php - Fix MessageBagInterface→MessageBag (interface doesn't exist) --- UPGRADE.md | 16 ++++++------- docs/bundles/ai-bundle.rst | 4 ++-- docs/components/agent.rst | 7 +++--- docs/components/chat.rst | 1 - docs/components/platform.rst | 32 ++++++++------------------ docs/components/platform/vertexai.rst | 1 - docs/components/store.rst | 11 +++++---- docs/components/store/local.rst | 33 ++++++++++++++------------- docs/components/store/s3-vectors.rst | 5 ++-- docs/components/store/sqlite.rst | 4 ++-- docs/components/store/supabase.rst | 10 ++++---- docs/cookbook/rag-implementation.rst | 8 +++---- 12 files changed, 60 insertions(+), 72 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 7f6f4692..549c87d3 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -104,7 +104,7 @@ AI Bundle +$container->get('ai.toolbox.my_agent.subagent.research_agent'); ``` - * An indexer configured with a `source`, now wraps the indexer with a `Symfony\AI\Store\ConfiguredSourceIndexer` decorator. This is + * An indexer configured with a `source`, now wraps the indexer with a `Symfony\AI\Store\Indexer\ConfiguredSourceIndexer` decorator. This is transparent - the configured source is still used by default, but can be overridden by passing a source to `index()`. * The `host_url` parameter for `Ollama` platform has been renamed `endpoint`. @@ -120,12 +120,12 @@ Store ----- * The `Symfony\AI\Store\Indexer` class has been replaced with two specialized implementations: - - `Symfony\AI\Store\SourceIndexer`: For indexing from sources (file paths, URLs, etc.) using a `LoaderInterface` - - `Symfony\AI\Store\DocumentIndexer`: For indexing documents directly without a loader + - `Symfony\AI\Store\Indexer\SourceIndexer`: For indexing from sources (file paths, URLs, etc.) using a `LoaderInterface` + - `Symfony\AI\Store\Indexer\DocumentIndexer`: For indexing documents directly without a loader ```diff -use Symfony\AI\Store\Indexer; - +use Symfony\AI\Store\SourceIndexer; + +use Symfony\AI\Store\Indexer\SourceIndexer; -$indexer = new Indexer($loader, $vectorizer, $store, '/path/to/source'); -$indexer->index(); @@ -143,11 +143,11 @@ Store $indexer->index([$document1, $document2]); ``` - * The `Symfony\AI\Store\ConfiguredIndexer` class has been renamed to `Symfony\AI\Store\ConfiguredSourceIndexer`: + * The `Symfony\AI\Store\ConfiguredIndexer` class has been renamed to `Symfony\AI\Store\Indexer\ConfiguredSourceIndexer`: ```diff -use Symfony\AI\Store\ConfiguredIndexer; - +use Symfony\AI\Store\ConfiguredSourceIndexer; + +use Symfony\AI\Store\Indexer\ConfiguredSourceIndexer; -$indexer = new ConfiguredIndexer($innerIndexer, 'default-source'); +$indexer = new ConfiguredSourceIndexer($sourceIndexer, 'default-source'); @@ -260,7 +260,7 @@ Platform * Run `composer require symfony/ai-cache-platform` * Change `Symfony\AI\Platform\CachedPlatform` namespace usages to `Symfony\AI\Platform\Bridge\Cache\CachePlatform` * The `ttl` option can be used in the configuration - * Adopt usage of class `Symfony\AI\Platform\Serializer\StructuredOuputSerializer` to `Symfony\AI\Platform\StructuredOutput\Serializer` + * Adopt usage of class `Symfony\AI\Platform\Serializer\StructuredOutputSerializer` to `Symfony\AI\Platform\StructuredOutput\Serializer` UPGRADE FROM 0.1 to 0.2 ======================= @@ -285,7 +285,7 @@ Agent * Constructor of `MemoryInputProcessor` now accepts an iterable of inputs instead of variadic arguments. ```php - use Symfony\AI\Agent\InputProcessor\MemoryInputProcessor; + use Symfony\AI\Agent\Memory\MemoryInputProcessor; // Before $processor = new MemoryInputProcessor($input1, $input2); diff --git a/docs/bundles/ai-bundle.rst b/docs/bundles/ai-bundle.rst index 3025ae0c..22968453 100644 --- a/docs/bundles/ai-bundle.rst +++ b/docs/bundles/ai-bundle.rst @@ -798,7 +798,7 @@ Use the :class:`Symfony\\AI\\Agent\\Agent` service to leverage models and tools: Message::ofUser($message), ); - return $this->agent->call($messages)->asText(); + return $this->agent->call($messages)->getContent(); } } @@ -943,7 +943,7 @@ The token usage information can be accessed from the result metadata:: use Symfony\AI\Agent\AgentInterface; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; - use Symfony\AI\Platform\Result\Metadata\TokenUsage\TokenUsage; + use Symfony\AI\Platform\TokenUsage\TokenUsage; final readonly class MyService { diff --git a/docs/components/agent.rst b/docs/components/agent.rst index 7cbd2698..6abe0243 100644 --- a/docs/components/agent.rst +++ b/docs/components/agent.rst @@ -16,10 +16,9 @@ Basic Usage ----------- To instantiate an agent, you need to pass a :class:`Symfony\\AI\\Platform\\PlatformInterface` and a -:class:`Symfony\\AI\\Platform\\Model` instance to the :class:`Symfony\\AI\\Agent\\Agent` class:: +model name to the :class:`Symfony\\AI\\Agent\\Agent` class:: use Symfony\AI\Agent\Agent; - use Symfony\AI\Platform\Bridge\OpenAi\Gpt; use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory; $platform = PlatformFactory::create($apiKey); @@ -27,7 +26,7 @@ To instantiate an agent, you need to pass a :class:`Symfony\\AI\\Platform\\Platf $agent = new Agent($platform, $model); -You can then run the agent with a :class:`Symfony\\AI\\Platform\\Message\\MessageBagInterface` instance as input and an optional +You can then run the agent with a :class:`Symfony\\AI\\Platform\\Message\\MessageBag` instance as input and an optional array of options:: use Symfony\AI\Agent\Agent; @@ -780,7 +779,7 @@ Code Examples .. _`Anthropic Toolbox Example`: https://github.com/symfony/ai/blob/main/examples/anthropic/toolcall.php .. _`Brave Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/brave.php .. _`Clock Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/clock.php -.. _`Crawler Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/brave.php +.. _`Crawler Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/firecrawl-crawl.php .. _`Mapbox Geocode Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/mapbox-geocode.php .. _`Mapbox Reverse Geocode Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/mapbox-reverse-geocode.php .. _`SerpAPI Tool`: https://github.com/symfony/ai/blob/main/examples/toolbox/serpapi.php diff --git a/docs/components/chat.rst b/docs/components/chat.rst index c3dcfb89..e92ebf40 100644 --- a/docs/components/chat.rst +++ b/docs/components/chat.rst @@ -20,7 +20,6 @@ with a ``Symfony\AI\Agent\AgentInterface`` and a ``Symfony\AI\Chat\MessageStoreI use Symfony\AI\Agent\Agent; use Symfony\AI\Chat\Chat; use Symfony\AI\Chat\InMemory\Store as InMemoryStore; - use Symfony\AI\Platform\Bridge\OpenAi\Gpt; use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory; use Symfony\AI\Platform\Message\Message; diff --git a/docs/components/platform.rst b/docs/components/platform.rst index 03d09ce4..d7fc3161 100644 --- a/docs/components/platform.rst +++ b/docs/components/platform.rst @@ -28,8 +28,6 @@ OpenAI, Anthropic, Google, Replicate, and others. For example, to use the OpenAI provider, you would typically do something like this:: - use Symfony\AI\Platform\Bridge\OpenAi\Embeddings; - use Symfony\AI\Platform\Bridge\OpenAi\Gpt; use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory; $platform = PlatformFactory::create(env('OPENAI_API_KEY')); @@ -37,7 +35,7 @@ For example, to use the OpenAI provider, you would typically do something like t With this :class:`Symfony\\AI\\Platform\\PlatformInterface` instance you can now interact with the LLM:: // Generate a vector embedding for a text, returns a Symfony\AI\Platform\Result\VectorResult - $vectorResult = $platform->invoke($embeddings, 'What is the capital of France?'); + $vectorResult = $platform->invoke('text-embedding-3-small', 'What is the capital of France?'); // Generate a text completion with GPT, returns a Symfony\AI\Platform\Result\TextResult $result = $platform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?'))); @@ -81,30 +79,18 @@ Custom models ~~~~~~~~~~~~~ For providers like Ollama, you can use custom models (built on top of ``Modelfile``), as those models are not listed in -the default catalog, you can use the built-in ``OllamaApiCatalog`` to query the model information from the API rather -than the default catalog:: +the default catalog. The ``ModelCatalog`` automatically queries the model information from the Ollama API:: - use Symfony\AI\Platform\Bridge\Ollama\OllamaApiCatalog; use Symfony\AI\Platform\Bridge\Ollama\PlatformFactory; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; - $platform = PlatformFactory::create('http://127.0.0.1:11434', HttpClient::create(), new OllamaApiCatalog( - 'http://127.0.0.1:11434', - HttpClient::create(), - )); + $platform = PlatformFactory::create('http://127.0.0.1:11434'); $platform->invoke('your_custom_model_name', new MessageBag( Message::ofUser(...) )); -When using the bundle, the usage of ``OllamaApiCatalog`` is available via the ``api_catalog`` option:: - - ai: - platform: - ollama: - api_catalog: true - Supported Models & Platforms ---------------------------- @@ -131,7 +117,7 @@ Supported Models & Platforms * `OpenAI's Whisper`_ with `OpenAI`_ and `Azure`_ as Platform * `LM Studio Catalog`_ and `HuggingFace`_ Models with `LM Studio`_ as Platform. * All models provided by `HuggingFace`_ can be listed with a command in the examples folder, - and also filtered, e.g. ``php examples/huggingface/_model-listing.php --provider=hf-inference --task=object-detection`` + and also filtered, e.g. ``php examples/huggingface/_model.php --provider=hf-inference --task=object-detection`` * **Voice Models** * `ElevenLabs TTS`_ with `ElevenLabs`_ as Platform * `ElevenLabs STT`_ with `ElevenLabs`_ as Platform @@ -556,7 +542,7 @@ Embeddings Creating embeddings of word, sentences, or paragraphs is a typical use case around the interaction with LLMs. -The standalone usage results in a :class:`Symfony\\AI\\Store\\Vector` instance:: +The standalone usage results in a :class:`Symfony\\AI\\Platform\\Vector\\Vector` instance:: use Symfony\AI\Platform\Bridge\OpenAi\Embeddings; @@ -677,7 +663,7 @@ Cached Platform Calls Thanks to Symfony's Cache component, platform calls can be cached to reduce calls and resources consumption:: use Symfony\AI\Agent\Agent; - use Symfony\AI\Platform\Bridge\Cache\CachedPlatform; + use Symfony\AI\Platform\Bridge\Cache\CachePlatform; use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; @@ -686,13 +672,13 @@ Thanks to Symfony's Cache component, platform calls can be cached to reduce call use Symfony\Component\HttpClient\HttpClient; $platform = PlatformFactory::create($apiKey, HttpClient::create()); - $cachedPlatform = new CachedPlatform($platform, cache: new TagAwareAdapter(new ArrayAdapter())); + $cachePlatform = new CachePlatform($platform, cache: new TagAwareAdapter(new ArrayAdapter())); - $firstResult = $cachedPlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?'))); + $firstResult = $cachePlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?'))); echo $firstResult->getContent().\PHP_EOL; - $secondResult = $cachedPlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?'))); + $secondResult = $cachePlatform->invoke('gpt-4o-mini', new MessageBag(Message::ofUser('What is the capital of France?'))); echo $secondResult->getContent().\PHP_EOL; diff --git a/docs/components/platform/vertexai.rst b/docs/components/platform/vertexai.rst index 4f00dfe7..0ccf1027 100644 --- a/docs/components/platform/vertexai.rst +++ b/docs/components/platform/vertexai.rst @@ -46,7 +46,6 @@ Configure your Google Cloud project and location: Basic usage example:: - use Symfony\AI\Platform\Bridge\VertexAi\Gemini\Model; use Symfony\AI\Platform\Bridge\VertexAi\PlatformFactory; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; diff --git a/docs/components/store.rst b/docs/components/store.rst index 4298d142..6f99eb38 100644 --- a/docs/components/store.rst +++ b/docs/components/store.rst @@ -22,15 +22,18 @@ for documents. Indexing -------- -One higher level feature is the :class:`Symfony\\AI\\Store\\Indexer`. The purpose of this service is to populate a store with documents. +One higher level feature is the :class:`Symfony\\AI\\Store\\Indexer\\DocumentIndexer`. The purpose of this service is to populate a store with documents. Therefore it accepts one or multiple :class:`Symfony\\AI\\Store\\Document\\TextDocument` objects, converts them into embeddings and stores them in the used vector store:: use Symfony\AI\Store\Document\TextDocument; - use Symfony\AI\Store\Indexer; + use Symfony\AI\Store\Document\Vectorizer; + use Symfony\AI\Store\Indexer\DocumentIndexer; + use Symfony\AI\Store\Indexer\DocumentProcessor; - $indexer = new Indexer($platform, $model, $store); - $document = new TextDocument('This is a sample document.'); + $vectorizer = new Vectorizer($platform, $model); + $indexer = new DocumentIndexer(new DocumentProcessor($vectorizer, $store)); + $document = new TextDocument('id-1', 'This is a sample document.'); $indexer->index($document); You can find more advanced usage in combination with an Agent using the store for RAG in the examples folder. diff --git a/docs/components/store/local.rst b/docs/components/store/local.rst index 3f89fc83..b8221f05 100644 --- a/docs/components/store/local.rst +++ b/docs/components/store/local.rst @@ -14,10 +14,11 @@ InMemoryStore Stores vectors in a PHP array. Data is not persisted and is lost when the PHP process ends:: use Symfony\AI\Store\InMemory\Store; + use Symfony\AI\Store\Query\VectorQuery; $store = new Store(); $store->add([$document1, $document2]); - $results = $store->query($vector); + $results = $store->query(new VectorQuery($vector)); CacheStore ---------- @@ -30,7 +31,7 @@ Stores vectors using a PSR-6 cache implementation. Persistence depends on the ca $cache = new FilesystemAdapter(); $store = new Store($cache); $store->add([$document1, $document2]); - $results = $store->query($vector); + $results = $store->query(new VectorQuery($vector)); Distance Strategies ------------------- @@ -70,7 +71,7 @@ candidates are kept, reducing peak memory from O(N) to O(maxItems + batchSize):: $store = new Store($calculator); // Batch processing is activated when both batchSize and maxItems are set - $results = $store->query($vector, [ + $results = $store->query($vectorQuery, [ 'maxItems' => 10, ]); @@ -87,34 +88,34 @@ Both stores support filtering search results based on document metadata using a use Symfony\AI\Store\Document\VectorDocument; - $results = $store->query($vector, [ - 'filter' => fn(VectorDocument $doc) => $doc->metadata['category'] === 'products', + $results = $store->query($vectorQuery, [ + 'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['category'] === 'products', ]); You can combine multiple conditions:: - $results = $store->query($vector, [ + $results = $store->query($vectorQuery, [ 'filter' => fn(VectorDocument $doc) => - $doc->metadata['price'] <= 100 - && $doc->metadata['stock'] > 0 - && $doc->metadata['enabled'] === true, + $doc->getMetadata()['price'] <= 100 + && $doc->getMetadata()['stock'] > 0 + && $doc->getMetadata()['enabled'] === true, 'maxItems' => 10, ]); Filter nested metadata:: - $results = $store->query($vector, [ + $results = $store->query($vectorQuery, [ 'filter' => fn(VectorDocument $doc) => - $doc->metadata['options']['size'] === 'S' - && $doc->metadata['options']['color'] === 'blue', + $doc->getMetadata()['options']['size'] === 'S' + && $doc->getMetadata()['options']['color'] === 'blue', ]); Use array functions for complex filtering:: $allowedBrands = ['Nike', 'Adidas', 'Puma']; - $results = $store->query($vector, [ + $results = $store->query($vectorQuery, [ 'filter' => fn(VectorDocument $doc) => - \in_array($doc->metadata['brand'] ?? '', $allowedBrands, true), + \in_array($doc->getMetadata()['brand'] ?? '', $allowedBrands, true), ]); .. note:: @@ -131,7 +132,7 @@ Both stores support the following query options: Example combining both options:: - $results = $store->query($vector, [ + $results = $store->query($vectorQuery, [ 'maxItems' => 5, - 'filter' => fn(VectorDocument $doc) => $doc->metadata['active'] === true, + 'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['active'] === true, ]); diff --git a/docs/components/store/s3-vectors.rst b/docs/components/store/s3-vectors.rst index 848403a3..e32a4efe 100644 --- a/docs/components/store/s3-vectors.rst +++ b/docs/components/store/s3-vectors.rst @@ -81,9 +81,10 @@ Query Similar Vectors :: use Symfony\AI\Platform\Vector\Vector; + use Symfony\AI\Store\Query\VectorQuery; $results = $store->query( - vector: new Vector([0.1, 0.2, 0.3, ...]), + query: new VectorQuery(new Vector([0.1, 0.2, 0.3, ...])), options: [ 'topK' => 5, 'filter' => ['category' => 'documentation'], @@ -91,7 +92,7 @@ Query Similar Vectors ); foreach ($results as $result) { - echo $result->metadata['title'] . ' (score: ' . $result->score . ')' . PHP_EOL; + echo $result->getMetadata()['title'] . ' (score: ' . $result->getScore() . ')' . PHP_EOL; } Remove Documents diff --git a/docs/components/store/sqlite.rst b/docs/components/store/sqlite.rst index c1ca80e1..0694c136 100644 --- a/docs/components/store/sqlite.rst +++ b/docs/components/store/sqlite.rst @@ -94,7 +94,7 @@ The SQLite store supports filtering search results based on document metadata us use Symfony\AI\Store\Document\VectorDocument; $results = $store->query($vectorQuery, [ - 'filter' => fn(VectorDocument $doc) => $doc->metadata['category'] === 'products', + 'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['category'] === 'products', ]); Query Options @@ -109,5 +109,5 @@ Example combining both options:: $results = $store->query($vectorQuery, [ 'maxItems' => 5, - 'filter' => fn(VectorDocument $doc) => $doc->metadata['active'] === true, + 'filter' => fn(VectorDocument $doc) => $doc->getMetadata()['active'] === true, ]); diff --git a/docs/components/store/supabase.rst b/docs/components/store/supabase.rst index 861f688c..6392980b 100644 --- a/docs/components/store/supabase.rst +++ b/docs/components/store/supabase.rst @@ -152,15 +152,17 @@ Querying Documents $queryVector = new Vector([0.1, 0.2, 0.3, /* ... 768 dimensions */]); - $results = $store->query($queryVector, [ + use Symfony\AI\Store\Query\VectorQuery; + + $results = $store->query(new VectorQuery($queryVector), [ 'max_items' => 10, 'min_score' => 0.7 ]); foreach ($results as $document) { - echo "ID: " . $document->id . "\n"; - echo "Score: " . $document->score . "\n"; - echo "Metadata: " . json_encode($document->metadata->getArrayCopy()) . "\n"; + echo "ID: " . $document->getId() . "\n"; + echo "Score: " . $document->getScore() . "\n"; + echo "Metadata: " . json_encode($document->getMetadata()->getArrayCopy()) . "\n"; } Customization diff --git a/docs/cookbook/rag-implementation.rst b/docs/cookbook/rag-implementation.rst index fcc565eb..14cf094c 100644 --- a/docs/cookbook/rag-implementation.rst +++ b/docs/cookbook/rag-implementation.rst @@ -168,13 +168,11 @@ Vector Store Selection For production environments, use persistent vector stores like ChromaDB:: + use Codewithkyrian\ChromaDB\ChromaDB; use Symfony\AI\Store\Bridge\ChromaDb\Store; - $store = new Store( - $httpClient, - 'http://localhost:8000', - 'my_collection' - ); + $client = ChromaDB::factory()->connect(); + $store = new Store($client, 'my_collection'); ChromaDB is a great choice for production RAG systems as it provides: