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
+48 -2
View File
@@ -8,6 +8,7 @@ import (
)
func resolveProductPromptTemplates(in ProductInput) (systemTpl, userTpl string) {
in = withDefaultCategoryFormula(in)
systemTpl = strings.TrimSpace(in.EnhanceSystemTemplate)
userTpl = strings.TrimSpace(in.EnhanceUserTemplate)
catPrompt := strings.TrimSpace(in.CategoryEnhancePrompt)
@@ -17,8 +18,12 @@ func resolveProductPromptTemplates(in ProductInput) (systemTpl, userTpl string)
// <name>/<metaDescription>/HTML). When formulas are set, rebuild that shape
// instead of burying instructions under the generic retail copywriter overlay.
if categoryUsesA1StyleFormula(catPrompt, in.TitleTemplate, descTpl) {
userTpl = buildA1StyleEnhanceUserTemplate(catPrompt, in.TitleTemplate, descTpl, in.OmitSEOMeta)
systemTpl = a1StyleEnhanceSystemTemplate
var slovenianFormula bool
userTpl, slovenianFormula = buildA1StyleEnhanceUserTemplate(catPrompt, in.TitleTemplate, descTpl, in.OmitSEOMeta)
systemTpl = a1StyleEnhanceSystemTemplateEN
if slovenianFormula {
systemTpl = a1StyleEnhanceSystemTemplateSL
}
allowed := enhanceAllowedAttrKeys(in, in.CategoryUniqueID)
userTpl = AppendAttributeConstraints(userTpl, allowed, in.TitleTemplate)
return systemTpl, userTpl
@@ -59,6 +64,47 @@ func resolveProductPromptTemplates(in ProductInput) (systemTpl, userTpl string)
return systemTpl, userTpl
}
// withDefaultCategoryFormula supplies the platform-default formula when the
// category carries none of its own.
//
// Categories created before defaults existed (and any tenant who never opened the
// formula editor) would otherwise enhance through the generic "1-3 factual
// paragraphs" rule and produce copy shaped by the feed rather than by a formula.
// The default is the English translation of the A1 template style; a category that
// has its own prompt or formula — every A1 category — is returned untouched.
func withDefaultCategoryFormula(in ProductInput) ProductInput {
// Only categorised products: with no category there is nothing to look a
// default up for, and the company/built-in enhance template still applies.
if strings.TrimSpace(in.CategoryUniqueID) == "" && strings.TrimSpace(in.CategoryDisplayName) == "" {
return in
}
// A tenant-authored enhance template is an explicit choice and outranks any
// platform default.
if !aiprompts.IsBuiltInProductEnhanceUserTemplate(in.EnhanceUserTemplate) {
return in
}
if strings.TrimSpace(in.CategoryEnhancePrompt) != "" {
return in
}
if FormatTitleFormulaConstraint(in.TitleTemplate) != "" ||
FormatDescriptionFormulaConstraint(in.DescriptionTemplate) != "" ||
FormatMetaFormulaConstraint(in.DescriptionTemplate) != "" {
return in
}
def := aiprompts.DefaultCategoryFormula(in.CategoryUniqueID, in.CategoryDisplayName)
if def.Overlay == "" {
return in
}
in.CategoryEnhancePrompt = def.Overlay
if in.TitleTemplate == nil && def.TitleTemplateJSON != "" {
in.TitleTemplate = decodeOptionalJSONObject([]byte(def.TitleTemplateJSON))
}
if in.DescriptionTemplate == nil && def.DescriptionTemplateJSON != "" {
in.DescriptionTemplate = decodeOptionalJSONObject([]byte(def.DescriptionTemplateJSON))
}
return in
}
// thinEnhanceUserInstruction is prepended when Desc is empty or ≈ Name so the model
// builds copy from Attrs+Category instead of echoing the title.
const thinEnhanceUserInstruction = "Build the description from Attrs and Category only; never copy Name."