""" Unit tests for shared.prompts.system_prompt_builder. Tests verify: - Full prompt with all fields produces expected sections - Minimal prompt (name + role only) still includes AI transparency clause - Empty tools and escalation_rules omit those sections - AI transparency clause is always present regardless of inputs """ from __future__ import annotations import pytest from shared.prompts.system_prompt_builder import build_system_prompt AI_TRANSPARENCY_CLAUSE = "When directly asked if you are an AI, always disclose that you are an AI assistant." class TestBuildSystemPromptFull: """Test build_system_prompt with all fields populated.""" def test_contains_name(self) -> None: prompt = build_system_prompt( name="Mara", role="Customer Support", persona="Friendly and helpful", tool_assignments=["knowledge_base_search"], escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}], ) assert "You are Mara" in prompt def test_contains_role(self) -> None: prompt = build_system_prompt( name="Mara", role="Customer Support", persona="Friendly and helpful", tool_assignments=["knowledge_base_search"], escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}], ) assert "Customer Support" in prompt def test_contains_persona(self) -> None: prompt = build_system_prompt( name="Mara", role="Customer Support", persona="Friendly and helpful", tool_assignments=["knowledge_base_search"], escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}], ) assert "Friendly and helpful" in prompt def test_contains_tool(self) -> None: prompt = build_system_prompt( name="Mara", role="Customer Support", persona="Friendly and helpful", tool_assignments=["knowledge_base_search"], escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}], ) assert "knowledge_base_search" in prompt def test_contains_escalation_rule(self) -> None: prompt = build_system_prompt( name="Mara", role="Customer Support", persona="Friendly and helpful", tool_assignments=["knowledge_base_search"], escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}], ) assert "billing_dispute AND attempts > 2" in prompt def test_contains_ai_transparency_clause(self) -> None: prompt = build_system_prompt( name="Mara", role="Customer Support", persona="Friendly and helpful", tool_assignments=["knowledge_base_search"], escalation_rules=[{"condition": "billing_dispute AND attempts > 2", "action": "handoff_human"}], ) assert AI_TRANSPARENCY_CLAUSE in prompt class TestBuildSystemPromptMinimal: """Test build_system_prompt with only name and role provided.""" def test_minimal_contains_name(self) -> None: prompt = build_system_prompt(name="Alex", role="Sales Assistant") assert "You are Alex" in prompt def test_minimal_contains_role(self) -> None: prompt = build_system_prompt(name="Alex", role="Sales Assistant") assert "Sales Assistant" in prompt def test_minimal_contains_ai_transparency_clause(self) -> None: prompt = build_system_prompt(name="Alex", role="Sales Assistant") assert AI_TRANSPARENCY_CLAUSE in prompt def test_minimal_is_string(self) -> None: prompt = build_system_prompt(name="Alex", role="Sales Assistant") assert isinstance(prompt, str) assert len(prompt) > 0 class TestBuildSystemPromptEmptySections: """Test that empty tools and escalation_rules omit those sections.""" def test_empty_tools_omits_tools_section(self) -> None: prompt = build_system_prompt( name="Bob", role="Office Manager", persona="Organized and efficient", tool_assignments=[], escalation_rules=[], ) # Should not contain a tools header/section assert "tools:" not in prompt.lower() or "tools" not in prompt.split("\n")[0] def test_empty_escalation_omits_escalation_section(self) -> None: prompt = build_system_prompt( name="Bob", role="Office Manager", persona="Organized and efficient", tool_assignments=[], escalation_rules=[], ) # Should not contain an escalation section assert "Escalation" not in prompt def test_none_tools_omits_tools_section(self) -> None: prompt = build_system_prompt( name="Bob", role="Office Manager", tool_assignments=None, escalation_rules=None, ) assert "Escalation" not in prompt def test_empty_still_has_ai_transparency(self) -> None: prompt = build_system_prompt( name="Bob", role="Office Manager", tool_assignments=[], escalation_rules=[], ) assert AI_TRANSPARENCY_CLAUSE in prompt class TestBuildSystemPromptAIClauseAlwaysPresent: """AI transparency clause must always be present — non-negotiable.""" def test_ai_clause_present_full_args(self) -> None: prompt = build_system_prompt( name="Mara", role="Support", persona="Helpful", tool_assignments=["kb_search"], escalation_rules=[{"condition": "x", "action": "handoff_human"}], ) assert AI_TRANSPARENCY_CLAUSE in prompt def test_ai_clause_present_name_role_only(self) -> None: prompt = build_system_prompt(name="Z", role="Y") assert AI_TRANSPARENCY_CLAUSE in prompt def test_ai_clause_present_with_persona_only(self) -> None: prompt = build_system_prompt(name="Sam", role="Analyst", persona="Detail-oriented") assert AI_TRANSPARENCY_CLAUSE in prompt class TestLanguageInstruction: """LANGUAGE_INSTRUCTION must be present in all system prompts before AI transparency clause.""" LANGUAGE_INSTRUCTION = ( "Detect the language of each user message and respond in that same language. " "You support English, Spanish, and Portuguese." ) def test_language_instruction_present_in_default_prompt(self) -> None: """build_system_prompt with name+role includes LANGUAGE_INSTRUCTION.""" prompt = build_system_prompt(name="Mara", role="Support Rep") assert self.LANGUAGE_INSTRUCTION in prompt def test_language_instruction_present_with_full_args(self) -> None: """build_system_prompt with all args includes LANGUAGE_INSTRUCTION.""" prompt = build_system_prompt( name="Mara", role="Support Rep", persona="Helpful and professional", tool_assignments=["knowledge_base_search"], escalation_rules=[{"condition": "billing_dispute", "action": "handoff_human"}], ) assert self.LANGUAGE_INSTRUCTION in prompt def test_language_instruction_before_transparency_clause(self) -> None: """LANGUAGE_INSTRUCTION appears before AI_TRANSPARENCY_CLAUSE in the prompt.""" prompt = build_system_prompt( name="Mara", role="Support Rep", persona="Helpful", tool_assignments=["kb_search"], escalation_rules=[{"condition": "x", "action": "handoff_human"}], ) lang_pos = prompt.index(self.LANGUAGE_INSTRUCTION) transparency_pos = prompt.index(AI_TRANSPARENCY_CLAUSE) assert lang_pos < transparency_pos, ( "LANGUAGE_INSTRUCTION must appear before AI_TRANSPARENCY_CLAUSE" )