fix(prompts): handle undecodable overrides

This commit is contained in:
chengyongru
2026-07-15 01:19:48 +08:00
committed by chengyongru
parent c1fd76add3
commit 0fd4d0ab29
3 changed files with 27 additions and 2 deletions
+2 -2
View File
@@ -25,7 +25,7 @@ def load_workspace_prompt_override(
Returns the loaded text and its original length. Missing, unreadable, and
empty files return ``(None, 0)`` so callers can fall back to their default.
"""
with suppress(OSError):
with suppress(OSError, UnicodeDecodeError):
text = path.read_text(encoding="utf-8").rstrip()
if text:
original_chars = len(text)
@@ -50,7 +50,7 @@ def initialize_workspace_prompt(path: Path, default_prompt: str) -> bool:
not path.is_file() or bool(path.read_text(encoding="utf-8").strip())
):
return False
except OSError:
except (OSError, UnicodeDecodeError):
return False
path.parent.mkdir(parents=True, exist_ok=True)
+8
View File
@@ -56,6 +56,14 @@ def test_resolve_evaluator_prompt_uses_default_for_empty_override(tmp_path) -> N
assert resolve_evaluator_prompt(tmp_path) == default_evaluator_prompt()
def test_resolve_evaluator_prompt_uses_default_for_undecodable_override(tmp_path) -> None:
path = evaluator_prompt_file(tmp_path)
path.parent.mkdir()
path.write_bytes("Custom evaluator prompt.".encode("utf-16"))
assert resolve_evaluator_prompt(tmp_path) == default_evaluator_prompt()
def test_resolve_evaluator_prompt_caps_workspace_override(tmp_path) -> None:
path = evaluator_prompt_file(tmp_path)
path.parent.mkdir()
@@ -59,6 +59,23 @@ async def test_evaluator_prompt_init_does_not_overwrite_existing_prompt(tmp_path
assert prompt_file.read_text(encoding="utf-8") == "custom"
@pytest.mark.asyncio
async def test_evaluator_prompt_handles_undecodable_existing_prompt(tmp_path) -> None:
prompt_file = tmp_path / "prompts" / "evaluator.md"
prompt_file.parent.mkdir()
original = "custom".encode("utf-16")
prompt_file.write_bytes(original)
status = await cmd_evaluator_prompt(_make_ctx(tmp_path))
init = await cmd_evaluator_prompt(
_make_ctx(tmp_path, "/evaluator-prompt init", "init")
)
assert "Heartbeat evaluator prompt: nanobot default" in status.content
assert "already exists" in init.content
assert prompt_file.read_bytes() == original
@pytest.mark.asyncio
async def test_evaluator_prompt_init_recreates_empty_prompt(tmp_path) -> None:
prompt_file = tmp_path / "prompts" / "evaluator.md"