feat(i18n): persist language preference and thread through chat, memoir, TTS
- Add users.language_preference (Alembic 0018, default zh); capture at signup/SMS only; expose on auth and profile APIs - Lite English prompts for chat and memoir; localized stage labels and agent names (Life Echo / 岁月知己) - Tencent TTS: language-aware synthesis, ModelType=1 for 501004, English chunking - WebSocket pipeline: emit all AGENT_RESPONSE segments when TTS cancels; INFO logs for tts_this_turn and TTS decisions; on-demand TTS logging - Expo: device language on auth, i18n tiers/agent name, [SPLIT] streaming UX fixes - Tests for migration, prompts, pipeline, router tts_this_turn, reply segments Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -51,8 +51,19 @@ def generate_story_title_after_create(
|
||||
ms,
|
||||
)
|
||||
return {"status": "skip_not_found"}
|
||||
expected_ph = _placeholder_title(chapter_category)
|
||||
if (st.title or "").strip() and (st.title or "").strip() != expected_ph:
|
||||
user_obj_pre = db.get(User, user_id)
|
||||
user_language = (
|
||||
"en"
|
||||
if user_obj_pre is not None
|
||||
and str(getattr(user_obj_pre, "language_preference", "zh") or "zh").lower()
|
||||
== "en"
|
||||
else "zh"
|
||||
)
|
||||
expected_ph_zh = _placeholder_title(chapter_category, language="zh")
|
||||
expected_ph_en = _placeholder_title(chapter_category, language="en")
|
||||
expected_ph = _placeholder_title(chapter_category, language=user_language)
|
||||
current = (st.title or "").strip()
|
||||
if current and current not in (expected_ph_zh, expected_ph_en):
|
||||
ms = (time.perf_counter() - t0) * 1000
|
||||
logger.info(
|
||||
"event=story_title_task_skip story_id={} reason=user_modified duration_ms={:.1f} "
|
||||
@@ -73,7 +84,7 @@ def generate_story_title_after_create(
|
||||
)
|
||||
return {"status": "skip_no_llm"}
|
||||
|
||||
user_obj = db.get(User, user_id)
|
||||
user_obj = user_obj_pre
|
||||
user_profile = ""
|
||||
birth_year = None
|
||||
if user_obj:
|
||||
@@ -83,6 +94,7 @@ def generate_story_title_after_create(
|
||||
birth_place=user_obj.birth_place,
|
||||
grew_up_place=user_obj.grew_up_place,
|
||||
occupation=user_obj.occupation,
|
||||
language=user_language,
|
||||
)
|
||||
|
||||
state = get_or_create_state_sync(user_id, db)
|
||||
@@ -101,8 +113,13 @@ def generate_story_title_after_create(
|
||||
user_birth_year=birth_year,
|
||||
llm=llm,
|
||||
oral_scope=oral_scope or "",
|
||||
language=user_language,
|
||||
)
|
||||
if not new_title.strip() or new_title.strip() == expected_ph:
|
||||
if not new_title.strip() or new_title.strip() in (
|
||||
expected_ph_zh,
|
||||
expected_ph_en,
|
||||
expected_ph,
|
||||
):
|
||||
ms = (time.perf_counter() - t0) * 1000
|
||||
logger.info(
|
||||
"event=story_title_task_skip story_id={} reason=placeholder duration_ms={:.1f} "
|
||||
|
||||
Reference in New Issue
Block a user