88 lines
3.7 KiB
Go
88 lines
3.7 KiB
Go
package domain
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.cin.su/m/Assistant/contracts/epistemics"
|
|
)
|
|
|
|
func TestAcceptedReminderResponseCreatesPositiveExperienceWithoutReflection(t *testing.T) {
|
|
experience, err := NewExperienceRecord(epistemics.ExperienceRecord{
|
|
SourceKind: epistemics.ExperienceSourceContinuity,
|
|
OriginalIntentID: "intent-1",
|
|
SourceUtteranceID: "utterance-1",
|
|
ContextRefs: []epistemics.ContextRef{"continuity:attention:attention-1"},
|
|
HelpMethod: epistemics.HelpMethodDeterministicFastPath,
|
|
SkillRef: "skill:obvious-reminder-response-v1",
|
|
ExpectedOutcome: epistemics.OutcomeSuccess,
|
|
ActualOutcome: epistemics.OutcomeSuccess,
|
|
OutcomeRef: "continuity:prospective:p1",
|
|
HumanResponseRef: "response-1",
|
|
VerificationEvidence: []epistemics.EvidenceRef{"target-resolver:single-recent-reminder", "human-response:complete"},
|
|
ConfidenceMillis: 950,
|
|
RecordedAtUnixMillis: 1000,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok, err := ReflectionForExperience(experience); err != nil || ok {
|
|
t.Fatalf("positive accepted experience should not force reflection: ok=%v err=%v", ok, err)
|
|
}
|
|
}
|
|
|
|
func TestUserCorrectionCreatesReflectionCandidate(t *testing.T) {
|
|
experience, err := NewExperienceRecord(epistemics.ExperienceRecord{
|
|
SourceKind: epistemics.ExperienceSourceInteraction,
|
|
OriginalIntentID: "intent-1",
|
|
SourceUtteranceID: "utterance-2",
|
|
HelpMethod: epistemics.HelpMethodClarification,
|
|
ExpectedOutcome: epistemics.OutcomeSuccess,
|
|
ActualOutcome: epistemics.OutcomeUserCorrected,
|
|
OutcomeDetail: "user corrected wrong target/project interpretation",
|
|
CorrectionUtteranceID: "utterance-2",
|
|
ConfidenceMillis: 1000,
|
|
RecordedAtUnixMillis: 1100,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
candidate, ok, err := ReflectionForExperience(experience)
|
|
if err != nil || !ok {
|
|
t.Fatalf("expected reflection candidate, ok=%v err=%v", ok, err)
|
|
}
|
|
if candidate.Trigger != epistemics.ReflectionUserCorrection || candidate.State != epistemics.ReflectionCandidateOpen || !candidate.RequiresCognition || len(candidate.EvidenceRefs) == 0 {
|
|
t.Fatalf("unexpected reflection candidate: %#v", candidate)
|
|
}
|
|
}
|
|
|
|
func TestReflectionNormalizesExperienceIDBeforeReferencingIt(t *testing.T) {
|
|
candidate, ok, err := ReflectionForExperience(epistemics.ExperienceRecord{
|
|
SourceKind: epistemics.ExperienceSourceInteraction,
|
|
OriginalIntentID: "intent-1",
|
|
SourceUtteranceID: "utterance-3",
|
|
HelpMethod: epistemics.HelpMethodClarification,
|
|
ExpectedOutcome: epistemics.OutcomeSuccess,
|
|
ActualOutcome: epistemics.OutcomeFailed,
|
|
OutcomeDetail: "deterministic route failed",
|
|
ConfidenceMillis: 800,
|
|
RecordedAtUnixMillis: 1200,
|
|
})
|
|
if err != nil || !ok || candidate.SourceExperienceID == "" || !candidate.RequiresCognition {
|
|
t.Fatalf("reflection did not preserve normalized source experience: candidate=%#v ok=%v err=%v", candidate, ok, err)
|
|
}
|
|
}
|
|
|
|
func TestFastPathDeclineReturnsToThinkingInsteadOfGuessing(t *testing.T) {
|
|
experience, err := FastPathDeclineExperience("intent-1", "utterance-1", "skill:obvious-reminder-response-v1", string(epistemics.OutcomeOutOfDistribution), 1200)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if experience.ActualOutcome != epistemics.OutcomeOutOfDistribution || experience.HelpMethod != epistemics.HelpMethodDeterministicFastPath {
|
|
t.Fatalf("unexpected fast path decline experience: %#v", experience)
|
|
}
|
|
candidate, ok, err := ReflectionForExperience(experience)
|
|
if err != nil || !ok || candidate.Trigger != epistemics.ReflectionSampledAudit {
|
|
t.Fatalf("decline should preserve reflection/escalation evidence, candidate=%#v ok=%v err=%v", candidate, ok, err)
|
|
}
|
|
}
|