PhotoAtomic.Internationalization.AI
0.6.0
dotnet add package PhotoAtomic.Internationalization.AI --version 0.6.0
NuGet\Install-Package PhotoAtomic.Internationalization.AI -Version 0.6.0
<PackageReference Include="PhotoAtomic.Internationalization.AI" Version="0.6.0" />
<PackageVersion Include="PhotoAtomic.Internationalization.AI" Version="0.6.0" />
<PackageReference Include="PhotoAtomic.Internationalization.AI" />
paket add PhotoAtomic.Internationalization.AI --version 0.6.0
#r "nuget: PhotoAtomic.Internationalization.AI, 0.6.0"
#:package PhotoAtomic.Internationalization.AI@0.6.0
#addin nuget:?package=PhotoAtomic.Internationalization.AI&version=0.6.0
#tool nuget:?package=PhotoAtomic.Internationalization.AI&version=0.6.0
PhotoAtomic.Internationalization.AI
AI-powered translation filler for PhotoAtomic.Internationalization: completes the missing entries of your translation catalog in the background, while the application keeps serving the source-language sentence until the translation lands.
Built on Microsoft.Extensions.AI, so it works with OpenAI and any OpenAI-compatible provider. Every translation request carries the structural information the core engine collects — facts, criteria, context, the legend of each placeholder — so the model translates with grammar-aware instructions instead of a bare string.
The grammatical cases a sentence needs are computed here, not left to the model:
ValueVocabulary observes which trait combinations the language's already-translated values
declare (and a real word for each), VariantCases turns them into the exact list of rows to
produce, and each case is asked for by name, one call at a time, with its example word already
sitting inside the placeholder. Answers are verified hole by hole and asked again when a
placeholder went missing, was invented, or an example word leaked into the template.
A hole is asked only for what can actually arrive in it. The vocabulary is split by the semantic domain a value belongs to — "item", "person" — because a hole that can only host people does not need the cases of things, and asking for them is what pushes the count past its ceiling so that the narrowing trims away the cases that mattered. When the cases must be cut, the first thing dropped is the traits nothing has to agree with: elision is applied mechanically after rendering and capitalization is about the value itself, while gender and number are kept. The surviving core is still observed, not a fixed list of four, so three genders and a dual survive it.
A unit already in the table can be topped up instead of redone: TranslationRequest.Covered
says which criteria it already has rows for, and only the missing cases are asked for. The
table grows a case at a time — the day a language declares one of its nouns plural, every
sentence that can host it needs a row it never needed before — and regenerating the whole unit
costs the most while throwing away rows that were already right.
A value is asked for as a term — bare, lowercase, with its gender declared — and, when the
noun the model picks is grammatically plural in the target language (Italian "cuffie", French
"ciseaux"), with the trait NUMBER-plural as well. Without it every sentence naming that value
puts a singular article in front of it: "la cuffie". It is asked for only when true, because an
axis with two states where one is almost always taken doubles the cases for nothing.
The prompt is explicit about who owns the capital letters: values come back bare and lowercase (the engine capitalizes the one that opens a sentence), while templates are never touched, so the model writes each with the capitalization it will have on screen — and a template that forgets it is reported by the lint rather than silently patched on the way to the display.
What the caller knows is said outright instead of being inferred. TranslationRequest.Kind
tells the model whether a key is a sentence or the name of a thing, however many words it
runs to — left to guess by length, a five-word name reads as a sentence and comes back with no
gender, and a value with no gender makes every sentence naming it fall back to the source
language. Setting describes the scene the term lives in, so a compound name is translated as
belonging to what it names ("base della pressa di pietra") with nothing copied out of the
line itself. Glossary lists the terms already settled in the same content, to be reused
exactly: two names for one object read as two objects.
When an answer has to be asked for again, the reason travels with the question:
TranslationRequest.Feedback reaches the model as the last paragraph of the prompt, because at
temperature 0 the same question returns the same defect forever. A call that never arrived is a
different failure from an answer that was refused: TransportRetry asks again after a doubling
pause when the line broke, timed out or throttled, and gives up immediately on a 4xx that will
fail the same way however often it is repeated.
Installing
dotnet add package PhotoAtomic.Internationalization.AI
Kept separate from the core on purpose: PhotoAtomic.Internationalization stays
dependency-free, and you add the AI machinery (and its Microsoft.Extensions.AI dependencies)
only where you want background fill. For a build-time / CI alternative, the same fill logic is
available as the pai18n
dotnet tool.
Part of PhotoAtomic.Libraries.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.AI (>= 10.8.3)
- Microsoft.Extensions.AI.OpenAI (>= 10.8.3)
- PhotoAtomic.Internationalization (>= 0.6.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.