use crate::engine::stable_id;
use crate::engine::{
chinese_unknown_answer, hindi_unknown_answer, russian_unknown_answer, unknown_answer,
unknown_language_fallback_answer,
};
use crate::Language;
const UNKNOWN_OPENERS_EN: &[&str] = &[
"I don't know how to answer that yet.",
"I didn't understand you.",
"I'm not sure how to respond to that yet.",
"I haven't learned to answer that yet.",
"That one is new to me.",
];
const UNKNOWN_OPENERS_RU: &[&str] = &[
"Я пока не знаю, как ответить на это.",
"Я тебя не понял.",
"Я не уверен, как на это ответить.",
"Я ещё не научился отвечать на это.",
"Это для меня новое.",
];
const UNKNOWN_OPENERS_HI: &[&str] = &[
"मुझे अभी इसका उत्तर देना नहीं आता।",
"मैं समझ नहीं पाया।",
"मुझे यकीन नहीं है कि कैसे उत्तर दूँ।",
"मैंने अभी तक यह उत्तर देना नहीं सीखा।",
"यह मेरे लिए नया है।",
];
const UNKNOWN_OPENERS_ZH: &[&str] = &[
"我还不知道如何回答这个问题。",
"我不太明白你说的意思。",
"我不确定该如何回答。",
"我还没有学会回答这个问题。",
"这对我来说是新的。",
];
fn unknown_openers_for(language: &str) -> &'static [&'static str] {
match language {
"ru" => UNKNOWN_OPENERS_RU,
"hi" => UNKNOWN_OPENERS_HI,
"zh" => UNKNOWN_OPENERS_ZH,
_ => UNKNOWN_OPENERS_EN,
}
}
#[must_use]
pub fn select_unknown_opener(prompt: &str, language: &str) -> &'static str {
let pool = unknown_openers_for(language);
debug_assert!(!pool.is_empty(), "unknown opener pool must be non-empty");
let trimmed = prompt.trim();
if trimmed.is_empty() {
return pool[0];
}
let id = stable_id("unknown_opener", trimmed);
let hex = id.rsplit('_').next().unwrap_or("0");
let value = u64::from_str_radix(hex, 16).unwrap_or(0);
let pool_len = pool.len() as u64;
let index = usize::try_from(value % pool_len).unwrap_or(0);
pool[index]
}
fn unknown_answer_with_variation(prompt: &str, language: &str, seed_text: &str) -> String {
let opener = select_unknown_opener(prompt, language);
let body = strip_leading_opener(seed_text, unknown_openers_for(language));
if body.is_empty() {
return String::from(opener);
}
format!("{opener} {body}")
}
fn strip_leading_opener(text: &str, openers: &[&str]) -> String {
let trimmed = text.trim_start();
for known in openers {
if let Some(rest) = trimmed.strip_prefix(known) {
return rest.trim_start().to_owned();
}
}
for separator in [". ", "。", "। "] {
if let Some(idx) = trimmed.find(separator) {
let start = idx + separator.len();
return trimmed[start..].trim_start().to_owned();
}
}
trimmed.to_owned()
}
#[must_use]
pub fn unknown_answer_variation_for(prompt: &str) -> String {
unknown_answer_with_variation(prompt, "en", unknown_answer())
}
#[must_use]
pub fn language_aware_unknown_answer(prompt: &str, language: Language) -> String {
let (seed_text, slug) = match language {
Language::Russian => (russian_unknown_answer(), "ru"),
Language::Hindi => (hindi_unknown_answer(), "hi"),
Language::Chinese => (chinese_unknown_answer(), "zh"),
Language::English => (unknown_answer(), "en"),
Language::Unknown => return String::from(unknown_language_fallback_answer()),
};
unknown_answer_with_variation(prompt, slug, seed_text)
}