"""The pinned parse rules — the ones two runtimes disagree on.""" from __future__ import annotations from alert_triage.protocol import extract_candidate, parse_reply FENCE = "```" def test_fence_wins_over_an_earlier_bare_brace() -> None: text = 'first {not it} then ' + FENCE + 'json\n{"action":"lookup","what":"documents"}\n' + FENCE assert extract_candidate(text) == '{"action":"lookup","what":"documents"}\n' obj, reason = parse_reply(text) assert obj == {"action": "lookup", "what": "documents"} and reason is None def test_first_balanced_span_is_string_aware() -> None: text = 'ok {"note":"a } inside \\" quotes","action":"close"} trailing {"x":1}' obj, _ = parse_reply(text) assert obj == {"note": 'a } inside " quotes', "action": "close"} def test_invalid_first_span_is_rejected_without_further_scanning() -> None: obj, reason = parse_reply('{"a":1,} {"action":"lookup","what":"documents"}') assert obj is None and reason def test_non_object_json_is_rejected() -> None: assert parse_reply("[1,2]")[0] is None assert parse_reply(FENCE + "json\n[{\"action\":\"lookup\"}]\n" + FENCE)[0] is None assert parse_reply("42")[0] is None def test_nan_and_infinity_are_rejected_like_json_parse_does() -> None: assert parse_reply('{"x":NaN}')[0] is None assert parse_reply('{"x":Infinity}')[0] is None def test_unbalanced_or_absent_braces() -> None: assert parse_reply('{"action":"lookup"')[0] is None assert parse_reply("no braces at all")[0] is None assert parse_reply("")[0] is None assert parse_reply(None)[0] is None def test_nested_object_is_the_outer_one() -> None: obj, _ = parse_reply('{"outer":{"action":"lookup"}}') assert obj == {"outer": {"action": "lookup"}}