| """ |
| deploy/i18n.py — 国际化字符串 (English default) |
| """ |
| import os |
|
|
| LANG = os.environ.get("BREADBUDDY_LANG", "en") |
|
|
| STRINGS = { |
| "app_title": {"en": "BreadBuddy", "zh": "BreadBuddy"}, |
| "app_subtitle": { |
| "en": "AI Bread Baking Assistant — Take a photo or describe your bread problem", |
| "zh": "AI 面包烘焙助手 — 拍张照片或描述面包问题" |
| }, |
| "hero_text": { |
| "en": "Snap a photo, let me check your bread", |
| "zh": "拍张照片,让我看看你的面包怎么了" |
| }, |
| "photo_label": { |
| "en": "📷 Tap to take a photo or upload", |
| "zh": "📷 点击拍照或上传照片" |
| }, |
| "desc_placeholder": { |
| "en": "Describe your bread problem... (optional)", |
| "zh": "描述一下你的面包问题...(可选)" |
| }, |
| "desc_value": { |
| "en": "Bread collapsed, inside is sticky and wet", |
| "zh": "面包塌陷,内部湿粘" |
| }, |
| "temp_preset_label": { |
| "en": "Environment Presets", |
| "zh": "环境温湿度预设" |
| }, |
| "preset_winter": {"en": "❄️ Winter 5-15°C", "zh": "❄️ 冬天 5-15°C"}, |
| "preset_spring": {"en": "🌸 Spring 15-25°C", "zh": "🌸 春天 15-25°C"}, |
| "preset_summer": {"en": "☀️ Summer 25-35°C", "zh": "☀️ 夏天 25-35°C"}, |
| "preset_custom": {"en": "⚙️ Custom", "zh": "⚙️ 自定义"}, |
| "btn_diagnose": {"en": "Start Diagnosis", "zh": "开始诊断"}, |
| "btn_rediagnose": {"en": "← Restart", "zh": "← 重新诊断"}, |
| "btn_followup_placeholder": { |
| "en": "Ask a follow-up... e.g. Can you explain the first cause?", |
| "zh": "继续追问... 例如:能详细说一下第二个原因吗?" |
| }, |
| "loading_connecting": { |
| "en": "Connecting to AI...", |
| "zh": "正在连接 AI 诊断师..." |
| }, |
| "loading_first_time": { |
| "en": "First time may take 30-60s to warm up the model", |
| "zh": "首次诊断需要约 30-60 秒预热模型" |
| }, |
| "thinking": {"en": "Analyzing...", "zh": "正在思考..."}, |
| "thinking_bread": {"en": "🧠 Analyzing bread photo...", "zh": "🔍 正在分析面包照片..."}, |
| "thinking_text": {"en": "🧠 Analyzing your question...", "zh": "🧠 正在分析面包问题..."}, |
| "empty_hint_title": { |
| "en": "Start Diagnosing Your Bread", |
| "zh": "开始诊断你的面包" |
| }, |
| "empty_hint_subtitle": { |
| "en": "Upload a photo or describe the problem, then click \"Start Diagnosis\"", |
| "zh": "上传照片或描述问题,点击「开始诊断」" |
| }, |
| "speed_prefix": {"en": "⏱️", "zh": "⏱️"}, |
| "speed_thinking": {"en": "⏱️ thinking...", "zh": "⏱️ 思考中..."}, |
| "api_error_prefix": {"en": "❌ API error: ", "zh": "❌ API error: "}, |
| "network_error_prefix": {"en": "❌ Network error: ", "zh": "❌ 网络错误: "}, |
| "api_url_not_configured": { |
| "en": "❌ API URL not configured", |
| "zh": "❌ API URL 未配置" |
| }, |
| "timeout_error": {"en": "❌ Response timeout, try again", "zh": "❌ 推理服务响应超时,请稍后重试"}, |
| "unavailable_error": {"en": "❌ Service unavailable, try again", "zh": "❌ 推理服务暂时不可用,请稍后重试"}, |
| "accordion_label": { |
| "en": "🧠 Model Thinking (optional)", |
| "zh": "🧠 模型思考过程(可选)" |
| }, |
| "followup_banner_prefix": { |
| "en": "🧠 Follow-up context: ", |
| "zh": "🧠 追问上下文:" |
| }, |
| "footer_line1": { |
| "en": "\u00a9 2026 Rockstone Games. All rights reserved. https://github.com/the-rockstone-games", |
| "zh": "\u00a9 2026 Rockstone Games. All rights reserved. https://github.com/the-rockstone-games" |
| }, |
| "footer_line2": { |
| "en": "", |
| "zh": "" |
| }, |
| "preset_q_detail": {"en": "🔍 Details on cause 1", "zh": "🔍 详细原因"}, |
| "preset_q_ferment": {"en": "⏱️ Fermentation tips", "zh": "⏱️ 发酵调整"}, |
| "preset_q_recipe": {"en": "📖 Simple recipe", "zh": "📖 简易配方"}, |
| "preset_q_detail_prompt": { |
| "en": "Can you explain the first cause in detail?", |
| "zh": "能详细说一下第一个原因吗?" |
| }, |
| "preset_q_ferment_prompt": { |
| "en": "How should I adjust fermentation time?", |
| "zh": "我该怎么调整发酵时间?" |
| }, |
| "preset_q_recipe_prompt": { |
| "en": "Is there a simpler recipe?", |
| "zh": "有没有更简单的配方?" |
| }, |
| "temperature_label": {"en": "Temperature", "zh": "温度"}, |
| "humidity_label": {"en": "Humidity", "zh": "湿度"}, |
| "lang_toggle_en": {"en": "中文", "zh": "EN"}, |
| } |
|
|
| |
| DIAGNOSIS_SYSTEM_PROMPT = { |
| "en": """You are a bread baking diagnostic assistant. Always respond in English. |
| |
| Diagnose the bread problem and provide structured output using these exact section headers: |
| |
| ### Possible Causes |
| 1. [Severity] Cause description |
| ### Fixes |
| 1. Fix suggestion |
| ### Recommended Recipes |
| 1. Recipe Name — Description |
| |
| Severity levels: [Severe], [Moderate], [Mild]""", |
| "zh": """### 可能原因 |
| 1. 原因 |
| ### 修复建议 |
| 1. 建议 |
| ### 推荐配方 |
| 1. 配方名 — 描述""", |
| } |
|
|
| FOLLOWUP_SYSTEM_SUFFIX = { |
| "en": "\nAnswer the follow-up based on the conversation above.", |
| "zh": "\n基于以上对话回答追问。", |
| } |
|
|
| USER_PROMPT_FALLBACK = { |
| "en": "Please diagnose this bread photo", |
| "zh": "请诊断这张面包照片的问题", |
| } |
|
|
|
|
| def t(key: str) -> str: |
| """Get translated string for current language.""" |
| s = STRINGS.get(key, {}) |
| return s.get(LANG, s.get("en", key)) |
|
|
|
|
| def set_lang(lang: str): |
| """Switch language.""" |
| global LANG |
| LANG = lang if lang in ("en", "zh") else "en" |
|
|
|
|
| def get_system_prompt() -> str: |
| return DIAGNOSIS_SYSTEM_PROMPT.get(LANG, DIAGNOSIS_SYSTEM_PROMPT["en"]) |
|
|
| def get_followup_suffix() -> str: |
| return FOLLOWUP_SYSTEM_SUFFIX.get(LANG, FOLLOWUP_SYSTEM_SUFFIX["en"]) |
|
|
| def get_user_fallback() -> str: |
| return USER_PROMPT_FALLBACK.get(LANG, USER_PROMPT_FALLBACK["en"]) |
|
|