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

@@ -32,6 +32,8 @@ export type TopicSuggestionsCallback = (payload: {
suggestions: TopicSuggestion[];
}) => void;
type TopicSuggestionsPayload = Parameters<TopicSuggestionsCallback>[0];
/** WebSocket `tts_audio`:服务端可能只带 base64、只带 COS URL或两者都有 */
export type TtsSegmentPayload = {
audioBase64?: string;
@@ -85,6 +87,8 @@ export class RealtimeSession {
private streamingBuffer = '';
/** 单段回复且服务端带 `assistant_message_id` 时用于落缓存 id */
private pendingAssistantMessageId: string | null = null;
/** WS 在聊天页挂载 `onTopicSuggestions` 之前到达(如列表预热连开场)时暂存,接棒后重放 */
private pendingTopicSuggestionsPayload: TopicSuggestionsPayload | null = null;
private destroyed = false;
/** 本条用户消息是否请求「先 TTS 再出字」的助手轮次 */
@@ -162,6 +166,15 @@ export class RealtimeSession {
if (!this.assistantTurnTtsSync && this.streamingBuffer.trim().length > 0) {
this.onStreamingText?.(this.streamingBuffer, false);
}
if (
this.uiOwner &&
this.pendingTopicSuggestionsPayload &&
this.onTopicSuggestions
) {
const p = this.pendingTopicSuggestionsPayload;
this.pendingTopicSuggestionsPayload = null;
this.onTopicSuggestions(p);
}
}
releaseUiCallbacks(
@@ -197,6 +210,7 @@ export class RealtimeSession {
this.resetAssistantTtsSyncState();
this.unsubEvent?.();
this.unsubState?.();
this.pendingTopicSuggestionsPayload = null;
this.client.dispose();
}
@@ -394,11 +408,17 @@ export class RealtimeSession {
}
if (event.kind === 'topic_suggestions') {
this.onTopicSuggestions?.({
const payload: TopicSuggestionsPayload = {
reason: event.reason,
stage: event.stage,
suggestions: event.suggestions,
});
};
if (this.uiOwner && this.onTopicSuggestions) {
this.pendingTopicSuggestionsPayload = null;
this.onTopicSuggestions(payload);
} else {
this.pendingTopicSuggestionsPayload = payload;
}
return;
}