Merge pull request #103 from zixuanguo786-ctrl/codex/robust-json-array-extraction

[codex] Harden JSON array extraction
This commit is contained in:
Yifan Yang
2026-07-14 17:41:52 +09:00
committed by GitHub
2 changed files with 135 additions and 4 deletions
+37
View File
@@ -5,6 +5,7 @@ import pytest
from skillopt.utils.json_utils import (
_top_level_brace_objects,
_top_level_bracket_arrays,
extract_json,
extract_json_array,
)
@@ -85,6 +86,26 @@ class TestTopLevelBraceObjects:
assert _top_level_brace_objects(text) == ['{"edit": "right"}']
class TestTopLevelBracketArrays:
"""_top_level_bracket_arrays — string/object-aware top-level array scan."""
def test_single_clean_array(self) -> None:
assert _top_level_bracket_arrays("[1, 2]") == ["[1, 2]"]
def test_two_top_level_arrays(self) -> None:
assert _top_level_bracket_arrays("[1]\n[2]") == ["[1]", "[2]"]
def test_array_inside_object_is_ignored(self) -> None:
assert _top_level_bracket_arrays('{"items": [1, 2]}') == []
def test_bracket_inside_quoted_prose_is_ignored(self) -> None:
assert _top_level_bracket_arrays('label is "set it to [x]" done') == []
def test_unmatched_prose_brace_does_not_hide_later_array(self) -> None:
text = "Explanation uses {placeholder, final answer [1, 2]"
assert _top_level_bracket_arrays(text) == ["[1, 2]"]
class TestExtractJsonTolerantFallback:
"""extract_json — json_repair fallback for malformed non-OpenAI output."""
@@ -186,3 +207,19 @@ class TestExtractJsonArray:
"""extract_json_array should not match a bare JSON object."""
text = '{"this is an object": true}'
assert extract_json_array(text) is None
def test_ignores_prose_brackets_before_valid_array(self) -> None:
text = "Use [not JSON] as prose. Final answer: [1, 2, 3]"
assert extract_json_array(text) == [1, 2, 3]
def test_multiple_valid_arrays_are_ambiguous(self) -> None:
text = "First candidate [1], second candidate [2]"
assert extract_json_array(text) is None
def test_nested_object_array_not_confused_with_array_answer(self) -> None:
text = '{"items": [1, 2, 3]}'
assert extract_json_array(text) is None
def test_unmatched_prose_brace_before_valid_array(self) -> None:
text = "Explanation uses {placeholder, final answer [1, 2]"
assert extract_json_array(text) == [1, 2]