AUD-117: derive person from the question via project people list
Decode the people list from each project's /capabilities and set the /ask person field from a whole-word, case-insensitive name in the question when the caller did not name a person. Match only the routed project's people, so a name from another project does not leak across. Fall back to asker when no name matches. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
37
src/understand/person.go
Normal file
37
src/understand/person.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package understand
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MatchPerson returns the household name from people that appears as a whole
|
||||
// word in the question, or "" when no name matches.
|
||||
//
|
||||
// It is deterministic: no LLM is in this path (AGENTS.md rule 4). The Hub uses
|
||||
// it to set the /ask person field from the question when the caller did not
|
||||
// name a person. A caller-supplied person always wins; the caller does not call
|
||||
// this function in that case.
|
||||
//
|
||||
// The match is case-insensitive and whole-word, so "harry" matches "What does
|
||||
// Harry have on today?" but not "harrypotter". The matched name is returned as
|
||||
// the project published it, trimmed.
|
||||
func MatchPerson(question string, people []string) string {
|
||||
if strings.TrimSpace(question) == "" || len(people) == 0 {
|
||||
return ""
|
||||
}
|
||||
q := strings.ToLower(question)
|
||||
for _, p := range people {
|
||||
name := strings.TrimSpace(p)
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
// \b is a word boundary in Go's RE2. QuoteMeta keeps a name that
|
||||
// holds a regexp character literal.
|
||||
re := regexp.MustCompile(`\b` + regexp.QuoteMeta(strings.ToLower(name)) + `\b`)
|
||||
if re.MatchString(q) {
|
||||
return name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user