Expand semantic memory decomposition checks
This commit is contained in:
@@ -48,6 +48,20 @@ func TestHouseholdMarketplaceBrandSearchUsesResearchRoute(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHouseholdSemanticMemoryControlsMarketplaceAlias(t *testing.T) {
|
||||
withoutMemory := interactiondomain.DecomposeTask("найди на WB бренд marka-wear")
|
||||
if withoutMemory.Source != "" || withoutMemory.Object != "" {
|
||||
t.Fatalf("core invented marketplace meaning without memory: %+v", withoutMemory)
|
||||
}
|
||||
withMemory := interactiondomain.DecomposeTaskWithLexicon("поищи марку marka-wear в Wildberries", interactiondomain.TaskLexicon{
|
||||
ObjectAliases: []interactiondomain.TaskLexiconEntry{{Alias: "марку", Value: "BRAND"}},
|
||||
SourceAliases: []interactiondomain.TaskLexiconEntry{{Alias: "wildberries", Value: "WILDBERRIES"}},
|
||||
})
|
||||
if withMemory.Intent != interactiondomain.TaskIntentSearch || withMemory.Object != "BRAND" || withMemory.Source != "WILDBERRIES" || withMemory.Target != "marka-wear" || !withMemory.NeedsResearch {
|
||||
t.Fatalf("semantic memory did not control marketplace decomposition: %+v", withMemory)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHouseholdBearDrawingUsesCreativeLocalRoute(t *testing.T) {
|
||||
candidate := interactiondomain.BuildDeterministicCandidate("нарисуй бурого медведя", "", time.Unix(10, 0).UnixMilli())
|
||||
decomposition := interactiondomain.DecomposeTaskWithLexicon("нарисуй бурого медведя", interactiondomain.TaskLexicon{ObjectAliases: []interactiondomain.TaskLexiconEntry{{Alias: "медвед", Value: "IMAGE"}}})
|
||||
|
||||
@@ -181,6 +181,26 @@ func TestDecomposeMarketplaceBrandRequestIntoExecutionAtoms(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecomposeDoesNotInventMutableAliases(t *testing.T) {
|
||||
got := DecomposeTask("найди на WB бренд marka-wear")
|
||||
if got.Source != "" || got.Object != "" || got.NeedsResearch {
|
||||
t.Fatalf("parser invented a mutable alias without memory: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecomposeUsesRememberedAliasesAcrossWordings(t *testing.T) {
|
||||
lexicon := TaskLexicon{
|
||||
ObjectAliases: []TaskLexiconEntry{{Alias: "бренд", Value: "BRAND"}, {Alias: "марку", Value: "BRAND"}},
|
||||
SourceAliases: []TaskLexiconEntry{{Alias: "wb", Value: "WILDBERRIES"}, {Alias: "wildberries", Value: "WILDBERRIES"}},
|
||||
}
|
||||
for _, message := range []string{"найди на WB бренд marka-wear", "поищи марку marka-wear в Wildberries"} {
|
||||
got := DecomposeTaskWithLexicon(message, lexicon)
|
||||
if got.Intent != TaskIntentSearch || got.Object != "BRAND" || got.Source != "WILDBERRIES" || got.Target != "marka-wear" || !got.NeedsResearch {
|
||||
t.Fatalf("remembered aliases failed for %q: %+v", message, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecomposeCreativeRequestDoesNotInventResearch(t *testing.T) {
|
||||
lexicon := TaskLexicon{ObjectAliases: []TaskLexiconEntry{{Alias: "медвед", Value: "IMAGE"}}}
|
||||
got := DecomposeTaskWithLexicon("нарисуй бурого медведя", lexicon)
|
||||
|
||||
@@ -53,13 +53,13 @@ func DecomposeTaskWithLexicon(message string, lexicon TaskLexicon) TaskDecomposi
|
||||
result.Intent = TaskIntentCreate
|
||||
}
|
||||
for _, entry := range lexicon.ObjectAliases {
|
||||
if containsStemInTokens(tokens, entry.Alias) {
|
||||
if lexiconAliasMatches(tokens, entry.Alias) {
|
||||
result.Object = entry.Value
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, entry := range lexicon.SourceAliases {
|
||||
if containsStemInTokens(tokens, entry.Alias) {
|
||||
if lexiconAliasMatches(tokens, entry.Alias) {
|
||||
result.Source = entry.Value
|
||||
break
|
||||
}
|
||||
@@ -87,6 +87,14 @@ func DecomposeTaskWithLexicon(message string, lexicon TaskLexicon) TaskDecomposi
|
||||
return result
|
||||
}
|
||||
|
||||
func lexiconAliasMatches(tokens []string, alias string) bool {
|
||||
alias = strings.TrimSpace(strings.ToLower(alias))
|
||||
if len([]rune(alias)) < 2 {
|
||||
return false
|
||||
}
|
||||
return containsStemInTokens(tokens, alias)
|
||||
}
|
||||
|
||||
func valueAfterAnyCue(message string, cues ...string) string {
|
||||
for _, cue := range cues {
|
||||
if value := valueAfterCue(message, cue); value != "" {
|
||||
@@ -103,8 +111,14 @@ func valueAfterCue(message, cue string) string {
|
||||
}
|
||||
value := strings.TrimSpace(message[index+len(cue):])
|
||||
value = strings.Trim(value, " \t:,-")
|
||||
if end := strings.IndexAny(value, "?!,.;"); end >= 0 {
|
||||
value = value[:end]
|
||||
end := len(value)
|
||||
if punctuation := strings.IndexAny(value, "?!,.;"); punctuation >= 0 && punctuation < end {
|
||||
end = punctuation
|
||||
}
|
||||
return strings.TrimSpace(value)
|
||||
for _, boundary := range []string{" в ", " на ", " из ", " для ", " около "} {
|
||||
if index := strings.Index(value, boundary); index >= 0 && index < end {
|
||||
end = index
|
||||
}
|
||||
}
|
||||
return strings.TrimSpace(value[:end])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user