"""Unit: locked persona prompt builder (PLAN §6 verbatim + both modes).""" from __future__ import annotations import uuid import pytest from app.models import Document from app.rag.prompts import PERSONA, _base, build_deflect_prompt, build_high_prompt def _doc(path: str, content: str, title: str) -> Document: return Document( id=uuid.uuid4(), source="Homelab", path=path, full_path=f"/tmp/{path}", title=title, content=content, content_hash="0" * 64, ) def test_persona_rules_present_verbatim() -> None: for fragment in ( 'You are "Brain of Reese" — the digital brain of Reese, a self-hoster and', 'optimistic about the user\'s ability to do things ("you\'ve got this")', "Answer ONLY from the provided document context. Cite which document(s)", "you used, by path.", "Be concrete: names, versions, ports, hosts, schedules", 'HONESTY GATE: if is "LOW", you must NOT pretend to know', 'Start your answer with a variant of: "I haven\'t done anything like that."', "Then offer 2-3 alternative questions about things you DO have notes on.", "Never invent facts, hosts, or steps that are not in the context.", "Keep answers tight: short paragraphs, bullets where helpful.", ): assert fragment in PERSONA def test_high_prompt_carries_relevance_marker_and_full_documents() -> None: doc = _doc("kubernetes.md", "Talos Linux on three nodes.", "Kubernetes Homelab Cluster") prompt = build_high_prompt([doc]) assert "HIGH" in prompt assert "DEFLECT_MODE" not in prompt assert "" in prompt and "" in prompt assert 'path="kubernetes.md"' in prompt assert "Talos Linux on three nodes." in prompt assert "HONESTY GATE" in prompt # persona intact def test_high_prompt_lists_multiple_documents_in_order() -> None: a = _doc("a.md", "CONTENT_A", "Title A") b = _doc("b.md", "CONTENT_B", "Title B") prompt = build_high_prompt([a, b]) assert prompt.index("CONTENT_A") < prompt.index("CONTENT_B") assert 'title="Title B"' in prompt def test_high_prompt_without_documents_stays_honest() -> None: prompt = build_high_prompt([]) assert "" in prompt assert "do not invent specifics" in prompt def test_low_prompt_has_deflect_mode_and_titles_only() -> None: titles = ["Kubernetes Homelab Cluster", "Backup Strategy"] prompt = build_deflect_prompt(titles) assert "LOW" in prompt assert "DEFLECT_MODE" in prompt # marker the E2E mock keys on assert "- Kubernetes Homelab Cluster" in prompt assert "- Backup Strategy" in prompt def test_low_prompt_never_contains_document_content() -> None: secret = "SECRET_DOCUMENT_CONTENT_12345" prompt = build_deflect_prompt(["Some Title"]) assert secret not in prompt assert "" not in prompt assert "HONESTY GATE" in prompt # the LOW rule is what the model must follow def test_low_prompt_with_no_titles() -> None: assert "nothing close at all" in build_deflect_prompt([]) def test_relevance_placeholder_rejected_for_garbage() -> None: with pytest.raises(ValueError, match="HIGH or LOW"): _base("MEDIUM")