78 lines
2.9 KiB
Go
78 lines
2.9 KiB
Go
package handoff
|
||
|
||
import (
|
||
"strings"
|
||
"unicode"
|
||
)
|
||
|
||
type DetectionResult struct {
|
||
Requested bool
|
||
Confidence float64
|
||
MatchedPhrase string
|
||
Language string
|
||
ReasonCode string
|
||
NeedsClarification bool
|
||
}
|
||
|
||
var handoffPhrases = []string{
|
||
"соедините с оператором", "переведите на оператора", "хочу оператора", "нужен оператор",
|
||
"позовите оператора", "можно с человеком", "хочу поговорить с человеком", "соедините с человеком",
|
||
"переключите на оператора", "не хочу робота", "не хочу ии", "позовите живого человека",
|
||
"мне нужен специалист", "соедините с консультантом", "живой оператор", "консультант",
|
||
"операторға қосыңыз", "операторға қос", "адаммен сөйлескім келеді", "тірі оператор",
|
||
"маман керек", "кеңесші керек", "кеңесшімен сөйлесу", "адамға қосыңыз",
|
||
"жасанды интеллект керек емес", "роботпен сөйлеспеймін", "оператор керек",
|
||
"human operator", "connect me to operator", "transfer to operator", "speak to human", "live agent",
|
||
}
|
||
|
||
var ambiguousPhrases = []string{"оператор связи", "operator schedule", "call center operator schedule"}
|
||
|
||
func DetectHandoffRequest(text string, language string) DetectionResult {
|
||
n := normalize(text)
|
||
if n == "" {
|
||
return DetectionResult{Language: language, ReasonCode: "empty_input"}
|
||
}
|
||
for _, p := range ambiguousPhrases {
|
||
if strings.Contains(n, p) {
|
||
return DetectionResult{Language: language, MatchedPhrase: p, Confidence: 0.45, ReasonCode: "ambiguous", NeedsClarification: true}
|
||
}
|
||
}
|
||
for _, p := range handoffPhrases {
|
||
if strings.Contains(n, p) {
|
||
return DetectionResult{Requested: true, Confidence: 0.95, MatchedPhrase: p, Language: language, ReasonCode: "exact_phrase"}
|
||
}
|
||
}
|
||
if hasWord(n, "оператор") || hasWord(n, "operator") {
|
||
return DetectionResult{Requested: true, Confidence: 0.80, MatchedPhrase: "оператор", Language: language, ReasonCode: "keyword"}
|
||
}
|
||
return DetectionResult{Language: language, ReasonCode: "no_match"}
|
||
}
|
||
|
||
func normalize(s string) string {
|
||
s = strings.ToLower(strings.TrimSpace(s))
|
||
s = strings.ReplaceAll(s, "ё", "е")
|
||
var b strings.Builder
|
||
lastSpace := false
|
||
for _, r := range s {
|
||
if unicode.IsLetter(r) || unicode.IsDigit(r) {
|
||
b.WriteRune(r)
|
||
lastSpace = false
|
||
continue
|
||
}
|
||
if !lastSpace {
|
||
b.WriteRune(' ')
|
||
lastSpace = true
|
||
}
|
||
}
|
||
return strings.Join(strings.Fields(b.String()), " ")
|
||
}
|
||
|
||
func hasWord(text, word string) bool {
|
||
for _, f := range strings.Fields(text) {
|
||
if f == word {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|