Repository navigation
Add --evaluator-args flag forwarding kwargs to evaluate() via signature sniffing - #506
Merged
codelion merged 2 commits intoOct 10, 2026
Conversation
…re sniffing
- New evaluator.evaluator_args config field (Optional[Dict[str, Any]]),
settable from YAML or the new --evaluator-args '{"weight": 2.0}' CLI flag
(invalid JSON or a non-object value exits 1 with an actionable message)
- Evaluator inspects evaluate() with inspect.signature: configured kwargs
are forwarded via functools.partial when the function accepts them
(named parameters or **kwargs); unsupported keys - or a kwarg colliding
with the positional program path - fail at startup with an error naming
the offending keys and the actual signature instead of failing on every
evaluation; single-argument evaluators without evaluator_args keep their
existing behavior unchanged
- Log kwarg key names only, never values (they may contain secrets)
- Document the flag in README, replacing the env-var workaround for
per-run evaluator settings
- Add tests/test_evaluator_args.py: kwargs forwarding (named + **kwargs),
backward compatibility, startup validation, YAML load, worker config
dict round-trip, CLI JSON parsing and invalid-JSON exit code
Cascade evaluate_stage1/2/3 functions are intentionally out of scope;
issue algorithmicsuperintelligence#474 only covers evaluate().
Fixes algorithmicsuperintelligence#474
…**kwargs evaluators at startup
Move the signature.bind guard ahead of the VAR_KEYWORD shortcut so a
configured key colliding with a positional parameter (e.g.
evaluator_args={"program_path": ...} for evaluate(program_path, **kwargs))
fails at load time with an actionable message instead of raising
TypeError on every evaluation. The bind check mirrors the actual call
functools.partial(evaluate, **args)(program_path), so it can only reject
configurations that would fail at call time anyway.
Adds two tests: collision rejection for **kwargs evaluators and continued
forwarding of non-colliding keys.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #474
Implements the approach @codelion outlined in the issue: a
--evaluator-argsCLI flag that accepts a JSON object and forwards the parsed kwargs to the user'sevaluate()function, usinginspect.signatureso that existing single-argument evaluators keep working unchanged.@ai-nikolai — this implements the approach discussed in #474. I left a comment on the issue before starting; if you had work in flight since July, happy to coordinate or step back in favor of your PR.
What it does
evaluator.evaluator_args: Optional[Dict[str, Any]](openevolve/config.py), settable from YAML or the CLI. It round-trips throughConfig.to_dict()→EvaluatorConfig(**d["evaluator"]), so it propagates to process-pool workers with no extra serialization work.--evaluator-args '{"weight": 2.0, "label": "exp-1"}'(openevolve/cli.py). Invalid JSON or a non-object value exits with code 1 and an actionable message. Only kwarg key names are logged, never values (they may contain secrets).Evaluator._resolve_evaluator_kwargs,openevolve/evaluator.py):evaluate()accepts**kwargs→ all configured kwargs are forwarded.evaluate()has named parameters covering the configured keys → forwarded on every call viafunctools.partialat therun_in_executorcall site.evaluate()cannot accept a configured key → startup error naming the offending keys and the actual signature (this also catches a kwarg colliding with the positional program path, e.g.evaluator_args={"program_path": ...}), instead of failing on every evaluation.evaluator_argsconfigured (the common single-program_pathcase) → behavior is completely unchanged.config.yamlkeys are silently dropped by the config parser (as @codelion pointed out in the issue).Out of scope (as discussed in #474)
Cascade
evaluate_stage1/2/3functions are not touched — the issue coversevaluate()only. Positional-argument forwarding is also not included.Testing (red → green)
New
tests/test_evaluator_args.py(15 tests,unittest, fully offline):**kwargsevaluatorsprogram_pathcollision, actual signature included in the error messageevaluator.evaluator_argsand worker config dict round-tripparse_evaluator_args: valid / empty / invalid-JSON / non-object--evaluator-argsJSON → exit code 1Red on
main(tests added first, source unchanged):Green after the change:
Full suite:
Format:
black --line-length 100/isort --profile black --line-length 100applied to all changed files (isort also removed two pre-existing duplicate imports inevaluator.py).Update (fix commit
dac0e21, pushed after the numbers above were written): thesignature.bindcollision guard now runs before the**kwargsshortcut, soevaluator_argskeys shadowing a positional parameter (e.g.{"program_path": ...}forevaluate(program_path, **kwargs)) are rejected at startup with an actionable message instead of raisingTypeErroron every evaluation. Two tests added:tests/test_evaluator_args.pynow has 17 tests, and the full suite isRan 622 tests ... OK.