diff --git a/cmd/cognitive-worker/interpretation_live_trace_test.go b/cmd/cognitive-worker/interpretation_live_trace_test.go index d4fdf5a..bb0bc9b 100644 --- a/cmd/cognitive-worker/interpretation_live_trace_test.go +++ b/cmd/cognitive-worker/interpretation_live_trace_test.go @@ -78,8 +78,12 @@ func TestLiveInterpretationTrace(t *testing.T) { for _, message := range []string{ "расскажи как это работает", "Расскажи, как это работает?", + "Расскажи как это работает", "можешь объяснить почему база растёт", "почему postgres использует столько памяти", + "ПОЧЕМУ postgres использует так много памяти", + "домовой не видит ии", + "домовой не вижит ии", "разберись почему сервис упал", "посмотри что произошло", "исправь ошибку если найдёшь", @@ -277,4 +281,4 @@ func cognitiveCandidateFromGateway(utteranceID interaction.HumanUtteranceID, can CapabilityHints: capabilityHints, RecordedAtUnixMillis: now.UnixMilli(), }, nil -} \ No newline at end of file +} diff --git a/modules/interaction/domain/semantics_test.go b/modules/interaction/domain/semantics_test.go index a13dd27..877579e 100644 --- a/modules/interaction/domain/semantics_test.go +++ b/modules/interaction/domain/semantics_test.go @@ -8,6 +8,7 @@ import ( "git.cin.su/m/Assistant/contracts/identity" "git.cin.su/m/Assistant/contracts/interaction" "git.cin.su/m/Assistant/contracts/situation" + "git.cin.su/m/Assistant/platform/ids" ) func TestInterpretUtteranceRecordsExplicitProjectFocus(t *testing.T) { @@ -136,6 +137,7 @@ func TestInterpretUtteranceNaturalRussianHelpflowUsesContextAwareCognitionInput( {message: "нет не UPO а UPO2 и обнови конфиг", wantSpeech: "", wantCognition: true, allowNoMatch: true}, {message: "postgres сейчас работает", wantSpeech: "", wantCognition: true, allowNoMatch: true}, {message: "сейчас домовой не видит ии", wantSpeech: "", wantCognition: true, allowNoMatch: true}, + {message: "домовой не видит ии", wantSpeech: "", wantCognition: true, allowNoMatch: true}, {message: "основная база называется UPO", wantSpeech: interaction.SpeechActAssertion, wantCognition: false}, {message: "привет", wantSpeech: interaction.SpeechActConversational, wantCognition: false}, {message: "спасибо", wantSpeech: interaction.SpeechActConversational, wantCognition: false}, @@ -151,6 +153,7 @@ func TestInterpretUtteranceNaturalRussianHelpflowUsesContextAwareCognitionInput( {message: "домовой не отвечает мне", wantSpeech: "", wantCognition: true, allowNoMatch: true}, {message: "домовой не слушает меня", wantSpeech: "", wantCognition: true, allowNoMatch: true}, {message: "домовой не отвечает на команды", wantSpeech: "", wantCognition: true, allowNoMatch: true}, + {message: "ПОЧЕМУ postgres использует так много памяти", wantSpeech: "", wantCognition: true, allowNoMatch: true}, } for _, tc := range cases { result := interpretForTest(t, tc.message, nil, "") @@ -169,6 +172,70 @@ func TestInterpretUtteranceNaturalRussianHelpflowUsesContextAwareCognitionInput( } } +func TestInterpretUtteranceDiagnosticTraceLineage(t *testing.T) { + message := "ты кто" + conversation := interaction.Conversation{ID: "conversation-1", ActorID: "actor-1", PrincipalID: "principal-1", Channel: interaction.ChannelWebChat, State: interaction.ConversationOpen} + utterance, _, _, err := NewHumanUtterance(conversation, interaction.ChatMessageRequest{Message: message}, time.Unix(100, 0)) + if err != nil { + t.Fatal(err) + } + result, err := InterpretUtterance(utterance, projectRegistryForTest(), nil, time.Unix(100, 0)) + if err != nil { + t.Fatal(err) + } + candidateID, err := ids.New() + if err != nil { + t.Fatal(err) + } + cognitiveCandidate := interaction.SemanticCandidate{ + ID: interaction.SemanticCandidateID(candidateID), + UtteranceID: utterance.ID, + Source: interaction.CandidateSourceCognitive, + SelectionState: interaction.CandidateObserved, + PrimarySpeechAct: interaction.SpeechActQuestion, + SecondarySpeechAct: interaction.SpeechActUnknown, + ConfidenceMillis: 780, + Applicability: interaction.SemanticNeedsBroaderInterpret, + RequestedOutcome: "", + Clarification: interaction.ClarificationNotRequired, + NeedsCognition: true, + SelectionReason: "trace-oriented cognitive clarification of identity-style intent", + CapabilityHints: []string{"COGNITIVE_REASONING"}, + RecordedAtUnixMillis: time.Unix(100, 0).UnixMilli(), + } + selected := ApplyCognitiveCandidate(result, message, cognitiveCandidate, nil) + var deterministic, selectedCandidate *interaction.SemanticCandidate + for index := range selected.Candidates { + c := &selected.Candidates[index] + if c.Source == interaction.CandidateSourceDeterministic { + deterministic = c + } + if c.SelectionState == interaction.CandidateSelected { + selectedCandidate = c + } + } + if deterministic == nil { + t.Fatal("expected deterministic candidate in trace") + } + if selectedCandidate == nil { + t.Fatal("expected selected candidate in trace") + } + if selected.Interpretation.Source != string(interaction.CandidateSourceCognitive) { + t.Fatalf("selection source should switch to cognitive, got %s", selected.Interpretation.Source) + } + if selected.Interpretation.NeedsCognition != selectedCandidate.NeedsCognition { + t.Fatalf("expected selected interpretation cognition=%t got %t", selectedCandidate.NeedsCognition, selected.Interpretation.NeedsCognition) + } + if selected.Interpretation.Clarification != selectedCandidate.Clarification { + t.Fatalf("expected selected candidate clarification to match interpretation clarification") + } + if selectedCandidate.SelectionReason == "" { + t.Fatal("expected clarification/selection reason in selected trace") + } + t.Logf("TRACE deterministic_source=%s cognitive_source=%s selected_source=%s needs_cognition=%t clarification_reason=%s", + deterministic.Source, selectedCandidate.Source, selected.Interpretation.Source, selected.Interpretation.NeedsCognition, selected.Interpretation.SelectionReason) +} + func TestInterpretUtteranceModalExplanationRequestStillRequestsCognition(t *testing.T) { for _, message := range []string{"можешь расказать об утре", "расскажи об утре", "про утро расскажешь"} { result := interpretForTest(t, message, nil, "")