thread-master/backend/internal/library/matrix/copy_generate.go

125 lines
3.0 KiB
Go
Raw Normal View History

2026-06-26 08:37:04 +00:00
package matrix
import (
"fmt"
"strings"
libprompt "haixun-backend/internal/library/prompt"
)
type CopyGenerateInput struct {
Count int
TopicLabel string
TopicBrief string
ResearchMap string
SelectedTags []string
ViralSamples string
PersonaBlock string
}
func BuildCopyUserPrompt(in CopyGenerateInput) (string, error) {
count := in.Count
if count <= 0 {
count = 5
}
if count > 12 {
count = 12
}
return libprompt.MatrixCopyUser(map[string]string{
"count": fmt.Sprintf("%d", count),
"topic_label": strings.TrimSpace(in.TopicLabel),
"topic_brief": strings.TrimSpace(in.TopicBrief),
"research_map_block": strings.TrimSpace(in.ResearchMap),
"selected_tags_block": formatTagList(in.SelectedTags),
"viral_samples_block": strings.TrimSpace(in.ViralSamples),
"persona_block": strings.TrimSpace(in.PersonaBlock),
})
}
func formatTagList(tags []string) string {
if len(tags) == 0 {
return "(尚未選擇)"
}
lines := make([]string, 0, len(tags))
for _, tag := range tags {
tag = strings.TrimSpace(tag)
if tag == "" {
continue
}
lines = append(lines, "- "+tag)
}
if len(lines) == 0 {
return "(尚未選擇)"
}
return strings.Join(lines, "\n")
}
2026-06-28 08:28:42 +00:00
func SelectKnowledgeItems(selected, all []string) []string {
source := selected
if len(source) == 0 {
source = all
}
return dedupeKnowledgeLines(source)
}
// MergeKnowledgeItems combines explicit user selections without falling back to unselected items.
func MergeKnowledgeItems(parts ...[]string) []string {
merged := make([]string, 0)
for _, part := range parts {
merged = append(merged, part...)
}
return dedupeKnowledgeLines(merged)
}
func dedupeKnowledgeLines(lines []string) []string {
out := make([]string, 0, len(lines))
seen := map[string]struct{}{}
for _, item := range lines {
item = strings.TrimSpace(item)
if item == "" {
continue
}
key := strings.ToLower(item)
if _, ok := seen[key]; ok {
continue
}
seen[key] = struct{}{}
out = append(out, item)
}
return out
}
func FormatCopyResearchMapBlock(audience, goal string, questions, pillars, exclusions []string, knowledgeItems ...[]string) string {
2026-06-26 08:37:04 +00:00
var b strings.Builder
if audience = strings.TrimSpace(audience); audience != "" {
b.WriteString("受眾:")
b.WriteString(audience)
b.WriteString("\n")
}
if goal = strings.TrimSpace(goal); goal != "" {
b.WriteString("內容目標:")
b.WriteString(goal)
b.WriteString("\n")
}
if len(pillars) > 0 {
b.WriteString("支柱:")
b.WriteString(strings.Join(pillars, "、"))
b.WriteString("\n")
}
if len(questions) > 0 {
b.WriteString("受眾問題:")
b.WriteString(strings.Join(questions, ""))
b.WriteString("\n")
}
2026-06-28 08:28:42 +00:00
if len(knowledgeItems) > 0 && len(knowledgeItems[0]) > 0 {
b.WriteString("勾選延伸知識:")
b.WriteString(strings.Join(knowledgeItems[0], ""))
b.WriteString("\n")
}
2026-06-26 08:37:04 +00:00
if len(exclusions) > 0 {
b.WriteString("排除:")
b.WriteString(strings.Join(exclusions, ""))
}
return strings.TrimSpace(b.String())
}