This commit is contained in:
2026-08-23 20:49:40 +02:00
parent 3b678ca857
commit f3d4fb56ed
31 changed files with 3608 additions and 111 deletions
@@ -191,7 +191,16 @@ func titleFormulaAttrKeys(template any) []string {
// FormatTitleFormulaConstraint turns categories.title_template into enhance-prompt
// constraints (element order: literal text + attribute variable keys).
//
// Brand-only stubs ({elements:[brand]}, the shape an older A1 migration wrote onto
// every category) are not a formula: instructing "name = brand" yields a
// brand-only title that the title picker then rejects in favour of the supplier
// name — an LLM call spent to reproduce the feed. Treat them as absent so the
// category prompt / built-in retail rules drive the name instead.
func FormatTitleFormulaConstraint(template any) string {
if aiprompts.TitleTemplateIsBrandOnly(template) {
return ""
}
elements, separator, ok := parseTitleFormula(template)
if !ok || len(elements) == 0 {
return ""
@@ -521,6 +530,31 @@ func categoryFormulasFor(in ProductInput, category string) (title, description a
return f.TitleTemplate, f.DescriptionTemplate
}
// effectiveDescriptionTemplateFor resolves the description formula RunSteps should
// judge a category's copy against: the category's own template, else one derived
// from its prompt, else the platform default. Mirrors what e.enhance renders, so
// the final repair pass cannot demand a different formula than the one the model
// was given.
func effectiveDescriptionTemplateFor(in ProductInput, out StepResult) any {
category := strings.TrimSpace(out.Category)
_, descTpl := categoryFormulasFor(in, category)
catPrompt := strings.TrimSpace(in.CategoryEnhancePrompt)
if catPrompt == "" {
catPrompt = categoryEnhancePromptFor(in.CategoryPromptsByLang, category, in.Language, in.Language)
}
if effective := aiprompts.EffectiveDescriptionTemplateAny(descTpl, catPrompt); effective != nil {
return effective
}
if catPrompt != "" || descTpl != nil {
return descTpl
}
probe := ProductInput{
CategoryUniqueID: category,
CategoryDisplayName: categoryDisplayLabel(out),
}
return withDefaultCategoryFormula(probe).DescriptionTemplate
}
func asObjectMap(v any) (map[string]any, error) {
switch t := v.(type) {
case map[string]any: