fix(registry): round-trip parameterized score reducers#4519
Conversation
ebarkhordar
left a comment
There was a problem hiding this comment.
Nice fix, and I checked it does what it says: installed the branch at 0d8d8f9 and confirmed at_least(3) now registers as at_least with params={"k": 3}, so registry_arg(registry_value(at_least(3))) round-trips and reducer_log_name still returns at_least_3. The old name="at_least_3" had no matching factory, so a restore couldn't have worked before.
One thing this opens up: the change removes the only reader of REDUCER_NAME. wrapper no longer calls getattr(score_reducer, REDUCER_NAME, ...), and reducer_log_name builds the _k suffix from registry_params, not from the attribute. But at_least/pass_at/pass_k still setattr(reduce, REDUCER_NAME, ...) at reducer.py:116, :162, and :202, so the attribute is now written and never read in src/. grep -rn __REDUCER_NAME__ src/ shows only the constant, the import, and those three writes.
Is REDUCER_NAME meant to stay (read by something downstream I missed), or can the three setattr calls plus the constant and import go? Asking because the new getattr(r3, REDUCER_NAME) == "at_least_3" assertions pin an attribute nothing consumes, which could read as load-bearing to the next person in this file.
0d8d8f9 to
5f4bde6
Compare
|
You're right. I removed the constant and import, all three Verification after the cleanup:
Thanks for catching this. |
This PR contains:
What is the current behavior? (You can also link to an open issue here)
Part of #4374.
Directly constructed parameterized score reducers such as
at_least(2),pass_at(2), andpass_k(2)serialize their human-facing names (at_least_2, etc.) intoRegistryDict.name. Those suffixed names are not registered factory keys, so replay throughregistry_arg(registry_value(reducer))raisesLookupErroreven thoughkis already present in the serialized params.What is the new behavior?
Score reducer instances keep the registered factory name as their registry identity. Parameterized reducers now serialize with names such as
at_leastplus{"k": 2}, so they restore through the registered factory.Human-facing reducer names remain unchanged:
reducer_log_name()still reportsat_least_2,pass_at_2, andpass_k_2from the restored params.Regression coverage exercises direct serialization and replay for all three affected reducers and preserves the existing custom numeric-name behavior.
Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)
No user-facing breaking change is expected. Parameterized reducer log names remain unchanged; only their internal registry identity is corrected to use a replayable factory key.
Other information:
Verification:
uv run pytest -q tests/util/test_registry.py tests/scorer/test_reducers.py tests/test_task_source.py(70 passed, 2 skipped)uv run make checkuv run make test:7752 passed, 3203 skipped; the two remaining Anthropic default-header failures reproduce on the unchanged base revision.