fix(conversation): 离屏不丢回复、列表预热 WS 与非阻塞进入聊天
- 后端:文本/转写后 AI 生成改为独立任务,避免断连取消整轮;按需 TTS 等与 WS 改动 - 前端:RealtimeSession 重绑 UI 时恢复流式 buffer;列表 onPressIn/挂载预热、已有会话立即 push - 同步会话相关类型、i18n、测试与 env/资源等累计改动 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,13 @@ import type {
|
||||
export type WsEventListener = (event: WsEvent) => void;
|
||||
export type WsStateListener = (state: WsConnectionState) => void;
|
||||
|
||||
function buildWsUrl(conversationId: string, token: string): string {
|
||||
const baseUrl = config.wsBaseUrl.replace(/\/+$/u, '');
|
||||
const encodedConversationId = encodeURIComponent(conversationId);
|
||||
const encodedToken = encodeURIComponent(token);
|
||||
return `${baseUrl}/ws/conversation/${encodedConversationId}?token=${encodedToken}`;
|
||||
}
|
||||
|
||||
function mapServerMessage(raw: RawServerMessage): WsEvent | null {
|
||||
const cid = raw.conversation_id;
|
||||
const d = raw.data;
|
||||
@@ -51,6 +58,7 @@ function mapServerMessage(raw: RawServerMessage): WsEvent | null {
|
||||
index: d.index as number | undefined,
|
||||
total: d.total as number | undefined,
|
||||
assistantMessageId: d.assistant_message_id as string | undefined,
|
||||
manual: d.manual as boolean | undefined,
|
||||
};
|
||||
|
||||
case 'end_conversation':
|
||||
@@ -102,7 +110,7 @@ export class WsClient {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = `${config.wsBaseUrl}/ws/conversation/${this.conversationId}?token=${token}`;
|
||||
const url = buildWsUrl(this.conversationId, token);
|
||||
|
||||
try {
|
||||
this.ws = new WebSocket(url);
|
||||
@@ -164,14 +172,40 @@ export class WsClient {
|
||||
return true;
|
||||
}
|
||||
|
||||
sendText(text: string): boolean {
|
||||
return this.send({ type: 'text', data: { text } });
|
||||
sendText(
|
||||
text: string,
|
||||
opts?: { ttsThisTurn?: boolean },
|
||||
): boolean {
|
||||
return this.send({
|
||||
type: 'text',
|
||||
data: {
|
||||
text,
|
||||
...(opts?.ttsThisTurn === true ? { tts_this_turn: true } : {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
sendTtsCancel(): boolean {
|
||||
return this.send({ type: 'tts_cancel', data: {} });
|
||||
}
|
||||
|
||||
sendTtsRequest(body: {
|
||||
assistantMessageId: string;
|
||||
segmentIndex: number;
|
||||
segmentText?: string;
|
||||
}): boolean {
|
||||
return this.send({
|
||||
type: 'tts_request',
|
||||
data: {
|
||||
assistant_message_id: body.assistantMessageId,
|
||||
segment_index: body.segmentIndex,
|
||||
...(body.segmentText != null && body.segmentText !== ''
|
||||
? { segment_text: body.segmentText }
|
||||
: {}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
sendEndConversation(): boolean {
|
||||
return this.send({ type: 'end_conversation', data: {} });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user