76 lines
3.1 KiB
Go
76 lines
3.1 KiB
Go
package domain
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.cin.su/m/Assistant/contracts/capability"
|
|
)
|
|
|
|
func TestRepeatedCapabilityFailuresDegradeSkillWithoutDeletingHistory(t *testing.T) {
|
|
profile := skillProfile()
|
|
profile.SupportingExperienceRefs = []capability.SkillEvidenceRef{"experience:success-1"}
|
|
for _, ref := range []capability.SkillEvidenceRef{"experience:failure-1", "experience:failure-2", "experience:failure-3"} {
|
|
next, err := ObserveSkillOutcome(profile, capability.SkillOutcomeObservation{ExperienceRef: ref, Outcome: capability.UsageFailed, ObservedAtUnixMillis: profile.RecordedAtUnixMillis + 100})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
profile = next
|
|
}
|
|
if profile.Status != capability.SkillDegraded {
|
|
t.Fatalf("expected degraded skill, got %#v", profile)
|
|
}
|
|
if len(profile.SupportingExperienceRefs) != 1 || len(profile.KnownFailureExperienceRefs) != 3 {
|
|
t.Fatalf("skill degradation must preserve success/failure evidence: %#v", profile)
|
|
}
|
|
}
|
|
|
|
func TestFastPathDeclinesUnsupportedInputAndEscalatesToThinking(t *testing.T) {
|
|
decision, err := DecideFastPath(skillProfile(), false, 900, false, false, 2000)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if decision.Decision != capability.FastPathEscalate || decision.DeclineReason != capability.FastPathOutOfDistribution || !decision.RequiresCognition {
|
|
t.Fatalf("unexpected fast path decision: %#v", decision)
|
|
}
|
|
}
|
|
|
|
func TestValidatedSkillCanApplyFastPathWhenFreshAndConfident(t *testing.T) {
|
|
decision, err := DecideFastPath(skillProfile(), true, 950, false, false, 2000)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if decision.Decision != capability.FastPathApplied || decision.RequiresCognition {
|
|
t.Fatalf("unexpected fast path decision: %#v", decision)
|
|
}
|
|
}
|
|
|
|
func TestUnknownAndSkippedOutcomesDoNotBecomeSkillFailures(t *testing.T) {
|
|
profile := skillProfile()
|
|
for _, outcome := range []capability.UsageOutcomeClass{capability.UsageUnknown, capability.UsageSkipped} {
|
|
next, err := ObserveSkillOutcome(profile, capability.SkillOutcomeObservation{ExperienceRef: capability.SkillEvidenceRef("experience:" + string(outcome)), Outcome: outcome, ObservedAtUnixMillis: profile.RecordedAtUnixMillis + 1})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if next.ObservedFailureCount != profile.ObservedFailureCount || len(next.KnownFailureExperienceRefs) != len(profile.KnownFailureExperienceRefs) || next.ConfidenceMillis != profile.ConfidenceMillis {
|
|
t.Fatalf("outcome %q was incorrectly recorded as failure: %#v", outcome, next)
|
|
}
|
|
profile = next
|
|
}
|
|
}
|
|
|
|
func skillProfile() capability.SkillProfile {
|
|
return capability.SkillProfile{
|
|
ID: "skill-obvious-reminder-response-v1",
|
|
Revision: 1,
|
|
Name: "Resolve obvious reminder continuation",
|
|
Description: "Use a recent unambiguous reminder/attention target for complete/snooze/cancel without cognition.",
|
|
ApplicableContext: []string{"continuity:reminder-response"},
|
|
ImplementationRef: "continuity:human-response-target-resolver-v1",
|
|
ImplementationVersion: "1",
|
|
Status: capability.SkillValidated,
|
|
ConfidenceMillis: 850,
|
|
LastValidatedUnixMillis: 1000,
|
|
RecordedAtUnixMillis: 1000,
|
|
}
|
|
}
|