"""WebSocket 下发话题 chips(opening / resume / 每轮助手回复后)。""" from datetime import datetime, timezone from app.agents.chat.prompts_conversation import build_topic_chips from app.agents.state_schema import ( MemoirStateSchema, interview_control_state, narrative_coverage_state, ) from app.core.config import settings from app.core.logging import get_logger from app.features.conversation.ws.connection_manager import manager from app.features.conversation.ws.message_types import MessageType from app.features.conversation.ws.profile_collector import get_missing_profile_fields from app.features.user.models import User log = get_logger(__name__) async def maybe_send_topic_chips_ws( conversation_id: str, *, user: User, memoir_state: MemoirStateSchema, reason: str, language: str, ) -> None: """资料齐备且开关开启时,按当前回忆录阶段下发 topic_suggestions。失败静默。""" if not settings.chat_topic_chips_enabled: return if get_missing_profile_fields(user): return stage = (memoir_state.current_stage or "").strip() or "childhood" try: narrative_state = narrative_coverage_state(memoir_state) control_state = interview_control_state(memoir_state) empty_slots = control_state.prompt_empty_slots_for_stage( narrative_state, stage ) chips = build_topic_chips( stage, empty_slots, max_chips=settings.chat_topic_chips_max, language=language, ) if not chips: return await manager.send_message( conversation_id, { "type": MessageType.TOPIC_SUGGESTIONS, "conversation_id": conversation_id, "data": { "reason": reason, "stage": stage, "suggestions": chips, }, "timestamp": datetime.now(timezone.utc).isoformat(), }, ) log.info( "event=ws_topic_chips_sent reason={} conversation_id={} stage={} count={}", reason, conversation_id, stage, len(chips), ) except Exception as e: log.warning("发送话题 chips 失败: {}", e)