mbochniak01
Fix compat, bugs, and types; expand retail KB
e181667
"""RosettaStone: canonical term -> client-specific term translation."""
from functools import lru_cache
from typing import Any
import yaml
from config import DISPLAY_NAMES, domain_for, term_catalog_path
@lru_cache(maxsize=8)
def _load_catalog(domain: str) -> dict[str, dict[str, str]]:
"""Returns {client_id: {CANONICAL_KEY: "client term"}}."""
data = yaml.safe_load(term_catalog_path(domain).read_text())
return {
client_id: client_data["terms"]
for client_id, client_data in data["clients"].items()
}
def translate(canonical_key: str, client: str) -> str | None:
"""Return client-specific term for a canonical key, or None if not mapped."""
catalog = _load_catalog(domain_for(client))
return catalog.get(client, {}).get(canonical_key)
def client_terms(client: str) -> dict[str, str]:
"""Return full {CANONICAL_KEY: client_term} mapping for a client."""
catalog = _load_catalog(domain_for(client))
return dict(catalog.get(client, {}))
def client_terms_doc(client: str) -> dict[str, str]:
"""Return the term catalog as a pinned KB document for context injection."""
terms = client_terms(client)
display = DISPLAY_NAMES.get(client, client.title())
lines = "\n".join(f"- {k.replace('_', ' ').title()}: use '{v}'" for k, v in terms.items())
return {
"id": f"terms_{client}",
"title": f"{display} Terminology Guide",
"content": f"Always use these exact terms when responding to {display} users:\n{lines}",
}
def check_terminology(response_text: str, client: str) -> dict[str, Any]:
"""
Deterministic chain_terminology check.
Flags cases where a rival client's term appears in the response for a
canonical key, without the correct client term also being present.
Returns:
{"pass": bool, "violations": [...], "checked": int}
"""
catalog = _load_catalog(domain_for(client))
expected = catalog.get(client, {})
other_clients = {c: terms for c, terms in catalog.items() if c != client}
text_lower = response_text.lower()
violations = []
for canonical_key, client_term in expected.items():
client_term_present = client_term.lower() in text_lower
for other_terms in other_clients.values():
rival_term = other_terms.get(canonical_key, "")
if rival_term and rival_term.lower() in text_lower and not client_term_present:
violations.append({
"canonical": canonical_key,
"expected": client_term,
"found": rival_term,
})
return {
"pass": len(violations) == 0,
"violations": violations,
"checked": len(expected),
}