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:
@@ -666,13 +666,21 @@ def process_memoir_phase2(
|
||||
user_birth_year = None
|
||||
background_voice = "default"
|
||||
user_occupation = ""
|
||||
user_language = "zh"
|
||||
if user_obj:
|
||||
user_birth_year = user_obj.birth_year
|
||||
user_language = (
|
||||
"en"
|
||||
if str(getattr(user_obj, "language_preference", "zh") or "zh").lower()
|
||||
== "en"
|
||||
else "zh"
|
||||
)
|
||||
user_profile = format_user_profile_context(
|
||||
birth_year=user_obj.birth_year,
|
||||
birth_place=user_obj.birth_place,
|
||||
grew_up_place=user_obj.grew_up_place,
|
||||
occupation=user_obj.occupation,
|
||||
language=user_language,
|
||||
)
|
||||
background_voice = infer_background_voice(user_obj.occupation)
|
||||
user_occupation = user_obj.occupation or ""
|
||||
@@ -752,6 +760,7 @@ def process_memoir_phase2(
|
||||
memoir_correlation_id=cid,
|
||||
llm_fast=llm_fast,
|
||||
memory_evidence=memory_evidence,
|
||||
language=user_language,
|
||||
)
|
||||
pipeline_elapsed = time.perf_counter() - pipeline_t0
|
||||
|
||||
@@ -931,6 +940,14 @@ def process_memoir_phase1(self, user_id: str, segment_ids: List[str]):
|
||||
|
||||
try:
|
||||
with get_sync_db() as db:
|
||||
user_obj_for_lang = db.get(User, user_id)
|
||||
user_language = (
|
||||
"en"
|
||||
if user_obj_for_lang is not None
|
||||
and str(getattr(user_obj_for_lang, "language_preference", "zh") or "zh").lower()
|
||||
== "en"
|
||||
else "zh"
|
||||
)
|
||||
stmt = (
|
||||
select(Segment)
|
||||
.where(Segment.id.in_(segment_ids))
|
||||
@@ -1056,6 +1073,7 @@ def process_memoir_phase1(self, user_id: str, segment_ids: List[str]):
|
||||
memoir_batch=True,
|
||||
),
|
||||
on_phase1_chunk=_phase1_chunk_cb,
|
||||
language=user_language,
|
||||
)
|
||||
prep_elapsed = time.perf_counter() - prep_t0
|
||||
merge_pipeline_run(
|
||||
@@ -1273,13 +1291,21 @@ def generate_chapter_content(self, user_id: str, stage: str, new_content: str):
|
||||
user_birth_year = None
|
||||
background_voice = "default"
|
||||
user_occupation = ""
|
||||
user_language = "zh"
|
||||
if user_obj:
|
||||
user_birth_year = user_obj.birth_year
|
||||
user_language = (
|
||||
"en"
|
||||
if str(getattr(user_obj, "language_preference", "zh") or "zh").lower()
|
||||
== "en"
|
||||
else "zh"
|
||||
)
|
||||
user_profile = format_user_profile_context(
|
||||
birth_year=user_obj.birth_year,
|
||||
birth_place=user_obj.birth_place,
|
||||
grew_up_place=user_obj.grew_up_place,
|
||||
occupation=user_obj.occupation,
|
||||
language=user_language,
|
||||
)
|
||||
background_voice = infer_background_voice(user_obj.occupation)
|
||||
user_occupation = user_obj.occupation or ""
|
||||
@@ -1303,6 +1329,7 @@ def generate_chapter_content(self, user_id: str, stage: str, new_content: str):
|
||||
occupation=user_occupation,
|
||||
memoir_correlation_id=cid,
|
||||
llm_fast=llm_fast,
|
||||
language=user_language,
|
||||
)
|
||||
db.flush()
|
||||
if chapter is None:
|
||||
|
||||
Reference in New Issue
Block a user