diff --git a/README.md b/README.md index 5213517..9affb7a 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ The setup is split into three parts, the Symfony application, the OpenAI configu Checkout the repository, start the docker environment and install dependencies: ```shell -git clone git@github.com:php-llm/symfony-demo.git -cd symfony-demo +git clone git@github.com:php-llm/llm-chain-symfony-demo.git +cd llm-chain-symfony-demo docker compose up -d docker compose run composer install ``` diff --git a/composer.json b/composer.json index c76d8ff..6826f64 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "ext-iconv": "*", "codewithkyrian/chromadb-php": "^0.4.0", "league/commonmark": "^2.7", - "php-llm/llm-chain-bundle": "^0.20.2", + "php-llm/llm-chain-bundle": "^0.22", "runtime/frankenphp-symfony": "^0.2.0", "symfony/asset": "7.3.*", "symfony/asset-mapper": "7.3.*", @@ -25,10 +25,10 @@ "symfony/runtime": "7.3.*", "symfony/twig-bundle": "7.3.*", "symfony/uid": "7.3.*", - "symfony/ux-icons": "^2.24", - "symfony/ux-live-component": "^2.24", - "symfony/ux-turbo": "^2.24", - "symfony/ux-typed": "^2.24", + "symfony/ux-icons": "^2.25", + "symfony/ux-live-component": "^2.25", + "symfony/ux-turbo": "^2.25", + "symfony/ux-typed": "^2.25", "symfony/yaml": "7.3.*", "twig/extra-bundle": "^3.21", "twig/markdown-extra": "^3.21", @@ -105,7 +105,7 @@ "bin/console lint:twig templates", "bin/console lint:yaml config", "bin/console lint:container", - "PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix --dry-run", + "PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fix", "phpstan analyse", "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=coverage" ] diff --git a/composer.lock b/composer.lock index b23cde7..9aaf5da 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8a4c1809f2836580a081189226994f7b", + "content-hash": "77581522a522ad0ebf6540fa79d0e10a", "packages": [ { "name": "codewithkyrian/chromadb-php", @@ -1152,16 +1152,16 @@ }, { "name": "php-llm/llm-chain", - "version": "0.20.0", + "version": "0.22.0", "source": { "type": "git", "url": "https://github.com/php-llm/llm-chain.git", - "reference": "6b6d8f1fc73b98e1e3281b1619c39da31921e35a" + "reference": "c27618db1646b46ae9524b356bb5561b56f04027" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-llm/llm-chain/zipball/6b6d8f1fc73b98e1e3281b1619c39da31921e35a", - "reference": "6b6d8f1fc73b98e1e3281b1619c39da31921e35a", + "url": "https://api.github.com/repos/php-llm/llm-chain/zipball/c27618db1646b46ae9524b356bb5561b56f04027", + "reference": "c27618db1646b46ae9524b356bb5561b56f04027", "shasum": "" }, "require": { @@ -1185,11 +1185,13 @@ "mongodb/mongodb": "<1.21" }, "require-dev": { - "codewithkyrian/chromadb-php": "^0.2.1 || ^0.3", + "async-aws/bedrock-runtime": "^0.1.0", + "codewithkyrian/chromadb-php": "^0.2.1 || ^0.3 || ^0.4", "codewithkyrian/transformers": "^0.5.3", "mongodb/mongodb": "^1.21", "php-cs-fixer/shim": "^3.70", "phpstan/phpstan": "^2.0", + "phpstan/phpstan-symfony": "^2.0", "phpstan/phpstan-webmozart-assert": "^2.0", "phpunit/phpunit": "^11.5", "probots-io/pinecone-php": "^1.0", @@ -1204,6 +1206,7 @@ "symfony/var-dumper": "^6.4 || ^7.1" }, "suggest": { + "async-aws/bedrock-runtime": "For using the Bedrock platform.", "codewithkyrian/chromadb-php": "For using the ChromaDB as retrieval vector store.", "codewithkyrian/transformers": "For using the TransformersPHP with FFI to run models in PHP.", "mongodb/mongodb": "For using MongoDB Atlas as retrieval vector store.", @@ -1231,30 +1234,36 @@ "email": "oskarstark@googlemail.com" } ], - "description": "A slim PHP component with tooling around LLMs.", + "description": "PHP library for building LLM-based and AI-based features and applications.", + "keywords": [ + "ai", + "huggingface", + "llm", + "transformers" + ], "support": { "issues": "https://github.com/php-llm/llm-chain/issues", - "source": "https://github.com/php-llm/llm-chain/tree/0.20.0" + "source": "https://github.com/php-llm/llm-chain/tree/0.22.0" }, - "time": "2025-04-18T22:42:24+00:00" + "time": "2025-06-01T13:51:19+00:00" }, { "name": "php-llm/llm-chain-bundle", - "version": "0.20.2", + "version": "0.22.0", "source": { "type": "git", "url": "https://github.com/php-llm/llm-chain-bundle.git", - "reference": "345ad7075c7fa9fce9de9c3829cfede445ff9f5b" + "reference": "e83812e10daa443598c5e577963e8b010213446d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-llm/llm-chain-bundle/zipball/345ad7075c7fa9fce9de9c3829cfede445ff9f5b", - "reference": "345ad7075c7fa9fce9de9c3829cfede445ff9f5b", + "url": "https://api.github.com/repos/php-llm/llm-chain-bundle/zipball/e83812e10daa443598c5e577963e8b010213446d", + "reference": "e83812e10daa443598c5e577963e8b010213446d", "shasum": "" }, "require": { "php": ">=8.2", - "php-llm/llm-chain": "^0.20", + "php-llm/llm-chain": "^0.22", "symfony/config": "^6.4 || ^7.0", "symfony/dependency-injection": "^6.4 || ^7.0", "symfony/framework-bundle": "^6.4 || ^7.0", @@ -1289,9 +1298,9 @@ "description": "Symfony integration bundle for php-llm/llm-chain", "support": { "issues": "https://github.com/php-llm/llm-chain-bundle/issues", - "source": "https://github.com/php-llm/llm-chain-bundle/tree/0.20.2" + "source": "https://github.com/php-llm/llm-chain-bundle/tree/0.22.0" }, - "time": "2025-05-13T21:51:14+00:00" + "time": "2025-06-01T20:53:32+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -6385,16 +6394,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.4.0", + "version": "v5.5.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9", + "reference": "ae59794362fe85e051a58ad36b289443f57be7a9", "shasum": "" }, "require": { @@ -6437,9 +6446,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0" }, - "time": "2024-12-30T11:07:19+00:00" + "time": "2025-05-31T08:24:38+00:00" }, { "name": "nyholm/nsa", @@ -8497,7 +8506,7 @@ }, "platform-dev": {}, "platform-overrides": { - "php": "8.4.1" + "php": "8.4.7" }, "plugin-api-version": "2.6.0" } diff --git a/config/packages/llm_chain.yaml b/config/packages/llm_chain.yaml index 55447d7..e8ea8f8 100644 --- a/config/packages/llm_chain.yaml +++ b/config/packages/llm_chain.yaml @@ -60,5 +60,6 @@ services: # PhpLlm\LlmChain\Chain\Toolbox\Tool\SerpApi: # $apiKey: '%env(SERP_API_KEY)%' PhpLlm\LlmChain\Chain\Toolbox\Tool\Wikipedia: ~ - PhpLlm\LlmChain\Chain\Toolbox\Tool\SimilaritySearch: ~ + PhpLlm\LlmChain\Chain\Toolbox\Tool\SimilaritySearch: + $model: '@llm_chain.embedder.default.model' diff --git a/config/packages/web_profiler.yaml b/config/packages/web_profiler.yaml index b946111..9bd6095 100644 --- a/config/packages/web_profiler.yaml +++ b/config/packages/web_profiler.yaml @@ -1,6 +1,8 @@ when@dev: web_profiler: - toolbar: true + toolbar: + enabled: true + ajax_replace: true intercept_redirects: false framework: diff --git a/src/Audio/Chat.php b/src/Audio/Chat.php index e41b6b8..f8ea7fc 100644 --- a/src/Audio/Chat.php +++ b/src/Audio/Chat.php @@ -4,15 +4,14 @@ namespace App\Audio; -use PhpLlm\LlmChain\Bridge\OpenAI\Whisper; -use PhpLlm\LlmChain\Bridge\OpenAI\Whisper\File; -use PhpLlm\LlmChain\ChainInterface; -use PhpLlm\LlmChain\Model\Message\Content\Audio; -use PhpLlm\LlmChain\Model\Message\Message; -use PhpLlm\LlmChain\Model\Message\MessageBag; -use PhpLlm\LlmChain\Model\Response\AsyncResponse; -use PhpLlm\LlmChain\Model\Response\TextResponse; -use PhpLlm\LlmChain\PlatformInterface; +use PhpLlm\LlmChain\Chain\ChainInterface; +use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Whisper; +use PhpLlm\LlmChain\Platform\Message\Content\Audio; +use PhpLlm\LlmChain\Platform\Message\Message; +use PhpLlm\LlmChain\Platform\Message\MessageBag; +use PhpLlm\LlmChain\Platform\PlatformInterface; +use PhpLlm\LlmChain\Platform\Response\AsyncResponse; +use PhpLlm\LlmChain\Platform\Response\TextResponse; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\HttpFoundation\RequestStack; diff --git a/src/Audio/TwigComponent.php b/src/Audio/TwigComponent.php index e607437..5ae5e63 100644 --- a/src/Audio/TwigComponent.php +++ b/src/Audio/TwigComponent.php @@ -4,7 +4,7 @@ namespace App\Audio; -use PhpLlm\LlmChain\Model\Message\MessageInterface; +use PhpLlm\LlmChain\Platform\Message\MessageInterface; use Symfony\UX\LiveComponent\Attribute\AsLiveComponent; use Symfony\UX\LiveComponent\Attribute\LiveAction; use Symfony\UX\LiveComponent\Attribute\LiveArg; diff --git a/src/Blog/Chat.php b/src/Blog/Chat.php index 328f610..4374106 100644 --- a/src/Blog/Chat.php +++ b/src/Blog/Chat.php @@ -4,10 +4,10 @@ namespace App\Blog; -use PhpLlm\LlmChain\ChainInterface; -use PhpLlm\LlmChain\Model\Message\Message; -use PhpLlm\LlmChain\Model\Message\MessageBag; -use PhpLlm\LlmChain\Model\Response\TextResponse; +use PhpLlm\LlmChain\Chain\ChainInterface; +use PhpLlm\LlmChain\Platform\Message\Message; +use PhpLlm\LlmChain\Platform\Message\MessageBag; +use PhpLlm\LlmChain\Platform\Response\TextResponse; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\HttpFoundation\RequestStack; diff --git a/src/Blog/Command/QueryCommand.php b/src/Blog/Command/QueryCommand.php index ca49404..2a5d15c 100644 --- a/src/Blog/Command/QueryCommand.php +++ b/src/Blog/Command/QueryCommand.php @@ -5,10 +5,10 @@ namespace App\Blog\Command; use Codewithkyrian\ChromaDB\Client; -use PhpLlm\LlmChain\Bridge\OpenAI\Embeddings; -use PhpLlm\LlmChain\Model\Response\AsyncResponse; -use PhpLlm\LlmChain\Model\Response\VectorResponse; -use PhpLlm\LlmChain\PlatformInterface; +use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings; +use PhpLlm\LlmChain\Platform\PlatformInterface; +use PhpLlm\LlmChain\Platform\Response\AsyncResponse; +use PhpLlm\LlmChain\Platform\Response\VectorResponse; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; diff --git a/src/Blog/Embedder.php b/src/Blog/Embedder.php index c9f5e7e..8185aae 100644 --- a/src/Blog/Embedder.php +++ b/src/Blog/Embedder.php @@ -4,9 +4,9 @@ namespace App\Blog; -use PhpLlm\LlmChain\Document\Metadata; -use PhpLlm\LlmChain\Document\TextDocument; -use PhpLlm\LlmChain\Embedder as LlmChainEmbedder; +use PhpLlm\LlmChain\Store\Document\Metadata; +use PhpLlm\LlmChain\Store\Document\TextDocument; +use PhpLlm\LlmChain\Store\Embedder as LlmChainEmbedder; final readonly class Embedder { diff --git a/src/Blog/TwigComponent.php b/src/Blog/TwigComponent.php index 3c1dc86..24a725e 100644 --- a/src/Blog/TwigComponent.php +++ b/src/Blog/TwigComponent.php @@ -4,7 +4,7 @@ namespace App\Blog; -use PhpLlm\LlmChain\Model\Message\MessageInterface; +use PhpLlm\LlmChain\Platform\Message\MessageInterface; use Symfony\UX\LiveComponent\Attribute\AsLiveComponent; use Symfony\UX\LiveComponent\Attribute\LiveAction; use Symfony\UX\LiveComponent\Attribute\LiveArg; diff --git a/src/ProfilerSubscriber.php b/src/ProfilerSubscriber.php deleted file mode 100644 index 26d3d46..0000000 --- a/src/ProfilerSubscriber.php +++ /dev/null @@ -1,43 +0,0 @@ - 'onKernelResponse', - ]; - } - - public function onKernelResponse(ResponseEvent $event): void - { - if (!$this->debug && !$event->isMainRequest()) { - return; - } - - $request = $event->getRequest(); - if (!$request->isXmlHttpRequest()) { - return; - } - - $response = $event->getResponse(); - $response->headers->set('Symfony-Debug-Toolbar-Replace', '1'); - } -} diff --git a/src/Video/TwigComponent.php b/src/Video/TwigComponent.php index ae5ea12..3b5cd05 100644 --- a/src/Video/TwigComponent.php +++ b/src/Video/TwigComponent.php @@ -4,13 +4,13 @@ namespace App\Video; -use PhpLlm\LlmChain\Bridge\OpenAI\GPT; -use PhpLlm\LlmChain\Model\Message\Content\Image; -use PhpLlm\LlmChain\Model\Message\Message; -use PhpLlm\LlmChain\Model\Message\MessageBag; -use PhpLlm\LlmChain\Model\Response\AsyncResponse; -use PhpLlm\LlmChain\Model\Response\TextResponse; -use PhpLlm\LlmChain\PlatformInterface; +use PhpLlm\LlmChain\Platform\Bridge\OpenAI\GPT; +use PhpLlm\LlmChain\Platform\Message\Content\Image; +use PhpLlm\LlmChain\Platform\Message\Message; +use PhpLlm\LlmChain\Platform\Message\MessageBag; +use PhpLlm\LlmChain\Platform\PlatformInterface; +use PhpLlm\LlmChain\Platform\Response\AsyncResponse; +use PhpLlm\LlmChain\Platform\Response\TextResponse; use Symfony\UX\LiveComponent\Attribute\AsLiveComponent; use Symfony\UX\LiveComponent\Attribute\LiveAction; use Symfony\UX\LiveComponent\Attribute\LiveArg; diff --git a/src/Wikipedia/Chat.php b/src/Wikipedia/Chat.php index 158be08..804d4af 100644 --- a/src/Wikipedia/Chat.php +++ b/src/Wikipedia/Chat.php @@ -4,10 +4,10 @@ namespace App\Wikipedia; -use PhpLlm\LlmChain\ChainInterface; -use PhpLlm\LlmChain\Model\Message\Message; -use PhpLlm\LlmChain\Model\Message\MessageBag; -use PhpLlm\LlmChain\Model\Response\TextResponse; +use PhpLlm\LlmChain\Chain\ChainInterface; +use PhpLlm\LlmChain\Platform\Message\Message; +use PhpLlm\LlmChain\Platform\Message\MessageBag; +use PhpLlm\LlmChain\Platform\Response\TextResponse; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\HttpFoundation\RequestStack; diff --git a/src/Wikipedia/TwigComponent.php b/src/Wikipedia/TwigComponent.php index 1ba1d21..a762321 100644 --- a/src/Wikipedia/TwigComponent.php +++ b/src/Wikipedia/TwigComponent.php @@ -4,7 +4,7 @@ namespace App\Wikipedia; -use PhpLlm\LlmChain\Model\Message\MessageInterface; +use PhpLlm\LlmChain\Platform\Message\MessageInterface; use Symfony\UX\LiveComponent\Attribute\AsLiveComponent; use Symfony\UX\LiveComponent\Attribute\LiveAction; use Symfony\UX\LiveComponent\Attribute\LiveArg; diff --git a/src/YouTube/Chat.php b/src/YouTube/Chat.php index f4cd824..50afffa 100644 --- a/src/YouTube/Chat.php +++ b/src/YouTube/Chat.php @@ -4,10 +4,10 @@ namespace App\YouTube; -use PhpLlm\LlmChain\ChainInterface; -use PhpLlm\LlmChain\Model\Message\Message; -use PhpLlm\LlmChain\Model\Message\MessageBag; -use PhpLlm\LlmChain\Model\Response\TextResponse; +use PhpLlm\LlmChain\Chain\ChainInterface; +use PhpLlm\LlmChain\Platform\Message\Message; +use PhpLlm\LlmChain\Platform\Message\MessageBag; +use PhpLlm\LlmChain\Platform\Response\TextResponse; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\HttpFoundation\RequestStack; diff --git a/src/YouTube/TwigComponent.php b/src/YouTube/TwigComponent.php index 5d41719..e155dff 100644 --- a/src/YouTube/TwigComponent.php +++ b/src/YouTube/TwigComponent.php @@ -4,7 +4,7 @@ namespace App\YouTube; -use PhpLlm\LlmChain\Model\Message\MessageInterface; +use PhpLlm\LlmChain\Platform\Message\MessageInterface; use Psr\Log\LoggerInterface; use Symfony\UX\LiveComponent\Attribute\AsLiveComponent; use Symfony\UX\LiveComponent\Attribute\LiveAction; diff --git a/tests/ProfilerSubscriberTest.php b/tests/ProfilerSubscriberTest.php deleted file mode 100644 index 8ada6fd..0000000 --- a/tests/ProfilerSubscriberTest.php +++ /dev/null @@ -1,67 +0,0 @@ -headers->set('X-Requested-With', 'XMLHttpRequest'); - } - - $response = new Response(); - $event = new ResponseEvent($this->createMock(Kernel::class), new Request(), $requestType, $response); - - $subscriber = new ProfilerSubscriber($debug); - $subscriber->onKernelResponse($event); - - self::assertFalse($response->headers->has('Symfony-Debug-Toolbar-Replace')); - } - - /** - * @return iterable - */ - public static function provideInvalidRequests(): iterable - { - yield 'sub request, not debug, not XHR' => [HttpKernelInterface::SUB_REQUEST, false, false]; - yield 'sub request, not debug, XHR' => [HttpKernelInterface::SUB_REQUEST, false, true]; - yield 'sub request, debug, XHR' => [HttpKernelInterface::SUB_REQUEST, true, true]; - yield 'main request, not debug, not XHR' => [HttpKernelInterface::MAIN_REQUEST, false, false]; - yield 'main request, debug, not XHR' => [HttpKernelInterface::MAIN_REQUEST, true, false]; - } - - public function testAjaxReplaceHeaderOnEnabledAndXHR(): void - { - $request = new Request(); - $request->headers->set('X-Requested-With', 'XMLHttpRequest'); - $response = new Response(); - $event = new ResponseEvent($this->createMock(Kernel::class), $request, HttpKernelInterface::MAIN_REQUEST, $response); - - $subscriber = new ProfilerSubscriber(true); - $subscriber->onKernelResponse($event); - - self::assertEquals('1', $response->headers->get('Symfony-Debug-Toolbar-Replace')); - } - - public function testSubscriberIsSubscribedToResponseEvent(): void - { - self::assertArrayHasKey(ResponseEvent::class, ProfilerSubscriber::getSubscribedEvents()); - self::assertIsString(ProfilerSubscriber::getSubscribedEvents()[ResponseEvent::class]); - } -}