Files
Assistant/modules/epistemics/domain/experience_test.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)
}
}