Preserve continuous rollout hard scores
Rollout hard scores can be continuous when smoothed rewards are used. Converting the field through int() turned values like 0.75 into 0, which loses signal before scoring and serialization. Constraint: Keep the existing RolloutResult dictionary shape unchanged. Rejected: Clamp hard scores to 0 or 1 | contradicts existing continuous-score support in compute_score and sleep replay types. Confidence: high Scope-risk: narrow Reversibility: clean Directive: Treat hard as numeric reward data, not only a binary label. Tested: uv run --with pytest pytest tests/test_types.py tests/test_scoring.py -q Tested: uv run --with ruff ruff check skillopt/types.py tests/test_types.py Not-tested: Full benchmark rollouts.
This commit is contained in:
+15
-2
@@ -3,8 +3,7 @@ from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from skillopt.types import Edit, Patch
|
||||
|
||||
from skillopt.types import Edit, Patch, RolloutResult
|
||||
|
||||
# ── Edit ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -247,3 +246,17 @@ class TestPatchEdgeCases:
|
||||
assert isinstance(p.edits[0], Edit)
|
||||
assert p.edits[0].op == "append"
|
||||
assert p.edits[0].content == "hello"
|
||||
|
||||
|
||||
# ── RolloutResult ────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
class TestRolloutResultRoundTrip:
|
||||
"""RolloutResult.to_dict() / RolloutResult.from_dict() round-trip."""
|
||||
|
||||
def test_preserves_fractional_hard_score(self) -> None:
|
||||
"""Hard can be a continuous reward and must not be truncated."""
|
||||
result = RolloutResult.from_dict({"id": "episode-1", "hard": 0.75, "soft": 0.5})
|
||||
|
||||
assert result.hard == pytest.approx(0.75)
|
||||
assert result.to_dict()["hard"] == pytest.approx(0.75)
|
||||
|
||||
Reference in New Issue
Block a user