Preserve context across conversation intents (V-542)

Owner explicitly requested direct commits to master; bypass the branch-only hook.
This commit is contained in:
2026-08-13 02:14:46 +04:00
parent a0e6643465
commit da9114b623
15 changed files with 499 additions and 56 deletions
+67
View File
@@ -138,6 +138,7 @@ func TestFollowUpMerge(t *testing.T) {
prior := &dialogue.Session{
Intent: dialogue.IntentFact,
Slots: dialogue.Slots{Key: "water", HasKey: true},
Utterance: "я выпил воду",
Timestamp: base,
TTL: 2 * time.Minute,
}
@@ -152,6 +153,72 @@ func TestFollowUpMerge(t *testing.T) {
if got.Slots.Key != "water" {
t.Errorf("query after fact: got key=%q, want water", got.Slots.Key)
}
if got.Intent != router.IntentChat {
t.Errorf("anaphoric query intent = %s, want chat with dialogue context", got.Intent)
}
})
t.Run("anaphoric query after unkeyed query uses raw dialogue context", func(t *testing.T) {
prior := &dialogue.Session{
Intent: dialogue.IntentQuery,
Slots: dialogue.Slots{Text: "кто изобрёл телефон?"},
Utterance: "кто изобрёл телефон?",
Timestamp: base,
TTL: 2 * time.Minute,
}
cur := router.Decision{
Intent: router.IntentQuery,
Utterance: "а когда он это сделал?",
Source: router.SourceWorld,
SourceAnchored: true,
}
got := followUpMerge(prior, cur, base.Add(30*time.Second))
if got.Intent != router.IntentChat {
t.Fatalf("intent = %s, want chat", got.Intent)
}
if got.Source != router.SourceUnknown || got.SourceAnchored {
t.Errorf("query-only source survived contextual chat: source=%s anchored=%v", got.Source, got.SourceAnchored)
}
})
t.Run("anaphora without a usable prior session stays routed", func(t *testing.T) {
prior := &dialogue.Session{
Intent: dialogue.IntentQuery,
Timestamp: base,
TTL: 2 * time.Minute,
}
cur := router.Decision{Intent: router.IntentQuery, Utterance: "что это?"}
got := followUpMerge(prior, cur, base.Add(30*time.Second))
if got.Intent != router.IntentQuery {
t.Errorf("empty session changed intent to %s", got.Intent)
}
})
t.Run("possessive determiner does not turn an explicit query into chat", func(t *testing.T) {
prior := &dialogue.Session{
Intent: dialogue.IntentChat, Utterance: "привет",
Timestamp: base, TTL: 2 * time.Minute,
}
cur := router.Decision{Intent: router.IntentQuery, Utterance: "где мой телефон?"}
got := followUpMerge(prior, cur, base.Add(30*time.Second))
if got.Intent != router.IntentQuery {
t.Errorf("explicit possessive query changed intent to %s", got.Intent)
}
})
t.Run("anaphoric act is never widened into chat", func(t *testing.T) {
prior := &dialogue.Session{
Intent: dialogue.IntentChat, Utterance: "сервер homesrv",
Timestamp: base, TTL: 2 * time.Minute,
}
cur := router.Decision{Intent: router.IntentAct, Utterance: "выключи его"}
got := followUpMerge(prior, cur, base.Add(30*time.Second))
if got.Intent != router.IntentAct {
t.Errorf("act intent changed to %s", got.Intent)
}
if got.Slots.HasFn {
t.Error("anaphora invented an executable function")
}
})
t.Run("query after fact without anaphora does not inherit", func(t *testing.T) {