mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-11-14 09:01:22 +00:00
fix(home): preserve literal formatting in structured reports
This commit is contained in:
parent
ea009c17fa
commit
4c2dbc8a33
3 changed files with 28 additions and 13 deletions
|
|
@ -72,8 +72,9 @@ def parse_json_object(message: Msg | str, *, report_name: str) -> dict[str, Any]
|
|||
try:
|
||||
payload = json.loads(_remove_trailing_commas(text.strip()))
|
||||
except json.JSONDecodeError:
|
||||
text = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL | re.IGNORECASE).strip()
|
||||
if "```" in text:
|
||||
# Strip only leading reasoning blocks; formatting inside report strings is data.
|
||||
text = re.sub(r"^(?:\s*<think>.*?</think>)+\s*", "", text, flags=re.DOTALL | re.IGNORECASE).strip()
|
||||
if re.search(r"^[ \t]*```", text, flags=re.MULTILINE):
|
||||
fences = list(
|
||||
re.finditer(
|
||||
r"^[ \t]*```(?:json)?[ \t]*\r?\n(.*?)^[ \t]*```[ \t]*\r?$",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,unused-argument
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
|
|
@ -51,17 +52,19 @@ def test_invalid_or_ambiguous_reports_require_correction(text):
|
|||
parse_json_object(AssistantMsg(name="review", content=text), report_name="review")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("template", ["{}", "Completed.\n```json\n{}\n```"])
|
||||
def test_text_input_preserves_literal_formatting_inside_json_strings(template):
|
||||
text = template.format('{"reason":"literal ```json"}')
|
||||
assert parse_json_object(text, report_name="review") == {
|
||||
"reason": "literal ```json",
|
||||
}
|
||||
|
||||
|
||||
def test_bare_json_preserves_literal_thinking_tags():
|
||||
text = '{"reason":"literal <think>evidence</think>"}'
|
||||
assert parse_json_object(text, report_name="review") == {"reason": "literal <think>evidence</think>"}
|
||||
@pytest.mark.parametrize(
|
||||
"template",
|
||||
[
|
||||
"{}",
|
||||
"Completed. {}",
|
||||
"Completed.\n```json\n{}\n```",
|
||||
'<think>{{"draft": "ignored"}}</think>\n<think>More analysis.</think>\n{}',
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("literal", ["literal ```json", "literal <think>evidence</think>", "<think>evidence</think>"])
|
||||
def test_text_input_preserves_literal_formatting_inside_json_strings(template, literal):
|
||||
value = {"reason": literal}
|
||||
assert parse_json_object(template.format(json.dumps(value)), report_name="review") == value
|
||||
|
||||
|
||||
def test_repairs_preserve_strings_and_nested_json():
|
||||
|
|
|
|||
|
|
@ -115,6 +115,17 @@ def test_parse_optimizer_result_formats(template):
|
|||
assert optimizer_module.parse_result(template.format(json.dumps(claim))).model_dump() == claim
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_optimizer_job_preserves_literal_formatting_in_final_report(app, prepared, sandbox):
|
||||
path = await baseline(app)
|
||||
claim = json.loads(final_report(prepared, path=path))
|
||||
claim["report"] = "<think>Evidence from the evaluated source</think>\n```python\nexample\n```"
|
||||
set_model(app, "home_optimizer", ScriptedModel(final="```json\n" + json.dumps(claim) + "\n```"))
|
||||
response = await app.run_job("home_optimize")
|
||||
assert response.success, response.answer
|
||||
assert response.answer["report"] == claim["report"]
|
||||
|
||||
|
||||
def test_optimizer_shared_recovery_rejects_competing_and_non_object_reports():
|
||||
claim = {"branch_name": "candidate", "commit_sha": "a" * 40, "evaluation_path": "run", "report": "Evidence"}
|
||||
text = json.dumps(claim)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue