Upgrade Notes¶
Everything you need to review before upgrading to a new version of the bundle. The same notes ship with the package as UPGRADES.md in the repository root.
0.7.0¶
Sulu minimum version raised¶
The bundles now require Sulu ^2.6.25 (2.6 line) or ^3.0.8 (3.0 line). These versions ship the admin support
for the configurable AI field types described below. Update your Sulu installation before upgrading the bundles.
symfony/ai packages upgraded to 0.10¶
Both bundles now require the symfony/ai-* packages in version ^0.10. If your application requires any
symfony/ai-* package directly (for example symfony/ai-bundle or symfony/ai-agent), update its constraint
to ^0.10 before upgrading.
New optional configuration¶
No action is required — the defaults match the previous behavior:
sulu_ai_platform.text_field_types(default['text_line', 'text_area']) andsulu_ai_platform.html_field_types(default['text_editor']) control which property types the AI features treat as plain-text respectively HTML content. Projects with custom property types containing translatable text should add them here — see the translator documentation.sulu_ai_platform.intelligent_search.identifieroptionally targets a specific intelligent search by UUID. When omitted, the project default is used.
0.6.0¶
New Sulu AI security contexts¶
The ai-platform-bundle now registers its own Sulu AI security category in the Sulu admin permission system.
Bundle users should review their roles and grant the new VIEW permissions for the AI features they want to expose:
sulu.ai.writing_assistantsulu.ai.translatesulu.ai.seo_generatorsulu.ai.excerpt_generatorsulu.ai.media_metadata_generatorsulu.ai.feedback
Without these permissions, the corresponding AI UI actions are hidden and the backend endpoints return 403 Access Denied.
Translation permissions are combined¶
The following translation-related permissions were combined into a single permission:
sulu.ai.translate_textsulu.ai.media_metadata_translatesulu.ai.category_translatesulu.ai.full_content_translate
Use sulu.ai.translate instead.
SQL helper for existing roles¶
If you want to grant all new Sulu AI VIEW permissions to an existing role directly in SQL, you can use the following statement.
Replace :ROLE_ID with the numeric role id from se_roles.id:
INSERT INTO se_permissions (`context`, `module`, `permissions`, `idRoles`)
VALUES
('sulu.ai.writing_assistant', NULL, 64, :ROLE_ID),
('sulu.ai.translate', NULL, 64, :ROLE_ID),
('sulu.ai.seo_generator', NULL, 64, :ROLE_ID),
('sulu.ai.excerpt_generator', NULL, 64, :ROLE_ID),
('sulu.ai.media_metadata_generator', NULL, 64, :ROLE_ID),
('sulu.ai.feedback', NULL, 64, :ROLE_ID)
ON DUPLICATE KEY UPDATE
`permissions` = `permissions` | VALUES(`permissions`);
64 is the Sulu bitmask for VIEW. The ON DUPLICATE KEY UPDATE clause preserves any existing permission bits and only adds VIEW where needed.
0.5.0¶
Context objects replace individual parameters¶
All expert interfaces now use dedicated context objects instead of individual $locale and $resourceKey parameters.
These context objects bundle locale, resourceKey, and the new webspaceKey together, enabling the platform to resolve
profile metadata per webspace.
ai-bundle: WritingAssistantGeneratorInterface¶
The $locale parameter was replaced by WritingAssistantContext:
// Before
public function optimize(
string $chatId,
string $text,
string $message,
?string $expertUuid,
string $locale,
): WritingAssistantResponse;
// After
use Sulu\Bundle\AiBundle\Expert\WritingAssistant\WritingAssistantContext;
public function optimize(
string $chatId,
string $text,
string $message,
?string $expertUuid,
WritingAssistantContext $context,
): WritingAssistantResponse;
The WritingAssistantContext provides locale, resourceId, resourceKey, schemeAndHttpHost, optional webspaceKey,
and optional content data (data, dataPath).
ai-bundle: WritingAssistantContextProviderInterface¶
The $locale parameter was removed and parameters were reordered. The context object now carries the locale:
// Before
public function generateContext(
string $text,
string $message,
string $locale,
?string $expertUuid,
): iterable;
// After
use Sulu\Bundle\AiBundle\Expert\WritingAssistant\WritingAssistantContext;
public function generateContext(
string $text,
string $message,
?string $expertUuid,
WritingAssistantContext $context,
): iterable;
ai-platform-bundle: SeoGeneratorInterface¶
The $locale and $resourceKey parameters were replaced by SeoGeneratorContext, and $expertUuid was moved:
// Before
public function generate(
string $id,
string $locale,
string $expertUuid,
?array $currentSeoData,
string $resourceKey,
): SeoGeneratorResponse;
// After
use Sulu\Bundle\AiPlatformBundle\Expert\SeoGenerator\SeoGeneratorContext;
public function generate(
string $id,
string $expertUuid,
?array $currentSeoData,
SeoGeneratorContext $context,
): SeoGeneratorResponse;
ai-platform-bundle: SeoContextProviderInterface¶
The $locale parameter was replaced by SeoGeneratorContext, and $expertUuid was moved:
// Before
public function generateContext(
ContentAdapterInterface $content,
string $locale,
string $expertUuid,
): iterable;
// After
use Sulu\Bundle\AiPlatformBundle\Expert\SeoGenerator\SeoGeneratorContext;
public function generateContext(
ContentAdapterInterface $content,
string $expertUuid,
SeoGeneratorContext $context,
): iterable;
ai-platform-bundle: ExcerptGeneratorInterface¶
Same pattern as SeoGeneratorInterface:
// Before
public function generate(
string $id,
string $locale,
string $expertUuid,
?array $currentExcerptData,
string $resourceKey,
): ExcerptGeneratorResponse;
// After
use Sulu\Bundle\AiPlatformBundle\Expert\ExcerptGenerator\ExcerptGeneratorContext;
public function generate(
string $id,
string $expertUuid,
?array $currentExcerptData,
ExcerptGeneratorContext $context,
): ExcerptGeneratorResponse;
ai-platform-bundle: ExcerptContextProviderInterface¶
Same pattern as SeoContextProviderInterface:
// Before
public function generateContext(
ContentAdapterInterface $content,
string $locale,
string $expertUuid,
): iterable;
// After
use Sulu\Bundle\AiPlatformBundle\Expert\ExcerptGenerator\ExcerptGeneratorContext;
public function generateContext(
ContentAdapterInterface $content,
string $expertUuid,
ExcerptGeneratorContext $context,
): iterable;
ai-bundle: TranslatorInterface new parameter¶
A new optional $webspaceKey parameter was added to translate():
// Before
public function translate(
string $translateId,
array $texts,
string $targetLanguage,
?string $sourceLanguage = null,
bool $html = true,
): TranslatorResponse;
// After
public function translate(
string $translateId,
array $texts,
string $targetLanguage,
?string $sourceLanguage = null,
bool $html = true,
?string $webspaceKey = null,
): TranslatorResponse;
Existing callers are unaffected. Implementations of this interface must add the new parameter.
New context factories¶
Context objects are now created via factories that handle webspace key resolution for articles:
Sulu\Bundle\AiBundle\Expert\WritingAssistant\WritingAssistantContextFactorySulu\Bundle\AiPlatformBundle\Expert\SeoGenerator\SeoGeneratorContextFactorySulu\Bundle\AiPlatformBundle\Expert\ExcerptGenerator\ExcerptGeneratorContextFactory
If you extend WritingAssistantController, SeoGeneratorController, or ExcerptGeneratorController,
note that their constructors now require the corresponding context factory as an additional parameter.
New WebspaceKeyResolverInterface¶
A new Sulu\Bundle\AiBundle\Compatibility\WebspaceKeyResolverInterface has been introduced.
The ai-platform-bundle provides implementations for both Sulu 2.6 (Sulu26WebspaceKeyResolver) and
Sulu 3.0 (Sulu3WebspaceKeyResolver) that resolve the webspaceKey for articles based on their main webspace.
New WritingAssistantMessageEnhancerInterface¶
A new WritingAssistantMessageEnhancerInterface has been introduced for enhancing the locale instruction message
with additional content parts (e.g., media images). Implementations are tagged with sulu_ai.writing_assistant_message_enhancer.
0.4.0¶
Migration from ModelflowAi to Symfony/AI¶
Quick Navigation: - For Bundle Users - If you're using AI features in Sulu admin - For Advanced Users - If you implement custom experts or extend the bundles
For Bundle Users¶
If you're using the AI features in Sulu admin, follow these steps:
1. Update Dependencies¶
composer update sulu/ai-platform-bundle -W
Note: This bundle requires Symfony 7.3 or higher due to the Symfony AI component dependencies.
2. Update Bundle Configuration¶
You have to enable the Symfony AI bundle in your application while removing the ModelflowAi Bundle.
Update config/bundles.php:
return [
// Remove this line:
// ModelflowAi\Integration\Symfony\ModelflowAiBundle::class => ['all' => true],
// Add Symfony AI bundle
Symfony\AI\AiBundle\AiBundle::class => ['all' => true],
// Keep these existing bundles:
Sulu\Bundle\AiPlatformBundle\SuluAiPlatformBundle::class => ['all' => true],
Sulu\Bundle\AiBundle\SuluAiBundle::class => ['all' => true],
];
For Advanced Users¶
If you implement custom experts or extend the bundles:
ExpertInterface Changes¶
Only relevant if you implement ExpertInterface yourself:
// Before
public function createThread(?string $expertUuid): ThreadInterface;
public function getVariants(): array; // Returns objects
// After
public function createThread(?string $variantUuid = null): ThreadInterface;
public function getVariants(): array; // Returns arrays
Variant access:
// Before: Objects
$variant->getUuid()
// After: Arrays
$variant['uuid']
Service Names¶
Only relevant if you inject expert services:
Expert services have been split into two distinct services following a consistent naming pattern:
| Old Service ID | New Service ID | Type |
|---|---|---|
modelflow_ai.experts.writing_assistant |
sulu_ai.writing_assistant_expert |
Expert (ExpertInterface) |
sulu_ai.experts.writing_assistant |
sulu_ai.writing_assistant_generator |
WritingAssistantGenerator implementation |
modelflow_ai.experts.seo_generator |
sulu_ai_platform.seo_expert |
Expert (ExpertInterface) |
sulu_ai_platform.experts.seo_generator |
sulu_ai_platform.seo_generator |
SeoGenerator implementation |
modelflow_ai.experts.excerpt_generator |
sulu_ai_platform.excerpt_expert |
Expert (ExpertInterface) |
sulu_ai_platform.experts.excerpt_generator |
sulu_ai_platform.excerpt_generator |
ExcerptGenerator implementation |
modelflow_ai.experts.media_metadata_generator |
sulu_ai_platform.media_metadata_expert |
Expert (ExpertInterface) |
sulu_ai_platform.experts.media_metadata_generator |
sulu_ai_platform.media_metadata_generator |
MediaMetadataGenerator implementation |
sulu_ai_platform.experts.translator |
sulu_ai_platform.translator |
Translator |
Naming Pattern:
- Services ending in _expert: Return ExpertVariant arrays for expert definitions
- Services ending in _generator: Implementation services for programmatic use
Expert/Thread Architecture Refactoring¶
Only relevant if you extend our generators (WritingAssistantGenerator, SeoGenerator, ExcerptGenerator, MediaMetadataGenerator):
We've simplified the generators to use the Expert/Thread pattern. If you're extending any of the generators, please check your implementation.
Context Provider Interface Change¶
Only relevant if you implement a custom SeoContextProviderInterface or ExcerptContextProviderInterface:
The $document parameter of generateContext() changed from object to ConentAdapterInterface:
// Before
public function generateContext(
StructureBehavior $document,
string $locale,
string $expertUuid,
): iterable;
// After
use Sulu\Bundle\AiPlatformBundle\Compatibility\ContentPersister\ConentAdapterInterface;
public function generateContext(
ConentAdapterInterface $content,
string $locale,
string $expertUuid,
): iterable;
Update your implementations to use ConentAdapterInterface and its methods (getTemplateData(), getSeoData(), getExcerptData(), etc.) instead of checking for version-specific types.
Class renamings¶
Following classes have been renamed:
| Old Class | New Class |
|---|---|
Sulu\Bundle\AiBundle\Expert\WritingAssistant\WritingAssistant |
Sulu\Bundle\AiBundle\Expert\WritingAssistant\WritingAssistantGenerator |
Sulu\Bundle\AiBundle\Expert\WritingAssistant\WritingAssistantInterface |
Sulu\Bundle\AiBundle\Expert\WritingAssistant\WritingAssistantGeneratorInterface |
Testing¶
Only relevant if you test AI features:
// Before
use Sulu\Bundle\AiBundle\Testing\TestAdapter\TestChatAdapter;
$adapter = new TestChatAdapter([...]);
// After
use Sulu\Bundle\AiBundle\Testing\MockPlatform;
$mockPlatform = new MockPlatform(/*...*/);
$mockPlatform->addMockResponse(fn($m, $msg) => true, '{"result": "test"}');
Removed Classes¶
Unlikely you were using these, but they're removed:
- Criteria\ExpertCriteria, Expert\ExpertFactory, Expert\ExpertFactoryInterface
- Testing\TestAdapter\TestChatAdapter
Quick Checklist¶
For all users:
- [ ] Update Symfony to ^7.3
- [ ] Update dependencies: composer update sulu/ai-platform-bundle -W
- [ ] Remove ModelflowAi\Integration\Symfony\ModelflowAiBundle from bundles.php
- [ ] Add Symfony\AI\AiBundle\AiBundle to bundles.php
For advanced users only:
- [ ] Update custom expert implementations (if you have any)
- [ ] Update service injection (if you inject expert services)
- [ ] Update test code (if you test AI features)
- [ ] Update generator extensions (if you extend generators)
- [ ] Update custom context provider implementations (if you implement SeoContextProviderInterface or ExcerptContextProviderInterface)