Summary
Python's EvaluatorFn is typed as taking BaseDataPoint (test_case_id: str | None), but the evaluator stepper always assigns a UUID before calling the callback — same as JS, which types the callback as BaseEvalDataPoint (testCaseId required).
Current behavior
In py/packages/genkit/src/genkit/_ai/_evaluator.py:
if datapoint.test_case_id is None:
datapoint.test_case_id = str(uuid.uuid4())
# ...
test_case_output = await fn(datapoint, req.options)
EvaluatorFn is still:
EvaluatorFn = Callable[[BaseDataPoint, T], Coroutine[Any, Any, EvalFnResponse]]
Both models already exist in genkit.evaluator / _typing.py:
| Type |
test_case_id |
BaseDataPoint |
optional (dataset input) |
BaseEvalDataPoint |
required |
Expected
Mirror the JS split:
- Dataset /
EvalRequest: BaseDataPoint (id optional)
- Evaluator callback:
BaseEvalDataPoint (id guaranteed after the fill-in)
So typecheckers don't force datapoint.test_case_id or '' in custom evaluators.
Suggested fix
- Change
EvaluatorFn to Callable[[BaseEvalDataPoint, T], ...].
- After the UUID fill-in, pass a
BaseEvalDataPoint (validate/construct) into fn rather than a mutated BaseDataPoint.
- Update first-party evaluators (
genkit-evaluators, google-genai evaluators) and tests/docs that annotate the callback arg.
References
- JS:
js/ai/src/evaluator.ts — testCaseId ?? randomUUID() then BaseEvalDataPoint runner type
- Python:
py/packages/genkit/src/genkit/_ai/_evaluator.py (eval_stepper_fn)
Summary
Python's
EvaluatorFnis typed as takingBaseDataPoint(test_case_id: str | None), but the evaluator stepper always assigns a UUID before calling the callback — same as JS, which types the callback asBaseEvalDataPoint(testCaseIdrequired).Current behavior
In
py/packages/genkit/src/genkit/_ai/_evaluator.py:EvaluatorFnis still:Both models already exist in
genkit.evaluator/_typing.py:test_case_idBaseDataPointBaseEvalDataPointExpected
Mirror the JS split:
EvalRequest:BaseDataPoint(id optional)BaseEvalDataPoint(id guaranteed after the fill-in)So typecheckers don't force
datapoint.test_case_id or ''in custom evaluators.Suggested fix
EvaluatorFntoCallable[[BaseEvalDataPoint, T], ...].BaseEvalDataPoint(validate/construct) intofnrather than a mutatedBaseDataPoint.genkit-evaluators, google-genai evaluators) and tests/docs that annotate the callback arg.References
js/ai/src/evaluator.ts—testCaseId ?? randomUUID()thenBaseEvalDataPointrunner typepy/packages/genkit/src/genkit/_ai/_evaluator.py(eval_stepper_fn)