43 lines
1.4 KiB
Go
43 lines
1.4 KiB
Go
package placement
|
|
|
|
import (
|
|
"strings"
|
|
|
|
libkg "haixun-backend/internal/library/knowledge"
|
|
)
|
|
|
|
// HasTangentialTopicMismatch uses the shared intent model: broad category overlap
|
|
// without product/research-map intent alignment (generalizes beyond hardcoded lists).
|
|
func HasTangentialTopicMismatch(text string, ctx PostScanContext) bool {
|
|
text = strings.TrimSpace(text)
|
|
if text == "" {
|
|
return false
|
|
}
|
|
if matchesTopicAnchor(text, ctx) {
|
|
return false
|
|
}
|
|
profile := libkg.BuildIntentProfile(intentProfileInputFromPostScan(ctx))
|
|
return libkg.IsTangentialToIntent(text, profile)
|
|
}
|
|
|
|
func PatrolTagInputFromScanContext(ctx PostScanContext) libkg.PatrolTagInput {
|
|
return intentProfileInputFromPostScan(ctx)
|
|
}
|
|
|
|
func intentProfileInputFromPostScan(ctx PostScanContext) libkg.PatrolTagInput {
|
|
return libkg.PatrolTagInput{
|
|
ProductName: ctx.ProductName,
|
|
ProductFeatures: ctx.ProductFeatures,
|
|
AudienceSummary: ctx.AudienceSummary,
|
|
TargetAudience: ctx.TargetAudience,
|
|
MatchTags: append([]string{}, ctx.MatchTags...),
|
|
Questions: append([]string{}, ctx.Questions...),
|
|
Pillars: append([]string{}, ctx.Pillars...),
|
|
}
|
|
}
|
|
|
|
// LocalIntentScore is the offline semantic scorer (no embedding API).
|
|
func LocalIntentScore(text string, ctx PostScanContext) int {
|
|
return libkg.ScoreIntentSimilarity(text, libkg.BuildIntentProfile(intentProfileInputFromPostScan(ctx)))
|
|
}
|