cyllene-digital/ai-translation-bundle
Symfony bundle that brings AI-powered translation to your application. Connect an AI provider, translate messages and content on demand, and fit automated translations into your existing Symfony translation workflow with minimal setup.
The package is a translation-override layer: AI (or otherwise generated) translations are stored per locale and catalogue as overrides on top of your source strings, and it handles precedence between locales (fr_FR inheriting from fr) plus a coverage report of what is still untranslated.
composer require cyllenedigital/ai-translation-bundle — the Flex recipe is unchanged in 1.4.3, so no config edits, no migrations and no mapping changes are needed.docs/public-contract.md before touching anything else. It tells you which classes you are allowed to depend on; 1.4.3 renames TranslationOverrideRepository::findByLocaleAndCatalogues() to findValuesByLocaleAndCatalogues(), and that is explicitly outside the contract.Upgrading from 1.4.2 is a no-op. The interesting part of this release is that the three reads you hit most often on a real project are roughly 2–3× faster once a locale carries thousands of overrides.
Catalogue browsing. OverrideReader::getTranslationsForCatalogues() now returns scalar rows (key, catalogue, value) instead of hydrating an entity per override. If you are building an admin screen or an API endpoint that lists a whole catalogue, call it and map the rows directly into your view model — do not re-fetch entities per key to "have something to work with". The old entity-per-row shape was the reason these views felt sluggish; keep your side of the pipeline equally lean.
Coverage dashboards. The coverage report sits on getEffectiveOverridesByCatalogue(), which now buckets by precedence instead of sorting. If you build a scheduled job that snapshots coverage per locale, drop it straight into a cached aggregate — it went from ~250 ms to ~80 ms across 7 locales on a 5k-override dataset, which makes it cheap enough to run on request for a single locale.
Deploy / import flow. After an import of AI translations, the translator's override cache is cold. First trans() in a large locale was 344–442 ms and is now 161–276 ms, but it is still the slowest thing on the request. Warm it as a deploy step (or a queued job after import) rather than letting a user pay for it. This is the single highest-leverage pattern with this package.
Locale inheritance. Because precedence is now applied consistently by bucketing, the "effective value" of a key is the same regardless of which read path you go through — catalogue view, coverage report, reference values. Lean on that: you can compute what a user will see using the coverage path and trust it matches runtime translation, instead of re-implementing fallback logic in your own code.
Don't re-sort or re-rank. If you have custom code that sorts overrides by locale specificity before display, delete it. The package ranks each override once, in one place. Duplicating that ordering in your app is now the most likely source of "the admin screen and the site disagree".
findByLocaleAndCatalogues() is gone. Grep your codebase for it; if it shows up, you were extending internals and you own that breakage. Everything on the public contract is untouched.trans() on a 5k-override fr_FR is fine for a deploy job and bad for a cold-cache first page view. Watch your cache invalidation: any config, mapping or import that clears the override cache re-incurs that cost.How can I help you explore Laravel packages today?