feat: add learner memory ingestion
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"tutor/internal/learnermemory"
|
||||
"tutor/internal/workflows"
|
||||
)
|
||||
|
||||
@@ -16,11 +17,12 @@ var ErrQuestionNotFound = errors.New("diagnostic question not found")
|
||||
type Service struct {
|
||||
store Store
|
||||
runner workflows.Runner
|
||||
memory *learnermemory.Service
|
||||
ids atomic.Uint64
|
||||
}
|
||||
|
||||
func NewService(store Store, runner workflows.Runner) *Service {
|
||||
return &Service{store: store, runner: runner}
|
||||
func NewService(store Store, runner workflows.Runner, memory *learnermemory.Service) *Service {
|
||||
return &Service{store: store, runner: runner, memory: memory}
|
||||
}
|
||||
|
||||
func (s *Service) CreateSession(_ context.Context, input CreateSessionInput) (Session, error) {
|
||||
@@ -45,6 +47,16 @@ func (s *Service) CreateSession(_ context.Context, input CreateSessionInput) (Se
|
||||
Questions: BackendDeveloperQuestions(),
|
||||
CreatedAt: time.Now().UTC(),
|
||||
}
|
||||
if s.memory != nil {
|
||||
if _, err := s.memory.EnsureProfile(learnermemory.ProfileInput{
|
||||
UserID: session.UserID,
|
||||
TargetRole: session.TargetRole,
|
||||
Stack: session.Stack,
|
||||
InterviewTimeline: session.InterviewTimeline,
|
||||
}); err != nil {
|
||||
return Session{}, err
|
||||
}
|
||||
}
|
||||
return s.store.Create(session)
|
||||
}
|
||||
|
||||
@@ -84,6 +96,15 @@ func (s *Service) SubmitAnswer(ctx context.Context, input SubmitAnswerInput) (An
|
||||
return Answer{}, err
|
||||
}
|
||||
answer.Grade = grade
|
||||
if s.memory != nil {
|
||||
candidate, err := s.runner.ExtractLearningMemory(ctx, grade)
|
||||
if err != nil {
|
||||
return Answer{}, err
|
||||
}
|
||||
if err := s.memory.ApplyCandidate(candidate); err != nil {
|
||||
return Answer{}, err
|
||||
}
|
||||
}
|
||||
|
||||
session.Answers = append(session.Answers, answer)
|
||||
if answeredQuestionCount(session.Answers) >= len(session.Questions) {
|
||||
|
||||
@@ -4,11 +4,13 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"tutor/internal/learnermemory"
|
||||
"tutor/internal/workflows"
|
||||
)
|
||||
|
||||
func TestDiagnosticSessionAnswerFlow(t *testing.T) {
|
||||
service := NewService(NewMemoryStore(), workflows.NewStubRunner())
|
||||
memory := learnermemory.NewService(learnermemory.NewMemoryStore())
|
||||
service := NewService(NewMemoryStore(), workflows.NewStubRunner(), memory)
|
||||
|
||||
session, err := service.CreateSession(context.Background(), CreateSessionInput{
|
||||
UserID: "user-1",
|
||||
@@ -53,10 +55,22 @@ func TestDiagnosticSessionAnswerFlow(t *testing.T) {
|
||||
if len(loaded.Answers) != 1 {
|
||||
t.Fatalf("answers = %d, want 1", len(loaded.Answers))
|
||||
}
|
||||
|
||||
snapshot, err := memory.Snapshot(session.UserID)
|
||||
if err != nil {
|
||||
t.Fatalf("memory snapshot error: %v", err)
|
||||
}
|
||||
if len(snapshot.Mastery) == 0 {
|
||||
t.Fatal("expected memory mastery updates")
|
||||
}
|
||||
if len(snapshot.Mastery[0].Evidence) == 0 {
|
||||
t.Fatal("expected memory evidence")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiagnosticSessionCompletesAfterAllQuestionsAnswered(t *testing.T) {
|
||||
service := NewService(NewMemoryStore(), workflows.NewStubRunner())
|
||||
memory := learnermemory.NewService(learnermemory.NewMemoryStore())
|
||||
service := NewService(NewMemoryStore(), workflows.NewStubRunner(), memory)
|
||||
|
||||
session, err := service.CreateSession(context.Background(), CreateSessionInput{
|
||||
UserID: "user-1",
|
||||
|
||||
Reference in New Issue
Block a user