feat: 语音流式输入管线 + VAD前端集成 + 插件-工具合并清理
- 前端: VAD语音检测(@ricky0123/vad-web) + useVoiceInput双模式(流式WS/REST) - Gateway: VoiceStreamManager代理WS流式STT到voice-service - Voice-service: DashScope REST → Realtime WS → Whisper三级引擎 + ffmpeg转码 - 共享模块: pkg/audio(音频转换) + pkg/dashscope(ASR REST客户端) - 清理: 移除旧plugin-manager和pkg/plugins,完成插件→工具合并 - 文档: 完善gateway-api.md和voice-service.md语音API文档 - 工具: scripts/voice/ 语音转换脚本集 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -36,7 +36,7 @@ function setHashSessionId(sessionId: string | null) {
|
||||
|
||||
export default function App() {
|
||||
const { isLoggedIn, login, register, loading: authLoading, userId } = useAuth();
|
||||
const { send } = useChat();
|
||||
const { send, sendVoiceStreamMessage } = useChat();
|
||||
const { loadSessionsFromServer, ensureMainSession, setCurrentSessionId, setMessages, loadMessagesFromServer, sessions, currentSessionId } = useSessionStore();
|
||||
|
||||
const [authMode, setAuthMode] = useState<'login' | 'register'>('login');
|
||||
@@ -330,41 +330,42 @@ export default function App() {
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<AppLayout>
|
||||
<PageRouter onSend={send} />
|
||||
<PageRouter onSend={send} onSendVoiceStream={sendVoiceStreamMessage} />
|
||||
</AppLayout>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
type SendFn = (content: string, mode?: import('@/types/chat').ChatMode, attachments?: import('@/types/chat').MessageAttachment[]) => void;
|
||||
type SendVoiceStreamFn = (msg: import('@/types/chat').WSClientMessage) => void;
|
||||
|
||||
function PageRouter({ onSend }: { onSend: SendFn }) {
|
||||
function PageRouter({ onSend, onSendVoiceStream }: { onSend: SendFn; onSendVoiceStream: SendVoiceStreamFn }) {
|
||||
const currentPage = usePageStore((s) => s.currentPage);
|
||||
const isAdmin = isAdminUser(localStorage.getItem('user_id') || '');
|
||||
|
||||
switch (currentPage) {
|
||||
case 'admin-models':
|
||||
if (!isAdmin) return <ChatPage onSend={onSend} />;
|
||||
if (!isAdmin) return <ChatPage onSend={onSend} onSendVoiceStream={onSendVoiceStream} />;
|
||||
return <ModelsAdminPage />;
|
||||
case 'admin-dashboard':
|
||||
if (!isAdmin) return <ChatPage onSend={onSend} />;
|
||||
if (!isAdmin) return <ChatPage onSend={onSend} onSendVoiceStream={onSendVoiceStream} />;
|
||||
return <AdminDashboard />;
|
||||
case 'profile':
|
||||
return <ProfilePage />;
|
||||
case 'chat':
|
||||
default:
|
||||
return <ChatPage onSend={onSend} />;
|
||||
return <ChatPage onSend={onSend} onSendVoiceStream={onSendVoiceStream} />;
|
||||
}
|
||||
}
|
||||
|
||||
function ChatPage({ onSend }: { onSend: SendFn }) {
|
||||
function ChatPage({ onSend, onSendVoiceStream }: { onSend: SendFn; onSendVoiceStream: SendVoiceStreamFn }) {
|
||||
return (
|
||||
<div className="flex flex-col h-full overflow-hidden">
|
||||
<div className="flex-1 min-h-0 overflow-hidden">
|
||||
<ChatContainer />
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<ChatInput onSend={onSend} />
|
||||
<ChatInput onSend={onSend} onSendVoiceStream={onSendVoiceStream} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user