fix
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
package processing
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// enhanceLogHeadTail caps each end of prompt/response bodies in worker logs.
|
||||
const enhanceLogHeadTail = 500
|
||||
|
||||
func emptyLogDash(s string) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return "-"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// truncateLogEnds returns a PII-safe preview: total rune length plus first/last
|
||||
// slices when the body is large (avoids megabyte log lines).
|
||||
func truncateLogEnds(s string, head, tail int) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return "len=0"
|
||||
}
|
||||
runes := []rune(s)
|
||||
n := len(runes)
|
||||
if head < 0 {
|
||||
head = 0
|
||||
}
|
||||
if tail < 0 {
|
||||
tail = 0
|
||||
}
|
||||
if n <= head+tail+32 {
|
||||
return fmt.Sprintf("len=%d body=%q", n, s)
|
||||
}
|
||||
return fmt.Sprintf("len=%d head=%q tail=%q", n, string(runes[:head]), string(runes[n-tail:]))
|
||||
}
|
||||
|
||||
// formulaTemplateSummary summarizes a category title/description formula for logs
|
||||
// (section/element types + JSON byte length + short content hash — not a full dump).
|
||||
func formulaTemplateSummary(template any, kind string) string {
|
||||
if template == nil {
|
||||
return "none"
|
||||
}
|
||||
raw, err := json.Marshal(template)
|
||||
if err != nil || len(raw) == 0 || string(raw) == "null" || string(raw) == "{}" {
|
||||
return "none"
|
||||
}
|
||||
sum := sha256.Sum256(raw)
|
||||
hash8 := hex.EncodeToString(sum[:4])
|
||||
switch kind {
|
||||
case "title":
|
||||
els, sep, ok := parseTitleFormula(template)
|
||||
if !ok {
|
||||
return fmt.Sprintf("unparsed len=%d hash=%s", len(raw), hash8)
|
||||
}
|
||||
types := make([]string, 0, len(els))
|
||||
for _, el := range els {
|
||||
types = append(types, el.Type)
|
||||
}
|
||||
return fmt.Sprintf("elements=%s sep=%q len=%d hash=%s", strings.Join(types, "+"), sep, len(raw), hash8)
|
||||
case "description":
|
||||
sections, ok := parseDescriptionFormulaSections(template)
|
||||
if !ok {
|
||||
return fmt.Sprintf("unparsed len=%d hash=%s", len(raw), hash8)
|
||||
}
|
||||
types := make([]string, 0, len(sections))
|
||||
for _, sec := range sections {
|
||||
if t := strings.TrimSpace(sec.Type); t != "" {
|
||||
types = append(types, t)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("sections=%s len=%d hash=%s", strings.Join(types, "+"), len(raw), hash8)
|
||||
default:
|
||||
return fmt.Sprintf("len=%d hash=%s", len(raw), hash8)
|
||||
}
|
||||
}
|
||||
|
||||
func finishReasonFromCompletion(comp Completion) string {
|
||||
m, ok := comp.Raw.(map[string]any)
|
||||
if !ok || m == nil {
|
||||
return ""
|
||||
}
|
||||
fr, _ := m["finish_reason"].(string)
|
||||
return strings.TrimSpace(fr)
|
||||
}
|
||||
|
||||
func enhanceFormulaOverride(in ProductInput) bool {
|
||||
return FormatDescriptionFormulaConstraint(in.DescriptionTemplate) != "" ||
|
||||
FormatTitleFormulaConstraint(in.TitleTemplate) != ""
|
||||
}
|
||||
|
||||
// logEnhancePrompt emits one structured line before the LLM call (truncated prompts).
|
||||
func logEnhancePrompt(in ProductInput, categoryUID, categoryName, system, user string) {
|
||||
log.Printf("processing: ai_enhance prompt job=%s company=%s raw=%s category_uid=%q category_name=%q title_formula=%s desc_formula=%s formula_override=%t system=%s user=%s",
|
||||
emptyLogDash(in.JobID), emptyLogDash(in.CompanyID), emptyLogDash(in.RawProductID),
|
||||
strings.TrimSpace(categoryUID), strings.TrimSpace(categoryName),
|
||||
formulaTemplateSummary(in.TitleTemplate, "title"),
|
||||
formulaTemplateSummary(in.DescriptionTemplate, "description"),
|
||||
enhanceFormulaOverride(in),
|
||||
truncateLogEnds(system, enhanceLogHeadTail, enhanceLogHeadTail),
|
||||
truncateLogEnds(user, enhanceLogHeadTail, enhanceLogHeadTail),
|
||||
)
|
||||
}
|
||||
|
||||
// logEnhanceOutcome emits one structured line for the enhance result (truncated response).
|
||||
func logEnhanceOutcome(in ProductInput, categoryUID, categoryName, outcome, reason string, comp Completion, elapsed time.Duration, forceReason string) {
|
||||
log.Printf("processing: ai_enhance outcome=%s reason=%s job=%s company=%s raw=%s category_uid=%q category_name=%q title_formula=%s desc_formula=%s formula_override=%t finish_reason=%s prompt_tokens=%d completion_tokens=%d total_tokens=%d elapsed=%s response=%s force_reason=%s",
|
||||
emptyLogDash(outcome), emptyLogDash(reason),
|
||||
emptyLogDash(in.JobID), emptyLogDash(in.CompanyID), emptyLogDash(in.RawProductID),
|
||||
strings.TrimSpace(categoryUID), strings.TrimSpace(categoryName),
|
||||
formulaTemplateSummary(in.TitleTemplate, "title"),
|
||||
formulaTemplateSummary(in.DescriptionTemplate, "description"),
|
||||
enhanceFormulaOverride(in),
|
||||
emptyLogDash(finishReasonFromCompletion(comp)),
|
||||
comp.PromptTokens, comp.OutputTokens, comp.TotalTokens,
|
||||
elapsed.Round(time.Millisecond),
|
||||
truncateLogEnds(comp.Text, enhanceLogHeadTail, enhanceLogHeadTail),
|
||||
emptyLogDash(forceReason),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user