feat: add diagnostic interview loop
This commit is contained in:
@@ -3,6 +3,7 @@ package workflows
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ErrNotImplemented = errors.New("workflow runner not implemented")
|
||||
@@ -27,6 +28,7 @@ type GradeAnswerInput struct {
|
||||
QuestionID string
|
||||
AnswerID string
|
||||
AnswerText string
|
||||
Concepts []ConceptRef
|
||||
}
|
||||
|
||||
type NextChallengeInput struct {
|
||||
@@ -49,8 +51,49 @@ func (StubRunner) DiagnoseJobSeeker(context.Context, DiagnosticInput) (Diagnosti
|
||||
return DiagnosticResult{}, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (StubRunner) GradeInterviewAnswer(context.Context, GradeAnswerInput) (GradedAnswer, error) {
|
||||
return GradedAnswer{}, ErrNotImplemented
|
||||
func (StubRunner) GradeInterviewAnswer(_ context.Context, input GradeAnswerInput) (GradedAnswer, error) {
|
||||
wordCount := len(strings.Fields(input.AnswerText))
|
||||
overall := AnswerPartial
|
||||
if wordCount >= 18 {
|
||||
overall = AnswerSolid
|
||||
}
|
||||
if wordCount < 8 {
|
||||
overall = AnswerMiss
|
||||
}
|
||||
|
||||
grade := GradedAnswer{
|
||||
AnswerID: input.AnswerID,
|
||||
QuestionID: input.QuestionID,
|
||||
Concepts: append([]ConceptRef(nil), input.Concepts...),
|
||||
Scores: AnswerScores{
|
||||
Correctness: scoreFromWords(wordCount, 8),
|
||||
Depth: scoreFromWords(wordCount, 14),
|
||||
Communication: scoreFromWords(wordCount, 10),
|
||||
ProductionJudgment: scoreFromWords(wordCount, 20),
|
||||
},
|
||||
Overall: overall,
|
||||
Strengths: []string{"Answer was captured and evaluated through the typed workflow boundary."},
|
||||
Gaps: []string{},
|
||||
Evidence: []EvidenceRef{
|
||||
{
|
||||
Kind: EvidenceAnswer,
|
||||
ID: input.AnswerID,
|
||||
Quote: input.AnswerText,
|
||||
Confidence: 1,
|
||||
},
|
||||
},
|
||||
FollowUp: FollowUpRecommendation{},
|
||||
}
|
||||
|
||||
if overall == AnswerMiss || overall == AnswerPartial {
|
||||
grade.Gaps = []string{"Answer needs more concrete reasoning and tradeoff discussion."}
|
||||
grade.FollowUp = FollowUpRecommendation{
|
||||
Needed: true,
|
||||
Question: "Can you give a concrete production example and explain the tradeoff?",
|
||||
Purpose: FollowUpRepair,
|
||||
}
|
||||
}
|
||||
return grade, nil
|
||||
}
|
||||
|
||||
func (StubRunner) ExtractLearningMemory(context.Context, GradedAnswer) (MemoryUpdateCandidate, error) {
|
||||
@@ -64,3 +107,13 @@ func (StubRunner) SelectNextChallenge(context.Context, NextChallengeInput) (Next
|
||||
func (StubRunner) UpdateReadinessMap(context.Context, ReadinessUpdateInput) (ReadinessUpdate, error) {
|
||||
return ReadinessUpdate{}, ErrNotImplemented
|
||||
}
|
||||
|
||||
func scoreFromWords(wordCount int, target int) int {
|
||||
if wordCount >= target {
|
||||
return 4
|
||||
}
|
||||
if wordCount >= target/2 {
|
||||
return 2
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user