diff --git a/.github/build-packages.php b/.github/build-packages.php
index 539002392..aeccc2d46 100644
--- a/.github/build-packages.php
+++ b/.github/build-packages.php
@@ -49,6 +49,9 @@
$repositories[] = [
'type' => 'path',
'url' => $packageInfo['path'],
+ 'options' => [
+ 'symlink' => false,
+ ],
];
$key = isset($packageData['require'][$packageName]) ? 'require' : 'require-dev';
$packageData[$key][$packageName] = '@dev';
diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml
index 5e56fcab0..b93326e38 100644
--- a/.github/workflows/unit-tests.yaml
+++ b/.github/workflows/unit-tests.yaml
@@ -27,9 +27,10 @@ jobs:
dependency-version: ['']
symfony-version: ['']
include:
+ # TODO: Uncomment once all platform bridge packages are published and at least one tag exists
# lowest deps
- - php-version: '8.2'
- dependency-version: 'lowest'
+ # - php-version: '8.2'
+ # dependency-version: 'lowest'
# Symfony 7.4 LTS
- php-version: '8.2'
symfony-version: '7.4.*'
diff --git a/.github/workflows/validation.yaml b/.github/workflows/validation.yaml
index e181f1b42..df7e04a4f 100644
--- a/.github/workflows/validation.yaml
+++ b/.github/workflows/validation.yaml
@@ -48,3 +48,16 @@ jobs:
- name: Validate tool bridges are in splitsh.json
run: .github/scripts/validate-bridge-splitsh.sh tool agent
+
+ validate_platforms:
+ name: Platform Bridges
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+
+ - name: Validate platform bridge naming conventions
+ run: .github/scripts/validate-bridge-naming.sh platform platform
+
+ - name: Validate platform bridges are in splitsh.json
+ run: .github/scripts/validate-bridge-splitsh.sh platform
diff --git a/demo/composer.json b/demo/composer.json
index d2c657782..5e0f1701a 100644
--- a/demo/composer.json
+++ b/demo/composer.json
@@ -15,6 +15,8 @@
"symfony/ai-bundle": "@dev",
"symfony/ai-chroma-db-store": "@dev",
"symfony/ai-clock-tool": "@dev",
+ "symfony/ai-hugging-face-platform": "@dev",
+ "symfony/ai-open-ai-platform": "@dev",
"symfony/ai-similarity-search-tool": "@dev",
"symfony/ai-wikipedia-tool": "@dev",
"symfony/asset": "^8.0",
diff --git a/demo/config/reference.php b/demo/config/reference.php
index f01ecae4f..65c259f48 100644
--- a/demo/config/reference.php
+++ b/demo/config/reference.php
@@ -1,6 +1,13 @@
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
diff --git a/examples/composer.json b/examples/composer.json
index 55d75be91..d0705846c 100644
--- a/examples/composer.json
+++ b/examples/composer.json
@@ -19,43 +19,164 @@
{
"type": "path",
"url": "../src/store"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/AiMlApi"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Albert"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Anthropic"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Azure"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Bedrock"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Cartesia"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Cerebras"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Decart"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/DeepSeek"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/DockerModelRunner"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/ElevenLabs"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Gemini"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Generic"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/HuggingFace"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/LmStudio"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Meta"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Mistral"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Ollama"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/OpenAi"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/OpenRouter"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Perplexity"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Scaleway"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/TransformersPhp"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/VertexAi"
+ },
+ {
+ "type": "path",
+ "url": "../src/platform/src/Bridge/Voyage"
}
],
"require": {
"php": ">=8.2",
- "async-aws/bedrock-runtime": "^1.1",
- "codewithkyrian/transformers": "^0.6.2",
"doctrine/dbal": "^3.3|^4.0",
- "google/auth": "^1.47",
"symfony/ai-agent": "@dev",
+ "symfony/ai-ai-ml-api-platform": "@dev",
+ "symfony/ai-albert-platform": "@dev",
+ "symfony/ai-anthropic-platform": "@dev",
+ "symfony/ai-azure-platform": "@dev",
"symfony/ai-azure-search-store": "@dev",
+ "symfony/ai-bedrock-platform": "@dev",
"symfony/ai-brave-tool": "@dev",
"symfony/ai-cache-store": "@dev",
+ "symfony/ai-cartesia-platform": "@dev",
+ "symfony/ai-cerebras-platform": "@dev",
"symfony/ai-chat": "@dev",
"symfony/ai-chroma-db-store": "@dev",
"symfony/ai-click-house-store": "@dev",
"symfony/ai-clock-tool": "@dev",
"symfony/ai-cloudflare-store": "@dev",
+ "symfony/ai-decart-platform": "@dev",
+ "symfony/ai-deep-seek-platform": "@dev",
+ "symfony/ai-docker-model-runner-platform": "@dev",
+ "symfony/ai-eleven-labs-platform": "@dev",
+ "symfony/ai-gemini-platform": "@dev",
+ "symfony/ai-generic-platform": "@dev",
+ "symfony/ai-hugging-face-platform": "@dev",
+ "symfony/ai-lm-studio-platform": "@dev",
"symfony/ai-manticore-search-store": "@dev",
"symfony/ai-maria-db-store": "@dev",
"symfony/ai-meilisearch-store": "@dev",
+ "symfony/ai-meta-platform": "@dev",
"symfony/ai-milvus-store": "@dev",
+ "symfony/ai-mistral-platform": "@dev",
"symfony/ai-mongo-db-store": "@dev",
"symfony/ai-neo4j-store": "@dev",
+ "symfony/ai-ollama-platform": "@dev",
+ "symfony/ai-open-ai-platform": "@dev",
"symfony/ai-open-meteo-tool": "@dev",
+ "symfony/ai-open-router-platform": "@dev",
"symfony/ai-open-search-store": "@dev",
+ "symfony/ai-perplexity-platform": "@dev",
"symfony/ai-pinecone-store": "@dev",
- "symfony/ai-platform": "@dev",
"symfony/ai-postgres-store": "@dev",
"symfony/ai-qdrant-store": "@dev",
"symfony/ai-redis-store": "@dev",
+ "symfony/ai-scaleway-platform": "@dev",
"symfony/ai-scraper-tool": "@dev",
"symfony/ai-serp-api-tool": "@dev",
"symfony/ai-similarity-search-tool": "@dev",
"symfony/ai-supabase-store": "@dev",
"symfony/ai-surreal-db-store": "@dev",
"symfony/ai-tavily-tool": "@dev",
+ "symfony/ai-transformers-php-platform": "@dev",
"symfony/ai-typesense-store": "@dev",
+ "symfony/ai-vertex-ai-platform": "@dev",
+ "symfony/ai-voyage-platform": "@dev",
"symfony/ai-weaviate-store": "@dev",
"symfony/ai-wikipedia-tool": "@dev",
"symfony/ai-youtube-tool": "@dev",
diff --git a/splitsh.json b/splitsh.json
index 485d84dad..d7ec64d77 100644
--- a/splitsh.json
+++ b/splitsh.json
@@ -18,7 +18,35 @@
"ai-bundle": "src/ai-bundle",
"ai-chat": "src/chat",
"mcp-bundle": "src/mcp-bundle",
- "ai-platform": "src/platform",
+ "ai-platform": {
+ "prefixes": [{ "from": "src/platform", "to": "", "excludes": ["src/Bridge"] }]
+ },
+ "ai-ai-ml-api-platform": "src/platform/src/Bridge/AiMlApi",
+ "ai-albert-platform": "src/platform/src/Bridge/Albert",
+ "ai-anthropic-platform": "src/platform/src/Bridge/Anthropic",
+ "ai-azure-platform": "src/platform/src/Bridge/Azure",
+ "ai-bedrock-platform": "src/platform/src/Bridge/Bedrock",
+ "ai-cartesia-platform": "src/platform/src/Bridge/Cartesia",
+ "ai-cerebras-platform": "src/platform/src/Bridge/Cerebras",
+ "ai-decart-platform": "src/platform/src/Bridge/Decart",
+ "ai-deep-seek-platform": "src/platform/src/Bridge/DeepSeek",
+ "ai-docker-model-runner-platform": "src/platform/src/Bridge/DockerModelRunner",
+ "ai-eleven-labs-platform": "src/platform/src/Bridge/ElevenLabs",
+ "ai-gemini-platform": "src/platform/src/Bridge/Gemini",
+ "ai-generic-platform": "src/platform/src/Bridge/Generic",
+ "ai-hugging-face-platform": "src/platform/src/Bridge/HuggingFace",
+ "ai-lm-studio-platform": "src/platform/src/Bridge/LmStudio",
+ "ai-meta-platform": "src/platform/src/Bridge/Meta",
+ "ai-mistral-platform": "src/platform/src/Bridge/Mistral",
+ "ai-ollama-platform": "src/platform/src/Bridge/Ollama",
+ "ai-open-ai-platform": "src/platform/src/Bridge/OpenAi",
+ "ai-open-router-platform": "src/platform/src/Bridge/OpenRouter",
+ "ai-perplexity-platform": "src/platform/src/Bridge/Perplexity",
+ "ai-replicate-platform": "src/platform/src/Bridge/Replicate",
+ "ai-scaleway-platform": "src/platform/src/Bridge/Scaleway",
+ "ai-transformers-php-platform": "src/platform/src/Bridge/TransformersPhp",
+ "ai-vertex-ai-platform": "src/platform/src/Bridge/VertexAi",
+ "ai-voyage-platform": "src/platform/src/Bridge/Voyage",
"ai-store": {
"prefixes": [{ "from": "src/store", "to": "", "excludes": ["src/Bridge"] }]
},
diff --git a/src/ai-bundle/composer.json b/src/ai-bundle/composer.json
index ddfcba4a3..92cf925f8 100644
--- a/src/ai-bundle/composer.json
+++ b/src/ai-bundle/composer.json
@@ -57,10 +57,7 @@
}
},
"config": {
- "sort-packages": true,
- "allow-plugins": {
- "php-http/discovery": true
- }
+ "sort-packages": true
},
"extra": {
"branch-alias": {
diff --git a/src/ai-bundle/src/AiBundle.php b/src/ai-bundle/src/AiBundle.php
index f7d879523..c07095a07 100644
--- a/src/ai-bundle/src/AiBundle.php
+++ b/src/ai-bundle/src/AiBundle.php
@@ -331,6 +331,10 @@ public function loadExtension(array $config, ContainerConfigurator $container, C
private function processPlatformConfig(string $type, array $platform, ContainerBuilder $container): void
{
if ('albert' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-albert-platform', AlbertPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Albert platform configuration requires "symfony/ai-albert-platform" package. Try running "composer require symfony/ai-albert-platform".');
+ }
+
$platformId = 'ai.platform.albert';
$definition = (new Definition(Platform::class))
->setFactory(AlbertPlatformFactory::class.'::create')
@@ -351,6 +355,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('anthropic' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-anthropic-platform', AnthropicPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Anthropic platform configuration requires "symfony/ai-anthropic-platform" package. Try running "composer require symfony/ai-anthropic-platform".');
+ }
+
$platformId = 'ai.platform.anthropic';
$definition = (new Definition(Platform::class))
->setFactory(AnthropicPlatformFactory::class.'::create')
@@ -371,6 +379,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('azure' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-azure-platform', AzureOpenAiPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Azure platform configuration requires "symfony/ai-azure-platform" package. Try running "composer require symfony/ai-azure-platform".');
+ }
+
foreach ($platform as $name => $config) {
$platformId = 'ai.platform.azure.'.$name;
$definition = (new Definition(Platform::class))
@@ -414,6 +426,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('cartesia' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-cartesia-platform', CartesiaPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Cartesia platform configuration requires "symfony/ai-cartesia-platform" package. Try running "composer require symfony/ai-cartesia-platform".');
+ }
+
$definition = (new Definition(Platform::class))
->setFactory(CartesiaPlatformFactory::class.'::create')
->setLazy(true)
@@ -455,6 +471,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('elevenlabs' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-eleven-labs-platform', ElevenLabsPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('ElevenLabs platform configuration requires "symfony/ai-eleven-labs-platform" package. Try running "composer require symfony/ai-eleven-labs-platform".');
+ }
+
if (\array_key_exists('api_catalog', $platform) && $platform['api_catalog']) {
$catalogDefinition = (new Definition(ElevenLabsApiCatalog::class))
->setLazy(true)
@@ -489,6 +509,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('gemini' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-gemini-platform', GeminiPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Gemini platform configuration requires "symfony/ai-gemini-platform" package. Try running "composer require symfony/ai-gemini-platform".');
+ }
+
$platformId = 'ai.platform.gemini';
$definition = (new Definition(Platform::class))
->setFactory(GeminiPlatformFactory::class.'::create')
@@ -509,6 +533,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('generic' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-generic-platform', GenericPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Generic platform configuration requires "symfony/ai-generic-platform" package. Try running "composer require symfony/ai-generic-platform".');
+ }
+
foreach ($platform as $name => $config) {
$platformId = 'ai.platform.generic.'.$name;
$definition = (new Definition(Platform::class))
@@ -536,6 +564,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('huggingface' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-hugging-face-platform', HuggingFacePlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('HuggingFace platform configuration requires "symfony/ai-hugging-face-platform" package. Try running "composer require symfony/ai-hugging-face-platform".');
+ }
+
$platformId = 'ai.platform.huggingface';
$definition = (new Definition(Platform::class))
->setFactory(HuggingFacePlatformFactory::class.'::create')
@@ -557,6 +589,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('vertexai' === $type && isset($platform['location'], $platform['project_id'])) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-vertex-ai-platform', VertexAiPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('VertexAI platform configuration requires "symfony/ai-vertex-ai-platform" package. Try running "composer require symfony/ai-vertex-ai-platform".');
+ }
+
if (!class_exists(ApplicationDefaultCredentials::class)) {
throw new RuntimeException('For using the Vertex AI platform, google/auth package is required. Try running "composer require google/auth".');
}
@@ -598,6 +634,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('openai' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-open-ai-platform', OpenAiPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('OpenAI platform configuration requires "symfony/ai-open-ai-platform" package. Try running "composer require symfony/ai-open-ai-platform".');
+ }
+
$platformId = 'ai.platform.openai';
$definition = (new Definition(Platform::class))
->setFactory(OpenAiPlatformFactory::class.'::create')
@@ -619,6 +659,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('openrouter' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-open-router-platform', OpenRouterPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('OpenRouter platform configuration requires "symfony/ai-open-router-platform" package. Try running "composer require symfony/ai-open-router-platform".');
+ }
+
$platformId = 'ai.platform.openrouter';
$definition = (new Definition(Platform::class))
->setFactory(OpenRouterPlatformFactory::class.'::create')
@@ -639,6 +683,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('mistral' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-mistral-platform', MistralPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Mistral platform configuration requires "symfony/ai-mistral-platform" package. Try running "composer require symfony/ai-mistral-platform".');
+ }
+
$platformId = 'ai.platform.mistral';
$definition = (new Definition(Platform::class))
->setFactory(MistralPlatformFactory::class.'::create')
@@ -659,6 +707,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('lmstudio' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-lm-studio-platform', LmStudioPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('LmStudio platform configuration requires "symfony/ai-lm-studio-platform" package. Try running "composer require symfony/ai-lm-studio-platform".');
+ }
+
$platformId = 'ai.platform.lmstudio';
$definition = (new Definition(Platform::class))
->setFactory(LmStudioPlatformFactory::class.'::create')
@@ -679,6 +731,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('ollama' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-ollama-platform', OllamaPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Ollama platform configuration requires "symfony/ai-ollama-platform" package. Try running "composer require symfony/ai-ollama-platform".');
+ }
+
if (\array_key_exists('api_catalog', $platform)) {
$catalogDefinition = (new Definition(OllamaApiCatalog::class))
->setLazy(true)
@@ -711,6 +767,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('cerebras' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-cerebras-platform', CerebrasPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Cerebras platform configuration requires "symfony/ai-cerebras-platform" package. Try running "composer require symfony/ai-cerebras-platform".');
+ }
+
$platformId = 'ai.platform.cerebras';
$definition = (new Definition(Platform::class))
->setFactory(CerebrasPlatformFactory::class.'::create')
@@ -731,6 +791,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('deepseek' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-deep-seek-platform', DeepSeekPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('DeepSeek platform configuration requires "symfony/ai-deep-seek-platform" package. Try running "composer require symfony/ai-deep-seek-platform".');
+ }
+
$platformId = 'ai.platform.deepseek';
$definition = (new Definition(Platform::class))
->setFactory(DeepSeekPlatformFactory::class.'::create')
@@ -751,6 +815,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('voyage' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-voyage-platform', VoyagePlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Voyage platform configuration requires "symfony/ai-voyage-platform" package. Try running "composer require symfony/ai-voyage-platform".');
+ }
+
$platformId = 'ai.platform.voyage';
$definition = (new Definition(Platform::class))
->setFactory(VoyagePlatformFactory::class.'::create')
@@ -771,6 +839,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('perplexity' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-perplexity-platform', PerplexityPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Perplexity platform configuration requires "symfony/ai-perplexity-platform" package. Try running "composer require symfony/ai-perplexity-platform".');
+ }
+
$platformId = 'ai.platform.perplexity';
$definition = (new Definition(Platform::class))
->setFactory(PerplexityPlatformFactory::class.'::create')
@@ -791,6 +863,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('dockermodelrunner' === $type) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-docker-model-runner-platform', DockerModelRunnerPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Docker Model Runner platform configuration requires "symfony/ai-docker-model-runner-platform" package. Try running "composer require symfony/ai-docker-model-runner-platform".');
+ }
+
$platformId = 'ai.platform.dockermodelrunner';
$definition = (new Definition(Platform::class))
->setFactory(DockerModelRunnerPlatformFactory::class.'::create')
@@ -811,6 +887,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
}
if ('scaleway' === $type && isset($platform['api_key'])) {
+ if (!ContainerBuilder::willBeAvailable('symfony/ai-scaleway-platform', ScalewayPlatformFactory::class, ['symfony/ai-bundle'])) {
+ throw new RuntimeException('Scaleway platform configuration requires "symfony/ai-scaleway-platform" package. Try running "composer require symfony/ai-scaleway-platform".');
+ }
+
$platformId = 'ai.platform.scaleway';
$definition = (new Definition(Platform::class))
->setFactory(ScalewayPlatformFactory::class.'::create')
diff --git a/src/platform/README.md b/src/platform/README.md
index bf45c979e..5e988a714 100644
--- a/src/platform/README.md
+++ b/src/platform/README.md
@@ -13,6 +13,39 @@ are not covered by Symfony's
composer require symfony/ai-platform
```
+## Platform Bridges
+
+To use a specific AI platform, install the corresponding bridge package:
+
+| Platform | Package |
+|----------|---------|
+| AI.ML API | `symfony/ai-ai-ml-api-platform` |
+| Albert | `symfony/ai-albert-platform` |
+| Anthropic | `symfony/ai-anthropic-platform` |
+| Azure OpenAI | `symfony/ai-azure-platform` |
+| AWS Bedrock | `symfony/ai-bedrock-platform` |
+| Cartesia | `symfony/ai-cartesia-platform` |
+| Cerebras | `symfony/ai-cerebras-platform` |
+| Decart | `symfony/ai-decart-platform` |
+| DeepSeek | `symfony/ai-deep-seek-platform` |
+| Docker Model Runner | `symfony/ai-docker-model-runner-platform` |
+| ElevenLabs | `symfony/ai-eleven-labs-platform` |
+| Generic | `symfony/ai-generic-platform` |
+| Google Gemini | `symfony/ai-gemini-platform` |
+| Hugging Face | `symfony/ai-hugging-face-platform` |
+| LM Studio | `symfony/ai-lm-studio-platform` |
+| Meta Llama | `symfony/ai-meta-platform` |
+| Mistral | `symfony/ai-mistral-platform` |
+| Ollama | `symfony/ai-ollama-platform` |
+| OpenAI | `symfony/ai-open-ai-platform` |
+| OpenRouter | `symfony/ai-open-router-platform` |
+| Perplexity | `symfony/ai-perplexity-platform` |
+| Replicate | `symfony/ai-replicate-platform` |
+| Scaleway | `symfony/ai-scaleway-platform` |
+| TransformersPHP | `symfony/ai-transformers-php-platform` |
+| Google Vertex AI | `symfony/ai-vertex-ai-platform` |
+| Voyage | `symfony/ai-voyage-platform` |
+
**This repository is a READ-ONLY sub-tree split**. See
https://github.com/symfony/ai to create issues or submit pull requests.
diff --git a/src/platform/composer.json b/src/platform/composer.json
index 18b7450f1..8440377bb 100644
--- a/src/platform/composer.json
+++ b/src/platform/composer.json
@@ -1,5 +1,33 @@
{
"name": "symfony/ai-platform",
+ "repositories": [
+ { "type": "path", "url": "src/Bridge/AiMlApi" },
+ { "type": "path", "url": "src/Bridge/Albert" },
+ { "type": "path", "url": "src/Bridge/Anthropic" },
+ { "type": "path", "url": "src/Bridge/Azure" },
+ { "type": "path", "url": "src/Bridge/Bedrock" },
+ { "type": "path", "url": "src/Bridge/Cartesia" },
+ { "type": "path", "url": "src/Bridge/Cerebras" },
+ { "type": "path", "url": "src/Bridge/Decart" },
+ { "type": "path", "url": "src/Bridge/DeepSeek" },
+ { "type": "path", "url": "src/Bridge/DockerModelRunner" },
+ { "type": "path", "url": "src/Bridge/ElevenLabs" },
+ { "type": "path", "url": "src/Bridge/Gemini" },
+ { "type": "path", "url": "src/Bridge/Generic" },
+ { "type": "path", "url": "src/Bridge/HuggingFace" },
+ { "type": "path", "url": "src/Bridge/LmStudio" },
+ { "type": "path", "url": "src/Bridge/Meta" },
+ { "type": "path", "url": "src/Bridge/Mistral" },
+ { "type": "path", "url": "src/Bridge/Ollama" },
+ { "type": "path", "url": "src/Bridge/OpenAi" },
+ { "type": "path", "url": "src/Bridge/OpenRouter" },
+ { "type": "path", "url": "src/Bridge/Perplexity" },
+ { "type": "path", "url": "src/Bridge/Replicate" },
+ { "type": "path", "url": "src/Bridge/Scaleway" },
+ { "type": "path", "url": "src/Bridge/TransformersPhp" },
+ { "type": "path", "url": "src/Bridge/VertexAi" },
+ { "type": "path", "url": "src/Bridge/Voyage" }
+ ],
"description": "PHP library for interacting with AI platform provider.",
"license": "MIT",
"type": "library",
@@ -54,7 +82,6 @@
"psr/log": "^3.0",
"symfony/clock": "^7.3|^8.0",
"symfony/event-dispatcher": "^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",
diff --git a/src/platform/src/Bridge/AiMlApi/.gitattributes b/src/platform/src/Bridge/AiMlApi/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/AiMlApi/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/AiMlApi/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/AiMlApi/.github/close-pull-request.yml b/src/platform/src/Bridge/AiMlApi/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/AiMlApi/.gitignore b/src/platform/src/Bridge/AiMlApi/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/AiMlApi/CHANGELOG.md b/src/platform/src/Bridge/AiMlApi/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/AiMlApi/LICENSE b/src/platform/src/Bridge/AiMlApi/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/AiMlApi/README.md b/src/platform/src/Bridge/AiMlApi/README.md
new file mode 100644
index 000000000..9414a2390
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/README.md
@@ -0,0 +1,12 @@
+AiMlApi Platform
+================
+
+AiML API platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/AiMlApi/ModelCatalogTest.php b/src/platform/src/Bridge/AiMlApi/Tests/ModelCatalogTest.php
similarity index 99%
rename from src/platform/tests/Bridge/AiMlApi/ModelCatalogTest.php
rename to src/platform/src/Bridge/AiMlApi/Tests/ModelCatalogTest.php
index f4ab7af30..5b2fbab8a 100644
--- a/src/platform/tests/Bridge/AiMlApi/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/AiMlApi/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\AiMlApi;
+namespace Symfony\AI\Platform\Bridge\AiMlApi\Tests;
use Symfony\AI\Platform\Bridge\AiMlApi\ModelCatalog;
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
diff --git a/src/platform/src/Bridge/AiMlApi/composer.json b/src/platform/src/Bridge/AiMlApi/composer.json
new file mode 100644
index 000000000..564c857b4
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-ai-ml-api-platform",
+ "description": "AiML API platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "aimlapi",
+ "bridge",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-generic-platform": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\AiMlApi\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\AiMlApi\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/AiMlApi/phpunit.xml.dist b/src/platform/src/Bridge/AiMlApi/phpunit.xml.dist
new file mode 100644
index 000000000..4d3567c2b
--- /dev/null
+++ b/src/platform/src/Bridge/AiMlApi/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Albert/.gitattributes b/src/platform/src/Bridge/Albert/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Albert/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Albert/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Albert/.github/close-pull-request.yml b/src/platform/src/Bridge/Albert/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Albert/.gitignore b/src/platform/src/Bridge/Albert/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Albert/CHANGELOG.md b/src/platform/src/Bridge/Albert/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Albert/LICENSE b/src/platform/src/Bridge/Albert/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Albert/README.md b/src/platform/src/Bridge/Albert/README.md
new file mode 100644
index 000000000..b997a4fc2
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/README.md
@@ -0,0 +1,12 @@
+Albert Platform
+===============
+
+Albert platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Albert/ModelCatalogTest.php b/src/platform/src/Bridge/Albert/Tests/ModelCatalogTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Albert/ModelCatalogTest.php
rename to src/platform/src/Bridge/Albert/Tests/ModelCatalogTest.php
index 6aafba68e..6e3a3e8fc 100644
--- a/src/platform/tests/Bridge/Albert/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Albert/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Albert;
+namespace Symfony\AI\Platform\Bridge\Albert\Tests;
use Symfony\AI\Platform\Bridge\Albert\ModelCatalog;
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
diff --git a/src/platform/tests/Bridge/Albert/PlatformFactoryTest.php b/src/platform/src/Bridge/Albert/Tests/PlatformFactoryTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Albert/PlatformFactoryTest.php
rename to src/platform/src/Bridge/Albert/Tests/PlatformFactoryTest.php
index d8c02c9b0..c59c3fc11 100644
--- a/src/platform/tests/Bridge/Albert/PlatformFactoryTest.php
+++ b/src/platform/src/Bridge/Albert/Tests/PlatformFactoryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Albert;
+namespace Symfony\AI\Platform\Bridge\Albert\Tests;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/src/Bridge/Albert/composer.json b/src/platform/src/Bridge/Albert/composer.json
new file mode 100644
index 000000000..6675c69d0
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-albert-platform",
+ "description": "Albert platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "albert",
+ "bridge",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-generic-platform": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Albert\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Albert\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Albert/phpunit.xml.dist b/src/platform/src/Bridge/Albert/phpunit.xml.dist
new file mode 100644
index 000000000..d72d34d32
--- /dev/null
+++ b/src/platform/src/Bridge/Albert/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Anthropic/.gitattributes b/src/platform/src/Bridge/Anthropic/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Anthropic/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Anthropic/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Anthropic/.github/close-pull-request.yml b/src/platform/src/Bridge/Anthropic/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Anthropic/.gitignore b/src/platform/src/Bridge/Anthropic/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Anthropic/CHANGELOG.md b/src/platform/src/Bridge/Anthropic/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Anthropic/LICENSE b/src/platform/src/Bridge/Anthropic/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Anthropic/README.md b/src/platform/src/Bridge/Anthropic/README.md
new file mode 100644
index 000000000..88475b758
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/README.md
@@ -0,0 +1,12 @@
+Anthropic Platform
+==================
+
+Anthropic (Claude) platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Anthropic/ClaudeTest.php b/src/platform/src/Bridge/Anthropic/Tests/ClaudeTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Anthropic/ClaudeTest.php
rename to src/platform/src/Bridge/Anthropic/Tests/ClaudeTest.php
index a0b69bcbc..ced7d786b 100644
--- a/src/platform/tests/Bridge/Anthropic/ClaudeTest.php
+++ b/src/platform/src/Bridge/Anthropic/Tests/ClaudeTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Anthropic;
+namespace Symfony\AI\Platform\Bridge\Anthropic\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Anthropic\Claude;
diff --git a/src/platform/tests/Bridge/Anthropic/Contract/AssistantMessageNormalizerTest.php b/src/platform/src/Bridge/Anthropic/Tests/Contract/AssistantMessageNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Anthropic/Contract/AssistantMessageNormalizerTest.php
rename to src/platform/src/Bridge/Anthropic/Tests/Contract/AssistantMessageNormalizerTest.php
index a523652fb..031b5b2b0 100644
--- a/src/platform/tests/Bridge/Anthropic/Contract/AssistantMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/Anthropic/Tests/Contract/AssistantMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Anthropic\Contract;
+namespace Symfony\AI\Platform\Bridge\Anthropic\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Anthropic/ModelCatalogTest.php b/src/platform/src/Bridge/Anthropic/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Anthropic/ModelCatalogTest.php
rename to src/platform/src/Bridge/Anthropic/Tests/ModelCatalogTest.php
index 1845f166a..a80710fa9 100644
--- a/src/platform/tests/Bridge/Anthropic/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Anthropic/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Anthropic;
+namespace Symfony\AI\Platform\Bridge\Anthropic\Tests;
use Symfony\AI\Platform\Bridge\Anthropic\Claude;
use Symfony\AI\Platform\Bridge\Anthropic\ModelCatalog;
diff --git a/src/platform/tests/Bridge/Anthropic/ModelClientTest.php b/src/platform/src/Bridge/Anthropic/Tests/ModelClientTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Anthropic/ModelClientTest.php
rename to src/platform/src/Bridge/Anthropic/Tests/ModelClientTest.php
index d15870b5c..b924e4f31 100644
--- a/src/platform/tests/Bridge/Anthropic/ModelClientTest.php
+++ b/src/platform/src/Bridge/Anthropic/Tests/ModelClientTest.php
@@ -97,6 +97,11 @@ public function testAnthropicBetaHeaderIsNotSetWhenBetaFeaturesIsNotProvided()
$this->modelClient->request($this->model, ['message' => 'test'], $options);
}
+ /**
+ * @param list $headers
+ *
+ * @return array
+ */
private function parseHeaders(array $headers): array
{
$parsed = [];
diff --git a/src/platform/tests/Bridge/Anthropic/ResultConverterRateLimitTest.php b/src/platform/src/Bridge/Anthropic/Tests/ResultConverterRateLimitTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Anthropic/ResultConverterRateLimitTest.php
rename to src/platform/src/Bridge/Anthropic/Tests/ResultConverterRateLimitTest.php
index e88873cd6..6f96e2fea 100644
--- a/src/platform/tests/Bridge/Anthropic/ResultConverterRateLimitTest.php
+++ b/src/platform/src/Bridge/Anthropic/Tests/ResultConverterRateLimitTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Anthropic;
+namespace Symfony\AI\Platform\Bridge\Anthropic\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Anthropic\ResultConverter;
diff --git a/src/platform/tests/Bridge/Anthropic/ResultConverterTest.php b/src/platform/src/Bridge/Anthropic/Tests/ResultConverterTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Anthropic/ResultConverterTest.php
rename to src/platform/src/Bridge/Anthropic/Tests/ResultConverterTest.php
index d64be5e8a..abd723be5 100644
--- a/src/platform/tests/Bridge/Anthropic/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Anthropic/Tests/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Anthropic;
+namespace Symfony\AI\Platform\Bridge\Anthropic\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Anthropic\ResultConverter;
diff --git a/src/platform/tests/Bridge/Anthropic/TokenOutputProcessorTest.php b/src/platform/src/Bridge/Anthropic/Tests/TokenOutputProcessorTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Anthropic/TokenOutputProcessorTest.php
rename to src/platform/src/Bridge/Anthropic/Tests/TokenOutputProcessorTest.php
index 45664b7ae..df58fff8f 100644
--- a/src/platform/tests/Bridge/Anthropic/TokenOutputProcessorTest.php
+++ b/src/platform/src/Bridge/Anthropic/Tests/TokenOutputProcessorTest.php
@@ -131,6 +131,9 @@ public function testItHandlesMissingUsageFields()
$this->assertNull($tokenUsage->getTotalTokens());
}
+ /**
+ * @param array $data
+ */
private function createRawResult(array $data = []): RawHttpResult
{
$rawResponse = $this->createStub(ResponseInterface::class);
diff --git a/src/platform/src/Bridge/Anthropic/composer.json b/src/platform/src/Bridge/Anthropic/composer.json
new file mode 100644
index 000000000..f20777c6b
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/composer.json
@@ -0,0 +1,59 @@
+{
+ "name": "symfony/ai-anthropic-platform",
+ "description": "Anthropic (Claude) platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "anthropic",
+ "bridge",
+ "claude",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-agent": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Anthropic\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Anthropic\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Anthropic/phpunit.xml.dist b/src/platform/src/Bridge/Anthropic/phpunit.xml.dist
new file mode 100644
index 000000000..29adc6b47
--- /dev/null
+++ b/src/platform/src/Bridge/Anthropic/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Azure/.gitattributes b/src/platform/src/Bridge/Azure/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Azure/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Azure/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Azure/.github/close-pull-request.yml b/src/platform/src/Bridge/Azure/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Azure/.gitignore b/src/platform/src/Bridge/Azure/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Azure/CHANGELOG.md b/src/platform/src/Bridge/Azure/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Azure/LICENSE b/src/platform/src/Bridge/Azure/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Azure/README.md b/src/platform/src/Bridge/Azure/README.md
new file mode 100644
index 000000000..a2294b689
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/README.md
@@ -0,0 +1,12 @@
+Azure Platform
+==============
+
+Azure AI platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Azure/OpenAi/CompletionsModelClientTest.php b/src/platform/src/Bridge/Azure/Tests/OpenAi/CompletionsModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Azure/OpenAi/CompletionsModelClientTest.php
rename to src/platform/src/Bridge/Azure/Tests/OpenAi/CompletionsModelClientTest.php
index 935abec3b..e3f8dc680 100644
--- a/src/platform/tests/Bridge/Azure/OpenAi/CompletionsModelClientTest.php
+++ b/src/platform/src/Bridge/Azure/Tests/OpenAi/CompletionsModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Azure\OpenAi;
+namespace Symfony\AI\Platform\Bridge\Azure\Tests\OpenAi;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Azure/OpenAi/EmbeddingsModelClientTest.php b/src/platform/src/Bridge/Azure/Tests/OpenAi/EmbeddingsModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Azure/OpenAi/EmbeddingsModelClientTest.php
rename to src/platform/src/Bridge/Azure/Tests/OpenAi/EmbeddingsModelClientTest.php
index 1b46e0f4a..37a9ed8fb 100644
--- a/src/platform/tests/Bridge/Azure/OpenAi/EmbeddingsModelClientTest.php
+++ b/src/platform/src/Bridge/Azure/Tests/OpenAi/EmbeddingsModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Azure\OpenAi;
+namespace Symfony\AI\Platform\Bridge\Azure\Tests\OpenAi;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Azure/OpenAi/WhisperModelClientTest.php b/src/platform/src/Bridge/Azure/Tests/OpenAi/WhisperModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Azure/OpenAi/WhisperModelClientTest.php
rename to src/platform/src/Bridge/Azure/Tests/OpenAi/WhisperModelClientTest.php
index 40084b314..86179dbb3 100644
--- a/src/platform/tests/Bridge/Azure/OpenAi/WhisperModelClientTest.php
+++ b/src/platform/src/Bridge/Azure/Tests/OpenAi/WhisperModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Azure\OpenAi;
+namespace Symfony\AI\Platform\Bridge\Azure\Tests\OpenAi;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/src/Bridge/Azure/composer.json b/src/platform/src/Bridge/Azure/composer.json
new file mode 100644
index 000000000..de1b4c1ef
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/composer.json
@@ -0,0 +1,61 @@
+{
+ "name": "symfony/ai-azure-platform",
+ "description": "Azure AI platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "azure",
+ "azure-openai",
+ "bridge",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-generic-platform": "@dev",
+ "symfony/ai-meta-platform": "@dev",
+ "symfony/ai-open-ai-platform": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Azure\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Azure\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Azure/phpunit.xml.dist b/src/platform/src/Bridge/Azure/phpunit.xml.dist
new file mode 100644
index 000000000..98b04e966
--- /dev/null
+++ b/src/platform/src/Bridge/Azure/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Bedrock/.gitattributes b/src/platform/src/Bridge/Bedrock/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Bedrock/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Bedrock/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Bedrock/.github/close-pull-request.yml b/src/platform/src/Bridge/Bedrock/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Bedrock/.gitignore b/src/platform/src/Bridge/Bedrock/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Bedrock/CHANGELOG.md b/src/platform/src/Bridge/Bedrock/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Bedrock/LICENSE b/src/platform/src/Bridge/Bedrock/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Bedrock/README.md b/src/platform/src/Bridge/Bedrock/README.md
new file mode 100644
index 000000000..ed76288eb
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/README.md
@@ -0,0 +1,12 @@
+Bedrock Platform
+================
+
+AWS Bedrock platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Bedrock/Anthropic/ClaudeResultConverterTest.php b/src/platform/src/Bridge/Bedrock/Tests/Anthropic/ClaudeResultConverterTest.php
similarity index 99%
rename from src/platform/tests/Bridge/Bedrock/Anthropic/ClaudeResultConverterTest.php
rename to src/platform/src/Bridge/Bedrock/Tests/Anthropic/ClaudeResultConverterTest.php
index fd26e0b16..5c5c1536e 100644
--- a/src/platform/tests/Bridge/Bedrock/Anthropic/ClaudeResultConverterTest.php
+++ b/src/platform/src/Bridge/Bedrock/Tests/Anthropic/ClaudeResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Bedrock\Anthropic;
+namespace Symfony\AI\Platform\Bridge\Bedrock\Tests\Anthropic;
use AsyncAws\BedrockRuntime\Result\InvokeModelResponse;
use AsyncAws\Core\Test\ResultMockFactory;
diff --git a/src/platform/tests/Bridge/Bedrock/Meta/LlamaResultConverterTest.php b/src/platform/src/Bridge/Bedrock/Tests/Meta/LlamaResultConverterTest.php
similarity index 99%
rename from src/platform/tests/Bridge/Bedrock/Meta/LlamaResultConverterTest.php
rename to src/platform/src/Bridge/Bedrock/Tests/Meta/LlamaResultConverterTest.php
index 97c392da8..9964ce30d 100644
--- a/src/platform/tests/Bridge/Bedrock/Meta/LlamaResultConverterTest.php
+++ b/src/platform/src/Bridge/Bedrock/Tests/Meta/LlamaResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Bedrock\Meta;
+namespace Symfony\AI\Platform\Bridge\Bedrock\Tests\Meta;
use AsyncAws\BedrockRuntime\Result\InvokeModelResponse;
use AsyncAws\Core\Test\ResultMockFactory;
diff --git a/src/platform/tests/Bridge/Bedrock/ModelCatalogTest.php b/src/platform/src/Bridge/Bedrock/Tests/ModelCatalogTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Bedrock/ModelCatalogTest.php
rename to src/platform/src/Bridge/Bedrock/Tests/ModelCatalogTest.php
index afaf68ad2..ada8f6e33 100644
--- a/src/platform/tests/Bridge/Bedrock/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Bedrock/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Bedrock;
+namespace Symfony\AI\Platform\Bridge\Bedrock\Tests;
use Symfony\AI\Platform\Bridge\Anthropic\Claude;
use Symfony\AI\Platform\Bridge\Bedrock\ModelCatalog;
diff --git a/src/platform/tests/Bridge/Bedrock/Nova/ContractTest.php b/src/platform/src/Bridge/Bedrock/Tests/Nova/ContractTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Bedrock/Nova/ContractTest.php
rename to src/platform/src/Bridge/Bedrock/Tests/Nova/ContractTest.php
index 505fa3483..33a285fe3 100644
--- a/src/platform/tests/Bridge/Bedrock/Nova/ContractTest.php
+++ b/src/platform/src/Bridge/Bedrock/Tests/Nova/ContractTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Bedrock\Nova;
+namespace Symfony\AI\Platform\Bridge\Bedrock\Tests\Nova;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Bedrock/Nova/NovaResultConverterTest.php b/src/platform/src/Bridge/Bedrock/Tests/Nova/NovaResultConverterTest.php
similarity index 99%
rename from src/platform/tests/Bridge/Bedrock/Nova/NovaResultConverterTest.php
rename to src/platform/src/Bridge/Bedrock/Tests/Nova/NovaResultConverterTest.php
index 34e8900cf..897c6dc86 100644
--- a/src/platform/tests/Bridge/Bedrock/Nova/NovaResultConverterTest.php
+++ b/src/platform/src/Bridge/Bedrock/Tests/Nova/NovaResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Bedrock\Nova;
+namespace Symfony\AI\Platform\Bridge\Bedrock\Tests\Nova;
use AsyncAws\BedrockRuntime\Result\InvokeModelResponse;
use AsyncAws\Core\Test\ResultMockFactory;
diff --git a/src/platform/src/Bridge/Bedrock/composer.json b/src/platform/src/Bridge/Bedrock/composer.json
new file mode 100644
index 000000000..f45dfec5a
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/composer.json
@@ -0,0 +1,54 @@
+{
+ "name": "symfony/ai-bedrock-platform",
+ "description": "AWS Bedrock platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": ["ai", "aws", "bedrock", "bridge", "platform"],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "async-aws/bedrock-runtime": "^0.1|^1.0",
+ "php": ">=8.2",
+ "symfony/ai-anthropic-platform": "@dev",
+ "symfony/ai-meta-platform": "@dev",
+ "symfony/ai-platform": "@dev"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Bedrock\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Bedrock\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Bedrock/phpunit.xml.dist b/src/platform/src/Bridge/Bedrock/phpunit.xml.dist
new file mode 100644
index 000000000..aa1ee79e7
--- /dev/null
+++ b/src/platform/src/Bridge/Bedrock/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Cartesia/.gitattributes b/src/platform/src/Bridge/Cartesia/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Cartesia/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Cartesia/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Cartesia/.github/close-pull-request.yml b/src/platform/src/Bridge/Cartesia/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Cartesia/.gitignore b/src/platform/src/Bridge/Cartesia/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Cartesia/CHANGELOG.md b/src/platform/src/Bridge/Cartesia/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Cartesia/LICENSE b/src/platform/src/Bridge/Cartesia/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Cartesia/README.md b/src/platform/src/Bridge/Cartesia/README.md
new file mode 100644
index 000000000..9c9d3fcf4
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/README.md
@@ -0,0 +1,12 @@
+Cartesia Platform
+=================
+
+Cartesia platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Cartesia/CartesiaClientTest.php b/src/platform/src/Bridge/Cartesia/Tests/CartesiaClientTest.php
similarity index 95%
rename from src/platform/tests/Bridge/Cartesia/CartesiaClientTest.php
rename to src/platform/src/Bridge/Cartesia/Tests/CartesiaClientTest.php
index 6ae2e3045..271022a61 100644
--- a/src/platform/tests/Bridge/Cartesia/CartesiaClientTest.php
+++ b/src/platform/src/Bridge/Cartesia/Tests/CartesiaClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Cartesia;
+namespace Symfony\AI\Platform\Bridge\Cartesia\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Cartesia\Cartesia;
@@ -87,7 +87,7 @@ public function testClientCannotPerformTextToSpeechOnInvalidResponse()
public function testClientCanPerformTextToSpeech()
{
- $payload = Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
+ $payload = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
$httpClient = new MockHttpClient([
new MockResponse($payload->asBinary()),
@@ -115,7 +115,7 @@ public function testClientCanPerformTextToSpeech()
public function testClientCannotPerformSpeechToTextOnInvalidResponse()
{
- $payload = Audio::fromFile(\dirname(__DIR__, 2).'/Fixtures/audio.mp3');
+ $payload = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
$normalizer = new AudioNormalizer();
@@ -141,7 +141,7 @@ public function testClientCannotPerformSpeechToTextOnInvalidResponse()
public function testClientCanPerformSpeechToText()
{
- $payload = Audio::fromFile(\dirname(__DIR__, 2).'/Fixtures/audio.mp3');
+ $payload = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
$normalizer = new AudioNormalizer();
diff --git a/src/platform/tests/Bridge/Cartesia/CartesiaResultConverterTest.php b/src/platform/src/Bridge/Cartesia/Tests/CartesiaResultConverterTest.php
similarity index 94%
rename from src/platform/tests/Bridge/Cartesia/CartesiaResultConverterTest.php
rename to src/platform/src/Bridge/Cartesia/Tests/CartesiaResultConverterTest.php
index c1ea9917d..da051c9dd 100644
--- a/src/platform/tests/Bridge/Cartesia/CartesiaResultConverterTest.php
+++ b/src/platform/src/Bridge/Cartesia/Tests/CartesiaResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Cartesia;
+namespace Symfony\AI\Platform\Bridge\Cartesia\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Cartesia\Cartesia;
@@ -58,7 +58,7 @@ public function getInfo(): string
public function getContent(): string
{
- return file_get_contents(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
+ return file_get_contents(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
}
});
diff --git a/src/platform/tests/Bridge/Cartesia/Contract/CartesiaContractTest.php b/src/platform/src/Bridge/Cartesia/Tests/Contract/CartesiaContractTest.php
similarity index 88%
rename from src/platform/tests/Bridge/Cartesia/Contract/CartesiaContractTest.php
rename to src/platform/src/Bridge/Cartesia/Tests/Contract/CartesiaContractTest.php
index ce691da92..8e8d09615 100644
--- a/src/platform/tests/Bridge/Cartesia/Contract/CartesiaContractTest.php
+++ b/src/platform/src/Bridge/Cartesia/Tests/Contract/CartesiaContractTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Cartesia\Contract;
+namespace Symfony\AI\Platform\Bridge\Cartesia\Tests\Contract;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Cartesia\Cartesia;
@@ -20,7 +20,7 @@ final class CartesiaContractTest extends TestCase
{
public function testItCanCreatePayloadWithAudio()
{
- $audio = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
+ $audio = Audio::fromFile(\dirname(__DIR__, 7).'/fixtures/audio.mp3');
$contract = CartesiaContract::create();
diff --git a/src/platform/tests/Bridge/Cartesia/ModelCatalogTest.php b/src/platform/src/Bridge/Cartesia/Tests/ModelCatalogTest.php
similarity index 94%
rename from src/platform/tests/Bridge/Cartesia/ModelCatalogTest.php
rename to src/platform/src/Bridge/Cartesia/Tests/ModelCatalogTest.php
index 80930d525..cc81c1b92 100644
--- a/src/platform/tests/Bridge/Cartesia/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Cartesia/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Cartesia;
+namespace Symfony\AI\Platform\Bridge\Cartesia\Tests;
use Symfony\AI\Platform\Bridge\Cartesia\Cartesia;
use Symfony\AI\Platform\Bridge\Cartesia\ModelCatalog;
diff --git a/src/platform/src/Bridge/Cartesia/composer.json b/src/platform/src/Bridge/Cartesia/composer.json
new file mode 100644
index 000000000..b5f3cea0e
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-cartesia-platform",
+ "description": "Cartesia platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "cartesia",
+ "platform",
+ "voice"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Cartesia\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Cartesia\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Cartesia/phpunit.xml.dist b/src/platform/src/Bridge/Cartesia/phpunit.xml.dist
new file mode 100644
index 000000000..619cf3d75
--- /dev/null
+++ b/src/platform/src/Bridge/Cartesia/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Cerebras/.gitattributes b/src/platform/src/Bridge/Cerebras/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Cerebras/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Cerebras/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Cerebras/.github/close-pull-request.yml b/src/platform/src/Bridge/Cerebras/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Cerebras/.gitignore b/src/platform/src/Bridge/Cerebras/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Cerebras/CHANGELOG.md b/src/platform/src/Bridge/Cerebras/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Cerebras/LICENSE b/src/platform/src/Bridge/Cerebras/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Cerebras/README.md b/src/platform/src/Bridge/Cerebras/README.md
new file mode 100644
index 000000000..21182aa74
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/README.md
@@ -0,0 +1,12 @@
+Cerebras Platform
+=================
+
+Cerebras platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Cerebras/ModelCatalogTest.php b/src/platform/src/Bridge/Cerebras/Tests/ModelCatalogTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Cerebras/ModelCatalogTest.php
rename to src/platform/src/Bridge/Cerebras/Tests/ModelCatalogTest.php
index 0da88e1d9..b73c3dc08 100644
--- a/src/platform/tests/Bridge/Cerebras/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Cerebras/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Cerebras;
+namespace Symfony\AI\Platform\Bridge\Cerebras\Tests;
use Symfony\AI\Platform\Bridge\Cerebras\ModelCatalog;
use Symfony\AI\Platform\Capability;
diff --git a/src/platform/tests/Bridge/Cerebras/ModelClientTest.php b/src/platform/src/Bridge/Cerebras/Tests/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Cerebras/ModelClientTest.php
rename to src/platform/src/Bridge/Cerebras/Tests/ModelClientTest.php
index f420dde73..f397da2e6 100644
--- a/src/platform/tests/Bridge/Cerebras/ModelClientTest.php
+++ b/src/platform/src/Bridge/Cerebras/Tests/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Cerebras;
+namespace Symfony\AI\Platform\Bridge\Cerebras\Tests;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Cerebras/ResultConverterTest.php b/src/platform/src/Bridge/Cerebras/Tests/ResultConverterTest.php
similarity index 93%
rename from src/platform/tests/Bridge/Cerebras/ResultConverterTest.php
rename to src/platform/src/Bridge/Cerebras/Tests/ResultConverterTest.php
index 864e14aef..8ee372f77 100644
--- a/src/platform/tests/Bridge/Cerebras/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Cerebras/Tests/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Cerebras;
+namespace Symfony\AI\Platform\Bridge\Cerebras\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Cerebras\Model;
diff --git a/src/platform/src/Bridge/Cerebras/composer.json b/src/platform/src/Bridge/Cerebras/composer.json
new file mode 100644
index 000000000..6f895514e
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/composer.json
@@ -0,0 +1,57 @@
+{
+ "name": "symfony/ai-cerebras-platform",
+ "description": "Cerebras platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "cerebras",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Cerebras\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Cerebras\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Cerebras/phpunit.xml.dist b/src/platform/src/Bridge/Cerebras/phpunit.xml.dist
new file mode 100644
index 000000000..b81296666
--- /dev/null
+++ b/src/platform/src/Bridge/Cerebras/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/tests/Bridge/Decart/Contract/DecartContractTest.php b/src/platform/src/Bridge/Decart/Tests/Contract/DecartContractTest.php
similarity index 88%
rename from src/platform/tests/Bridge/Decart/Contract/DecartContractTest.php
rename to src/platform/src/Bridge/Decart/Tests/Contract/DecartContractTest.php
index 4dbec2e3a..ad8bed38a 100644
--- a/src/platform/tests/Bridge/Decart/Contract/DecartContractTest.php
+++ b/src/platform/src/Bridge/Decart/Tests/Contract/DecartContractTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Decart\Contract;
+namespace Symfony\AI\Platform\Bridge\Decart\Tests\Contract;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Decart\Contract\DecartContract;
@@ -21,7 +21,7 @@ final class DecartContractTest extends TestCase
{
public function testItCanCreatePayloadWithImage()
{
- $image = Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg');
+ $image = Image::fromFile(\dirname(__DIR__, 7).'/fixtures/image.jpg');
$contract = DecartContract::create();
@@ -39,7 +39,7 @@ public function testItCanCreatePayloadWithImage()
public function testItCanCreatePayloadWithVideo()
{
- $image = Video::fromFile(\dirname(__DIR__, 6).'/fixtures/ocean.mp4');
+ $image = Video::fromFile(\dirname(__DIR__, 7).'/fixtures/ocean.mp4');
$contract = DecartContract::create();
diff --git a/src/platform/tests/Bridge/Decart/DecartClientTest.php b/src/platform/src/Bridge/Decart/Tests/DecartClientTest.php
similarity index 78%
rename from src/platform/tests/Bridge/Decart/DecartClientTest.php
rename to src/platform/src/Bridge/Decart/Tests/DecartClientTest.php
index 13ae8e019..1f833a159 100644
--- a/src/platform/tests/Bridge/Decart/DecartClientTest.php
+++ b/src/platform/src/Bridge/Decart/Tests/DecartClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Decart;
+namespace Symfony\AI\Platform\Bridge\Decart\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Decart\Contract\ImageNormalizer;
@@ -52,12 +52,10 @@ public function testClientCannotGenerateOnInvalidModel()
public function testClientCanGenerateTextToImage()
{
- $normalizer = new ImageNormalizer();
-
- $payload = $normalizer->normalize(Image::fromFile(\dirname(__DIR__, 5).'/fixtures/image.jpg'));
+ $imageContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/image.jpg');
$httpClient = new MockHttpClient([
- new MockResponse($payload),
+ new MockResponse($imageContent, ['response_headers' => ['content-type' => 'image/jpeg']]),
]);
$client = new DecartClient(
@@ -74,12 +72,10 @@ public function testClientCanGenerateTextToImage()
public function testClientCanGenerateTextToVideo()
{
- $normalizer = new VideoNormalizer();
-
- $payload = $normalizer->normalize(Video::fromFile(\dirname(__DIR__, 5).'/fixtures/ocean.mp4'));
+ $videoContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/ocean.mp4');
$httpClient = new MockHttpClient([
- new MockResponse($payload),
+ new MockResponse($videoContent, ['response_headers' => ['content-type' => 'video/mp4']]),
]);
$client = new DecartClient(
@@ -97,11 +93,12 @@ public function testClientCanGenerateTextToVideo()
public function testClientCanGenerateImageToImage()
{
$normalizer = new ImageNormalizer();
+ $imageContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/image.jpg');
- $payload = $normalizer->normalize(Image::fromFile(\dirname(__DIR__, 5).'/fixtures/image.jpg'));
+ $payload = $normalizer->normalize(Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg'));
$httpClient = new MockHttpClient([
- new MockResponse($payload),
+ new MockResponse($imageContent, ['response_headers' => ['content-type' => 'image/jpeg']]),
]);
$client = new DecartClient(
@@ -119,13 +116,12 @@ public function testClientCanGenerateImageToImage()
public function testClientCanGenerateImageToVideo()
{
$normalizer = new ImageNormalizer();
- $videoNormalizer = new VideoNormalizer();
+ $videoContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/ocean.mp4');
- $payload = $normalizer->normalize(Image::fromFile(\dirname(__DIR__, 5).'/fixtures/image.jpg'));
- $responsePayload = $videoNormalizer->normalize(Video::fromFile(\dirname(__DIR__, 5).'/fixtures/ocean.mp4'));
+ $payload = $normalizer->normalize(Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg'));
$httpClient = new MockHttpClient([
- new MockResponse($responsePayload),
+ new MockResponse($videoContent, ['response_headers' => ['content-type' => 'video/mp4']]),
]);
$client = new DecartClient(
@@ -143,11 +139,12 @@ public function testClientCanGenerateImageToVideo()
public function testClientCanGenerateVideoToVideo()
{
$normalizer = new VideoNormalizer();
+ $videoContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/ocean.mp4');
- $payload = $normalizer->normalize(Video::fromFile(\dirname(__DIR__, 5).'/fixtures/ocean.mp4'));
+ $payload = $normalizer->normalize(Video::fromFile(\dirname(__DIR__, 6).'/fixtures/ocean.mp4'));
$httpClient = new MockHttpClient([
- new MockResponse($payload),
+ new MockResponse($videoContent, ['response_headers' => ['content-type' => 'video/mp4']]),
]);
$client = new DecartClient(
diff --git a/src/platform/tests/Bridge/Decart/ModelCatalogTest.php b/src/platform/src/Bridge/Decart/Tests/ModelCatalogTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Decart/ModelCatalogTest.php
rename to src/platform/src/Bridge/Decart/Tests/ModelCatalogTest.php
index cc28f99d3..df6bcaef8 100644
--- a/src/platform/tests/Bridge/Decart/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Decart/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Decart;
+namespace Symfony\AI\Platform\Bridge\Decart\Tests;
use Symfony\AI\Platform\Bridge\Decart\Decart;
use Symfony\AI\Platform\Bridge\Decart\ModelCatalog;
diff --git a/src/platform/src/Bridge/Decart/composer.json b/src/platform/src/Bridge/Decart/composer.json
new file mode 100644
index 000000000..999f0dd38
--- /dev/null
+++ b/src/platform/src/Bridge/Decart/composer.json
@@ -0,0 +1,52 @@
+{
+ "name": "symfony/ai-decart-platform",
+ "description": "Decart platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": ["ai", "bridge", "decart", "image", "platform", "video"],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Decart\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Decart\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Decart/phpunit.xml.dist b/src/platform/src/Bridge/Decart/phpunit.xml.dist
new file mode 100644
index 000000000..455f2d66b
--- /dev/null
+++ b/src/platform/src/Bridge/Decart/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/DeepSeek/.gitattributes b/src/platform/src/Bridge/DeepSeek/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/DeepSeek/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/DeepSeek/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/DeepSeek/.github/close-pull-request.yml b/src/platform/src/Bridge/DeepSeek/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/DeepSeek/.gitignore b/src/platform/src/Bridge/DeepSeek/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/DeepSeek/CHANGELOG.md b/src/platform/src/Bridge/DeepSeek/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/DeepSeek/LICENSE b/src/platform/src/Bridge/DeepSeek/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/DeepSeek/README.md b/src/platform/src/Bridge/DeepSeek/README.md
new file mode 100644
index 000000000..5fd5e5c89
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/README.md
@@ -0,0 +1,12 @@
+DeepSeek Platform
+=================
+
+DeepSeek platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/DeepSeek/DeepSeekTest.php b/src/platform/src/Bridge/DeepSeek/Tests/DeepSeekTest.php
similarity index 95%
rename from src/platform/tests/Bridge/DeepSeek/DeepSeekTest.php
rename to src/platform/src/Bridge/DeepSeek/Tests/DeepSeekTest.php
index 988dd2f77..141ce2ccd 100644
--- a/src/platform/tests/Bridge/DeepSeek/DeepSeekTest.php
+++ b/src/platform/src/Bridge/DeepSeek/Tests/DeepSeekTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DeepSeek;
+namespace Symfony\AI\Platform\Bridge\DeepSeek\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\DeepSeek\DeepSeek;
diff --git a/src/platform/tests/Bridge/DeepSeek/ModelCatalogTest.php b/src/platform/src/Bridge/DeepSeek/Tests/ModelCatalogTest.php
similarity index 95%
rename from src/platform/tests/Bridge/DeepSeek/ModelCatalogTest.php
rename to src/platform/src/Bridge/DeepSeek/Tests/ModelCatalogTest.php
index 436b7c440..86f7e5358 100644
--- a/src/platform/tests/Bridge/DeepSeek/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/DeepSeek/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DeepSeek;
+namespace Symfony\AI\Platform\Bridge\DeepSeek\Tests;
use Symfony\AI\Platform\Bridge\DeepSeek\DeepSeek;
use Symfony\AI\Platform\Bridge\DeepSeek\ModelCatalog;
diff --git a/src/platform/tests/Bridge/DeepSeek/ModelClientTest.php b/src/platform/src/Bridge/DeepSeek/Tests/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/DeepSeek/ModelClientTest.php
rename to src/platform/src/Bridge/DeepSeek/Tests/ModelClientTest.php
index 904ea0e87..85dd72c25 100644
--- a/src/platform/tests/Bridge/DeepSeek/ModelClientTest.php
+++ b/src/platform/src/Bridge/DeepSeek/Tests/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DeepSeek;
+namespace Symfony\AI\Platform\Bridge\DeepSeek\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\DeepSeek\DeepSeek;
diff --git a/src/platform/tests/Bridge/DeepSeek/ResultConverterTest.php b/src/platform/src/Bridge/DeepSeek/Tests/ResultConverterTest.php
similarity index 98%
rename from src/platform/tests/Bridge/DeepSeek/ResultConverterTest.php
rename to src/platform/src/Bridge/DeepSeek/Tests/ResultConverterTest.php
index 01b7c4d65..90066b8b2 100644
--- a/src/platform/tests/Bridge/DeepSeek/ResultConverterTest.php
+++ b/src/platform/src/Bridge/DeepSeek/Tests/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DeepSeek;
+namespace Symfony\AI\Platform\Bridge\DeepSeek\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\DeepSeek\DeepSeek;
diff --git a/src/platform/src/Bridge/DeepSeek/composer.json b/src/platform/src/Bridge/DeepSeek/composer.json
new file mode 100644
index 000000000..38a3b77c1
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-deep-seek-platform",
+ "description": "DeepSeek platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "deepseek",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-agent": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\DeepSeek\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\DeepSeek\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/DeepSeek/phpunit.xml.dist b/src/platform/src/Bridge/DeepSeek/phpunit.xml.dist
new file mode 100644
index 000000000..3665d63cd
--- /dev/null
+++ b/src/platform/src/Bridge/DeepSeek/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/DockerModelRunner/.gitattributes b/src/platform/src/Bridge/DockerModelRunner/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/DockerModelRunner/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/DockerModelRunner/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/DockerModelRunner/.github/close-pull-request.yml b/src/platform/src/Bridge/DockerModelRunner/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/DockerModelRunner/.gitignore b/src/platform/src/Bridge/DockerModelRunner/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/DockerModelRunner/CHANGELOG.md b/src/platform/src/Bridge/DockerModelRunner/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/DockerModelRunner/LICENSE b/src/platform/src/Bridge/DockerModelRunner/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/DockerModelRunner/README.md b/src/platform/src/Bridge/DockerModelRunner/README.md
new file mode 100644
index 000000000..8942c7fc2
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/README.md
@@ -0,0 +1,12 @@
+DockerModelRunner Platform
+==========================
+
+Docker Model Runner platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/DockerModelRunner/Completions/ModelClientTest.php b/src/platform/src/Bridge/DockerModelRunner/Tests/Completions/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/DockerModelRunner/Completions/ModelClientTest.php
rename to src/platform/src/Bridge/DockerModelRunner/Tests/Completions/ModelClientTest.php
index 3bb36d0c3..622c41ca9 100644
--- a/src/platform/tests/Bridge/DockerModelRunner/Completions/ModelClientTest.php
+++ b/src/platform/src/Bridge/DockerModelRunner/Tests/Completions/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DockerModelRunner\Completions;
+namespace Symfony\AI\Platform\Bridge\DockerModelRunner\Tests\Completions;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\DockerModelRunner\Completions;
diff --git a/src/platform/tests/Bridge/DockerModelRunner/Completions/ResultConverterTest.php b/src/platform/src/Bridge/DockerModelRunner/Tests/Completions/ResultConverterTest.php
similarity index 97%
rename from src/platform/tests/Bridge/DockerModelRunner/Completions/ResultConverterTest.php
rename to src/platform/src/Bridge/DockerModelRunner/Tests/Completions/ResultConverterTest.php
index 67d6815d6..5108778b5 100644
--- a/src/platform/tests/Bridge/DockerModelRunner/Completions/ResultConverterTest.php
+++ b/src/platform/src/Bridge/DockerModelRunner/Tests/Completions/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DockerModelRunner\Completions;
+namespace Symfony\AI\Platform\Bridge\DockerModelRunner\Tests\Completions;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/DockerModelRunner/Embeddings/ModelClientTest.php b/src/platform/src/Bridge/DockerModelRunner/Tests/Embeddings/ModelClientTest.php
similarity index 97%
rename from src/platform/tests/Bridge/DockerModelRunner/Embeddings/ModelClientTest.php
rename to src/platform/src/Bridge/DockerModelRunner/Tests/Embeddings/ModelClientTest.php
index cb853c7e0..7623ead45 100644
--- a/src/platform/tests/Bridge/DockerModelRunner/Embeddings/ModelClientTest.php
+++ b/src/platform/src/Bridge/DockerModelRunner/Tests/Embeddings/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DockerModelRunner\Embeddings;
+namespace Symfony\AI\Platform\Bridge\DockerModelRunner\Tests\Embeddings;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\DockerModelRunner\Embeddings;
diff --git a/src/platform/tests/Bridge/DockerModelRunner/Embeddings/ResultConverterTest.php b/src/platform/src/Bridge/DockerModelRunner/Tests/Embeddings/ResultConverterTest.php
similarity index 98%
rename from src/platform/tests/Bridge/DockerModelRunner/Embeddings/ResultConverterTest.php
rename to src/platform/src/Bridge/DockerModelRunner/Tests/Embeddings/ResultConverterTest.php
index 55349a5fd..b33eb905f 100644
--- a/src/platform/tests/Bridge/DockerModelRunner/Embeddings/ResultConverterTest.php
+++ b/src/platform/src/Bridge/DockerModelRunner/Tests/Embeddings/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DockerModelRunner\Embeddings;
+namespace Symfony\AI\Platform\Bridge\DockerModelRunner\Tests\Embeddings;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/DockerModelRunner/ModelCatalogTest.php b/src/platform/src/Bridge/DockerModelRunner/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/DockerModelRunner/ModelCatalogTest.php
rename to src/platform/src/Bridge/DockerModelRunner/Tests/ModelCatalogTest.php
index 04c62cb4b..eae4c3310 100644
--- a/src/platform/tests/Bridge/DockerModelRunner/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/DockerModelRunner/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\DockerModelRunner;
+namespace Symfony\AI\Platform\Bridge\DockerModelRunner\Tests;
use Symfony\AI\Platform\Bridge\DockerModelRunner\Completions;
use Symfony\AI\Platform\Bridge\DockerModelRunner\Embeddings;
diff --git a/src/platform/src/Bridge/DockerModelRunner/composer.json b/src/platform/src/Bridge/DockerModelRunner/composer.json
new file mode 100644
index 000000000..daf7fc311
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/composer.json
@@ -0,0 +1,57 @@
+{
+ "name": "symfony/ai-docker-model-runner-platform",
+ "description": "Docker Model Runner platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "docker",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\DockerModelRunner\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\DockerModelRunner\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/DockerModelRunner/phpunit.xml.dist b/src/platform/src/Bridge/DockerModelRunner/phpunit.xml.dist
new file mode 100644
index 000000000..995026918
--- /dev/null
+++ b/src/platform/src/Bridge/DockerModelRunner/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/ElevenLabs/.gitattributes b/src/platform/src/Bridge/ElevenLabs/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/ElevenLabs/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/ElevenLabs/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/ElevenLabs/.github/close-pull-request.yml b/src/platform/src/Bridge/ElevenLabs/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/ElevenLabs/.gitignore b/src/platform/src/Bridge/ElevenLabs/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/ElevenLabs/CHANGELOG.md b/src/platform/src/Bridge/ElevenLabs/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/ElevenLabs/LICENSE b/src/platform/src/Bridge/ElevenLabs/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/ElevenLabs/README.md b/src/platform/src/Bridge/ElevenLabs/README.md
new file mode 100644
index 000000000..75cf019a8
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/README.md
@@ -0,0 +1,12 @@
+ElevenLabs Platform
+===================
+
+ElevenLabs platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/ElevenLabs/Contract/ElevenLabsContractTest.php b/src/platform/src/Bridge/ElevenLabs/Tests/Contract/ElevenLabsContractTest.php
similarity index 88%
rename from src/platform/tests/Bridge/ElevenLabs/Contract/ElevenLabsContractTest.php
rename to src/platform/src/Bridge/ElevenLabs/Tests/Contract/ElevenLabsContractTest.php
index 5fd637065..4a64f32b6 100644
--- a/src/platform/tests/Bridge/ElevenLabs/Contract/ElevenLabsContractTest.php
+++ b/src/platform/src/Bridge/ElevenLabs/Tests/Contract/ElevenLabsContractTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\ElevenLabs\Contract;
+namespace Symfony\AI\Platform\Bridge\ElevenLabs\Tests\Contract;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\ElevenLabs\Contract\ElevenLabsContract;
@@ -20,7 +20,7 @@ final class ElevenLabsContractTest extends TestCase
{
public function testItCanCreatePayloadWithAudio()
{
- $audio = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
+ $audio = Audio::fromFile(\dirname(__DIR__, 7).'/fixtures/audio.mp3');
$contract = ElevenLabsContract::create();
diff --git a/src/platform/tests/Bridge/ElevenLabs/ElevenLabsApiCatalogTest.php b/src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsApiCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/ElevenLabs/ElevenLabsApiCatalogTest.php
rename to src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsApiCatalogTest.php
index db3991244..d4d2eaaea 100644
--- a/src/platform/tests/Bridge/ElevenLabs/ElevenLabsApiCatalogTest.php
+++ b/src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsApiCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\ElevenLabs;
+namespace Symfony\AI\Platform\Bridge\ElevenLabs\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\ElevenLabs\ElevenLabs;
diff --git a/src/platform/tests/Bridge/ElevenLabs/ElevenLabsClientTest.php b/src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsClientTest.php
similarity index 94%
rename from src/platform/tests/Bridge/ElevenLabs/ElevenLabsClientTest.php
rename to src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsClientTest.php
index fca5a1fbe..ac663f8e9 100644
--- a/src/platform/tests/Bridge/ElevenLabs/ElevenLabsClientTest.php
+++ b/src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\ElevenLabs;
+namespace Symfony\AI\Platform\Bridge\ElevenLabs\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\ElevenLabs\Contract\AudioNormalizer;
@@ -56,7 +56,7 @@ public function testClientCannotPerformWithInvalidModel()
'my-api-key',
);
- $payload = $normalizer->normalize(Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3'));
+ $payload = $normalizer->normalize(Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3'));
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('The model "foo" does not support text-to-speech or speech-to-text, please check the model information.');
@@ -91,7 +91,7 @@ public function testClientCanPerformSpeechToTextRequest()
'my-api-key',
);
- $payload = $normalizer->normalize(Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3'));
+ $payload = $normalizer->normalize(Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3'));
$client->request(new ElevenLabs('scribe_v1', [Capability::INPUT_AUDIO, Capability::OUTPUT_TEXT, Capability::SPEECH_TO_TEXT]), $payload);
@@ -112,7 +112,7 @@ public function testClientCanPerformSpeechToTextRequestWithExperimentalModel()
'my-api-key',
);
- $payload = $normalizer->normalize(Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3'));
+ $payload = $normalizer->normalize(Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3'));
$client->request(new ElevenLabs('scribe_v1_experimental', [Capability::INPUT_AUDIO, Capability::OUTPUT_TEXT, Capability::SPEECH_TO_TEXT]), $payload);
@@ -140,7 +140,7 @@ public function testClientCannotPerformTextToSpeechRequestWithoutValidPayload()
public function testClientCanPerformTextToSpeechRequest()
{
- $payload = Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
+ $payload = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
$httpClient = new MockHttpClient([
new MockResponse($payload->asBinary()),
@@ -162,7 +162,7 @@ public function testClientCanPerformTextToSpeechRequest()
public function testClientCanPerformTextToSpeechRequestWhenVoiceKeyIsProvidedAsRequestOption()
{
- $payload = Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
+ $payload = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
$httpClient = new MockHttpClient([
new MockResponse($payload->asBinary()),
@@ -184,7 +184,7 @@ public function testClientCanPerformTextToSpeechRequestWhenVoiceKeyIsProvidedAsR
public function testClientCanPerformTextToSpeechRequestAsStream()
{
- $payload = Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
+ $payload = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
$httpClient = new MockHttpClient([
new MockResponse($payload->asBinary()),
@@ -208,7 +208,7 @@ public function testClientCanPerformTextToSpeechRequestAsStream()
public function testClientCanPerformTextToSpeechRequestAsStreamVoiceKeyIsProvidedAsRequestOption()
{
- $payload = Audio::fromFile(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
+ $payload = Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
$httpClient = new MockHttpClient([
new MockResponse($payload->asBinary()),
diff --git a/src/platform/tests/Bridge/ElevenLabs/ElevenLabsConverterTest.php b/src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsConverterTest.php
similarity index 94%
rename from src/platform/tests/Bridge/ElevenLabs/ElevenLabsConverterTest.php
rename to src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsConverterTest.php
index 4821bed16..9890043c7 100644
--- a/src/platform/tests/Bridge/ElevenLabs/ElevenLabsConverterTest.php
+++ b/src/platform/src/Bridge/ElevenLabs/Tests/ElevenLabsConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\ElevenLabs;
+namespace Symfony\AI\Platform\Bridge\ElevenLabs\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\ElevenLabs\ElevenLabs;
@@ -59,7 +59,7 @@ public function getInfo(): string
public function getContent(): string
{
- return file_get_contents(\dirname(__DIR__, 5).'/fixtures/audio.mp3');
+ return file_get_contents(\dirname(__DIR__, 6).'/fixtures/audio.mp3');
}
});
diff --git a/src/platform/tests/Bridge/ElevenLabs/ModelCatalogTest.php b/src/platform/src/Bridge/ElevenLabs/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/ElevenLabs/ModelCatalogTest.php
rename to src/platform/src/Bridge/ElevenLabs/Tests/ModelCatalogTest.php
index ccac7dc7b..1eb8d561b 100644
--- a/src/platform/tests/Bridge/ElevenLabs/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/ElevenLabs/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\ElevenLabs;
+namespace Symfony\AI\Platform\Bridge\ElevenLabs\Tests;
use Symfony\AI\Platform\Bridge\ElevenLabs\ElevenLabs;
use Symfony\AI\Platform\Bridge\ElevenLabs\ModelCatalog;
diff --git a/src/platform/src/Bridge/ElevenLabs/composer.json b/src/platform/src/Bridge/ElevenLabs/composer.json
new file mode 100644
index 000000000..749399669
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/composer.json
@@ -0,0 +1,59 @@
+{
+ "name": "symfony/ai-eleven-labs-platform",
+ "description": "ElevenLabs platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "elevenlabs",
+ "platform",
+ "text-to-speech",
+ "voice"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\ElevenLabs\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\ElevenLabs\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/ElevenLabs/phpunit.xml.dist b/src/platform/src/Bridge/ElevenLabs/phpunit.xml.dist
new file mode 100644
index 000000000..2edd9626b
--- /dev/null
+++ b/src/platform/src/Bridge/ElevenLabs/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Gemini/.gitattributes b/src/platform/src/Bridge/Gemini/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Gemini/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Gemini/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Gemini/.github/close-pull-request.yml b/src/platform/src/Bridge/Gemini/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Gemini/.gitignore b/src/platform/src/Bridge/Gemini/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Gemini/CHANGELOG.md b/src/platform/src/Bridge/Gemini/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Gemini/LICENSE b/src/platform/src/Bridge/Gemini/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Gemini/README.md b/src/platform/src/Bridge/Gemini/README.md
new file mode 100644
index 000000000..a88ba2d9c
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/README.md
@@ -0,0 +1,12 @@
+Gemini Platform
+===============
+
+Google Gemini platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Gemini/CodeExecution/ResultConverterTest.php b/src/platform/src/Bridge/Gemini/Tests/CodeExecution/ResultConverterTest.php
similarity index 88%
rename from src/platform/tests/Bridge/Gemini/CodeExecution/ResultConverterTest.php
rename to src/platform/src/Bridge/Gemini/Tests/CodeExecution/ResultConverterTest.php
index 1f4140208..a75581672 100644
--- a/src/platform/tests/Bridge/Gemini/CodeExecution/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/CodeExecution/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\CodeExecution;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\CodeExecution;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Gemini\Gemini\ResultConverter;
@@ -22,7 +22,7 @@ final class ResultConverterTest extends TestCase
public function testItReturnsAggregatedTextOnSuccess()
{
$response = $this->createStub(ResponseInterface::class);
- $responseContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/Bridge/Gemini/code_execution_outcome_ok.json');
+ $responseContent = file_get_contents(\dirname(__DIR__, 7).'/fixtures/Bridge/Gemini/code_execution_outcome_ok.json');
$response
->method('toArray')
@@ -39,7 +39,7 @@ public function testItReturnsAggregatedTextOnSuccess()
public function testItThrowsExceptionOnFailure()
{
$response = $this->createStub(ResponseInterface::class);
- $responseContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/Bridge/Gemini/code_execution_outcome_failed.json');
+ $responseContent = file_get_contents(\dirname(__DIR__, 7).'/fixtures/Bridge/Gemini/code_execution_outcome_failed.json');
$response
->method('toArray')
@@ -54,7 +54,7 @@ public function testItThrowsExceptionOnFailure()
public function testItThrowsExceptionOnTimeout()
{
$response = $this->createStub(ResponseInterface::class);
- $responseContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/Bridge/Gemini/code_execution_outcome_deadline_exceeded.json');
+ $responseContent = file_get_contents(\dirname(__DIR__, 7).'/fixtures/Bridge/Gemini/code_execution_outcome_deadline_exceeded.json');
$response
->method('toArray')
diff --git a/src/platform/tests/Bridge/Gemini/Contract/AssistantMessageNormalizerTest.php b/src/platform/src/Bridge/Gemini/Tests/Contract/AssistantMessageNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Gemini/Contract/AssistantMessageNormalizerTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Contract/AssistantMessageNormalizerTest.php
index ccf964a83..5f111c011 100644
--- a/src/platform/tests/Bridge/Gemini/Contract/AssistantMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Contract/AssistantMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Contract;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Gemini/Contract/MessageBagNormalizerTest.php b/src/platform/src/Bridge/Gemini/Tests/Contract/MessageBagNormalizerTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Gemini/Contract/MessageBagNormalizerTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Contract/MessageBagNormalizerTest.php
index ee2e3f27b..8acdf6ca4 100644
--- a/src/platform/tests/Bridge/Gemini/Contract/MessageBagNormalizerTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Contract/MessageBagNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Contract;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -92,13 +92,13 @@ public static function provideMessageBagData(): iterable
yield 'text with image' => [
new MessageBag(
- Message::ofUser('Tell me about this instrument', Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg'))
+ Message::ofUser('Tell me about this instrument', Image::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/image.jpg'))
),
[
'contents' => [
['role' => 'user', 'parts' => [
['text' => 'Tell me about this instrument'],
- ['inline_data' => ['mime_type' => 'image/jpeg', 'data' => base64_encode(file_get_contents(\dirname(__DIR__, 6).'/fixtures/image.jpg'))]],
+ ['inline_data' => ['mime_type' => 'image/jpeg', 'data' => base64_encode(file_get_contents(\dirname(__DIR__, 5).'/tests/Fixtures/image.jpg'))]],
]],
],
],
diff --git a/src/platform/tests/Bridge/Gemini/Contract/ToolCallMessageNormalizerTest.php b/src/platform/src/Bridge/Gemini/Tests/Contract/ToolCallMessageNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Gemini/Contract/ToolCallMessageNormalizerTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Contract/ToolCallMessageNormalizerTest.php
index 260483840..6b4bbcd75 100644
--- a/src/platform/tests/Bridge/Gemini/Contract/ToolCallMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Contract/ToolCallMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Contract;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Gemini/Contract/ToolNormalizerTest.php b/src/platform/src/Bridge/Gemini/Tests/Contract/ToolNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Gemini/Contract/ToolNormalizerTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Contract/ToolNormalizerTest.php
index e59e84ead..cc20eeffa 100644
--- a/src/platform/tests/Bridge/Gemini/Contract/ToolNormalizerTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Contract/ToolNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Contract;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Gemini/Contract/UserMessageNormalizerTest.php b/src/platform/src/Bridge/Gemini/Tests/Contract/UserMessageNormalizerTest.php
similarity index 88%
rename from src/platform/tests/Bridge/Gemini/Contract/UserMessageNormalizerTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Contract/UserMessageNormalizerTest.php
index 17261a509..4f1d94a52 100644
--- a/src/platform/tests/Bridge/Gemini/Contract/UserMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Contract/UserMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Contract;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -52,6 +52,16 @@ public function testNormalizeTextContent()
$this->assertSame([['text' => 'Write a story about a magic backpack.']], $normalized);
}
+ /**
+ * @return iterable
+ */
+ public static function binaryContentProvider(): iterable
+ {
+ yield 'image' => [Image::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/image.jpg'), 'image/jpeg', '/9j/'];
+ yield 'document' => [Document::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/document.pdf'), 'application/pdf', 'JVBE'];
+ yield 'audio' => [Audio::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/audio.mp3'), 'audio/mpeg', 'SUQz'];
+ }
+
#[DataProvider('binaryContentProvider')]
public function testNormalizeBinaryContent(File $content, string $expectedMimeType, string $expectedPrefix)
{
@@ -69,14 +79,4 @@ public function testNormalizeBinaryContent(File $content, string $expectedMimeTy
// Verify that the base64 data string starts correctly
$this->assertStringStartsWith($expectedPrefix, $normalized[1]['inline_data']['data']);
}
-
- /**
- * @return iterable
- */
- public static function binaryContentProvider(): iterable
- {
- yield 'image' => [Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg'), 'image/jpeg', '/9j/'];
- yield 'document' => [Document::fromFile(\dirname(__DIR__, 6).'/fixtures/document.pdf'), 'application/pdf', 'JVBE'];
- yield 'audio' => [Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3'), 'audio/mpeg', 'SUQz'];
- }
}
diff --git a/src/platform/tests/Bridge/Gemini/Embeddings/ModelClientTest.php b/src/platform/src/Bridge/Gemini/Tests/Embeddings/ModelClientTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Gemini/Embeddings/ModelClientTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Embeddings/ModelClientTest.php
index bc61f2f6a..2983b8858 100644
--- a/src/platform/tests/Bridge/Gemini/Embeddings/ModelClientTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Embeddings/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Embeddings;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Embeddings;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Gemini\Embeddings;
diff --git a/src/platform/tests/Bridge/Gemini/Embeddings/ResultConverterTest.php b/src/platform/src/Bridge/Gemini/Tests/Embeddings/ResultConverterTest.php
similarity index 95%
rename from src/platform/tests/Bridge/Gemini/Embeddings/ResultConverterTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Embeddings/ResultConverterTest.php
index 849884394..9660d75b1 100644
--- a/src/platform/tests/Bridge/Gemini/Embeddings/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Embeddings/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Embeddings;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Embeddings;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Gemini\Embeddings\ResultConverter;
diff --git a/src/platform/tests/Bridge/Gemini/Gemini/ResultConverterRateLimitTest.php b/src/platform/src/Bridge/Gemini/Tests/Gemini/ResultConverterRateLimitTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Gemini/Gemini/ResultConverterRateLimitTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Gemini/ResultConverterRateLimitTest.php
index 2b7c80a90..9263e91c5 100644
--- a/src/platform/tests/Bridge/Gemini/Gemini/ResultConverterRateLimitTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Gemini/ResultConverterRateLimitTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Gemini;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Gemini;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Gemini\Gemini\ResultConverter;
diff --git a/src/platform/tests/Bridge/Gemini/Gemini/ResultConverterTest.php b/src/platform/src/Bridge/Gemini/Tests/Gemini/ResultConverterTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Gemini/Gemini/ResultConverterTest.php
rename to src/platform/src/Bridge/Gemini/Tests/Gemini/ResultConverterTest.php
index 9f21feaf1..f7a141937 100644
--- a/src/platform/tests/Bridge/Gemini/Gemini/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/Gemini/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini\Gemini;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests\Gemini;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Gemini\Gemini\ResultConverter;
@@ -84,7 +84,7 @@ public function testConvertsInlineDataToBinaryResult()
$converter = new ResultConverter();
$httpResponse = self::createMock(ResponseInterface::class);
$httpResponse->method('getStatusCode')->willReturn(200);
- $image = Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg');
+ $image = Image::fromFile(\dirname(__DIR__, 7).'/fixtures/image.jpg');
$httpResponse->method('toArray')->willReturn([
'candidates' => [
[
@@ -114,7 +114,7 @@ public function testConvertsInlineDataWithoutMimeTypeToBinaryResult()
$converter = new ResultConverter();
$httpResponse = self::createMock(ResponseInterface::class);
$httpResponse->method('getStatusCode')->willReturn(200);
- $image = Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg');
+ $image = Image::fromFile(\dirname(__DIR__, 7).'/fixtures/image.jpg');
$httpResponse->method('toArray')->willReturn([
'candidates' => [
[
diff --git a/src/platform/tests/Bridge/Gemini/ModelCatalogTest.php b/src/platform/src/Bridge/Gemini/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Gemini/ModelCatalogTest.php
rename to src/platform/src/Bridge/Gemini/Tests/ModelCatalogTest.php
index 3f0b2cd85..e582b610b 100644
--- a/src/platform/tests/Bridge/Gemini/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests;
use Symfony\AI\Platform\Bridge\Gemini\Embeddings;
use Symfony\AI\Platform\Bridge\Gemini\Gemini;
diff --git a/src/platform/tests/Bridge/Gemini/TokenOutputProcessorTest.php b/src/platform/src/Bridge/Gemini/Tests/TokenOutputProcessorTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Gemini/TokenOutputProcessorTest.php
rename to src/platform/src/Bridge/Gemini/Tests/TokenOutputProcessorTest.php
index d7d552698..b13bcc476 100644
--- a/src/platform/tests/Bridge/Gemini/TokenOutputProcessorTest.php
+++ b/src/platform/src/Bridge/Gemini/Tests/TokenOutputProcessorTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Gemini;
+namespace Symfony\AI\Platform\Bridge\Gemini\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Agent\Output;
@@ -130,6 +130,9 @@ public function testItHandlesMissingUsageFields()
$this->assertNull($tokenUsage->getTotalTokens());
}
+ /**
+ * @param array $data
+ */
private function createRawResult(array $data = []): RawHttpResult
{
$rawResponse = $this->createStub(ResponseInterface::class);
diff --git a/src/platform/src/Bridge/Gemini/composer.json b/src/platform/src/Bridge/Gemini/composer.json
new file mode 100644
index 000000000..9637f4d91
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/composer.json
@@ -0,0 +1,59 @@
+{
+ "name": "symfony/ai-gemini-platform",
+ "description": "Google Gemini platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "gemini",
+ "google",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-agent": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Gemini\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Gemini\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Gemini/phpunit.xml.dist b/src/platform/src/Bridge/Gemini/phpunit.xml.dist
new file mode 100644
index 000000000..0c477ebac
--- /dev/null
+++ b/src/platform/src/Bridge/Gemini/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Generic/.gitattributes b/src/platform/src/Bridge/Generic/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Generic/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Generic/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Generic/.github/close-pull-request.yml b/src/platform/src/Bridge/Generic/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Generic/.gitignore b/src/platform/src/Bridge/Generic/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Generic/CHANGELOG.md b/src/platform/src/Bridge/Generic/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Generic/LICENSE b/src/platform/src/Bridge/Generic/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Generic/README.md b/src/platform/src/Bridge/Generic/README.md
new file mode 100644
index 000000000..6c58756cd
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/README.md
@@ -0,0 +1,12 @@
+Generic Platform
+================
+
+Generic platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Generic/Completions/ModelClientTest.php b/src/platform/src/Bridge/Generic/Tests/Completions/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Generic/Completions/ModelClientTest.php
rename to src/platform/src/Bridge/Generic/Tests/Completions/ModelClientTest.php
index 59d142161..a2dea9f0e 100644
--- a/src/platform/tests/Bridge/Generic/Completions/ModelClientTest.php
+++ b/src/platform/src/Bridge/Generic/Tests/Completions/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Generic\Completions;
+namespace Symfony\AI\Platform\Bridge\Generic\Tests\Completions;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Generic/Completions/ResultConverterTest.php b/src/platform/src/Bridge/Generic/Tests/Completions/ResultConverterTest.php
similarity index 99%
rename from src/platform/tests/Bridge/Generic/Completions/ResultConverterTest.php
rename to src/platform/src/Bridge/Generic/Tests/Completions/ResultConverterTest.php
index f381a7176..3028b3f1b 100644
--- a/src/platform/tests/Bridge/Generic/Completions/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Generic/Tests/Completions/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Generic\Completions;
+namespace Symfony\AI\Platform\Bridge\Generic\Tests\Completions;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Generic\Completions\ResultConverter;
diff --git a/src/platform/tests/Bridge/Generic/Embeddings/ModelClientTest.php b/src/platform/src/Bridge/Generic/Tests/Embeddings/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Generic/Embeddings/ModelClientTest.php
rename to src/platform/src/Bridge/Generic/Tests/Embeddings/ModelClientTest.php
index 405ab63a9..e54a73a87 100644
--- a/src/platform/tests/Bridge/Generic/Embeddings/ModelClientTest.php
+++ b/src/platform/src/Bridge/Generic/Tests/Embeddings/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Generic\Embeddings;
+namespace Symfony\AI\Platform\Bridge\Generic\Tests\Embeddings;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Generic/Embeddings/ResultConverterTest.php b/src/platform/src/Bridge/Generic/Tests/Embeddings/ResultConverterTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Generic/Embeddings/ResultConverterTest.php
rename to src/platform/src/Bridge/Generic/Tests/Embeddings/ResultConverterTest.php
index 4831f2274..db2a45794 100644
--- a/src/platform/tests/Bridge/Generic/Embeddings/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Generic/Tests/Embeddings/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Generic\Embeddings;
+namespace Symfony\AI\Platform\Bridge\Generic\Tests\Embeddings;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Generic\Embeddings\ResultConverter;
diff --git a/src/platform/src/Bridge/Generic/composer.json b/src/platform/src/Bridge/Generic/composer.json
new file mode 100644
index 000000000..46de21ef4
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/composer.json
@@ -0,0 +1,57 @@
+{
+ "name": "symfony/ai-generic-platform",
+ "description": "Generic platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "generic",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Generic\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Generic\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Generic/phpunit.xml.dist b/src/platform/src/Bridge/Generic/phpunit.xml.dist
new file mode 100644
index 000000000..c5f4e67d1
--- /dev/null
+++ b/src/platform/src/Bridge/Generic/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/HuggingFace/.gitattributes b/src/platform/src/Bridge/HuggingFace/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/HuggingFace/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/HuggingFace/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/HuggingFace/.github/close-pull-request.yml b/src/platform/src/Bridge/HuggingFace/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/HuggingFace/.gitignore b/src/platform/src/Bridge/HuggingFace/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/HuggingFace/CHANGELOG.md b/src/platform/src/Bridge/HuggingFace/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/HuggingFace/LICENSE b/src/platform/src/Bridge/HuggingFace/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/tests/Bridge/HuggingFace/ApiClientTest.php b/src/platform/src/Bridge/HuggingFace/Tests/ApiClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/ApiClientTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/ApiClientTest.php
index 4ef902cfa..6d195ccf1 100644
--- a/src/platform/tests/Bridge/HuggingFace/ApiClientTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/ApiClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/HuggingFace/Contract/FileNormalizerTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Contract/FileNormalizerTest.php
similarity index 80%
rename from src/platform/tests/Bridge/HuggingFace/Contract/FileNormalizerTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Contract/FileNormalizerTest.php
index 31d765768..ef8cc9249 100644
--- a/src/platform/tests/Bridge/HuggingFace/Contract/FileNormalizerTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Contract/FileNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Contract;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -54,26 +54,26 @@ public function testNormalize(File $file, array $expected)
public static function normalizeDataProvider(): iterable
{
yield 'image from file' => [
- File::fromFile(\dirname(__DIR__, 3).'/Fixtures/image.jpg'),
+ File::fromFile(\dirname(__DIR__, 7).'/fixtures/image.jpg'),
[
'headers' => ['Content-Type' => 'image/jpeg'],
- 'body' => file_get_contents(\dirname(__DIR__, 3).'/Fixtures/image.jpg'),
+ 'body' => file_get_contents(\dirname(__DIR__, 7).'/fixtures/image.jpg'),
],
];
yield 'pdf document from file' => [
- File::fromFile(\dirname(__DIR__, 3).'/Fixtures/document.pdf'),
+ File::fromFile(\dirname(__DIR__, 7).'/fixtures/document.pdf'),
[
'headers' => ['Content-Type' => 'application/pdf'],
- 'body' => file_get_contents(\dirname(__DIR__, 3).'/Fixtures/document.pdf'),
+ 'body' => file_get_contents(\dirname(__DIR__, 7).'/fixtures/document.pdf'),
],
];
yield 'audio from file' => [
- File::fromFile(\dirname(__DIR__, 3).'/Fixtures/audio.mp3'),
+ File::fromFile(\dirname(__DIR__, 7).'/fixtures/audio.mp3'),
[
'headers' => ['Content-Type' => 'audio/mpeg'],
- 'body' => file_get_contents(\dirname(__DIR__, 3).'/Fixtures/audio.mp3'),
+ 'body' => file_get_contents(\dirname(__DIR__, 7).'/fixtures/audio.mp3'),
],
];
diff --git a/src/platform/tests/Bridge/HuggingFace/Contract/MessageBagNormalizerTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Contract/MessageBagNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Contract/MessageBagNormalizerTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Contract/MessageBagNormalizerTest.php
index 09af37150..86d8c499a 100644
--- a/src/platform/tests/Bridge/HuggingFace/Contract/MessageBagNormalizerTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Contract/MessageBagNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Contract;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/HuggingFace/ModelClientTest.php b/src/platform/src/Bridge/HuggingFace/Tests/ModelClientTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/ModelClientTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/ModelClientTest.php
index e7b25bf42..c9520ad01 100644
--- a/src/platform/tests/Bridge/HuggingFace/ModelClientTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/ClassificationResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/ClassificationResultTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Output/ClassificationResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/ClassificationResultTest.php
index 8de3ad6bd..da624134c 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/ClassificationResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/ClassificationResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/ClassificationTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/ClassificationTest.php
similarity index 96%
rename from src/platform/tests/Bridge/HuggingFace/Output/ClassificationTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/ClassificationTest.php
index e5b7a80c0..1e288f058 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/ClassificationTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/ClassificationTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/DetectedObjectTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/DetectedObjectTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Output/DetectedObjectTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/DetectedObjectTest.php
index b87c9994b..fbfb31c59 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/DetectedObjectTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/DetectedObjectTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/FillMaskResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/FillMaskResultTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/Output/FillMaskResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/FillMaskResultTest.php
index d8f7399cb..ed10663f5 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/FillMaskResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/FillMaskResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/ImageSegmentTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/ImageSegmentTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Output/ImageSegmentTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/ImageSegmentTest.php
index 2eeb624f1..af731939d 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/ImageSegmentTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/ImageSegmentTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/ImageSegmentationResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/ImageSegmentationResultTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/Output/ImageSegmentationResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/ImageSegmentationResultTest.php
index 222166a1c..75e5c73be 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/ImageSegmentationResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/ImageSegmentationResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/MaskFillTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/MaskFillTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Output/MaskFillTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/MaskFillTest.php
index 465798703..0d51add29 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/MaskFillTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/MaskFillTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/ObjectDetectionResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/ObjectDetectionResultTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/Output/ObjectDetectionResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/ObjectDetectionResultTest.php
index 5e43dd406..4c543072f 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/ObjectDetectionResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/ObjectDetectionResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/QuestionAnsweringResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/QuestionAnsweringResultTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Output/QuestionAnsweringResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/QuestionAnsweringResultTest.php
index 609a566ff..8a67e9850 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/QuestionAnsweringResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/QuestionAnsweringResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/SentenceSimilarityResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/SentenceSimilarityResultTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Output/SentenceSimilarityResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/SentenceSimilarityResultTest.php
index 6a39380de..7631f2ae2 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/SentenceSimilarityResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/SentenceSimilarityResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/TableQuestionAnsweringResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/TableQuestionAnsweringResultTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/Output/TableQuestionAnsweringResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/TableQuestionAnsweringResultTest.php
index 5f0d3e92c..69bdf5a10 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/TableQuestionAnsweringResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/TableQuestionAnsweringResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/TokenClassificationResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/TokenClassificationResultTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/Output/TokenClassificationResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/TokenClassificationResultTest.php
index c8b9425ce..dc771d92e 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/TokenClassificationResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/TokenClassificationResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/TokenTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/TokenTest.php
similarity index 98%
rename from src/platform/tests/Bridge/HuggingFace/Output/TokenTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/TokenTest.php
index feefd29cd..1ae649787 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/TokenTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/TokenTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/Output/ZeroShotClassificationResultTest.php b/src/platform/src/Bridge/HuggingFace/Tests/Output/ZeroShotClassificationResultTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/Output/ZeroShotClassificationResultTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/Output/ZeroShotClassificationResultTest.php
index 5858f14ee..0377fa827 100644
--- a/src/platform/tests/Bridge/HuggingFace/Output/ZeroShotClassificationResultTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/Output/ZeroShotClassificationResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace\Output;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests\Output;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/PlatformFactoryTest.php b/src/platform/src/Bridge/HuggingFace/Tests/PlatformFactoryTest.php
similarity index 97%
rename from src/platform/tests/Bridge/HuggingFace/PlatformFactoryTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/PlatformFactoryTest.php
index 559681211..ff5fa6b52 100644
--- a/src/platform/tests/Bridge/HuggingFace/PlatformFactoryTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/PlatformFactoryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/tests/Bridge/HuggingFace/ResultConverterTest.php b/src/platform/src/Bridge/HuggingFace/Tests/ResultConverterTest.php
similarity index 99%
rename from src/platform/tests/Bridge/HuggingFace/ResultConverterTest.php
rename to src/platform/src/Bridge/HuggingFace/Tests/ResultConverterTest.php
index 91d055dac..58941b382 100644
--- a/src/platform/tests/Bridge/HuggingFace/ResultConverterTest.php
+++ b/src/platform/src/Bridge/HuggingFace/Tests/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\HuggingFace;
+namespace Symfony\AI\Platform\Bridge\HuggingFace\Tests;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\Attributes\TestWith;
diff --git a/src/platform/src/Bridge/HuggingFace/composer.json b/src/platform/src/Bridge/HuggingFace/composer.json
new file mode 100644
index 000000000..1ff3bffe4
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/composer.json
@@ -0,0 +1,57 @@
+{
+ "name": "symfony/ai-hugging-face-platform",
+ "description": "HuggingFace platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "huggingface",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\HuggingFace\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\HuggingFace\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/HuggingFace/phpunit.xml.dist b/src/platform/src/Bridge/HuggingFace/phpunit.xml.dist
new file mode 100644
index 000000000..1836cbe7c
--- /dev/null
+++ b/src/platform/src/Bridge/HuggingFace/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/LmStudio/.gitattributes b/src/platform/src/Bridge/LmStudio/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/LmStudio/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/LmStudio/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/LmStudio/.github/close-pull-request.yml b/src/platform/src/Bridge/LmStudio/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/LmStudio/.gitignore b/src/platform/src/Bridge/LmStudio/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/LmStudio/CHANGELOG.md b/src/platform/src/Bridge/LmStudio/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/LmStudio/LICENSE b/src/platform/src/Bridge/LmStudio/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/LmStudio/README.md b/src/platform/src/Bridge/LmStudio/README.md
new file mode 100644
index 000000000..ef286139d
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/README.md
@@ -0,0 +1,12 @@
+LmStudio Platform
+=================
+
+LM Studio platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/LmStudio/ModelCatalogTest.php b/src/platform/src/Bridge/LmStudio/Tests/ModelCatalogTest.php
similarity index 96%
rename from src/platform/tests/Bridge/LmStudio/ModelCatalogTest.php
rename to src/platform/src/Bridge/LmStudio/Tests/ModelCatalogTest.php
index f768f370e..50b14ece2 100644
--- a/src/platform/tests/Bridge/LmStudio/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/LmStudio/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\LmStudio;
+namespace Symfony\AI\Platform\Bridge\LmStudio\Tests;
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
use Symfony\AI\Platform\Bridge\Generic\EmbeddingsModel;
diff --git a/src/platform/tests/Bridge/LmStudio/PlatformFactoryTest.php b/src/platform/src/Bridge/LmStudio/Tests/PlatformFactoryTest.php
similarity index 96%
rename from src/platform/tests/Bridge/LmStudio/PlatformFactoryTest.php
rename to src/platform/src/Bridge/LmStudio/Tests/PlatformFactoryTest.php
index 8ea4d2a59..d640e8193 100644
--- a/src/platform/tests/Bridge/LmStudio/PlatformFactoryTest.php
+++ b/src/platform/src/Bridge/LmStudio/Tests/PlatformFactoryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\LmStudio;
+namespace Symfony\AI\Platform\Bridge\LmStudio\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\LmStudio\PlatformFactory;
diff --git a/src/platform/src/Bridge/LmStudio/composer.json b/src/platform/src/Bridge/LmStudio/composer.json
new file mode 100644
index 000000000..43f46b265
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/composer.json
@@ -0,0 +1,59 @@
+{
+ "name": "symfony/ai-lm-studio-platform",
+ "description": "LM Studio platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "lmstudio",
+ "local",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-generic-platform": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\LmStudio\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\LmStudio\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/LmStudio/phpunit.xml.dist b/src/platform/src/Bridge/LmStudio/phpunit.xml.dist
new file mode 100644
index 000000000..77caffd58
--- /dev/null
+++ b/src/platform/src/Bridge/LmStudio/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Meta/.gitattributes b/src/platform/src/Bridge/Meta/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Meta/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Meta/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Meta/.github/close-pull-request.yml b/src/platform/src/Bridge/Meta/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Meta/.gitignore b/src/platform/src/Bridge/Meta/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Meta/CHANGELOG.md b/src/platform/src/Bridge/Meta/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Meta/LICENSE b/src/platform/src/Bridge/Meta/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Meta/README.md b/src/platform/src/Bridge/Meta/README.md
new file mode 100644
index 000000000..06495c738
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/README.md
@@ -0,0 +1,12 @@
+Meta Platform
+=============
+
+Meta (Llama) platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Meta/LlamaPromptConverterTest.php b/src/platform/src/Bridge/Meta/Tests/LlamaPromptConverterTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Meta/LlamaPromptConverterTest.php
rename to src/platform/src/Bridge/Meta/Tests/LlamaPromptConverterTest.php
index 0f133be00..3dacf371a 100644
--- a/src/platform/tests/Bridge/Meta/LlamaPromptConverterTest.php
+++ b/src/platform/src/Bridge/Meta/Tests/LlamaPromptConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Meta;
+namespace Symfony\AI\Platform\Bridge\Meta\Tests;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Meta/ModelCatalogTest.php b/src/platform/src/Bridge/Meta/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Meta/ModelCatalogTest.php
rename to src/platform/src/Bridge/Meta/Tests/ModelCatalogTest.php
index f5e8b922f..26992bbae 100644
--- a/src/platform/tests/Bridge/Meta/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Meta/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Meta;
+namespace Symfony\AI\Platform\Bridge\Meta\Tests;
use Symfony\AI\Platform\Bridge\Meta\Llama;
use Symfony\AI\Platform\Bridge\Meta\ModelCatalog;
diff --git a/src/platform/src/Bridge/Meta/composer.json b/src/platform/src/Bridge/Meta/composer.json
new file mode 100644
index 000000000..25027d5dd
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/composer.json
@@ -0,0 +1,51 @@
+{
+ "name": "symfony/ai-meta-platform",
+ "description": "Meta (Llama) platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": ["ai", "bridge", "llama", "meta", "platform"],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Meta\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Meta\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Meta/phpunit.xml.dist b/src/platform/src/Bridge/Meta/phpunit.xml.dist
new file mode 100644
index 000000000..98069dec0
--- /dev/null
+++ b/src/platform/src/Bridge/Meta/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Mistral/.gitattributes b/src/platform/src/Bridge/Mistral/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Mistral/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Mistral/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Mistral/.github/close-pull-request.yml b/src/platform/src/Bridge/Mistral/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Mistral/.gitignore b/src/platform/src/Bridge/Mistral/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Mistral/CHANGELOG.md b/src/platform/src/Bridge/Mistral/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Mistral/LICENSE b/src/platform/src/Bridge/Mistral/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Mistral/README.md b/src/platform/src/Bridge/Mistral/README.md
new file mode 100644
index 000000000..de50da226
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/README.md
@@ -0,0 +1,12 @@
+Mistral Platform
+================
+
+Mistral platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Mistral/Contract/DocumentNormalizerTest.php b/src/platform/src/Bridge/Mistral/Tests/Contract/DocumentNormalizerTest.php
similarity index 88%
rename from src/platform/tests/Bridge/Mistral/Contract/DocumentNormalizerTest.php
rename to src/platform/src/Bridge/Mistral/Tests/Contract/DocumentNormalizerTest.php
index e418e72bc..f53366cfc 100644
--- a/src/platform/tests/Bridge/Mistral/Contract/DocumentNormalizerTest.php
+++ b/src/platform/src/Bridge/Mistral/Tests/Contract/DocumentNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Mistral\Contract;
+namespace Symfony\AI\Platform\Bridge\Mistral\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -54,11 +54,11 @@ public function testNormalize(Document $file, array $expected)
public static function normalizeDataProvider(): iterable
{
yield 'document from file' => [
- Document::fromFile(\dirname(__DIR__, 3).'/Fixtures/document.pdf'),
+ Document::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/document.pdf'),
[
'type' => 'document_url',
'document_name' => 'document.pdf',
- 'document_url' => 'data:application/pdf;base64,'.base64_encode(file_get_contents(\dirname(__DIR__, 3).'/Fixtures/document.pdf')),
+ 'document_url' => 'data:application/pdf;base64,'.base64_encode(file_get_contents(\dirname(__DIR__, 5).'/tests/Fixtures/document.pdf')),
],
];
}
diff --git a/src/platform/tests/Bridge/Mistral/Contract/DocumentUrlNormalizerTest.php b/src/platform/src/Bridge/Mistral/Tests/Contract/DocumentUrlNormalizerTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Mistral/Contract/DocumentUrlNormalizerTest.php
rename to src/platform/src/Bridge/Mistral/Tests/Contract/DocumentUrlNormalizerTest.php
index 573e24091..536497866 100644
--- a/src/platform/tests/Bridge/Mistral/Contract/DocumentUrlNormalizerTest.php
+++ b/src/platform/src/Bridge/Mistral/Tests/Contract/DocumentUrlNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Mistral\Contract;
+namespace Symfony\AI\Platform\Bridge\Mistral\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Mistral/Contract/ImageUrlNormalizerTest.php b/src/platform/src/Bridge/Mistral/Tests/Contract/ImageUrlNormalizerTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Mistral/Contract/ImageUrlNormalizerTest.php
rename to src/platform/src/Bridge/Mistral/Tests/Contract/ImageUrlNormalizerTest.php
diff --git a/src/platform/tests/Bridge/Mistral/ModelCatalogTest.php b/src/platform/src/Bridge/Mistral/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Mistral/ModelCatalogTest.php
rename to src/platform/src/Bridge/Mistral/Tests/ModelCatalogTest.php
index eea0290df..542d83958 100644
--- a/src/platform/tests/Bridge/Mistral/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Mistral/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Mistral;
+namespace Symfony\AI\Platform\Bridge\Mistral\Tests;
use Symfony\AI\Platform\Bridge\Mistral\Embeddings;
use Symfony\AI\Platform\Bridge\Mistral\Mistral;
diff --git a/src/platform/tests/Bridge/Mistral/TokenOutputProcessorTest.php b/src/platform/src/Bridge/Mistral/Tests/TokenOutputProcessorTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Mistral/TokenOutputProcessorTest.php
rename to src/platform/src/Bridge/Mistral/Tests/TokenOutputProcessorTest.php
index ca42f6b14..a0d416789 100644
--- a/src/platform/tests/Bridge/Mistral/TokenOutputProcessorTest.php
+++ b/src/platform/src/Bridge/Mistral/Tests/TokenOutputProcessorTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Mistral;
+namespace Symfony\AI\Platform\Bridge\Mistral\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Agent\Output;
diff --git a/src/platform/src/Bridge/Mistral/composer.json b/src/platform/src/Bridge/Mistral/composer.json
new file mode 100644
index 000000000..a6de39ea0
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-mistral-platform",
+ "description": "Mistral platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "mistral",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-agent": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Mistral\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Mistral\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Mistral/phpunit.xml.dist b/src/platform/src/Bridge/Mistral/phpunit.xml.dist
new file mode 100644
index 000000000..d6c865091
--- /dev/null
+++ b/src/platform/src/Bridge/Mistral/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Ollama/.gitattributes b/src/platform/src/Bridge/Ollama/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Ollama/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Ollama/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Ollama/.github/close-pull-request.yml b/src/platform/src/Bridge/Ollama/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Ollama/.gitignore b/src/platform/src/Bridge/Ollama/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Ollama/CHANGELOG.md b/src/platform/src/Bridge/Ollama/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Ollama/LICENSE b/src/platform/src/Bridge/Ollama/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Ollama/README.md b/src/platform/src/Bridge/Ollama/README.md
new file mode 100644
index 000000000..b711cf4e3
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/README.md
@@ -0,0 +1,12 @@
+Ollama Platform
+===============
+
+Ollama platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Ollama/Contract/AssistantMessageNormalizerTest.php b/src/platform/src/Bridge/Ollama/Tests/Contract/AssistantMessageNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Ollama/Contract/AssistantMessageNormalizerTest.php
rename to src/platform/src/Bridge/Ollama/Tests/Contract/AssistantMessageNormalizerTest.php
index 6f9ee9eb3..64584a145 100644
--- a/src/platform/tests/Bridge/Ollama/Contract/AssistantMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/Ollama/Tests/Contract/AssistantMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Ollama\Contract;
+namespace Symfony\AI\Platform\Bridge\Ollama\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Ollama/ModelCatalogTest.php b/src/platform/src/Bridge/Ollama/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Ollama/ModelCatalogTest.php
rename to src/platform/src/Bridge/Ollama/Tests/ModelCatalogTest.php
index fe2930583..e296eb7ce 100644
--- a/src/platform/tests/Bridge/Ollama/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Ollama/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Ollama;
+namespace Symfony\AI\Platform\Bridge\Ollama\Tests;
use Symfony\AI\Platform\Bridge\Ollama\ModelCatalog;
use Symfony\AI\Platform\Bridge\Ollama\Ollama;
diff --git a/src/platform/tests/Bridge/Ollama/OllamaApiCatalogTest.php b/src/platform/src/Bridge/Ollama/Tests/OllamaApiCatalogTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Ollama/OllamaApiCatalogTest.php
rename to src/platform/src/Bridge/Ollama/Tests/OllamaApiCatalogTest.php
index 4377f5691..2f1e0911c 100644
--- a/src/platform/tests/Bridge/Ollama/OllamaApiCatalogTest.php
+++ b/src/platform/src/Bridge/Ollama/Tests/OllamaApiCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Ollama;
+namespace Symfony\AI\Platform\Bridge\Ollama\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Ollama\Ollama;
diff --git a/src/platform/tests/Bridge/Ollama/OllamaClientTest.php b/src/platform/src/Bridge/Ollama/Tests/OllamaClientTest.php
similarity index 99%
rename from src/platform/tests/Bridge/Ollama/OllamaClientTest.php
rename to src/platform/src/Bridge/Ollama/Tests/OllamaClientTest.php
index f23b7a143..b6daba070 100644
--- a/src/platform/tests/Bridge/Ollama/OllamaClientTest.php
+++ b/src/platform/src/Bridge/Ollama/Tests/OllamaClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Ollama;
+namespace Symfony\AI\Platform\Bridge\Ollama\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Ollama\Ollama;
diff --git a/src/platform/tests/Bridge/Ollama/OllamaResultConverterTest.php b/src/platform/src/Bridge/Ollama/Tests/OllamaResultConverterTest.php
similarity index 99%
rename from src/platform/tests/Bridge/Ollama/OllamaResultConverterTest.php
rename to src/platform/src/Bridge/Ollama/Tests/OllamaResultConverterTest.php
index d4e7a0098..40709416c 100644
--- a/src/platform/tests/Bridge/Ollama/OllamaResultConverterTest.php
+++ b/src/platform/src/Bridge/Ollama/Tests/OllamaResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Ollama;
+namespace Symfony\AI\Platform\Bridge\Ollama\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Ollama\Ollama;
diff --git a/src/platform/src/Bridge/Ollama/composer.json b/src/platform/src/Bridge/Ollama/composer.json
new file mode 100644
index 000000000..f254c0a8a
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-ollama-platform",
+ "description": "Ollama platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "local",
+ "ollama",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Ollama\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Ollama\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Ollama/phpunit.xml.dist b/src/platform/src/Bridge/Ollama/phpunit.xml.dist
new file mode 100644
index 000000000..14b4f6595
--- /dev/null
+++ b/src/platform/src/Bridge/Ollama/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/OpenAi/.gitattributes b/src/platform/src/Bridge/OpenAi/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/OpenAi/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/OpenAi/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/OpenAi/.github/close-pull-request.yml b/src/platform/src/Bridge/OpenAi/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/OpenAi/.gitignore b/src/platform/src/Bridge/OpenAi/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/OpenAi/CHANGELOG.md b/src/platform/src/Bridge/OpenAi/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/OpenAi/LICENSE b/src/platform/src/Bridge/OpenAi/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/OpenAi/README.md b/src/platform/src/Bridge/OpenAi/README.md
new file mode 100644
index 000000000..10333fd86
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/README.md
@@ -0,0 +1,19 @@
+OpenAI Platform
+===============
+
+Provides [OpenAI](https://openai.com/) platform integration for Symfony AI Platform.
+
+This bridge includes support for:
+- GPT models (chat completions)
+- Embeddings
+- DALL-E (image generation)
+- Whisper (audio transcription)
+- Text-to-Speech
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/DocumentNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/DocumentNormalizerTest.php
similarity index 90%
rename from src/platform/tests/Bridge/OpenAi/Contract/DocumentNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/DocumentNormalizerTest.php
index afc5cc4f7..c602bfb6b 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/DocumentNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/DocumentNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -54,12 +54,12 @@ public function testNormalize(Document $document, array $expected)
public static function normalizeDataProvider(): iterable
{
yield 'document from file' => [
- Document::fromFile(\dirname(__DIR__, 6).'/fixtures/document.pdf'),
+ Document::fromFile(\dirname(__DIR__, 7).'/fixtures/document.pdf'),
[
'type' => 'file',
'file' => [
'filename' => 'document.pdf',
- 'file_data' => 'data:application/pdf;base64,'.base64_encode(file_get_contents(\dirname(__DIR__, 6).'/fixtures/document.pdf')),
+ 'file_data' => 'data:application/pdf;base64,'.base64_encode(file_get_contents(\dirname(__DIR__, 7).'/fixtures/document.pdf')),
],
],
];
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/AssistantMessageNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/AssistantMessageNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/AssistantMessageNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/AssistantMessageNormalizerTest.php
index b8c401a81..8c24ae1cc 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/AssistantMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/AssistantMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt\Message;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt\Message;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/DocumentNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/DocumentNormalizerTest.php
similarity index 89%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/DocumentNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/DocumentNormalizerTest.php
index 9525ace68..75d8ba702 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/DocumentNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/DocumentNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt\Message\Content;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt\Message\Content;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -26,7 +26,7 @@ class DocumentNormalizerTest extends TestCase
{
public function testNormalize()
{
- $doc = Document::fromFile(\dirname(__DIR__, 9).'/fixtures/document.pdf');
+ $doc = Document::fromFile(\dirname(__DIR__, 10).'/fixtures/document.pdf');
$actual = (new DocumentNormalizer())->normalize($doc, null, [Contract::CONTEXT_MODEL => new Gpt('o3')]);
$this->assertEquals([
@@ -47,7 +47,7 @@ public function testSupportsNormalization(mixed $data, Model $model, bool $expec
public static function supportsNormalizationProvider(): \Generator
{
- $doc = Document::fromFile(\dirname(__DIR__, 9).'/fixtures/document.pdf');
+ $doc = Document::fromFile(\dirname(__DIR__, 10).'/fixtures/document.pdf');
$gpt = new Gpt('o3', [Capability::INPUT_PDF]);
yield 'supported' => [$doc, $gpt, true];
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/ImageNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/ImageNormalizerTest.php
similarity index 89%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/ImageNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/ImageNormalizerTest.php
index 55f986f2e..49929e007 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/ImageNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/ImageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt\Message\Content;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt\Message\Content;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -26,7 +26,7 @@ class ImageNormalizerTest extends TestCase
{
public function testNormalize()
{
- $image = Image::fromFile(\dirname(__DIR__, 9).'/fixtures/image.jpg');
+ $image = Image::fromFile(\dirname(__DIR__, 10).'/fixtures/image.jpg');
$actual = (new ImageNormalizer())->normalize($image, null, [Contract::CONTEXT_MODEL => new Gpt('o3')]);
$this->assertEquals([
@@ -46,7 +46,7 @@ public function testSupportsNormalization(mixed $data, Model $model, bool $expec
public static function supportsNormalizationProvider(): \Generator
{
- $image = Image::fromFile(\dirname(__DIR__, 9).'/fixtures/image.jpg');
+ $image = Image::fromFile(\dirname(__DIR__, 10).'/fixtures/image.jpg');
$gpt = new Gpt('o3', [Capability::INPUT_IMAGE]);
yield 'supported' => [$image, $gpt, true];
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/ImageUrlNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/ImageUrlNormalizerTest.php
similarity index 96%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/ImageUrlNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/ImageUrlNormalizerTest.php
index 60ae8fe94..4079e841b 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/ImageUrlNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/ImageUrlNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt\Message\Content;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt\Message\Content;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/TextNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/TextNormalizerTest.php
similarity index 96%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/TextNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/TextNormalizerTest.php
index 2527638b6..5b8bfab63 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/Content/TextNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/Content/TextNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt\Message\Content;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt\Message\Content;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/MessageBagNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/MessageBagNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/MessageBagNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/MessageBagNormalizerTest.php
index 019220c8c..8cf9914f3 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/MessageBagNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/MessageBagNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt\Message;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt\Message;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/ToolCallMessageNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/ToolCallMessageNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/ToolCallMessageNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/ToolCallMessageNormalizerTest.php
index 4bb69a131..d213c4282 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/Message/ToolCallMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/Message/ToolCallMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt\Message;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt\Message;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/ToolCallNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/ToolCallNormalizerTest.php
similarity index 96%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/ToolCallNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/ToolCallNormalizerTest.php
index 0b4e7c188..ef2c99365 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/ToolCallNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/ToolCallNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/ToolNormalizerTest.php b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/ToolNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/OpenAi/Contract/Gpt/ToolNormalizerTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/ToolNormalizerTest.php
index 71b7d2868..e6e330fc0 100644
--- a/src/platform/tests/Bridge/OpenAi/Contract/Gpt/ToolNormalizerTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Contract/Gpt/ToolNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Contract\Gpt;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Contract\Gpt;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/DallE/Base64ImageTest.php b/src/platform/src/Bridge/OpenAi/Tests/DallE/Base64ImageTest.php
similarity index 94%
rename from src/platform/tests/Bridge/OpenAi/DallE/Base64ImageTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/DallE/Base64ImageTest.php
index 79eddb197..0bd63fd16 100644
--- a/src/platform/tests/Bridge/OpenAi/DallE/Base64ImageTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/DallE/Base64ImageTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\DallE;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\DallE;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\DallE\Base64Image;
diff --git a/src/platform/tests/Bridge/OpenAi/DallE/ImageResultTest.php b/src/platform/src/Bridge/OpenAi/Tests/DallE/ImageResultTest.php
similarity index 97%
rename from src/platform/tests/Bridge/OpenAi/DallE/ImageResultTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/DallE/ImageResultTest.php
index cae6017ee..74915d93d 100644
--- a/src/platform/tests/Bridge/OpenAi/DallE/ImageResultTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/DallE/ImageResultTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\DallE;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\DallE;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\DallE\Base64Image;
diff --git a/src/platform/tests/Bridge/OpenAi/DallE/ModelClientTest.php b/src/platform/src/Bridge/OpenAi/Tests/DallE/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/OpenAi/DallE/ModelClientTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/DallE/ModelClientTest.php
index cd365d9e1..757445b8e 100644
--- a/src/platform/tests/Bridge/OpenAi/DallE/ModelClientTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/DallE/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\DallE;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\DallE;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/DallE/ResultConverterTest.php b/src/platform/src/Bridge/OpenAi/Tests/DallE/ResultConverterTest.php
similarity index 97%
rename from src/platform/tests/Bridge/OpenAi/DallE/ResultConverterTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/DallE/ResultConverterTest.php
index d96030c46..7c6bac4ed 100644
--- a/src/platform/tests/Bridge/OpenAi/DallE/ResultConverterTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/DallE/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\DallE;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\DallE;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\DallE\Base64Image;
diff --git a/src/platform/tests/Bridge/OpenAi/DallE/UrlImageTest.php b/src/platform/src/Bridge/OpenAi/Tests/DallE/UrlImageTest.php
similarity index 93%
rename from src/platform/tests/Bridge/OpenAi/DallE/UrlImageTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/DallE/UrlImageTest.php
index 0e97b591d..70f8e4b96 100644
--- a/src/platform/tests/Bridge/OpenAi/DallE/UrlImageTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/DallE/UrlImageTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\DallE;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\DallE;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\DallE\UrlImage;
diff --git a/src/platform/tests/Bridge/OpenAi/DallETest.php b/src/platform/src/Bridge/OpenAi/Tests/DallETest.php
similarity index 94%
rename from src/platform/tests/Bridge/OpenAi/DallETest.php
rename to src/platform/src/Bridge/OpenAi/Tests/DallETest.php
index 01d9738c1..8bd3a7b66 100644
--- a/src/platform/tests/Bridge/OpenAi/DallETest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/DallETest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\DallE;
diff --git a/src/platform/tests/Bridge/OpenAi/Embeddings/ModelClientTest.php b/src/platform/src/Bridge/OpenAi/Tests/Embeddings/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/OpenAi/Embeddings/ModelClientTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Embeddings/ModelClientTest.php
index 1f37e77a3..32ba0ad5a 100644
--- a/src/platform/tests/Bridge/OpenAi/Embeddings/ModelClientTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Embeddings/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Embeddings;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Embeddings;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Embeddings/ResultConverterTest.php b/src/platform/src/Bridge/OpenAi/Tests/Embeddings/ResultConverterTest.php
similarity index 96%
rename from src/platform/tests/Bridge/OpenAi/Embeddings/ResultConverterTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Embeddings/ResultConverterTest.php
index e7c6689f0..e3c13b851 100644
--- a/src/platform/tests/Bridge/OpenAi/Embeddings/ResultConverterTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Embeddings/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Embeddings;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Embeddings;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\Embeddings\ResultConverter;
diff --git a/src/platform/tests/Bridge/OpenAi/EmbeddingsTest.php b/src/platform/src/Bridge/OpenAi/Tests/EmbeddingsTest.php
similarity index 96%
rename from src/platform/tests/Bridge/OpenAi/EmbeddingsTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/EmbeddingsTest.php
index 3b72d0c86..90ae7d5fc 100644
--- a/src/platform/tests/Bridge/OpenAi/EmbeddingsTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/EmbeddingsTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\Embeddings;
diff --git a/src/platform/tests/Bridge/OpenAi/Gpt/ModelClientTest.php b/src/platform/src/Bridge/OpenAi/Tests/Gpt/ModelClientTest.php
similarity index 99%
rename from src/platform/tests/Bridge/OpenAi/Gpt/ModelClientTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Gpt/ModelClientTest.php
index be7bb756a..0be6d8d3d 100644
--- a/src/platform/tests/Bridge/OpenAi/Gpt/ModelClientTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Gpt/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Gpt;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Gpt;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterRateLimitTest.php b/src/platform/src/Bridge/OpenAi/Tests/Gpt/ResultConverterRateLimitTest.php
similarity index 97%
rename from src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterRateLimitTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Gpt/ResultConverterRateLimitTest.php
index c2537b8fb..807c862dc 100644
--- a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterRateLimitTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Gpt/ResultConverterRateLimitTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Gpt;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Gpt;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter;
diff --git a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php b/src/platform/src/Bridge/OpenAi/Tests/Gpt/ResultConverterTest.php
similarity index 99%
rename from src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Gpt/ResultConverterTest.php
index 1138fef56..0ade6d797 100644
--- a/src/platform/tests/Bridge/OpenAi/Gpt/ResultConverterTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Gpt/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Gpt;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Gpt;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\Gpt\ResultConverter;
diff --git a/src/platform/tests/Bridge/OpenAi/GptTest.php b/src/platform/src/Bridge/OpenAi/Tests/GptTest.php
similarity index 94%
rename from src/platform/tests/Bridge/OpenAi/GptTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/GptTest.php
index 2073cd93d..b70b57c75 100644
--- a/src/platform/tests/Bridge/OpenAi/GptTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/GptTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\Gpt;
diff --git a/src/platform/tests/Bridge/OpenAi/ModelCatalogTest.php b/src/platform/src/Bridge/OpenAi/Tests/ModelCatalogTest.php
similarity index 99%
rename from src/platform/tests/Bridge/OpenAi/ModelCatalogTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/ModelCatalogTest.php
index ff02cfc02..a6734d994 100644
--- a/src/platform/tests/Bridge/OpenAi/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests;
use Symfony\AI\Platform\Bridge\OpenAi\DallE;
use Symfony\AI\Platform\Bridge\OpenAi\Embeddings;
diff --git a/src/platform/tests/Bridge/OpenAi/PlatformFactoryTest.php b/src/platform/src/Bridge/OpenAi/Tests/PlatformFactoryTest.php
similarity index 96%
rename from src/platform/tests/Bridge/OpenAi/PlatformFactoryTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/PlatformFactoryTest.php
index 2c97ffcb9..1e4337144 100644
--- a/src/platform/tests/Bridge/OpenAi/PlatformFactoryTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/PlatformFactoryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
diff --git a/src/platform/tests/Bridge/OpenAi/TextToSpeech/ModelClientTest.php b/src/platform/src/Bridge/OpenAi/Tests/TextToSpeech/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/OpenAi/TextToSpeech/ModelClientTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/TextToSpeech/ModelClientTest.php
index 018f74d6d..3d4dd7303 100644
--- a/src/platform/tests/Bridge/OpenAi/TextToSpeech/ModelClientTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/TextToSpeech/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\TextToSpeech;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\TextToSpeech;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\TextToSpeech;
diff --git a/src/platform/tests/Bridge/OpenAi/TextToSpeech/ResultConverterTest.php b/src/platform/src/Bridge/OpenAi/Tests/TextToSpeech/ResultConverterTest.php
similarity index 97%
rename from src/platform/tests/Bridge/OpenAi/TextToSpeech/ResultConverterTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/TextToSpeech/ResultConverterTest.php
index 3071c140f..e99b21a67 100644
--- a/src/platform/tests/Bridge/OpenAi/TextToSpeech/ResultConverterTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/TextToSpeech/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\TextToSpeech;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\TextToSpeech;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\TextToSpeech;
diff --git a/src/platform/tests/Bridge/OpenAi/TokenOutputProcessorTest.php b/src/platform/src/Bridge/OpenAi/Tests/TokenOutputProcessorTest.php
similarity index 98%
rename from src/platform/tests/Bridge/OpenAi/TokenOutputProcessorTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/TokenOutputProcessorTest.php
index 7e46efeb2..ffef442e9 100644
--- a/src/platform/tests/Bridge/OpenAi/TokenOutputProcessorTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/TokenOutputProcessorTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Agent\Output;
diff --git a/src/platform/tests/Bridge/OpenAi/Whisper/ModelClientTest.php b/src/platform/src/Bridge/OpenAi/Tests/Whisper/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/OpenAi/Whisper/ModelClientTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/Whisper/ModelClientTest.php
index 70065a7e1..a9968f7a2 100644
--- a/src/platform/tests/Bridge/OpenAi/Whisper/ModelClientTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/Whisper/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi\Whisper;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests\Whisper;
use PHPUnit\Framework\Attributes\TestWith;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/OpenAi/WhisperTest.php b/src/platform/src/Bridge/OpenAi/Tests/WhisperTest.php
similarity index 95%
rename from src/platform/tests/Bridge/OpenAi/WhisperTest.php
rename to src/platform/src/Bridge/OpenAi/Tests/WhisperTest.php
index 0a8b79f85..07bc1259b 100644
--- a/src/platform/tests/Bridge/OpenAi/WhisperTest.php
+++ b/src/platform/src/Bridge/OpenAi/Tests/WhisperTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenAi;
+namespace Symfony\AI\Platform\Bridge\OpenAi\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenAi\Whisper;
diff --git a/src/platform/src/Bridge/OpenAi/composer.json b/src/platform/src/Bridge/OpenAi/composer.json
new file mode 100644
index 000000000..65fcf2f1a
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/composer.json
@@ -0,0 +1,64 @@
+{
+ "name": "symfony/ai-open-ai-platform",
+ "description": "OpenAI platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "chatgpt",
+ "dall-e",
+ "embeddings",
+ "gpt",
+ "openai",
+ "platform",
+ "text-to-speech",
+ "whisper"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-agent": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\OpenAi\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\OpenAi\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/OpenAi/phpunit.xml.dist b/src/platform/src/Bridge/OpenAi/phpunit.xml.dist
new file mode 100644
index 000000000..9e2e89daf
--- /dev/null
+++ b/src/platform/src/Bridge/OpenAi/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/OpenRouter/.gitattributes b/src/platform/src/Bridge/OpenRouter/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/OpenRouter/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/OpenRouter/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/OpenRouter/.github/close-pull-request.yml b/src/platform/src/Bridge/OpenRouter/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/OpenRouter/.gitignore b/src/platform/src/Bridge/OpenRouter/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/OpenRouter/CHANGELOG.md b/src/platform/src/Bridge/OpenRouter/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/OpenRouter/LICENSE b/src/platform/src/Bridge/OpenRouter/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/OpenRouter/README.md b/src/platform/src/Bridge/OpenRouter/README.md
new file mode 100644
index 000000000..0277fcc10
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/README.md
@@ -0,0 +1,12 @@
+OpenRouter Platform
+===================
+
+OpenRouter platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/OpenRouter/ModelApiCatalogTest.php b/src/platform/src/Bridge/OpenRouter/Tests/ModelApiCatalogTest.php
similarity index 99%
rename from src/platform/tests/Bridge/OpenRouter/ModelApiCatalogTest.php
rename to src/platform/src/Bridge/OpenRouter/Tests/ModelApiCatalogTest.php
index f37ab15a6..aa0cb21e1 100644
--- a/src/platform/tests/Bridge/OpenRouter/ModelApiCatalogTest.php
+++ b/src/platform/src/Bridge/OpenRouter/Tests/ModelApiCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenRouter;
+namespace Symfony\AI\Platform\Bridge\OpenRouter\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
diff --git a/src/platform/tests/Bridge/OpenRouter/ModelCatalogTest.php b/src/platform/src/Bridge/OpenRouter/Tests/ModelCatalogTest.php
similarity index 99%
rename from src/platform/tests/Bridge/OpenRouter/ModelCatalogTest.php
rename to src/platform/src/Bridge/OpenRouter/Tests/ModelCatalogTest.php
index 8ff5c4463..798ef6288 100644
--- a/src/platform/tests/Bridge/OpenRouter/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/OpenRouter/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenRouter;
+namespace Symfony\AI\Platform\Bridge\OpenRouter\Tests;
use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\AI\Platform\Bridge\Generic\CompletionsModel;
diff --git a/src/platform/tests/Bridge/OpenRouter/PlatformFactoryTest.php b/src/platform/src/Bridge/OpenRouter/Tests/PlatformFactoryTest.php
similarity index 96%
rename from src/platform/tests/Bridge/OpenRouter/PlatformFactoryTest.php
rename to src/platform/src/Bridge/OpenRouter/Tests/PlatformFactoryTest.php
index a392cb0e3..717bdadef 100644
--- a/src/platform/tests/Bridge/OpenRouter/PlatformFactoryTest.php
+++ b/src/platform/src/Bridge/OpenRouter/Tests/PlatformFactoryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\OpenRouter;
+namespace Symfony\AI\Platform\Bridge\OpenRouter\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\OpenRouter\PlatformFactory;
diff --git a/src/platform/src/Bridge/OpenRouter/composer.json b/src/platform/src/Bridge/OpenRouter/composer.json
new file mode 100644
index 000000000..bd24f682c
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-open-router-platform",
+ "description": "OpenRouter platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "openrouter",
+ "platform"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-generic-platform": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\OpenRouter\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\OpenRouter\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/OpenRouter/phpunit.xml.dist b/src/platform/src/Bridge/OpenRouter/phpunit.xml.dist
new file mode 100644
index 000000000..e6f0a260f
--- /dev/null
+++ b/src/platform/src/Bridge/OpenRouter/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Perplexity/.gitattributes b/src/platform/src/Bridge/Perplexity/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Perplexity/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Perplexity/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Perplexity/.github/close-pull-request.yml b/src/platform/src/Bridge/Perplexity/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Perplexity/.gitignore b/src/platform/src/Bridge/Perplexity/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Perplexity/CHANGELOG.md b/src/platform/src/Bridge/Perplexity/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Perplexity/LICENSE b/src/platform/src/Bridge/Perplexity/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Perplexity/README.md b/src/platform/src/Bridge/Perplexity/README.md
new file mode 100644
index 000000000..c007a4754
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/README.md
@@ -0,0 +1,12 @@
+Perplexity Platform
+===================
+
+Perplexity platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Perplexity/Contract/FileUrlNormalizerTest.php b/src/platform/src/Bridge/Perplexity/Tests/Contract/FileUrlNormalizerTest.php
similarity index 87%
rename from src/platform/tests/Bridge/Perplexity/Contract/FileUrlNormalizerTest.php
rename to src/platform/src/Bridge/Perplexity/Tests/Contract/FileUrlNormalizerTest.php
index de8228354..7ddcfe6e5 100644
--- a/src/platform/tests/Bridge/Perplexity/Contract/FileUrlNormalizerTest.php
+++ b/src/platform/src/Bridge/Perplexity/Tests/Contract/FileUrlNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Perplexity\Contract;
+namespace Symfony\AI\Platform\Bridge\Perplexity\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -24,7 +24,7 @@ public function testSupportsNormalization()
{
$normalizer = new FileUrlNormalizer();
- $this->assertTrue($normalizer->supportsNormalization(new DocumentUrl(\dirname(__DIR__, 6).'/fixtures/not-a-document.pdf'), context: [
+ $this->assertTrue($normalizer->supportsNormalization(new DocumentUrl(\dirname(__DIR__, 7).'/fixtures/not-a-document.pdf'), context: [
Contract::CONTEXT_MODEL => new Perplexity('sonar'),
]));
$this->assertFalse($normalizer->supportsNormalization('not a document'));
@@ -54,11 +54,11 @@ public function testNormalize(DocumentUrl $document, array $expected)
public static function normalizeDataProvider(): iterable
{
yield 'document from file url' => [
- new DocumentUrl(\dirname(__DIR__, 6).'/fixtures/document.pdf'),
+ new DocumentUrl(\dirname(__DIR__, 7).'/fixtures/document.pdf'),
[
'type' => 'file_url',
'file_url' => [
- 'url' => \dirname(__DIR__, 6).'/fixtures/document.pdf',
+ 'url' => \dirname(__DIR__, 7).'/fixtures/document.pdf',
],
],
];
diff --git a/src/platform/tests/Bridge/Perplexity/ModelCatalogTest.php b/src/platform/src/Bridge/Perplexity/Tests/ModelCatalogTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Perplexity/ModelCatalogTest.php
rename to src/platform/src/Bridge/Perplexity/Tests/ModelCatalogTest.php
index ae1180661..c94b60a11 100644
--- a/src/platform/tests/Bridge/Perplexity/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Perplexity/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Perplexity;
+namespace Symfony\AI\Platform\Bridge\Perplexity\Tests;
use Symfony\AI\Platform\Bridge\Perplexity\ModelCatalog;
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
diff --git a/src/platform/tests/Bridge/Perplexity/ModelClientTest.php b/src/platform/src/Bridge/Perplexity/Tests/ModelClientTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Perplexity/ModelClientTest.php
rename to src/platform/src/Bridge/Perplexity/Tests/ModelClientTest.php
diff --git a/src/platform/tests/Bridge/Perplexity/PerplexityTest.php b/src/platform/src/Bridge/Perplexity/Tests/PerplexityTest.php
similarity index 94%
rename from src/platform/tests/Bridge/Perplexity/PerplexityTest.php
rename to src/platform/src/Bridge/Perplexity/Tests/PerplexityTest.php
index 5c9300861..f6f770cd8 100644
--- a/src/platform/tests/Bridge/Perplexity/PerplexityTest.php
+++ b/src/platform/src/Bridge/Perplexity/Tests/PerplexityTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Perplexity;
+namespace Symfony\AI\Platform\Bridge\Perplexity\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
diff --git a/src/platform/tests/Bridge/Perplexity/PlatformFactoryTest.php b/src/platform/src/Bridge/Perplexity/Tests/PlatformFactoryTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Perplexity/PlatformFactoryTest.php
rename to src/platform/src/Bridge/Perplexity/Tests/PlatformFactoryTest.php
index 0a6b6d07c..0fd484600 100644
--- a/src/platform/tests/Bridge/Perplexity/PlatformFactoryTest.php
+++ b/src/platform/src/Bridge/Perplexity/Tests/PlatformFactoryTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Perplexity;
+namespace Symfony\AI\Platform\Bridge\Perplexity\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
diff --git a/src/platform/tests/Bridge/Perplexity/ResultConverterTest.php b/src/platform/src/Bridge/Perplexity/Tests/ResultConverterTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Perplexity/ResultConverterTest.php
rename to src/platform/src/Bridge/Perplexity/Tests/ResultConverterTest.php
index 0d589baf0..f16957b72 100644
--- a/src/platform/tests/Bridge/Perplexity/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Perplexity/Tests/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Perplexity;
+namespace Symfony\AI\Platform\Bridge\Perplexity\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Perplexity\ResultConverter;
diff --git a/src/platform/tests/Bridge/Perplexity/TokenOutputProcessorTest.php b/src/platform/src/Bridge/Perplexity/Tests/TokenOutputProcessorTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Perplexity/TokenOutputProcessorTest.php
rename to src/platform/src/Bridge/Perplexity/Tests/TokenOutputProcessorTest.php
index cb640dc9a..3660ce091 100644
--- a/src/platform/tests/Bridge/Perplexity/TokenOutputProcessorTest.php
+++ b/src/platform/src/Bridge/Perplexity/Tests/TokenOutputProcessorTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Perplexity;
+namespace Symfony\AI\Platform\Bridge\Perplexity\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Agent\Output;
diff --git a/src/platform/src/Bridge/Perplexity/composer.json b/src/platform/src/Bridge/Perplexity/composer.json
new file mode 100644
index 000000000..3934ccf7c
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/composer.json
@@ -0,0 +1,59 @@
+{
+ "name": "symfony/ai-perplexity-platform",
+ "description": "Perplexity platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "perplexity",
+ "platform",
+ "search"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-agent": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Perplexity\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Perplexity\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Perplexity/phpunit.xml.dist b/src/platform/src/Bridge/Perplexity/phpunit.xml.dist
new file mode 100644
index 000000000..69ee9f367
--- /dev/null
+++ b/src/platform/src/Bridge/Perplexity/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Replicate/.gitattributes b/src/platform/src/Bridge/Replicate/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Replicate/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Replicate/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Replicate/.github/close-pull-request.yml b/src/platform/src/Bridge/Replicate/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Replicate/.gitignore b/src/platform/src/Bridge/Replicate/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Replicate/CHANGELOG.md b/src/platform/src/Bridge/Replicate/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Replicate/LICENSE b/src/platform/src/Bridge/Replicate/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Replicate/README.md b/src/platform/src/Bridge/Replicate/README.md
new file mode 100644
index 000000000..300a1f7a7
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/README.md
@@ -0,0 +1,12 @@
+Replicate Platform
+==================
+
+Replicate platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Replicate/ClientTest.php b/src/platform/src/Bridge/Replicate/Tests/ClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Replicate/ClientTest.php
rename to src/platform/src/Bridge/Replicate/Tests/ClientTest.php
index 3c0054aaf..97fec5e7b 100644
--- a/src/platform/tests/Bridge/Replicate/ClientTest.php
+++ b/src/platform/src/Bridge/Replicate/Tests/ClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Replicate;
+namespace Symfony\AI\Platform\Bridge\Replicate\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Replicate\Client;
diff --git a/src/platform/tests/Bridge/Replicate/Contract/LlamaMessageBagNormalizerTest.php b/src/platform/src/Bridge/Replicate/Tests/Contract/LlamaMessageBagNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Replicate/Contract/LlamaMessageBagNormalizerTest.php
rename to src/platform/src/Bridge/Replicate/Tests/Contract/LlamaMessageBagNormalizerTest.php
index ba0768c4b..d1368fdc6 100644
--- a/src/platform/tests/Bridge/Replicate/Contract/LlamaMessageBagNormalizerTest.php
+++ b/src/platform/src/Bridge/Replicate/Tests/Contract/LlamaMessageBagNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Replicate\Contract;
+namespace Symfony\AI\Platform\Bridge\Replicate\Tests\Contract;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Meta\Llama;
diff --git a/src/platform/tests/Bridge/Replicate/LlamaModelClientTest.php b/src/platform/src/Bridge/Replicate/Tests/LlamaModelClientTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Replicate/LlamaModelClientTest.php
rename to src/platform/src/Bridge/Replicate/Tests/LlamaModelClientTest.php
index 04494ebd0..3edf3dc95 100644
--- a/src/platform/tests/Bridge/Replicate/LlamaModelClientTest.php
+++ b/src/platform/src/Bridge/Replicate/Tests/LlamaModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Replicate;
+namespace Symfony\AI\Platform\Bridge\Replicate\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Meta\Llama;
diff --git a/src/platform/tests/Bridge/Replicate/LlamaResultConverterTest.php b/src/platform/src/Bridge/Replicate/Tests/LlamaResultConverterTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Replicate/LlamaResultConverterTest.php
rename to src/platform/src/Bridge/Replicate/Tests/LlamaResultConverterTest.php
index ab30e0696..7a6558094 100644
--- a/src/platform/tests/Bridge/Replicate/LlamaResultConverterTest.php
+++ b/src/platform/src/Bridge/Replicate/Tests/LlamaResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Replicate;
+namespace Symfony\AI\Platform\Bridge\Replicate\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Meta\Llama;
diff --git a/src/platform/tests/Bridge/Replicate/ModelCatalogTest.php b/src/platform/src/Bridge/Replicate/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Replicate/ModelCatalogTest.php
rename to src/platform/src/Bridge/Replicate/Tests/ModelCatalogTest.php
index 7c8aea162..0de3d74c4 100644
--- a/src/platform/tests/Bridge/Replicate/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Replicate/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Replicate;
+namespace Symfony\AI\Platform\Bridge\Replicate\Tests;
use Symfony\AI\Platform\Bridge\Meta\Llama;
use Symfony\AI\Platform\Bridge\Replicate\ModelCatalog;
diff --git a/src/platform/src/Bridge/Replicate/composer.json b/src/platform/src/Bridge/Replicate/composer.json
new file mode 100644
index 000000000..b488aea90
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-replicate-platform",
+ "description": "Replicate platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "platform",
+ "replicate"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-meta-platform": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Replicate\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Replicate\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Replicate/phpunit.xml.dist b/src/platform/src/Bridge/Replicate/phpunit.xml.dist
new file mode 100644
index 000000000..03b5ac241
--- /dev/null
+++ b/src/platform/src/Bridge/Replicate/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Scaleway/.gitattributes b/src/platform/src/Bridge/Scaleway/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Scaleway/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Scaleway/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Scaleway/.github/close-pull-request.yml b/src/platform/src/Bridge/Scaleway/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Scaleway/.gitignore b/src/platform/src/Bridge/Scaleway/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Scaleway/CHANGELOG.md b/src/platform/src/Bridge/Scaleway/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Scaleway/LICENSE b/src/platform/src/Bridge/Scaleway/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Scaleway/README.md b/src/platform/src/Bridge/Scaleway/README.md
new file mode 100644
index 000000000..e99640545
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/README.md
@@ -0,0 +1,12 @@
+Scaleway Platform
+=================
+
+Scaleway platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Scaleway/Embeddings/ModelClientTest.php b/src/platform/src/Bridge/Scaleway/Tests/Embeddings/ModelClientTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Scaleway/Embeddings/ModelClientTest.php
rename to src/platform/src/Bridge/Scaleway/Tests/Embeddings/ModelClientTest.php
diff --git a/src/platform/tests/Bridge/Scaleway/Embeddings/ResultConverterTest.php b/src/platform/src/Bridge/Scaleway/Tests/Embeddings/ResultConverterTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Scaleway/Embeddings/ResultConverterTest.php
rename to src/platform/src/Bridge/Scaleway/Tests/Embeddings/ResultConverterTest.php
diff --git a/src/platform/tests/Bridge/Scaleway/EmbeddingsTest.php b/src/platform/src/Bridge/Scaleway/Tests/EmbeddingsTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Scaleway/EmbeddingsTest.php
rename to src/platform/src/Bridge/Scaleway/Tests/EmbeddingsTest.php
diff --git a/src/platform/tests/Bridge/Scaleway/Llm/ModelClientTest.php b/src/platform/src/Bridge/Scaleway/Tests/Llm/ModelClientTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Scaleway/Llm/ModelClientTest.php
rename to src/platform/src/Bridge/Scaleway/Tests/Llm/ModelClientTest.php
diff --git a/src/platform/tests/Bridge/Scaleway/Llm/ResultConverterTest.php b/src/platform/src/Bridge/Scaleway/Tests/Llm/ResultConverterTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Scaleway/Llm/ResultConverterTest.php
rename to src/platform/src/Bridge/Scaleway/Tests/Llm/ResultConverterTest.php
diff --git a/src/platform/tests/Bridge/Scaleway/ModelCatalogTest.php b/src/platform/src/Bridge/Scaleway/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Scaleway/ModelCatalogTest.php
rename to src/platform/src/Bridge/Scaleway/Tests/ModelCatalogTest.php
index e323d408a..6eec0739f 100644
--- a/src/platform/tests/Bridge/Scaleway/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Scaleway/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Scaleway;
+namespace Symfony\AI\Platform\Bridge\Scaleway\Tests;
use Symfony\AI\Platform\Bridge\Scaleway\Embeddings;
use Symfony\AI\Platform\Bridge\Scaleway\ModelCatalog;
diff --git a/src/platform/tests/Bridge/Scaleway/PlatformFactoryTest.php b/src/platform/src/Bridge/Scaleway/Tests/PlatformFactoryTest.php
similarity index 100%
rename from src/platform/tests/Bridge/Scaleway/PlatformFactoryTest.php
rename to src/platform/src/Bridge/Scaleway/Tests/PlatformFactoryTest.php
diff --git a/src/platform/src/Bridge/Scaleway/composer.json b/src/platform/src/Bridge/Scaleway/composer.json
new file mode 100644
index 000000000..d505c5227
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/composer.json
@@ -0,0 +1,57 @@
+{
+ "name": "symfony/ai-scaleway-platform",
+ "description": "Scaleway platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "platform",
+ "scaleway"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Scaleway\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Scaleway\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Scaleway/phpunit.xml.dist b/src/platform/src/Bridge/Scaleway/phpunit.xml.dist
new file mode 100644
index 000000000..b9ce20946
--- /dev/null
+++ b/src/platform/src/Bridge/Scaleway/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/TransformersPhp/.gitattributes b/src/platform/src/Bridge/TransformersPhp/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/TransformersPhp/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/TransformersPhp/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/TransformersPhp/.github/close-pull-request.yml b/src/platform/src/Bridge/TransformersPhp/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/TransformersPhp/.gitignore b/src/platform/src/Bridge/TransformersPhp/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/TransformersPhp/CHANGELOG.md b/src/platform/src/Bridge/TransformersPhp/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/TransformersPhp/LICENSE b/src/platform/src/Bridge/TransformersPhp/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/TransformersPhp/README.md b/src/platform/src/Bridge/TransformersPhp/README.md
new file mode 100644
index 000000000..2794c1d5d
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/README.md
@@ -0,0 +1,12 @@
+TransformersPhp Platform
+========================
+
+TransformersPhp platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/TransformersPhp/ModelCatalogTest.php b/src/platform/src/Bridge/TransformersPhp/Tests/ModelCatalogTest.php
similarity index 95%
rename from src/platform/tests/Bridge/TransformersPhp/ModelCatalogTest.php
rename to src/platform/src/Bridge/TransformersPhp/Tests/ModelCatalogTest.php
index 345479666..947c6f361 100644
--- a/src/platform/tests/Bridge/TransformersPhp/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/TransformersPhp/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\TransformersPhp;
+namespace Symfony\AI\Platform\Bridge\TransformersPhp\Tests;
use Symfony\AI\Platform\Bridge\TransformersPhp\ModelCatalog;
use Symfony\AI\Platform\Capability;
diff --git a/src/platform/src/Bridge/TransformersPhp/composer.json b/src/platform/src/Bridge/TransformersPhp/composer.json
new file mode 100644
index 000000000..2ed49607f
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/composer.json
@@ -0,0 +1,56 @@
+{
+ "name": "symfony/ai-transformers-php-platform",
+ "description": "TransformersPhp platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": ["ai", "bridge", "local", "platform", "transformers"],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "codewithkyrian/transformers": "^0.6.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\TransformersPhp\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\TransformersPhp\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "allow-plugins": {
+ "codewithkyrian/platform-package-installer": true,
+ "codewithkyrian/transformers-libsloader": true
+ },
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/TransformersPhp/phpunit.xml.dist b/src/platform/src/Bridge/TransformersPhp/phpunit.xml.dist
new file mode 100644
index 000000000..0e4c671ac
--- /dev/null
+++ b/src/platform/src/Bridge/TransformersPhp/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/VertexAi/.gitattributes b/src/platform/src/Bridge/VertexAi/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/VertexAi/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/VertexAi/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/VertexAi/.github/close-pull-request.yml b/src/platform/src/Bridge/VertexAi/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/VertexAi/.gitignore b/src/platform/src/Bridge/VertexAi/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/VertexAi/CHANGELOG.md b/src/platform/src/Bridge/VertexAi/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/VertexAi/LICENSE b/src/platform/src/Bridge/VertexAi/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/VertexAi/README.md b/src/platform/src/Bridge/VertexAi/README.md
new file mode 100644
index 000000000..66c6f8933
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/README.md
@@ -0,0 +1,12 @@
+VertexAi Platform
+=================
+
+Google Vertex AI platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/VertexAi/Contract/AssistantMessageNormalizerTest.php b/src/platform/src/Bridge/VertexAi/Tests/Contract/AssistantMessageNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/VertexAi/Contract/AssistantMessageNormalizerTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Contract/AssistantMessageNormalizerTest.php
index 0e356fb2a..5974e3570 100644
--- a/src/platform/tests/Bridge/VertexAi/Contract/AssistantMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Contract/AssistantMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Contract;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/VertexAi/Contract/MessageBagNormalizerTest.php b/src/platform/src/Bridge/VertexAi/Tests/Contract/MessageBagNormalizerTest.php
similarity index 96%
rename from src/platform/tests/Bridge/VertexAi/Contract/MessageBagNormalizerTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Contract/MessageBagNormalizerTest.php
index 6292a99b9..c81dae4f7 100644
--- a/src/platform/tests/Bridge/VertexAi/Contract/MessageBagNormalizerTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Contract/MessageBagNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Contract;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -92,13 +92,13 @@ public static function provideMessageBagData(): iterable
yield 'text with image' => [
new MessageBag(
- Message::ofUser('Tell me about this instrument', Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg'))
+ Message::ofUser('Tell me about this instrument', Image::fromFile(\dirname(__DIR__, 7).'/fixtures/image.jpg'))
),
[
'contents' => [
['role' => 'user', 'parts' => [
['text' => 'Tell me about this instrument'],
- ['inlineData' => ['mimeType' => 'image/jpeg', 'data' => base64_encode(file_get_contents(\dirname(__DIR__, 6).'/fixtures/image.jpg'))]],
+ ['inlineData' => ['mimeType' => 'image/jpeg', 'data' => base64_encode(file_get_contents(\dirname(__DIR__, 7).'/fixtures/image.jpg'))]],
]],
],
],
diff --git a/src/platform/tests/Bridge/VertexAi/Contract/ToolCallMessageNormalizerTest.php b/src/platform/src/Bridge/VertexAi/Tests/Contract/ToolCallMessageNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/VertexAi/Contract/ToolCallMessageNormalizerTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Contract/ToolCallMessageNormalizerTest.php
index 20ee5ba77..cdf7c6687 100644
--- a/src/platform/tests/Bridge/VertexAi/Contract/ToolCallMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Contract/ToolCallMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Contract;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/VertexAi/Contract/ToolNormalizerTest.php b/src/platform/src/Bridge/VertexAi/Tests/Contract/ToolNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/VertexAi/Contract/ToolNormalizerTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Contract/ToolNormalizerTest.php
index 53b819a7f..64f950495 100644
--- a/src/platform/tests/Bridge/VertexAi/Contract/ToolNormalizerTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Contract/ToolNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Contract;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/VertexAi/Contract/UserMessageNormalizerTest.php b/src/platform/src/Bridge/VertexAi/Tests/Contract/UserMessageNormalizerTest.php
similarity index 88%
rename from src/platform/tests/Bridge/VertexAi/Contract/UserMessageNormalizerTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Contract/UserMessageNormalizerTest.php
index 4c46f6858..67f4e7515 100644
--- a/src/platform/tests/Bridge/VertexAi/Contract/UserMessageNormalizerTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Contract/UserMessageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Contract;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -52,6 +52,16 @@ public function testNormalizeTextContent()
$this->assertSame([['text' => 'Write a story about a magic backpack.']], $normalized);
}
+ /**
+ * @return iterable
+ */
+ public static function binaryContentProvider(): iterable
+ {
+ yield 'image' => [Image::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/image.jpg'), 'image/jpeg', '/9j/'];
+ yield 'document' => [Document::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/document.pdf'), 'application/pdf', 'JVBE'];
+ yield 'audio' => [Audio::fromFile(\dirname(__DIR__, 5).'/tests/Fixtures/audio.mp3'), 'audio/mpeg', 'SUQz'];
+ }
+
#[DataProvider('binaryContentProvider')]
public function testNormalizeBinaryContent(File $content, string $expectedMimeType, string $expectedPrefix)
{
@@ -68,14 +78,4 @@ public function testNormalizeBinaryContent(File $content, string $expectedMimeTy
$this->assertStringStartsWith($expectedPrefix, $normalized[1]['inlineData']['data']);
}
-
- /**
- * @return iterable
- */
- public static function binaryContentProvider(): iterable
- {
- yield 'image' => [Image::fromFile(\dirname(__DIR__, 6).'/fixtures/image.jpg'), 'image/jpeg', '/9j/'];
- yield 'document' => [Document::fromFile(\dirname(__DIR__, 6).'/fixtures/document.pdf'), 'application/pdf', 'JVBE'];
- yield 'audio' => [Audio::fromFile(\dirname(__DIR__, 6).'/fixtures/audio.mp3'), 'audio/mpeg', 'SUQz'];
- }
}
diff --git a/src/platform/tests/Bridge/VertexAi/Embeddings/ModelClientTest.php b/src/platform/src/Bridge/VertexAi/Tests/Embeddings/ModelClientTest.php
similarity index 95%
rename from src/platform/tests/Bridge/VertexAi/Embeddings/ModelClientTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Embeddings/ModelClientTest.php
index a78e0c67b..6b11786f9 100644
--- a/src/platform/tests/Bridge/VertexAi/Embeddings/ModelClientTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Embeddings/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Embeddings;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Embeddings;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\VertexAi\Embeddings\Model;
diff --git a/src/platform/tests/Bridge/VertexAi/Embeddings/ResultConverterTest.php b/src/platform/src/Bridge/VertexAi/Tests/Embeddings/ResultConverterTest.php
similarity index 95%
rename from src/platform/tests/Bridge/VertexAi/Embeddings/ResultConverterTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Embeddings/ResultConverterTest.php
index a37c49cd5..5e4dfccb7 100644
--- a/src/platform/tests/Bridge/VertexAi/Embeddings/ResultConverterTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Embeddings/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Embeddings;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Embeddings;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\VertexAi\Embeddings\ResultConverter;
diff --git a/src/platform/tests/Bridge/VertexAi/Gemini/ModelClientTest.php b/src/platform/src/Bridge/VertexAi/Tests/Gemini/ModelClientTest.php
similarity index 97%
rename from src/platform/tests/Bridge/VertexAi/Gemini/ModelClientTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Gemini/ModelClientTest.php
index 8af8f4b54..69bf0662f 100644
--- a/src/platform/tests/Bridge/VertexAi/Gemini/ModelClientTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Gemini/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Gemini;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Gemini;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\VertexAi\Gemini\Model;
diff --git a/src/platform/tests/Bridge/VertexAi/Gemini/ResultConverterTest.php b/src/platform/src/Bridge/VertexAi/Tests/Gemini/ResultConverterTest.php
similarity index 96%
rename from src/platform/tests/Bridge/VertexAi/Gemini/ResultConverterTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/Gemini/ResultConverterTest.php
index b6ab31e79..27249c14f 100644
--- a/src/platform/tests/Bridge/VertexAi/Gemini/ResultConverterTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/Gemini/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi\Gemini;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests\Gemini;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\VertexAi\Gemini\ResultConverter;
@@ -46,7 +46,7 @@ public function testItConvertsAResponseToAVectorResult()
public function testItReturnsAggregatedTextOnSuccess()
{
$response = $this->createStub(ResponseInterface::class);
- $responseContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/Bridge/VertexAi/code_execution_outcome_ok.json');
+ $responseContent = file_get_contents(\dirname(__DIR__, 7).'/fixtures/Bridge/VertexAi/code_execution_outcome_ok.json');
$response
->method('toArray')
@@ -99,7 +99,7 @@ public function testItReturnsToolCallEvenIfMultipleContentPartsAreGiven()
public function testItThrowsExceptionOnFailure()
{
$response = $this->createStub(ResponseInterface::class);
- $responseContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/Bridge/VertexAi/code_execution_outcome_failed.json');
+ $responseContent = file_get_contents(\dirname(__DIR__, 7).'/fixtures/Bridge/VertexAi/code_execution_outcome_failed.json');
$response
->method('toArray')
@@ -114,7 +114,7 @@ public function testItThrowsExceptionOnFailure()
public function testItThrowsExceptionOnTimeout()
{
$response = $this->createStub(ResponseInterface::class);
- $responseContent = file_get_contents(\dirname(__DIR__, 6).'/fixtures/Bridge/VertexAi/code_execution_outcome_deadline_exceeded.json');
+ $responseContent = file_get_contents(\dirname(__DIR__, 7).'/fixtures/Bridge/VertexAi/code_execution_outcome_deadline_exceeded.json');
$response
->method('toArray')
diff --git a/src/platform/tests/Bridge/VertexAi/ModelCatalogTest.php b/src/platform/src/Bridge/VertexAi/Tests/ModelCatalogTest.php
similarity index 98%
rename from src/platform/tests/Bridge/VertexAi/ModelCatalogTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/ModelCatalogTest.php
index 92000eed6..3e47036a8 100644
--- a/src/platform/tests/Bridge/VertexAi/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests;
use Symfony\AI\Platform\Bridge\VertexAi\Embeddings\Model as EmbeddingsModel;
use Symfony\AI\Platform\Bridge\VertexAi\Gemini\Model as GeminiModel;
diff --git a/src/platform/tests/Bridge/VertexAi/TokenOutputProcessorTest.php b/src/platform/src/Bridge/VertexAi/Tests/TokenOutputProcessorTest.php
similarity index 99%
rename from src/platform/tests/Bridge/VertexAi/TokenOutputProcessorTest.php
rename to src/platform/src/Bridge/VertexAi/Tests/TokenOutputProcessorTest.php
index ca5d1edd3..81ad24270 100644
--- a/src/platform/tests/Bridge/VertexAi/TokenOutputProcessorTest.php
+++ b/src/platform/src/Bridge/VertexAi/Tests/TokenOutputProcessorTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\VertexAi;
+namespace Symfony\AI\Platform\Bridge\VertexAi\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Agent\Output;
diff --git a/src/platform/src/Bridge/VertexAi/composer.json b/src/platform/src/Bridge/VertexAi/composer.json
new file mode 100644
index 000000000..506959de7
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/composer.json
@@ -0,0 +1,61 @@
+{
+ "name": "symfony/ai-vertex-ai-platform",
+ "description": "Google Vertex AI platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "google",
+ "platform",
+ "vertexai"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "google/auth": "^1.47",
+ "php": ">=8.2",
+ "symfony/ai-agent": "@dev",
+ "symfony/ai-gemini-platform": "@dev",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\VertexAi\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\VertexAi\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/VertexAi/phpunit.xml.dist b/src/platform/src/Bridge/VertexAi/phpunit.xml.dist
new file mode 100644
index 000000000..664307b7f
--- /dev/null
+++ b/src/platform/src/Bridge/VertexAi/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+
diff --git a/src/platform/src/Bridge/Voyage/.gitattributes b/src/platform/src/Bridge/Voyage/.gitattributes
new file mode 100644
index 000000000..14c3c3594
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/.gitattributes
@@ -0,0 +1,3 @@
+/Tests export-ignore
+/phpunit.xml.dist export-ignore
+/.git* export-ignore
diff --git a/src/platform/src/Bridge/Voyage/.github/PULL_REQUEST_TEMPLATE.md b/src/platform/src/Bridge/Voyage/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..fcb87228a
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,8 @@
+Please do not submit any Pull Requests here. They will be closed.
+---
+
+Please submit your PR here instead:
+https://github.com/symfony/ai
+
+This repository is what we call a "subtree split": a read-only subset of that main repository.
+We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Voyage/.github/close-pull-request.yml b/src/platform/src/Bridge/Voyage/.github/close-pull-request.yml
new file mode 100644
index 000000000..bb5a02835
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/.github/close-pull-request.yml
@@ -0,0 +1,20 @@
+name: Close Pull Request
+
+on:
+ pull_request_target:
+ types: [opened]
+
+jobs:
+ run:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ comment: |
+ Thanks for your Pull Request! We love contributions.
+
+ However, you should instead open your PR on the main repository:
+ https://github.com/symfony/ai
+
+ This repository is what we call a "subtree split": a read-only subset of that main repository.
+ We're looking forward to your PR there!
diff --git a/src/platform/src/Bridge/Voyage/.gitignore b/src/platform/src/Bridge/Voyage/.gitignore
new file mode 100644
index 000000000..76367ee5b
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+.phpunit.result.cache
diff --git a/src/platform/src/Bridge/Voyage/CHANGELOG.md b/src/platform/src/Bridge/Voyage/CHANGELOG.md
new file mode 100644
index 000000000..0915f3546
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/CHANGELOG.md
@@ -0,0 +1,7 @@
+CHANGELOG
+=========
+
+0.1
+---
+
+ * Add the bridge
diff --git a/src/platform/src/Bridge/Voyage/LICENSE b/src/platform/src/Bridge/Voyage/LICENSE
new file mode 100644
index 000000000..bc38d714e
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2025-present Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/platform/src/Bridge/Voyage/README.md b/src/platform/src/Bridge/Voyage/README.md
new file mode 100644
index 000000000..bb076aa19
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/README.md
@@ -0,0 +1,12 @@
+Voyage Platform
+===============
+
+Voyage platform bridge for Symfony AI.
+
+Resources
+---------
+
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/ai/issues) and
+ [send Pull Requests](https://github.com/symfony/ai/pulls)
+ in the [main Symfony AI repository](https://github.com/symfony/ai)
diff --git a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/CollectionNormalizerTest.php b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/CollectionNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Voyage/Contract/Multimodal/CollectionNormalizerTest.php
rename to src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/CollectionNormalizerTest.php
index 0a8e057bd..96878362f 100644
--- a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/CollectionNormalizerTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/CollectionNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage\Contract\Multimodal;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests\Contract\Multimodal;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/ImageNormalizerTest.php b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/ImageNormalizerTest.php
similarity index 94%
rename from src/platform/tests/Bridge/Voyage/Contract/Multimodal/ImageNormalizerTest.php
rename to src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/ImageNormalizerTest.php
index 3e9beab49..0a8e67a4b 100644
--- a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/ImageNormalizerTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/ImageNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage\Contract\Multimodal;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests\Contract\Multimodal;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
@@ -62,6 +62,6 @@ public static function supportsNormalizationDataProvider(): \Generator
private static function getFixtureImage(): Image
{
- return Image::fromFile(\dirname(__DIR__, 7).'/fixtures/image.jpg');
+ return Image::fromFile(\dirname(__DIR__, 8).'/fixtures/image.jpg');
}
}
diff --git a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/ImageUrlNormalizerTest.php b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/ImageUrlNormalizerTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Voyage/Contract/Multimodal/ImageUrlNormalizerTest.php
rename to src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/ImageUrlNormalizerTest.php
index ff7416a8b..7dfcc78f8 100644
--- a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/ImageUrlNormalizerTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/ImageUrlNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage\Contract\Multimodal;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests\Contract\Multimodal;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/MultimodalNormalizerTest.php b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/MultimodalNormalizerTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Voyage/Contract/Multimodal/MultimodalNormalizerTest.php
rename to src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/MultimodalNormalizerTest.php
index 067d80b6b..bbbaf3c32 100644
--- a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/MultimodalNormalizerTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/MultimodalNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage\Contract\Multimodal;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests\Contract\Multimodal;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/TextNormalizerTest.php b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/TextNormalizerTest.php
similarity index 96%
rename from src/platform/tests/Bridge/Voyage/Contract/Multimodal/TextNormalizerTest.php
rename to src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/TextNormalizerTest.php
index 3efce10f7..aaa16f101 100644
--- a/src/platform/tests/Bridge/Voyage/Contract/Multimodal/TextNormalizerTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/Contract/Multimodal/TextNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage\Contract\Multimodal;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests\Contract\Multimodal;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Voyage/Contract/VoyageContractTest.php b/src/platform/src/Bridge/Voyage/Tests/Contract/VoyageContractTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Voyage/Contract/VoyageContractTest.php
rename to src/platform/src/Bridge/Voyage/Tests/Contract/VoyageContractTest.php
index 4575a9a7a..8889893f2 100644
--- a/src/platform/tests/Bridge/Voyage/Contract/VoyageContractTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/Contract/VoyageContractTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage\Contract;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests\Contract;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Voyage/ModelCatalogTest.php b/src/platform/src/Bridge/Voyage/Tests/ModelCatalogTest.php
similarity index 97%
rename from src/platform/tests/Bridge/Voyage/ModelCatalogTest.php
rename to src/platform/src/Bridge/Voyage/Tests/ModelCatalogTest.php
index 171fcd4c6..4d6d7cbdd 100644
--- a/src/platform/tests/Bridge/Voyage/ModelCatalogTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/ModelCatalogTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests;
use Symfony\AI\Platform\Bridge\Voyage\ModelCatalog;
use Symfony\AI\Platform\Bridge\Voyage\Voyage;
diff --git a/src/platform/tests/Bridge/Voyage/ModelClientTest.php b/src/platform/src/Bridge/Voyage/Tests/ModelClientTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Voyage/ModelClientTest.php
rename to src/platform/src/Bridge/Voyage/Tests/ModelClientTest.php
index 62b89a0e4..f3c2f3193 100644
--- a/src/platform/tests/Bridge/Voyage/ModelClientTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/ModelClientTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
diff --git a/src/platform/tests/Bridge/Voyage/ResultConverterTest.php b/src/platform/src/Bridge/Voyage/Tests/ResultConverterTest.php
similarity index 98%
rename from src/platform/tests/Bridge/Voyage/ResultConverterTest.php
rename to src/platform/src/Bridge/Voyage/Tests/ResultConverterTest.php
index 88f9da9ec..772c0050f 100644
--- a/src/platform/tests/Bridge/Voyage/ResultConverterTest.php
+++ b/src/platform/src/Bridge/Voyage/Tests/ResultConverterTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace Symfony\AI\Platform\Tests\Bridge\Voyage;
+namespace Symfony\AI\Platform\Bridge\Voyage\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\AI\Platform\Bridge\Voyage\ResultConverter;
diff --git a/src/platform/src/Bridge/Voyage/composer.json b/src/platform/src/Bridge/Voyage/composer.json
new file mode 100644
index 000000000..b73827f5d
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/composer.json
@@ -0,0 +1,58 @@
+{
+ "name": "symfony/ai-voyage-platform",
+ "description": "Voyage platform bridge for Symfony AI",
+ "license": "MIT",
+ "type": "symfony-ai-platform",
+ "keywords": [
+ "ai",
+ "bridge",
+ "embeddings",
+ "platform",
+ "voyage"
+ ],
+ "authors": [
+ {
+ "name": "Christopher Hertel",
+ "email": "mail@christopher-hertel.de"
+ },
+ {
+ "name": "Oskar Stark",
+ "email": "oskarstark@googlemail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "symfony/ai-platform": "@dev",
+ "symfony/http-client": "^7.3|^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^11.5.46"
+ },
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Voyage\\": ""
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Symfony\\AI\\Platform\\Bridge\\Voyage\\Tests\\": "Tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.x-dev"
+ },
+ "thanks": {
+ "name": "symfony/ai",
+ "url": "https://github.com/symfony/ai"
+ }
+ }
+}
diff --git a/src/platform/src/Bridge/Voyage/phpunit.xml.dist b/src/platform/src/Bridge/Voyage/phpunit.xml.dist
new file mode 100644
index 000000000..b915abebb
--- /dev/null
+++ b/src/platform/src/Bridge/Voyage/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+ ./Tests/
+
+
+
+
+
+ ./
+
+
+ ./Resources
+ ./Tests
+ ./vendor
+
+
+