flexigo-support-bot / tests /test_prompts.py
victor34593993's picture
fix(lang): pin the detected customer language explicitly (Spanish-heavy context was overriding plain mirror); None->mirror fallback
1316064 verified
Raw
History Blame
4.22 kB
from __future__ import annotations
from app.prompts import build_system_prompt
def test_system_prompt_includes_rules_and_brand():
p = build_system_prompt("TOORX Assist")
assert "TOORX Assist" in p
# language is the prominent RULE #1
assert "RULE #1" in p
assert "language" in p.lower()
# A DETECTED language is pinned explicitly (the Spanish-heavy context otherwise
# drags the model into Spanish even for an English customer). The Hungarian bug
# is fixed at the DETECTOR, not by refusing to pin.
pinned = build_system_prompt("X", language="portugués de Portugal (pt-PT)")
assert "pt-PT" in pinned
# when detection is unsure (None) we fall back to mirroring
assert "mirror" in build_system_prompt("X", language=None).lower()
# anti-hallucination grounding
assert "invent" in p.lower()
# order verification (email + order number / postal code)
assert "email" in p.lower() and "order number" in p.lower() and "postal code" in p.lower()
assert "NEVER" in p # no full address / payment
# tools referenced by name
assert "escalate_to_human" in p
assert "search_knowledge" in p and "search_products" in p and "lookup_order" in p
# no emojis + don't translate identifiers
assert "emoji" in p.lower()
assert "variant_ids" in p
def test_system_prompt_covers_attached_photo_product_search():
p = build_system_prompt("X")
# the attached-file marker is explained and tied to the product search tool
assert "[El cliente ha adjuntado" in p
assert "CALL search_products" in p
# attribute extraction is spelled out so the model searches with key terms
assert "color" in p and "brand or model" in p
# honest fallback when nothing similar exists
assert "say so honestly" in p
def test_system_prompt_default_brand():
assert "Asistente" in build_system_prompt("")
def test_prompt_channel_handoff_is_mutually_exclusive():
web = build_system_prompt("X", channel="web")
wa = build_system_prompt("X", channel="whatsapp")
assert "show_form" in web and "WhatsApp" not in web
assert "WhatsApp" in wa and "show_form" not in wa
def test_brand_name_braces_are_sanitized():
# a brand name with { } must not break .format or inject placeholders
p = build_system_prompt("Acme {evil}")
assert "{evil}" not in p
assert "Acme" in p
def test_business_rules_are_top_priority_and_override_ficha():
"""The merchant's custom_instructions must land HIGH in the prompt (before the
GROUNDING block) and be framed as overriding the product sheet — otherwise weak
models defer to the retrieved ficha (the 28mm-rule bug)."""
rule = "Los discos de 28mm SI son compatibles con soporte de 25mm."
p = build_system_prompt("TOORX", extra_instructions=rule)
assert rule in p
assert "BUSINESS RULES (HIGHEST PRIORITY" in p
# the business block comes BEFORE the grounding block (position = weight)
assert p.index("BUSINESS RULES") < p.index("# GROUNDING")
# the grounding "say only what tools return" carries the override exception
assert "a business rule" in p.lower() and "outranks the ficha" in p.lower()
def test_no_business_block_when_no_custom_instructions():
p = build_system_prompt("TOORX")
# the SECTION (with merchant content) is absent; the end-reminder mention of
# "business rules" is harmless boilerplate, so check the section header.
assert "these OVERRIDE the grounding" not in p
def test_business_rules_truncation_raised_to_6000():
big = "x" * 5000
p = build_system_prompt("TOORX", extra_instructions=big)
assert big in p # 5000-char rule set not silently cut (old cap was 2000)
def test_shipping_cost_vs_time_routing_is_disambiguated():
"""Shipping COST/zone -> get_shipping_cost; delivery TIME -> search_knowledge
even when a destination is named (the 'cuánto tarda a Canarias' overlap)."""
p = build_system_prompt("X")
assert "get_shipping_cost" in p
# the cost tool is explicitly scoped to zones/prices, not transit times
assert "NOT transit times" in p
# delivery-time questions with a destination are explicitly routed away
assert "cuánto tarda a Canarias" in p