Add DriftJudge AI role with verdict parsing

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 16:45:59 -04:00
parent 7e9d00b80b
commit 83bae00e45
3 changed files with 144 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
package ai
import (
"context"
"errors"
"strings"
"testing"
)
func TestParseVerdictOnTask(t *testing.T) {
v, err := parseVerdict(`{"on_task": true, "reason": ""}`)
if err != nil {
t.Fatalf("parse: %v", err)
}
if !v.OnTask {
t.Fatalf("expected on-task, got %+v", v)
}
}
func TestParseVerdictDriftingChatty(t *testing.T) {
v, err := parseVerdict("Sure! here is the call:\n{\"on_task\": false, \"reason\": \"Reddit is unrelated\"}\nhope that helps")
if err != nil {
t.Fatalf("parse: %v", err)
}
if v.OnTask || v.Reason != "Reddit is unrelated" {
t.Fatalf("bad verdict: %+v", v)
}
}
func TestParseVerdictDriftingNeedsReason(t *testing.T) {
if _, err := parseVerdict(`{"on_task": false}`); !errors.Is(err, ErrInvalidVerdict) {
t.Fatalf("want ErrInvalidVerdict for reasonless drift, got %v", err)
}
}
func TestParseVerdictEmpty(t *testing.T) {
if _, err := parseVerdict(" "); !errors.Is(err, ErrEmptyResponse) {
t.Fatalf("want ErrEmptyResponse, got %v", err)
}
}
func TestParseVerdictNoJSON(t *testing.T) {
if _, err := parseVerdict("I cannot help"); !errors.Is(err, ErrNoJSON) {
t.Fatalf("want ErrNoJSON, got %v", err)
}
}
func TestServiceJudgeDrift(t *testing.T) {
fb := &fakeBackend{out: `{"on_task": false, "reason": "YouTube is off-task"}`}
v, err := NewService(fb).JudgeDrift(context.Background(), "write the report", "firefox", "YouTube")
if err != nil {
t.Fatalf("judge: %v", err)
}
if v.OnTask || v.Reason == "" {
t.Fatalf("bad verdict: %+v", v)
}
if !strings.Contains(fb.gotPrompt, "write the report") || !strings.Contains(fb.gotPrompt, "YouTube") {
t.Fatalf("prompt should embed commitment and window: %s", fb.gotPrompt)
}
}
func TestServiceJudgeDriftBackendError(t *testing.T) {
fb := &fakeBackend{err: errors.New("boom")}
if _, err := NewService(fb).JudgeDrift(context.Background(), "x", "c", "t"); err == nil {
t.Fatal("want backend error")
}
}