feat: 添加realtime_dialog和realtime_dialog_external_rag_test项目,更新test2项目

This commit is contained in:
User
2026-03-13 13:06:46 +08:00
parent 9dab61345c
commit 5521b673f5
215 changed files with 7626 additions and 1876 deletions

View File

@@ -1,12 +1,14 @@
import { useState, useEffect, useCallback, useRef } from 'react';
import { Settings2, Zap, Mic, MessageSquare } from 'lucide-react';
import { Settings2, Zap, Mic, MessageSquare, History, Plus } from 'lucide-react';
import VoicePanel from './components/VoicePanel';
import ChatPanel from './components/ChatPanel';
import SettingsPanel from './components/SettingsPanel';
import { getVoiceConfig } from './services/voiceApi';
import SessionHistoryPanel from './components/SessionHistoryPanel';
export default function App() {
const [showSettings, setShowSettings] = useState(false);
const [showHistory, setShowHistory] = useState(false);
const [voiceConfig, setVoiceConfig] = useState(null);
// 'voice' | 'chat'
const [mode, setMode] = useState('voice');
@@ -20,6 +22,7 @@ export default function App() {
botName: '小智',
systemRole: '你是一个友善的智能助手,名叫小智。你擅长帮用户解答各类问题。',
speakingStyle: '请使用温和、清晰的口吻。',
greetingText: '你好,我是你的智能语音助手,有什么可以帮你的吗?',
modelVersion: '1.2.1.0',
speaker: 'zh_female_vv_jupiter_bigtts',
enableWebSearch: false,
@@ -51,16 +54,47 @@ export default function App() {
setMode('voice');
}, [currentSessionId]);
// 直接进入文字模式(新会话
// 切换到文字模式(复用已有 sessionId没有时新建
const handleStartChat = useCallback(() => {
const newSid = `chat_${Date.now().toString(36)}`;
setCurrentSessionId(newSid);
const sid = currentSessionId || `chat_${Date.now().toString(36)}`;
setCurrentSessionId(sid);
setHandoff({
sessionId: newSid,
sessionId: sid,
subtitles: [],
});
setMode('chat');
console.log(`[App] New chat session: ${newSid}`);
console.log(`[App] Switch to chat, sessionId=${sid}`);
}, [currentSessionId]);
// 语音会话创建时同步 sessionId 到 App 状态
const handleSessionCreated = useCallback((sessionId) => {
if (sessionId && sessionId !== currentSessionId) {
setCurrentSessionId(sessionId);
console.log(`[App] Voice session synced: ${sessionId}`);
}
}, [currentSessionId]);
// 新建会话:重置所有状态
const handleNewSession = useCallback(() => {
setCurrentSessionId(null);
setHandoff(null);
setChatMessages([]);
setMode('voice');
console.log('[App] New session created');
}, []);
// 从历史记录中选择会话
const handleSelectSession = useCallback((session) => {
const sid = session.id;
setCurrentSessionId(sid);
setChatMessages([]);
// 根据会话最后的模式决定打开方式,默认用文字模式查看历史
setHandoff({
sessionId: sid,
subtitles: [],
});
setMode('chat');
console.log(`[App] Selected session: ${sid}, mode: ${session.mode}`);
}, []);
return (
@@ -78,7 +112,7 @@ export default function App() {
</h1>
<p className="text-[11px] text-slate-400 leading-tight">
{mode === 'voice'
? '混合编排模式 · OutputMode=1'
? '直连 S2S 语音 · ChatTTSText'
: handoff?.subtitles?.length > 0
? '语音转接 · 上下文已延续'
: '方舟 LLM · Function Calling'}
@@ -86,6 +120,22 @@ export default function App() {
</div>
</div>
<div className="flex items-center gap-1.5">
{/* History button */}
<button
onClick={() => setShowHistory(true)}
className="p-2 rounded-lg hover:bg-slate-700/50 text-slate-400 hover:text-white transition-colors mr-1"
title="会话历史"
>
<History className="w-4 h-4" />
</button>
{/* New session button */}
<button
onClick={handleNewSession}
className="p-2 rounded-lg hover:bg-slate-700/50 text-slate-400 hover:text-white transition-colors"
title="新建会话"
>
<Plus className="w-4 h-4" />
</button>
{/* Mode toggle buttons */}
<div className="flex items-center bg-slate-800/60 rounded-lg border border-slate-700/40 p-0.5 mr-2">
<button
@@ -136,23 +186,23 @@ export default function App() {
{mode === 'voice' ? (
<>
{/* Voice Panel */}
<VoicePanel settings={settings} onVoiceEnd={handleVoiceEnd} chatHistory={chatMessages} sessionId={currentSessionId} />
<VoicePanel settings={settings} onVoiceEnd={handleVoiceEnd} chatHistory={chatMessages} sessionId={currentSessionId} onSessionCreated={handleSessionCreated} />
{/* Architecture Info */}
<div className="mt-6 p-4 rounded-xl bg-slate-800/40 border border-slate-700/40">
<h3 className="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3">方案B 混合编排架构</h3>
<h3 className="text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3">RTC 直路由语音架构</h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3 text-xs">
<div className="p-3 rounded-lg bg-slate-700/30 border border-slate-600/30">
<div className="text-emerald-400 font-medium mb-1">闲聊场景</div>
<div className="text-slate-400">端到端模型直接回复 · ~300-800ms</div>
<div className="text-emerald-400 font-medium mb-1">上行链路</div>
<div className="text-slate-400">浏览器 RTC 麦克风 房间字幕/消息 后端前置路由</div>
</div>
<div className="p-3 rounded-lg bg-slate-700/30 border border-slate-600/30">
<div className="text-amber-400 font-medium mb-1">工具调用场景</div>
<div className="text-slate-400">LLM 决策 + Function Calling · ~1-2s</div>
<div className="text-amber-400 font-medium mb-1">应答链路</div>
<div className="text-slate-400">知识库/工具结果 ExternalTextToSpeech 语音播报</div>
</div>
<div className="p-3 rounded-lg bg-slate-700/30 border border-slate-600/30">
<div className="text-violet-400 font-medium mb-1">自动切换</div>
<div className="text-slate-400">系统自动判断走 S2S LLM 分支</div>
<div className="text-violet-400 font-medium mb-1">当前目标</div>
<div className="text-slate-400">彻底绕开原生链纯 S2S 抢答保证知识库结果能播报</div>
</div>
</div>
</div>
@@ -161,6 +211,7 @@ export default function App() {
/* Chat Panel */
handoff && (
<ChatPanel
key={handoff.sessionId}
sessionId={handoff.sessionId}
voiceSubtitles={handoff.subtitles}
settings={settings}
@@ -170,6 +221,16 @@ export default function App() {
)
)}
</main>
{/* Session History Sidebar */}
{showHistory && (
<SessionHistoryPanel
currentSessionId={currentSessionId}
onSelectSession={handleSelectSession}
onNewSession={handleNewSession}
onClose={() => setShowHistory(false)}
/>
)}
</div>
);
}