81 lines
4.1 KiB
Python
81 lines
4.1 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
|
|
def customer_persona_mode() -> str:
|
|
return str(os.getenv("AI_CUSTOMER_PERSONA_MODE", "operator_humanlike") or "operator_humanlike").strip().lower()
|
|
|
|
|
|
def disclosure_mode() -> str:
|
|
return str(os.getenv("AI_DISCLOSURE_MODE", "hidden") or "hidden").strip().lower()
|
|
|
|
|
|
def voice_policy_mode() -> str:
|
|
return str(os.getenv("AI_VOICE_POLICY_MODE", "llm_guarded") or "llm_guarded").strip().lower()
|
|
|
|
|
|
def disclosure_hidden() -> bool:
|
|
return disclosure_mode() == "hidden"
|
|
|
|
|
|
def voice_disclosure_prefix(language: str) -> str:
|
|
if disclosure_hidden():
|
|
return ""
|
|
if str(language or "").strip().lower() == "kz":
|
|
return "Men kompaniya atynan jauap berip turmyn. "
|
|
return "Отвечаю от имени линии поддержки компании. "
|
|
|
|
|
|
def voice_greeting(language: str) -> str:
|
|
if str(language or "").strip().lower() == "kz":
|
|
return "Сәлеметсіз бе. Сұрағыңызды айтыңызшы, көмектесуге тырысамын."
|
|
return "Здравствуйте. Подскажите, пожалуйста, чем помочь."
|
|
|
|
|
|
def voice_handoff_reply(language: str) -> str:
|
|
if str(language or "").strip().lower() == "kz":
|
|
return "Бір сәт, сізді операторға қосамын."
|
|
return "Секунду, соединяю вас с оператором."
|
|
|
|
|
|
def text_resolution_reply(language: str) -> str:
|
|
if str(language or "").strip().lower() == "kz":
|
|
return "Жақсы, белгілеп қоямын. Қажет болса, осы жерден қайта жаза аласыз."
|
|
return "Хорошо, отмечу это. Если понадобится, можно продолжить здесь."
|
|
|
|
|
|
def human_fallback_reply(language: str, *, is_greeting: bool = False) -> str:
|
|
if str(language or "").strip().lower() == "kz":
|
|
if is_greeting:
|
|
return "Сәлеметсіз бе. Сұрағыңызды жазыңыз не айтыңыз, көмектесуге тырысамын."
|
|
return "Түсіндім. Нақтырақ айтып жіберсеңіз, бірден жалғастырамын."
|
|
if is_greeting:
|
|
return "Здравствуйте. Напишите или коротко расскажите, чем помочь."
|
|
return "Понял вас. Уточните, пожалуйста, детальнее, и я сразу продолжу."
|
|
|
|
|
|
def operator_system_prompt(*, language: str, channel_label: str, is_voice: bool) -> str:
|
|
preferred_language = "Kazakh" if str(language or "").strip().lower() == "kz" else "Russian"
|
|
delivery_hint = (
|
|
"The reply will be spoken aloud over a phone call, so keep it concise, natural, and easy to listen to. "
|
|
"Prefer one or two short sentences and at most one clarifying question."
|
|
if is_voice
|
|
else "The reply should read like a concise message from a live first-line operator."
|
|
)
|
|
return (
|
|
f"You are a first-line company operator handling customer conversations in {channel_label}. "
|
|
f"Reply in {preferred_language}. Speak naturally, warmly, and confidently like a human operator. "
|
|
"Do not say or imply that you are an AI, bot, assistant, model, or automated system. "
|
|
"Do not mention a knowledge base, snippets, internal notes, policies, or hidden tools. "
|
|
"Use the provided business context, conversation history, and KB snippets only as factual sources. "
|
|
"Paraphrase them naturally instead of quoting them verbatim. "
|
|
"Never invent order statuses, tariffs, discounts, deadlines, addresses, availability, approvals, or actions "
|
|
"that are not supported by context. If the available facts are insufficient, ask one short clarifying question. "
|
|
"If the customer explicitly asks for a live operator, if the request is sensitive, or if the case is blocked, "
|
|
"set needs_handoff=true. "
|
|
f"{delivery_hint} "
|
|
"Return only a JSON object with keys: language, intent, reply_text, confidence, needs_handoff, "
|
|
"handoff_reason, case_action, kb_refs. case_action must be one of none, close, escalate, keep_open."
|
|
)
|