fix(conversation): topic chips after warmup + English chip copy

- Buffer topic_suggestions until chat UI attaches (uiOwner + callback); replay on attach
- build_topic_chips respects user language for label/text; router passes user_language

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin
2026-05-12 11:10:21 +08:00
parent 7e64fc3faf
commit d155e45a44
5 changed files with 101 additions and 16 deletions

View File

@@ -710,41 +710,47 @@ def build_topic_chips(
empty_slots: List[str],
*,
max_chips: int = 4,
language: str = "zh",
) -> List[Dict[str, str]]:
"""根据当前阶段与空 slot 列表生成 quick-start 话题 chips。
返回结构:[{"id": slot_key, "label": 短标签, "text": 用户点击后发出的句子}]
"""
slot_labels = slot_name_map_for(language)
stage_bank = _STAGE_TOPIC_CHIP_BANK.get(current_stage) or []
seen: set[str] = set()
chips: List[Dict[str, str]] = []
# 优先从「当前阶段空 slot」挑选与开场提问方向一致
empty_set = {s for s in empty_slots if s}
for slot_key, label in stage_bank:
for slot_key, zh_label in stage_bank:
if slot_key in empty_set and slot_key not in seen:
chips.append(
{
"id": slot_key,
"label": label,
"text": f"我想聊聊{label}",
}
label = (
zh_label if language != "en" else slot_labels.get(slot_key, zh_label)
)
text = (
f"I'd like to talk about {label}."
if language == "en"
else f"我想聊聊{label}"
)
chips.append({"id": slot_key, "label": label, "text": text})
seen.add(slot_key)
if len(chips) >= max_chips:
return chips
# 不足则用阶段默认话题补齐
for slot_key, label in stage_bank:
for slot_key, zh_label in stage_bank:
if slot_key in seen:
continue
chips.append(
{
"id": slot_key,
"label": label,
"text": f"我想聊聊{label}",
}
label = (
zh_label if language != "en" else slot_labels.get(slot_key, zh_label)
)
text = (
f"I'd like to talk about {label}."
if language == "en"
else f"我想聊聊{label}"
)
chips.append({"id": slot_key, "label": label, "text": text})
seen.add(slot_key)
if len(chips) >= max_chips:
return chips

View File

@@ -235,6 +235,7 @@ async def websocket_endpoint(
memoir_state.current_stage,
empty_slots,
max_chips=settings.chat_topic_chips_max,
language=user_language,
)
if not chips:
return

View File

@@ -286,3 +286,13 @@ def test_plan_follow_when_no_empty_slots():
)
assert p.mode == "follow_user_only"
assert p.low_information_reply is True
def test_build_topic_chips_english_uses_slot_name_map_en():
from app.agents.chat.prompts_conversation import build_topic_chips
chips = build_topic_chips("childhood", ["place"], max_chips=2, language="en")
assert len(chips) >= 1
place_chip = next(c for c in chips if c["id"] == "place")
assert place_chip["label"] == "where you grew up"
assert place_chip["text"].startswith("I'd like to talk about")