Inject CmsGenerateEntryContentUseCase (from webiny/api/ai-powerups) and call
execute(...). It uses the provider the user configured in AI Power Ups and applies an
optional Project, Writer Persona, or Reader Persona — so you never pick
models, decrypt API keys, or hardcode prompts. It returns the AI-generated entry values as
a JSON string; parse it and take the field(s) you want.
Prefer this over a raw Ai.generateText call whenever the point is "apply the user's
configured AI setup" — it composes the product with itself and is far less plumbing.
import { CmsGenerateEntryContentUseCase } from "webiny/api/ai-powerups";
class MyThing {
constructor(private generate: CmsGenerateEntryContentUseCase.Interface) {}
async run(model, entry, ctx) {
const result = await this.generate.execute({
modelId: model.modelId,
prompt: `Write a one-sentence marketing summary for "${entry.values.name}". Fill only the "aiSummary" field.`,
// Any of these are optional; they map to what the user configured in AI Power Ups:
projectId: ctx?.projectId, // a bundled context (instructions + files + default personas)
writerPersonaId: ctx?.writerPersonaId, // tone
readerPersonaId: ctx?.readerPersonaId // audience
});
if (result.isFail()) {
throw result.error; // e.g. "No AI provider configured. Add a provider in AI Power Ups settings."
}
return result.value; // { values, telemetry }
}
}
Register the dependency: dependencies: [CmsGenerateEntryContentUseCase].
result.value.values is an entry-shaped object keyed by the model's field ids (the use
case is built to fill an entry from its schema). The AI decides which fields it fills, so:
result.value.values.aiSummary) — do NOT blindly
write the whole object back, or the AI could overwrite name, price, etc.execute<{ aiSummary?: string }>(...), which
makes result.value.values.aiSummary typed (defaults to Record<string, any>).""
and, if you're inside a converging background task, still mark the entry done so it
doesn't loop.Then persist with UpdateEntryUseCase (values nested; skipValidation: true for a
targeted field write).
To let the user pick a Project/Persona in the Admin UI, read AI Power Ups settings with
GetSettingsFeature (from webiny/admin/ai-powerups):
import { useFeature } from "webiny/admin";
import { GetSettingsFeature } from "webiny/admin/ai-powerups";
const { useCase: getSettings } = useFeature(GetSettingsFeature);
const settings = await getSettings.execute();
// settings.writerPersonas.presets / settings.readerPersonas.presets / settings.projects.presets
// each preset: { id, name, description, ... }
Forward the chosen id(s) to your backend (e.g. via a bulk action's data).
webiny-cms-bulk-actions — the common host for this: a bulk action whose processData
calls CmsGenerateEntryContentUseCase and writes the result, as a background task.@webiny/ai-powerups's AiImageEnrichmentTask shows the alternative (raw, hardcoded
Ai.generateText) — use that only when you deliberately don't want the configured setup.