import unittest from agent_harness.interactive_experiment import ( InteractiveExperimentError, parse_query, score_selection_response, ) class InteractiveExperimentTests(unittest.TestCase): def test_invalid_query_response_is_rejected_for_runner_fallback(self) -> None: response = {"choices": [{"message": {"content": "unfinished reasoning"}}]} with self.assertRaises(InteractiveExperimentError): parse_query(response) def test_invalid_candidate_selection_is_scored_as_protocol_violation(self) -> None: response = { "choices": [ { "message": { "content": '{"files":["not-offered.go"],"reasoning":"guess"}' } } ] } selection, violation = score_selection_response(response, {"offered.go"}) self.assertEqual(selection, {"files": [], "reasoning": ""}) self.assertIsNotNone(violation) self.assertIn("outside the candidates", violation or "") def test_valid_candidate_selection_has_no_protocol_violation(self) -> None: response = { "choices": [ { "message": { "content": '{"files":["offered.go"],"reasoning":"direct match"}' } } ] } selection, violation = score_selection_response(response, {"offered.go"}) self.assertEqual(selection["files"], ["offered.go"]) self.assertIsNone(violation)