evaluator.mojo (2579B)
1 from std.collections import List 2 3 4 @fieldwise_init 5 struct TypedAnswer(Copyable, Movable): 6 var question_id: String 7 var kind: String 8 var choice: String 9 var score: Int 10 var noul: Float64 11 var confidence: Float64 12 13 14 @fieldwise_init 15 struct SemanticEvaluatorRequest(Copyable, Movable): 16 var state: String 17 var question_bundle: String 18 19 20 @fieldwise_init 21 struct SemanticEvaluatorResponse(Copyable, Movable): 22 var model: String 23 var answers: List[TypedAnswer] 24 25 26 @fieldwise_init 27 struct DisabledSemanticEvaluator(Copyable, Movable): 28 def evaluate( 29 self, request: SemanticEvaluatorRequest 30 ) raises -> SemanticEvaluatorResponse: 31 raise Error("semantic evaluator is disabled") 32 33 34 def typed_choice( 35 question_id: String, choice: String, confidence: Float64 36 ) raises -> TypedAnswer: 37 if question_id.strip() == "" or choice.strip() == "": 38 raise Error("choice answer requires question id and choice") 39 if confidence < 0.0 or confidence > 1.0: 40 raise Error("choice confidence must be within [0, 1]") 41 return TypedAnswer( 42 question_id=String(question_id), 43 kind="choice", 44 choice=String(choice), 45 score=0, 46 noul=0.0, 47 confidence=confidence, 48 ) 49 50 51 def typed_noul(question_id: String, noul: Float64) raises -> TypedAnswer: 52 if noul < 0.0 or noul > 1.0: 53 raise Error("noul probability must be within [0, 1]") 54 return TypedAnswer( 55 question_id=String(question_id), 56 kind="noul", 57 choice="", 58 score=0, 59 noul=noul, 60 confidence=noul, 61 ) 62 63 64 def typed_score( 65 question_id: String, score: Int, levels: Int, confidence: Float64 66 ) raises -> TypedAnswer: 67 if levels < 2: 68 raise Error("score rubric requires at least two levels") 69 if score < 0 or score >= levels: 70 raise Error("score is out of rubric range") 71 if confidence < 0.0 or confidence > 1.0: 72 raise Error("score confidence must be within [0, 1]") 73 return TypedAnswer( 74 question_id=String(question_id), 75 kind="score", 76 choice="", 77 score=score, 78 noul=0.0, 79 confidence=confidence, 80 ) 81 82 83 def normalize_score(answer: TypedAnswer, levels: Int) raises -> Float64: 84 if answer.kind != "score": 85 raise Error("normalize_score requires a score answer") 86 if levels < 2: 87 raise Error("score rubric requires at least two levels") 88 if answer.score < 0 or answer.score >= levels: 89 raise Error("score is out of rubric range") 90 return Float64(answer.score) / Float64(levels - 1)