diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index d848d8e0..e460d4c0 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -30,12 +30,15 @@ jobs: # lowest deps - php-version: '8.2' dependency-version: 'lowest' - # LTS version of Symfony + # Symfony 7.4 LTS - php-version: '8.2' - symfony-version: '6.4.*' + symfony-version: '7.4.*' + # Symfony 8.0 + - php-version: '8.3' + symfony-version: '8.0.*' env: - SYMFONY_REQUIRE: ${{ matrix.symfony-version || '>=6.4' }} + SYMFONY_REQUIRE: ${{ matrix.symfony-version || '>=7.3' }} steps: - uses: actions/checkout@v4 diff --git a/composer.json b/composer.json index d94d57ce..75f55f26 100644 --- a/composer.json +++ b/composer.json @@ -8,8 +8,8 @@ "require-dev": { "php": ">=8.2", "php-cs-fixer/shim": "^3.75", - "symfony/finder": "^6.4 || ^7.0", - "symfony/filesystem": "^6.4 || ^7.0" + "symfony/finder": "^7.3|^8.0", + "symfony/filesystem": "^7.3|^8.0" }, "config": { "sort-packages": true diff --git a/examples/composer.json b/examples/composer.json index 43646835..1f806c5a 100644 --- a/examples/composer.json +++ b/examples/composer.json @@ -15,15 +15,15 @@ "symfony/ai-agent": "@dev", "symfony/ai-platform": "@dev", "symfony/ai-store": "@dev", - "symfony/console": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0", - "symfony/dom-crawler": "^6.4|^7.0", - "symfony/dotenv": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/filesystem": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/console": "^7.3|^8.0", + "symfony/css-selector": "^7.3|^8.0", + "symfony/dom-crawler": "^7.3|^8.0", + "symfony/dotenv": "^7.3|^8.0", + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/filesystem": "^7.3|^8.0", + "symfony/finder": "^7.3|^8.0", + "symfony/process": "^7.3|^8.0", + "symfony/var-dumper": "^7.3|^8.0" }, "autoload": { "psr-4": { diff --git a/src/agent/composer.json b/src/agent/composer.json index 73249209..bcc202ad 100644 --- a/src/agent/composer.json +++ b/src/agent/composer.json @@ -25,23 +25,23 @@ "phpstan/phpdoc-parser": "^2.1", "psr/log": "^3.0", "symfony/ai-platform": "@dev", - "symfony/clock": "^6.4 || ^7.1", - "symfony/http-client": "^6.4 || ^7.1", - "symfony/property-access": "^6.4 || ^7.1", - "symfony/property-info": "^6.4 || ^7.1", - "symfony/serializer": "^6.4 || ^7.1", - "symfony/type-info": "^7.2.3" + "symfony/clock": "^7.3|^8.0", + "symfony/http-client": "^7.3|^8.0", + "symfony/property-access": "^7.3|^8.0", + "symfony/property-info": "^7.3|^8.0", + "symfony/serializer": "^7.3|^8.0", + "symfony/type-info": "^7.3|^8.0" }, "require-dev": { "mrmysql/youtube-transcript": "^v0.0.5", "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^11.5.13", "symfony/ai-store": "@dev", - "symfony/cache": "^6.4 || ^7.1", - "symfony/css-selector": "^6.4 || ^7.1", - "symfony/dom-crawler": "^6.4 || ^7.1", - "symfony/event-dispatcher": "^6.4 || ^7.1", - "symfony/http-foundation": "^6.4 || ^7.1" + "symfony/cache": "^7.3|^8.0", + "symfony/css-selector": "^7.3|^8.0", + "symfony/dom-crawler": "^7.3|^8.0", + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/http-foundation": "^7.3|^8.0" }, "config": { "sort-packages": true diff --git a/src/agent/tests/Toolbox/Tool/BraveTest.php b/src/agent/tests/Toolbox/Tool/BraveTest.php index f196de3d..ee33e926 100644 --- a/src/agent/tests/Toolbox/Tool/BraveTest.php +++ b/src/agent/tests/Toolbox/Tool/BraveTest.php @@ -23,7 +23,7 @@ final class BraveTest extends TestCase { public function testReturnsSearchResults() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/brave.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/brave.json'); $httpClient = new MockHttpClient($result); $brave = new Brave($httpClient, 'test-api-key'); @@ -40,7 +40,7 @@ public function testReturnsSearchResults() public function testPassesCorrectParametersToApi() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/brave.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/brave.json'); $httpClient = new MockHttpClient($result); $brave = new Brave($httpClient, 'test-api-key', ['extra' => 'option']); @@ -67,12 +67,4 @@ public function testHandlesEmptyResults() $this->assertEmpty($results); } - - /** - * This can be replaced by `JsonMockResponse::fromFile` when dropping Symfony 6.4. - */ - private function jsonMockResponseFromFile(string $file): JsonMockResponse - { - return new JsonMockResponse(json_decode(file_get_contents($file), true)); - } } diff --git a/src/agent/tests/Toolbox/Tool/OpenMeteoTest.php b/src/agent/tests/Toolbox/Tool/OpenMeteoTest.php index bbcd58c1..50bd29a2 100644 --- a/src/agent/tests/Toolbox/Tool/OpenMeteoTest.php +++ b/src/agent/tests/Toolbox/Tool/OpenMeteoTest.php @@ -22,7 +22,7 @@ final class OpenMeteoTest extends TestCase { public function testCurrent() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/openmeteo-current.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/openmeteo-current.json'); $httpClient = new MockHttpClient($result); $openMeteo = new OpenMeteo($httpClient); @@ -40,7 +40,7 @@ public function testCurrent() public function testForecast() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/openmeteo-forecast.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/openmeteo-forecast.json'); $httpClient = new MockHttpClient($result); $openMeteo = new OpenMeteo($httpClient); @@ -69,12 +69,4 @@ public function testForecast() $this->assertSame($expected, $actual); } - - /** - * This can be replaced by `JsonMockResponse::fromFile` when dropping Symfony 6.4. - */ - private function jsonMockResponseFromFile(string $file): JsonMockResponse - { - return new JsonMockResponse(json_decode(file_get_contents($file), true)); - } } diff --git a/src/agent/tests/Toolbox/Tool/WikipediaTest.php b/src/agent/tests/Toolbox/Tool/WikipediaTest.php index 1b752f2b..21ddf819 100644 --- a/src/agent/tests/Toolbox/Tool/WikipediaTest.php +++ b/src/agent/tests/Toolbox/Tool/WikipediaTest.php @@ -22,7 +22,7 @@ final class WikipediaTest extends TestCase { public function testSearchWithResults() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/wikipedia-search-result.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/wikipedia-search-result.json'); $httpClient = new MockHttpClient($result); $wikipedia = new Wikipedia($httpClient); @@ -49,7 +49,7 @@ public function testSearchWithResults() public function testSearchWithoutResults() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/wikipedia-search-empty.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/wikipedia-search-empty.json'); $httpClient = new MockHttpClient($result); $wikipedia = new Wikipedia($httpClient); @@ -62,7 +62,7 @@ public function testSearchWithoutResults() public function testArticleWithResult() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/wikipedia-article.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/wikipedia-article.json'); $httpClient = new MockHttpClient($result); $wikipedia = new Wikipedia($httpClient); @@ -78,7 +78,7 @@ public function testArticleWithResult() public function testArticleWithRedirect() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/wikipedia-article-redirect.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/wikipedia-article-redirect.json'); $httpClient = new MockHttpClient($result); $wikipedia = new Wikipedia($httpClient); @@ -96,7 +96,7 @@ public function testArticleWithRedirect() public function testArticleMissing() { - $result = $this->jsonMockResponseFromFile(__DIR__.'/fixtures/wikipedia-article-missing.json'); + $result = JsonMockResponse::fromFile(__DIR__.'/fixtures/wikipedia-article-missing.json'); $httpClient = new MockHttpClient($result); $wikipedia = new Wikipedia($httpClient); @@ -106,12 +106,4 @@ public function testArticleMissing() $this->assertSame($expected, $actual); } - - /** - * This can be replaced by `JsonMockResponse::fromFile` when dropping Symfony 6.4. - */ - private function jsonMockResponseFromFile(string $file): JsonMockResponse - { - return new JsonMockResponse(json_decode(file_get_contents($file), true)); - } } diff --git a/src/ai-bundle/composer.json b/src/ai-bundle/composer.json index f73ffbca..916c2161 100644 --- a/src/ai-bundle/composer.json +++ b/src/ai-bundle/composer.json @@ -18,16 +18,16 @@ "symfony/ai-agent": "@dev", "symfony/ai-platform": "@dev", "symfony/ai-store": "@dev", - "symfony/config": "^6.4 || ^7.0", - "symfony/dependency-injection": "^6.4 || ^7.0", - "symfony/framework-bundle": "^6.4 || ^7.0", - "symfony/string": "^6.4 || ^7.0" + "symfony/config": "^7.3|^8.0", + "symfony/dependency-injection": "^7.3|^8.0", + "symfony/framework-bundle": "^7.3|^8.0", + "symfony/string": "^7.3|^8.0" }, "require-dev": { "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^11.5", - "symfony/expression-language": "^6.4 || ^7.0", - "symfony/security-core": "^6.4 || ^7.0" + "symfony/expression-language": "^7.3|^8.0", + "symfony/security-core": "^7.3|^8.0" }, "config": { "sort-packages": true diff --git a/src/mcp-bundle/composer.json b/src/mcp-bundle/composer.json index 59bd7557..864e6fbe 100644 --- a/src/mcp-bundle/composer.json +++ b/src/mcp-bundle/composer.json @@ -10,14 +10,14 @@ } ], "require": { - "symfony/config": "^6.4 || ^7.0", - "symfony/console": "^6.4 || ^7.0", - "symfony/dependency-injection": "^6.4 || ^7.0", - "symfony/framework-bundle": "^6.4 || ^7.0", - "symfony/http-foundation": "^6.4 || ^7.0", - "symfony/http-kernel": "^6.4 || ^7.0", + "symfony/config": "^7.3|^8.0", + "symfony/console": "^7.3|^8.0", + "symfony/dependency-injection": "^7.3|^8.0", + "symfony/framework-bundle": "^7.3|^8.0", + "symfony/http-foundation": "^7.3|^8.0", + "symfony/http-kernel": "^7.3|^8.0", "symfony/mcp-sdk": "@dev", - "symfony/routing": "^6.4 || ^7.0" + "symfony/routing": "^7.3|^8.0" }, "require-dev": { "phpstan/phpstan": "^2.1", diff --git a/src/mcp-sdk/composer.json b/src/mcp-sdk/composer.json index e515ae89..ac520049 100644 --- a/src/mcp-sdk/composer.json +++ b/src/mcp-sdk/composer.json @@ -16,12 +16,13 @@ "require": { "php": "^8.2", "psr/log": "^1.0 || ^2.0 || ^3.0", - "symfony/uid": "^6.4 || ^7.0" + "symfony/uid": "^7.3|^8.0" }, "require-dev": { "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^11.5", - "symfony/console": "^6.4 || ^7.0", + "symfony/console": "^7.3|^8.0", + "rector/rector": "^2.0", "psr/cache": "^3.0" }, "suggest": { diff --git a/src/mcp-sdk/examples/cli/composer.json b/src/mcp-sdk/examples/cli/composer.json index 5975efcb..8c4729d8 100644 --- a/src/mcp-sdk/examples/cli/composer.json +++ b/src/mcp-sdk/examples/cli/composer.json @@ -12,7 +12,7 @@ "require": { "php": ">=8.2", "symfony/mcp-sdk": "@dev", - "symfony/console": "^7.2" + "symfony/console": "^7.3|^8.0" }, "minimum-stability": "stable", "autoload": { diff --git a/src/platform/composer.json b/src/platform/composer.json index d8d3b622..b74323fa 100644 --- a/src/platform/composer.json +++ b/src/platform/composer.json @@ -26,13 +26,13 @@ "phpdocumentor/reflection-docblock": "^5.4", "phpstan/phpdoc-parser": "^2.1", "psr/log": "^3.0", - "symfony/clock": "^6.4 || ^7.1", - "symfony/http-client": "^6.4 || ^7.1", - "symfony/property-access": "^6.4 || ^7.1", - "symfony/property-info": "^6.4 || ^7.1", - "symfony/serializer": "^6.4 || ^7.1", - "symfony/type-info": "^7.2.3", - "symfony/uid": "^6.4 || ^7.1" + "symfony/clock": "^7.3|^8.0", + "symfony/http-client": "^7.3|^8.0", + "symfony/property-access": "^7.3|^8.0", + "symfony/property-info": "^7.3|^8.0", + "symfony/serializer": "^7.3|^8.0", + "symfony/type-info": "^7.3|^8.0", + "symfony/uid": "^7.3|^8.0" }, "require-dev": { "async-aws/bedrock-runtime": "^0.1.0", @@ -40,13 +40,13 @@ "phpstan/phpstan": "^2.1.17", "phpstan/phpstan-symfony": "^2.0.6", "phpunit/phpunit": "^11.5", - "symfony/console": "^6.4 || ^7.1", - "symfony/dotenv": "^6.4 || ^7.1", + "symfony/console": "^7.3|^8.0", + "symfony/dotenv": "^7.3|^8.0", "symfony/ai-agent": "@dev", - "symfony/event-dispatcher": "^6.4 || ^7.1", - "symfony/finder": "^6.4 || ^7.1", - "symfony/process": "^6.4 || ^7.1", - "symfony/var-dumper": "^6.4 || ^7.1" + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/finder": "^7.3|^8.0", + "symfony/process": "^7.3|^8.0", + "symfony/var-dumper": "^7.3|^8.0" }, "config": { "allow-plugins": { diff --git a/src/platform/src/Bridge/Anthropic/ResultConverter.php b/src/platform/src/Bridge/Anthropic/ResultConverter.php index 92edde31..0143d7e2 100644 --- a/src/platform/src/Bridge/Anthropic/ResultConverter.php +++ b/src/platform/src/Bridge/Anthropic/ResultConverter.php @@ -23,7 +23,6 @@ use Symfony\AI\Platform\ResultConverterInterface; use Symfony\Component\HttpClient\Chunk\ServerSentEvent; use Symfony\Component\HttpClient\EventSourceHttpClient; -use Symfony\Component\HttpClient\Exception\JsonException; use Symfony\Contracts\HttpClient\ResponseInterface as HttpResponse; /** @@ -73,12 +72,7 @@ private function convertStream(HttpResponse $result): \Generator continue; } - try { - $data = $chunk->getArrayData(); - } catch (JsonException) { - // try catch only needed for Symfony 6.4 - continue; - } + $data = $chunk->getArrayData(); if ('content_block_delta' != $data['type'] || !isset($data['delta']['text'])) { continue; diff --git a/src/platform/src/Bridge/Mistral/Llm/ResultConverter.php b/src/platform/src/Bridge/Mistral/Llm/ResultConverter.php index a6b84026..a5e40f70 100644 --- a/src/platform/src/Bridge/Mistral/Llm/ResultConverter.php +++ b/src/platform/src/Bridge/Mistral/Llm/ResultConverter.php @@ -25,7 +25,6 @@ use Symfony\AI\Platform\ResultConverterInterface; use Symfony\Component\HttpClient\Chunk\ServerSentEvent; use Symfony\Component\HttpClient\EventSourceHttpClient; -use Symfony\Component\HttpClient\Exception\JsonException; use Symfony\Contracts\HttpClient\ResponseInterface as HttpResponse; /** @@ -72,12 +71,7 @@ private function convertStream(HttpResponse $result): \Generator continue; } - try { - $data = $chunk->getArrayData(); - } catch (JsonException) { - // try catch only needed for Symfony 6.4 - continue; - } + $data = $chunk->getArrayData(); if ($this->streamIsToolCall($data)) { $toolCalls = $this->convertStreamToToolCalls($toolCalls, $data); diff --git a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php b/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php index 72714e81..6f18f0e2 100644 --- a/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php +++ b/src/platform/src/Bridge/OpenAi/Gpt/ResultConverter.php @@ -26,7 +26,6 @@ use Symfony\AI\Platform\ResultConverterInterface as PlatformResponseConverter; use Symfony\Component\HttpClient\Chunk\ServerSentEvent; use Symfony\Component\HttpClient\EventSourceHttpClient; -use Symfony\Component\HttpClient\Exception\JsonException; use Symfony\Contracts\HttpClient\ResponseInterface as HttpResponse; /** @@ -69,12 +68,7 @@ private function convertStream(HttpResponse $result): \Generator continue; } - try { - $data = $chunk->getArrayData(); - } catch (JsonException) { - // try catch only needed for Symfony 6.4 - continue; - } + $data = $chunk->getArrayData(); if ($this->streamIsToolCall($data)) { $toolCalls = $this->convertStreamToToolCalls($toolCalls, $data); diff --git a/src/store/composer.json b/src/store/composer.json index 9b89bb86..e2c4d8bf 100644 --- a/src/store/composer.json +++ b/src/store/composer.json @@ -30,9 +30,9 @@ "ext-fileinfo": "*", "psr/log": "^3.0", "symfony/ai-platform": "@dev", - "symfony/clock": "^6.4 || ^7.1", - "symfony/http-client": "^6.4 || ^7.1", - "symfony/uid": "^6.4 || ^7.1" + "symfony/clock": "^7.3|^8.0", + "symfony/http-client": "^7.3|^8.0", + "symfony/uid": "^7.3|^8.0" }, "require-dev": { "codewithkyrian/chromadb-php": "^0.2.1 || ^0.3 || ^0.4",