hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit 067e7ce760f162cceecc2066a58f3496089420fe
parent 1a8bc7d1b9ae247e958408e478b306d86e1d1003
Author: triesap <tyson@radroots.org>
Date:   Mon, 21 Sep 2026 13:03:22 +0000

core: implement strict scripted evaluator

Diffstat:
Asrc/hyf_assist/scripted.mojo | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test_assist.mojo | 22++++++++++++++++++++++
2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/src/hyf_assist/scripted.mojo b/src/hyf_assist/scripted.mojo @@ -0,0 +1,49 @@ +from std.collections import List + +from hyf_assist.evaluator import ( + SemanticEvaluatorRequest, + SemanticEvaluatorResponse, + TypedAnswer, +) + + +@fieldwise_init +struct ScriptedEvaluator(Copyable, Movable): + var model: String + var answers: List[TypedAnswer] + var max_calls: Int + var call_count: Int + + +def scripted_evaluator( + model: String, answers: List[TypedAnswer], max_calls: Int +) raises -> ScriptedEvaluator: + if model.strip() == "": + raise Error("scripted evaluator requires a model") + if max_calls <= 0: + raise Error("scripted evaluator max_calls must be positive") + var copied = List[TypedAnswer]() + for answer in answers: + copied.append(answer.copy()) + return ScriptedEvaluator( + model=String(model), + answers=copied^, + max_calls=max_calls, + call_count=0, + ) + + +def scripted_evaluate( + mut evaluator: ScriptedEvaluator, request: SemanticEvaluatorRequest +) raises -> SemanticEvaluatorResponse: + if request.state.strip() == "": + raise Error("scripted evaluator requires non-empty state") + if request.question_bundle.strip() == "": + raise Error("scripted evaluator requires a question bundle") + if evaluator.call_count >= evaluator.max_calls: + raise Error("unexpected_scripted_call") + evaluator.call_count += 1 + var answers = List[TypedAnswer]() + for answer in evaluator.answers: + answers.append(answer.copy()) + return SemanticEvaluatorResponse(model=String(evaluator.model), answers=answers^) diff --git a/tests/test_assist.mojo b/tests/test_assist.mojo @@ -66,3 +66,25 @@ def test_clock_ports_are_injectable_and_monotonic() raises: assert_equal(monotonic_elapsed_ns(start, end), 5000) assert_true(system_wall_epoch_seconds() > 1600000000) assert_true(system_monotonic_ns() > 0) + + +from hyf_assist.scripted import scripted_evaluate, scripted_evaluator + + +def test_scripted_evaluator_is_strict_and_bounded() raises: + var answers = List[TypedAnswer]() + answers.append(typed_choice("supply_status", "offered", 1.0)) + var evaluator = scripted_evaluator("jev-1.13.0", answers, 1) + var response = scripted_evaluate( + evaluator, SemanticEvaluatorRequest(state="s", question_bundle="qb1") + ) + assert_equal(response.answers[0].choice, "offered") + assert_equal(evaluator.call_count, 1) + with assert_raises(): + _ = scripted_evaluate( + evaluator, SemanticEvaluatorRequest(state="s", question_bundle="qb1") + ) + with assert_raises(): + _ = scripted_evaluate( + evaluator, SemanticEvaluatorRequest(state="", question_bundle="qb1") + )