mavend: carry ResolvedBy through dialogue Slots bridge

Add ResolvedBy to dialogue.Slots and the toDialogueSlots/
applyDialogueSlots converters. Skip reflect-type check for this field
in parity test (dialogue cannot import router: import cycle).
This commit is contained in:
2026-09-06 13:50:30 +04:00
parent 66f06796cb
commit bdd79ad585
2 changed files with 27 additions and 18 deletions
+11 -9
View File
@@ -72,15 +72,16 @@ func dialogueIDOf(ctx context.Context) string {
// toDialogueSlots projects the router's slots onto the dialogue layer's copy. // toDialogueSlots projects the router's slots onto the dialogue layer's copy.
func toDialogueSlots(s router.Slots) dialogue.Slots { func toDialogueSlots(s router.Slots) dialogue.Slots {
return dialogue.Slots{ return dialogue.Slots{
Time: s.Time, Time: s.Time,
HasTime: s.HasTime, HasTime: s.HasTime,
Key: s.Key, Key: s.Key,
Value: s.Value, Value: s.Value,
HasKey: s.HasKey, HasKey: s.HasKey,
Text: s.Text, Text: s.Text,
Fn: s.Fn, Fn: s.Fn,
Args: s.Args, Args: s.Args,
HasFn: s.HasFn, HasFn: s.HasFn,
ResolvedBy: string(s.ResolvedBy),
} }
} }
@@ -90,6 +91,7 @@ func applyDialogueSlots(base router.Slots, d dialogue.Slots) router.Slots {
base.Key, base.Value, base.HasKey = d.Key, d.Value, d.HasKey base.Key, base.Value, base.HasKey = d.Key, d.Value, d.HasKey
base.Text = d.Text base.Text = d.Text
base.Fn, base.Args, base.HasFn = d.Fn, d.Args, d.HasFn base.Fn, base.Args, base.HasFn = d.Fn, d.Args, d.HasFn
base.ResolvedBy = router.ActionResolutionMethod(d.ResolvedBy)
return base return base
} }
+16 -9
View File
@@ -31,6 +31,12 @@ func TestSlotsParity(t *testing.T) {
t.Errorf("router.Slots.%s (%s) missing from dialogue.Slots", name, typ) t.Errorf("router.Slots.%s (%s) missing from dialogue.Slots", name, typ)
continue continue
} }
// ResolvedBy is ActionResolutionMethod in router and string in dialogue
// (dialogue cannot import router: import cycle). The underlying type is
// string in both; skip the reflect-type check for this field.
if name == "ResolvedBy" {
continue
}
if dt != typ { if dt != typ {
t.Errorf("field %s: router has %s, dialogue has %s", name, typ, dt) t.Errorf("field %s: router has %s, dialogue has %s", name, typ, dt)
} }
@@ -47,15 +53,16 @@ func TestSlotsParity(t *testing.T) {
// populated value and compare. // populated value and compare.
func TestSlotsRoundTrip(t *testing.T) { func TestSlotsRoundTrip(t *testing.T) {
full := router.Slots{ full := router.Slots{
Time: time.Date(2026, 8, 2, 11, 0, 0, 0, time.UTC), Time: time.Date(2026, 8, 2, 11, 0, 0, 0, time.UTC),
HasTime: true, HasTime: true,
Fn: "restart", Fn: "restart",
Args: []string{"nginx"}, Args: []string{"nginx"},
HasFn: true, HasFn: true,
Key: "water", ResolvedBy: router.ActionResolutionGrammarMatcher,
Value: `"drank"`, Key: "water",
HasKey: true, Value: `"drank"`,
Text: "выпил воды", HasKey: true,
Text: "выпил воды",
} }
// Every field must be non-zero, or the round-trip proves nothing. // Every field must be non-zero, or the round-trip proves nothing.
rv := reflect.ValueOf(full) rv := reflect.ValueOf(full)