feat(tenant): inject brand description context into every generation path
Include the current brand description in template, custom, imitation, and KOL article-generation prompts while bounding prompt growth. - Add a shared brand-context builder that resolves the current brand, compacts long descriptions, and caps rendered output at 2000 runes. - Snapshot a structured brand prompt context on queued tasks so old jobs stay reproducible and retries stay stable. - Route brand-profile facts through the existing typed fact guard so founding dates and year counts get the same pre-persistence validation as RAG facts, with brand facts outranking conflicting RAG facts. - Fix the KOL creator to attach the brand scope its worker consumes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
package app
|
||||
|
||||
import "github.com/geo-platform/tenant-api/internal/tenant/repository"
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/tenant/repository"
|
||||
)
|
||||
|
||||
const (
|
||||
generationPayloadTemplateKey = "__snapshot_template_key"
|
||||
@@ -13,6 +17,8 @@ const (
|
||||
generationPayloadPromptRuleTone = "__snapshot_prompt_rule_tone"
|
||||
generationPayloadPromptRuleWordCount = "__snapshot_prompt_rule_word_count"
|
||||
generationPayloadKnowledgePrompt = "__snapshot_knowledge_prompt"
|
||||
generationPayloadKnowledgeFacts = "__snapshot_knowledge_fact_constraints"
|
||||
generationPayloadBrandPromptContext = "__snapshot_brand_prompt_context"
|
||||
)
|
||||
|
||||
func attachTemplateSnapshot(payload map[string]interface{}, record *repository.TemplateRecord) map[string]interface{} {
|
||||
@@ -32,6 +38,65 @@ func attachTemplateSnapshot(payload map[string]interface{}, record *repository.T
|
||||
return payload
|
||||
}
|
||||
|
||||
func attachBrandPromptContext(payload map[string]interface{}, brandCtx *BrandPromptContext) map[string]interface{} {
|
||||
if payload == nil {
|
||||
payload = map[string]interface{}{}
|
||||
}
|
||||
if brandCtx == nil {
|
||||
delete(payload, generationPayloadBrandPromptContext)
|
||||
return payload
|
||||
}
|
||||
normalized := normalizeBrandPromptContext(*brandCtx)
|
||||
payload[generationPayloadBrandPromptContext] = &normalized
|
||||
return payload
|
||||
}
|
||||
|
||||
func extractBrandPromptContext(payload map[string]interface{}) *BrandPromptContext {
|
||||
if payload == nil || payload[generationPayloadBrandPromptContext] == nil {
|
||||
return nil
|
||||
}
|
||||
encoded, err := json.Marshal(payload[generationPayloadBrandPromptContext])
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var brandCtx BrandPromptContext
|
||||
if err := json.Unmarshal(encoded, &brandCtx); err != nil {
|
||||
return nil
|
||||
}
|
||||
if brandCtx.BrandID <= 0 {
|
||||
return nil
|
||||
}
|
||||
brandCtx = normalizeBrandPromptContext(brandCtx)
|
||||
return &brandCtx
|
||||
}
|
||||
|
||||
func attachKnowledgeFactConstraints(payload map[string]interface{}, constraints []KnowledgeFactConstraint) map[string]interface{} {
|
||||
if payload == nil {
|
||||
payload = map[string]interface{}{}
|
||||
}
|
||||
if len(constraints) == 0 {
|
||||
delete(payload, generationPayloadKnowledgeFacts)
|
||||
return payload
|
||||
}
|
||||
payload[generationPayloadKnowledgeFacts] = constraints
|
||||
return payload
|
||||
}
|
||||
|
||||
func extractKnowledgeFactConstraints(payload map[string]interface{}) []KnowledgeFactConstraint {
|
||||
if payload == nil || payload[generationPayloadKnowledgeFacts] == nil {
|
||||
return nil
|
||||
}
|
||||
encoded, err := json.Marshal(payload[generationPayloadKnowledgeFacts])
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
var constraints []KnowledgeFactConstraint
|
||||
if err := json.Unmarshal(encoded, &constraints); err != nil {
|
||||
return nil
|
||||
}
|
||||
return constraints
|
||||
}
|
||||
|
||||
func extractTemplateSnapshot(payload map[string]interface{}) (string, string, *string) {
|
||||
templateKey := extractString(payload, generationPayloadTemplateKey)
|
||||
templateName := extractString(payload, generationPayloadTemplateName)
|
||||
|
||||
Reference in New Issue
Block a user