Skip to content

Conversation

OskarStark
Copy link
Contributor

@OskarStark OskarStark commented Sep 19, 2025

Q A
Bug fix? no
New feature? yes
Docs? yes
Issues --
License MIT

Recipe-PR:

ModelCatalog Architecture Refactoring

BC Breaks

  • ⚠️ All model constants removed
  • ⚠️ Child model class constructors were changed and now have an $capabilities parameter
  • ⚠️ PlatformFactory constructor changed for all bridges to be able to receive a ModelCatalogInterface
  • ⚠️ PlatformInterface now has an additional getModelCatalog method
  • ⚠️ PlatformInterface::__invoke no receives an model as string (before Model)
  • ⚠️ Vectorizer::__construct no receives an model as string (before Model)
  • ⚠️ Agent::__construct no receives an model as string (before Model)

Overview

This PR refactors how models are defined and managed in the Symfony AI Platform, moving from constants in Model classes to centralized ModelCatalogs.

Before (Old Configuration)

Defining Models

Models were defined as constants in Model classes:

// src/platform/src/Bridge/OpenAi/Gpt.php
class Gpt extends Model
{
    public const GPT_4O = 'gpt-4o';
    public const GPT_4O_MINI = 'gpt-4o-mini';
    // ... more constants
    
    public function __construct(string $name = self::GPT_4O, array $options = [])
    {
        $capabilities = [
            Capability::INPUT_MESSAGES,
            Capability::OUTPUT_TEXT,
            // ... capabilities determined in constructor
        ];
        
        if (self::GPT_4O_AUDIO === $name) {
            $capabilities[] = Capability::INPUT_AUDIO;
        }
        // ... more logic
        
        parent::__construct($name, $capabilities, $options);
    }
}

Using Models

use Symfony\AI\Platform\Bridge\OpenAi\Gpt;
use Symfony\AI\Platform\Bridge\Voyage\Voyage;

// Had to create Model objects
$model = new Gpt('gpt-4o-mini');
$result = $platform->invoke($model, $input);

// Or with constants
$embeddings = new Voyage(Voyage::V3);
$result = $platform->invoke($embeddings, $text);

Adding Custom Models

There was no standardized way to add custom models. You had to:

  • Either extend a Model class and override the constructor
  • Or create a Model instance with hardcoded capabilities

After (New Configuration)

Defining Models

Models are now defined in centralized ModelCatalog classes:

// src/platform/src/Bridge/OpenAi/ModelCatalog.php
final class ModelCatalog extends AbstractModelCatalog
{
    public function __construct(array $additionalModels = [])
    {
        $defaultModels = [
            'gpt-4o' => [
                'class' => Gpt::class,
                'capabilities' => [
                    Capability::INPUT_MESSAGES,
                    Capability::OUTPUT_TEXT,
                    Capability::OUTPUT_STREAMING,
                    Capability::TOOL_CALLING,
                    Capability::INPUT_IMAGE,
                    Capability::OUTPUT_STRUCTURED,
                ],
            ],
            'gpt-4o-mini' => [
                'class' => Gpt::class,
                'capabilities' => [
                    Capability::INPUT_MESSAGES,
                    Capability::OUTPUT_TEXT,
                    Capability::OUTPUT_STREAMING,
                    Capability::TOOL_CALLING,
                    Capability::INPUT_IMAGE,
                    Capability::OUTPUT_STRUCTURED,
                ],
            ],
            // ... more models
        ];
        
        $this->models = array_merge($defaultModels, $additionalModels);
    }
}

Using Models

// Just pass model name as string - much simpler!
$result = $platform->invoke('gpt-4o-mini', $input);

// Works with any platform
$result = $platform->invoke('voyage-3', $text);

Adding Custom Models

Option 1: Via ModelCatalog Constructor

use Symfony\AI\Platform\Bridge\OpenAi\ModelCatalog;
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;

$customModels = [
    'custom-gpt-4' => [
        'class' => Gpt::class,
        'capabilities' => [
            Capability::INPUT_MESSAGES,
            Capability::OUTPUT_TEXT,
            Capability::OUTPUT_STREAMING,
            Capability::TOOL_CALLING,
            Capability::OUTPUT_STRUCTURED,
        ],
    ],
];

$modelCatalog = new ModelCatalog($customModels);
$platform = new Platform($modelClients, $resultConverters, $modelCatalog, $contract);

// Use the custom model
$result = $platform->invoke('custom-gpt-4', $input);

Option 2: Via Symfony Configuration (if using AI Bundle)

# config/packages/ai.yaml
ai:
    platform:
        openai:
            models:
                custom-gpt-4:
                    class: OpenAi\Gpt
                    capabilities:
                        - input_messages
                        - output_text
                        - output_streaming
                        - tool_calling
                        - output_structured

Benefits

  1. Cleaner API: Use simple strings instead of Model objects
  2. Centralized Model Management: All models defined in one place per platform
  3. Easier Custom Models: Add custom models via constructor or configuration
  4. Better Testing: Standardized ModelCatalogTestCase for all implementations
  5. No More Constants: Model classes are simpler, no need for constants
  6. Flexible Capabilities: Capabilities defined per model, not in constructor logic

Migration Guide

For Application Code

- $result = $platform->invoke(new Gpt(Gpt::GPT_4O), $input);
+ $result = $platform->invoke('gpt-4o', $input);

For Custom Platforms

// Before: Had to extend Model class or handle in constructor
class MyModel extends Model {
    public function __construct() {
        // Complex capability logic
    }
}

// After: Just add to ModelCatalog
$catalog = new ModelCatalog([
    'my-model' => [
        'class' => MyModel::class,
        'capabilities' => [...],
    ],
]);

Special Cases

HuggingFace

HuggingFace ModelCatalog accepts any model name since they support thousands of models:

final class ModelCatalog extends DynamicModelCatalog
{
    // HuggingFace supports a wide range of models dynamically
    // Models are identified by repository/model format (e.g., "microsoft/DialoGPT-medium")
}

Testing

All ModelCatalogs can now be tested using the base ModelCatalogTestCase:

final class MyModelCatalogTest extends ModelCatalogTestCase
{
    protected function createCatalog(): ModelCatalogInterface
    {
        return new MyModelCatalog();
    }
    
    public static function modelsProvider(): iterable
    {
        yield 'model-name' => [
            'model-name',
            ModelClass::class,
            [Capability::INPUT_MESSAGES, Capability::OUTPUT_TEXT],
        ];
    }
}

@OskarStark OskarStark added Platform Issues & PRs about the AI Platform component AI Bundle Issues & PRs about the AI integration bundle labels Sep 19, 2025
@carsonbot carsonbot changed the title [Platform] Add ModelCatalog [AI Bundle][Platform] Add ModelCatalog Sep 19, 2025
@OskarStark OskarStark force-pushed the model-catalog-yaml-config branch 2 times, most recently from 1106c17 to 65f3f3f Compare September 19, 2025 21:30
@OskarStark
Copy link
Contributor Author

@chr-hertel do we need the $options on the Model?

@OskarStark OskarStark force-pushed the model-catalog-yaml-config branch from cbfe1f1 to 663750f Compare September 19, 2025 22:22
@OskarStark OskarStark self-assigned this Sep 19, 2025
@OskarStark OskarStark marked this pull request as draft September 19, 2025 22:34
@OskarStark OskarStark added the BC Break Breaking the Backwards Compatibility Promise label Sep 22, 2025
@OskarStark OskarStark force-pushed the model-catalog-yaml-config branch 3 times, most recently from f982e57 to f1fc8ba Compare September 22, 2025 16:39
@OskarStark OskarStark force-pushed the model-catalog-yaml-config branch 2 times, most recently from 0a32d4d to 099f170 Compare September 23, 2025 06:22
@OskarStark OskarStark force-pushed the model-catalog-yaml-config branch from 8fbb310 to 1440e16 Compare September 27, 2025 10:08
@OskarStark OskarStark force-pushed the model-catalog-yaml-config branch 2 times, most recently from a19e234 to a3a1bf3 Compare September 28, 2025 16:07
@chr-hertel
Copy link
Member

replicate, anthropic, elevenlabs and azure look good now - only bedrock is failing:
image

@OskarStark
Copy link
Contributor Author

Will have a look at bedrock, but cannot test it on my own 👍🏻

@chr-hertel
Copy link
Member

just give me a ping and i'll rerun 👍

@OskarStark OskarStark force-pushed the model-catalog-yaml-config branch 2 times, most recently from 3c267aa to 41d1ed5 Compare September 28, 2025 20:53
Copy link
Member

@chr-hertel chr-hertel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's get it merged while it works :D

@chr-hertel chr-hertel force-pushed the model-catalog-yaml-config branch from f39a859 to 4f06377 Compare September 28, 2025 20:58
@chr-hertel
Copy link
Member

Thank you @OskarStark.

@chr-hertel chr-hertel merged commit a745742 into symfony:main Sep 28, 2025
14 checks passed
@OskarStark OskarStark deleted the model-catalog-yaml-config branch September 28, 2025 21:03
@OskarStark
Copy link
Contributor Author

Thanks for your help

OskarStark added a commit that referenced this pull request Sep 28, 2025
This PR was squashed before being merged into the main branch.

Discussion
----------

[AI Bundle] Fix service registration

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| Docs?         | no
| Issues        | Follows #640
| License       | MIT

Commits
-------

906041e [AI Bundle] Fix service registration
OskarStark added a commit that referenced this pull request Sep 30, 2025
This PR was merged into the main branch.

Discussion
----------

[Platform] Fix array shape

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| Docs?         | no
| Issues        | Follows #640
| License       | MIT

Nice catch Sonnet 4.5 👏

Commits
-------

b07733a [Platform] Fix array shape
OskarStark added a commit that referenced this pull request Sep 30, 2025
This PR was merged into the main branch.

Discussion
----------

[Platform] Fix array shape

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| Docs?         | no
| Issues        | Follows #640
| License       | MIT

Commits
-------

fbc78a9 [Platform] Fix array shape
OskarStark added a commit that referenced this pull request Oct 2, 2025
… syntax (OskarStark)

This PR was merged into the main branch.

Discussion
----------

[AI Bundle] Update documentation to use plain string model syntax

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| Docs?         | yes
| Issues        | Follows #640
| License       | MIT

Replace deprecated class and constant-based model configuration with plain string syntax across all examples in the AI Bundle documentation.

Commits
-------

993490f [AI Bundle] Update documentation to use plain string model syntax
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AI Bundle Issues & PRs about the AI integration bundle BC Break Breaking the Backwards Compatibility Promise Feature New feature Platform Issues & PRs about the AI Platform component Status: Reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants