fix(prompts): handle undecodable overrides
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user