fix(conversation): 修复实时会话 TTS/回复被离屏 WS 抢占
- 列表预热仅预取消息缓存,避免后台 WebSocket 覆盖服务端连接 - RealtimeSession UI 回调按 owner 独占,防止 offscreen 覆盖聊天页 - 列表页聚焦时再 prewarm,会话页 TTS 入队优先 base64 - 管线下发 TTS 同时带 audio_base64 与 audio_url;协议说明同步 - 移除 TTS 排查用前后端调试日志,保留错误/告警 - 补充 WS / RealtimeSession / entry-warmup / 播放器相关单测 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -118,6 +118,45 @@ describe('WsClient', () => {
|
||||
client.dispose();
|
||||
});
|
||||
|
||||
test('maps tts audio with base64 and url playback channels', async () => {
|
||||
const client = new WsClient('conv-123');
|
||||
const events: WsEvent[] = [];
|
||||
client.onEvent((e) => events.push(e));
|
||||
|
||||
await client.connect();
|
||||
await new Promise((r) => setTimeout(r, 10));
|
||||
|
||||
const ws = (client as unknown as { ws: MockWebSocket }).ws;
|
||||
ws.simulateMessage({
|
||||
type: 'tts_audio',
|
||||
conversation_id: 'conv-123',
|
||||
data: {
|
||||
audio_base64: 'ZmFrZS1tcDM=',
|
||||
audio_url: 'https://example.com/tts.mp3',
|
||||
index: 0,
|
||||
total: 1,
|
||||
assistant_message_id: 'aa11aa11-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||
manual: true,
|
||||
},
|
||||
timestamp: '2026-01-01T00:00:00Z',
|
||||
});
|
||||
|
||||
expect(events).toEqual([
|
||||
{
|
||||
kind: 'tts_audio_received',
|
||||
conversationId: 'conv-123',
|
||||
audioBase64: 'ZmFrZS1tcDM=',
|
||||
audioUrl: 'https://example.com/tts.mp3',
|
||||
index: 0,
|
||||
total: 1,
|
||||
assistantMessageId: 'aa11aa11-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||
manual: true,
|
||||
},
|
||||
]);
|
||||
|
||||
client.dispose();
|
||||
});
|
||||
|
||||
test('sends text messages', async () => {
|
||||
const client = new WsClient('conv-123');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user