thousand-token-wood-sim / tests /test_normalize.py
AdmiralTaco's picture
Fix gpt-oss harmony leak: drop truncated analysis channel + raise narrator budget
8fc86db
Raw
History Blame Contribute Delete
1.98 kB
"""Tests for the per-engine output normalizers. No GPU, no network.
Run: python -m pytest tests/ -q
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from ttw.actions import _extract_json
from ttw.normalize import NORMALIZERS, harmony_final, identity
def test_harmony_extracts_final_channel_and_json_parses():
"""A harmony wrapper is stripped to the final channel, and the bare result
feeds _extract_json to the intended action dict."""
text = (
"analysis The owl is cautious, sell honey while it is high."
'assistantfinal{"thought":"sell honey","offers":'
'[{"side":"sell","good":"honey","price":9,"qty":3}],"gossip":""}'
)
final = harmony_final(text)
assert "analysis" not in final
parsed = _extract_json(final)
assert parsed is not None
assert parsed["thought"] == "sell honey"
assert parsed["offers"][0]["good"] == "honey"
def test_harmony_without_marker_is_unchanged():
text = '{"thought":"hold","offers":[],"gossip":""}'
assert harmony_final(text) == text
def test_harmony_truncated_analysis_is_dropped():
"""When the budget runs out before `assistantfinal`, the model is still in
its analysis channel; raw chain-of-thought must never leak downstream."""
text = "analysisWe need to produce a punchy headline, optionally a short qu"
assert harmony_final(text) == ""
def test_harmony_empty_string_is_empty():
assert harmony_final("") == ""
def test_harmony_final_channel_is_stripped():
"""Leading/trailing whitespace around the final-channel answer is removed."""
assert harmony_final('analysis ...assistantfinal {"x":1} ') == '{"x":1}'
def test_identity_returns_text_unchanged():
text = "anything at all, even {broken json"
assert identity(text) == text
def test_normalizers_registry_maps_keys():
assert NORMALIZERS["harmony"] is harmony_final
assert NORMALIZERS["identity"] is identity