From c83ccdc25f5f5fc23a03269e8edc8184301335db Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Tue, 8 Jul 2025 01:00:35 +0200 Subject: [PATCH] docs: fix example scripts for docker, class names and env var names --- .php-cs-fixer.dist.php | 2 +- examples/README.md | 16 ++++++++++++ compose.yaml => examples/compose.yaml | 0 examples/composer.json | 4 ++- examples/google/embeddings.php | 11 +++----- examples/google/server-tools.php | 26 +++++++++---------- examples/google/structured-output-clock.php | 4 +-- examples/google/structured-output-math.php | 4 +-- .../mariadb-similarity-search-gemini.php | 4 +-- examples/store/mariadb-similarity-search.php | 12 +++++---- examples/store/postgres-similarity-search.php | 6 +++-- src/platform/doc/index.rst | 2 +- src/store/src/Bridge/Postgres/Store.php | 3 +++ 13 files changed, 58 insertions(+), 36 deletions(-) rename compose.yaml => examples/compose.yaml (100%) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index ca5cf0f6..1c05560d 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -44,6 +44,6 @@ (new PhpCsFixer\Finder()) ->in([__DIR__.'/demo', __DIR__.'/examples', __DIR__.'/fixtures', __DIR__.'/src']) ->append([__FILE__]) - ->exclude(__DIR__.'/demo/var') + ->exclude('var') ) ; diff --git a/examples/README.md b/examples/README.md index 5b95e493..725bda5a 100644 --- a/examples/README.md +++ b/examples/README.md @@ -7,6 +7,13 @@ On top, the examples are used as integration tests to ensure that the components ## Running the examples +For setting up and running the examples, you can either run them standalone or via the example runner. You find the +commands for that in this section. Make sure to change into the `examples` directory before running the commands. + +```bash +cd examples +``` + ### Setup #### Dependencies @@ -25,6 +32,15 @@ corresponding example you want to run. _Now you can run examples standalone or via the example runner._ +#### Store with Docker + +Some of the store examples require locally running services, meaning that you need to have Docker installed and running +to test these examples. + +```bash +docker compose up -d +``` + ### Running examples standalone Every example script is a standalone PHP script that can be run from the command line. diff --git a/compose.yaml b/examples/compose.yaml similarity index 100% rename from compose.yaml rename to examples/compose.yaml diff --git a/examples/composer.json b/examples/composer.json index d8d96122..64594c9d 100644 --- a/examples/composer.json +++ b/examples/composer.json @@ -8,6 +8,7 @@ "async-aws/bedrock-runtime": "^1.1", "codewithkyrian/transformers": "^0.5.3", "doctrine/dbal": "^3.3|^4.0", + "mrmysql/youtube-transcript": "^0.0.5", "php-http/discovery": "^1.20", "probots-io/pinecone-php": "^1.1", "psr/http-factory-implementation": "*", @@ -38,6 +39,7 @@ "allow-plugins": { "codewithkyrian/transformers-libsloader": true, "php-http/discovery": true - } + }, + "sort-packages": true } } diff --git a/examples/google/embeddings.php b/examples/google/embeddings.php index 9547c850..be96c7b4 100644 --- a/examples/google/embeddings.php +++ b/examples/google/embeddings.php @@ -11,18 +11,17 @@ use Symfony\AI\Platform\Bridge\Google\Embeddings; use Symfony\AI\Platform\Bridge\Google\PlatformFactory; -use Symfony\AI\Platform\Response\VectorResponse; use Symfony\Component\Dotenv\Dotenv; require_once dirname(__DIR__).'/vendor/autoload.php'; (new Dotenv())->loadEnv(dirname(__DIR__).'/.env'); -if (empty($_ENV['GOOGLE_API_KEY'])) { - echo 'Please set the GOOGLE_API_KEY environment variable.'.\PHP_EOL; +if (!isset($_ENV['GEMINI_API_KEY'])) { + echo 'Please set the GEMINI_API_KEY environment variable.'.\PHP_EOL; exit(1); } -$platform = PlatformFactory::create($_ENV['GOOGLE_API_KEY']); +$platform = PlatformFactory::create($_ENV['GEMINI_API_KEY']); $embeddings = new Embeddings(); $response = $platform->request($embeddings, <<getContent()[0]->getDimensions().\PHP_EOL; +echo 'Dimensions: '.$response->asVectors()[0]->getDimensions().\PHP_EOL; diff --git a/examples/google/server-tools.php b/examples/google/server-tools.php index e4a94850..dbfcaeff 100644 --- a/examples/google/server-tools.php +++ b/examples/google/server-tools.php @@ -9,18 +9,18 @@ * file that was distributed with this source code. */ -use PhpLlm\LlmChain\Chain\Chain; -use PhpLlm\LlmChain\Chain\Toolbox\ChainProcessor; -use PhpLlm\LlmChain\Chain\Toolbox\Tool\Clock; -use PhpLlm\LlmChain\Chain\Toolbox\Toolbox; -use PhpLlm\LlmChain\Platform\Bridge\Google\Gemini; -use PhpLlm\LlmChain\Platform\Bridge\Google\PlatformFactory; -use PhpLlm\LlmChain\Platform\Message\Message; -use PhpLlm\LlmChain\Platform\Message\MessageBag; +use Symfony\AI\Agent\Agent; +use Symfony\AI\Agent\Toolbox\AgentProcessor; +use Symfony\AI\Agent\Toolbox\Tool\Clock; +use Symfony\AI\Agent\Toolbox\Toolbox; +use Symfony\AI\Platform\Bridge\Google\Gemini; +use Symfony\AI\Platform\Bridge\Google\PlatformFactory; +use Symfony\AI\Platform\Message\Message; +use Symfony\AI\Platform\Message\MessageBag; use Symfony\Component\Dotenv\Dotenv; -require_once dirname(__DIR__, 2).'/vendor/autoload.php'; -(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env'); +require_once dirname(__DIR__).'/vendor/autoload.php'; +(new Dotenv())->loadEnv(dirname(__DIR__).'/.env'); if (!isset($_ENV['GEMINI_API_KEY'])) { echo 'Please set the GEMINI_API_KEY environment variable.'.\PHP_EOL; @@ -33,8 +33,8 @@ $llm = new Gemini('gemini-2.5-pro-preview-03-25', ['server_tools' => ['url_context' => true], 'temperature' => 1.0]); $toolbox = Toolbox::create(new Clock()); -$processor = new ChainProcessor($toolbox); -$chain = new Chain($platform, $llm); +$processor = new AgentProcessor($toolbox); +$agent = new Agent($platform, $llm); $messages = new MessageBag( Message::ofUser( @@ -44,6 +44,6 @@ ), ); -$response = $chain->call($messages); +$response = $agent->call($messages); echo $response->getContent().\PHP_EOL; diff --git a/examples/google/structured-output-clock.php b/examples/google/structured-output-clock.php index fbeb329d..3fa000c3 100644 --- a/examples/google/structured-output-clock.php +++ b/examples/google/structured-output-clock.php @@ -21,8 +21,8 @@ use Symfony\Component\Clock\Clock as SymfonyClock; use Symfony\Component\Dotenv\Dotenv; -require_once dirname(__DIR__, 2).'/vendor/autoload.php'; -(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env'); +require_once dirname(__DIR__).'/vendor/autoload.php'; +(new Dotenv())->loadEnv(dirname(__DIR__).'/.env'); if (!isset($_ENV['GEMINI_API_KEY'])) { echo 'Please set the GEMINI_API_KEY environment variable.'.\PHP_EOL; diff --git a/examples/google/structured-output-math.php b/examples/google/structured-output-math.php index f1d57100..6aac71a9 100644 --- a/examples/google/structured-output-math.php +++ b/examples/google/structured-output-math.php @@ -18,8 +18,8 @@ use Symfony\AI\Platform\Message\MessageBag; use Symfony\Component\Dotenv\Dotenv; -require_once dirname(__DIR__, 2).'/vendor/autoload.php'; -(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env'); +require_once dirname(__DIR__).'/vendor/autoload.php'; +(new Dotenv())->loadEnv(dirname(__DIR__).'/.env'); if (!isset($_ENV['GEMINI_API_KEY'])) { echo 'Please set the GEMINI_API_KEY environment variable.'.\PHP_EOL; diff --git a/examples/store/mariadb-similarity-search-gemini.php b/examples/store/mariadb-similarity-search-gemini.php index 6ce12eea..9c0f4a32 100644 --- a/examples/store/mariadb-similarity-search-gemini.php +++ b/examples/store/mariadb-similarity-search-gemini.php @@ -29,8 +29,8 @@ use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\Uid\Uuid; -require_once dirname(__DIR__, 2).'/vendor/autoload.php'; -(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env'); +require_once dirname(__DIR__).'/vendor/autoload.php'; +(new Dotenv())->loadEnv(dirname(__DIR__).'/.env'); if (!isset($_ENV['GEMINI_API_KEY'], $_ENV['MARIADB_URI'])) { echo 'Please set GEMINI_API_KEY and MARIADB_URI environment variables.'.\PHP_EOL; diff --git a/examples/store/mariadb-similarity-search.php b/examples/store/mariadb-similarity-search.php index ffc4bc12..bc0fe772 100644 --- a/examples/store/mariadb-similarity-search.php +++ b/examples/store/mariadb-similarity-search.php @@ -11,6 +11,8 @@ use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Tools\DsnParser; +use Symfony\AI\Agent\Agent; +use Symfony\AI\Agent\Toolbox\AgentProcessor; use Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch; use Symfony\AI\Agent\Toolbox\Toolbox; use Symfony\AI\Platform\Bridge\OpenAI\Embeddings; @@ -26,8 +28,8 @@ use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\Uid\Uuid; -require_once dirname(__DIR__, 2).'/vendor/autoload.php'; -(new Dotenv())->loadEnv(dirname(__DIR__, 2).'/.env'); +require_once dirname(__DIR__).'/vendor/autoload.php'; +(new Dotenv())->loadEnv(dirname(__DIR__).'/.env'); if (!isset($_ENV['OPENAI_API_KEY'], $_ENV['MARIADB_URI'])) { echo 'Please set OPENAI_API_KEY and MARIADB_URI environment variables.'.\PHP_EOL; @@ -71,13 +73,13 @@ $similaritySearch = new SimilaritySearch($platform, $embeddings, $store); $toolbox = Toolbox::create($similaritySearch); -$processor = new ChainProcessor($toolbox); -$chain = new Chain($platform, $model, [$processor], [$processor]); +$processor = new AgentProcessor($toolbox); +$agent = new Agent($platform, $model, [$processor], [$processor]); $messages = new MessageBag( Message::forSystem('Please answer all user questions only using SimilaritySearch function.'), Message::ofUser('Which movie fits the theme of the mafia?') ); -$response = $chain->call($messages); +$response = $agent->call($messages); echo $response->getContent().\PHP_EOL; diff --git a/examples/store/postgres-similarity-search.php b/examples/store/postgres-similarity-search.php index 8e73d68b..c15e4cd6 100644 --- a/examples/store/postgres-similarity-search.php +++ b/examples/store/postgres-similarity-search.php @@ -23,6 +23,7 @@ use Symfony\AI\Store\Bridge\Postgres\Store; use Symfony\AI\Store\Document\Metadata; use Symfony\AI\Store\Document\TextDocument; +use Symfony\AI\Store\Document\Vectorizer; use Symfony\AI\Store\Indexer; use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\Uid\Uuid; @@ -30,7 +31,7 @@ require_once dirname(__DIR__).'/vendor/autoload.php'; (new Dotenv())->loadEnv(dirname(__DIR__).'/.env'); -if (empty($_ENV['OPENAI_API_KEY']) || empty($_ENV['POSTGRES_URI'])) { +if (!isset($_ENV['OPENAI_API_KEY'], $_ENV['POSTGRES_URI'])) { echo 'Please set OPENAI_API_KEY and POSTGRES_URI environment variables.'.\PHP_EOL; exit(1); } @@ -64,7 +65,8 @@ // create embeddings for documents $platform = PlatformFactory::create($_ENV['OPENAI_API_KEY']); -$indexer = new Indexer($platform, $embeddings = new Embeddings(), $store); +$vectorizer = new Vectorizer($platform, $embeddings = new Embeddings()); +$indexer = new Indexer($vectorizer, $store); $indexer->index($documents); $model = new GPT(GPT::GPT_4O_MINI); diff --git a/src/platform/doc/index.rst b/src/platform/doc/index.rst index 68d54a59..95155127 100644 --- a/src/platform/doc/index.rst +++ b/src/platform/doc/index.rst @@ -136,7 +136,7 @@ This provides several benefits: :: - use PhpLlm\LlmChain\Platform\Message\Message; + use Symfony\AI\Platform\Message\Message; $message = Message::ofUser('Hello, AI!'); diff --git a/src/store/src/Bridge/Postgres/Store.php b/src/store/src/Bridge/Postgres/Store.php index 30d3faf4..a336da28 100644 --- a/src/store/src/Bridge/Postgres/Store.php +++ b/src/store/src/Bridge/Postgres/Store.php @@ -155,6 +155,9 @@ private function toPgvector(VectorInterface $vector): string return '['.implode(',', $vector->getData()).']'; } + /** + * @return float[] + */ private function fromPgvector(string $vector): array { return json_decode($vector, true, 512, \JSON_THROW_ON_ERROR);