feat: Add core UI components, Assistants page, Dashscope and Volcengine agent configurations, and a WAV client example.

This commit is contained in:
Xin Wang
2026-03-10 03:31:39 +08:00
parent 373be4eb97
commit 47293ac46d
2 changed files with 16 additions and 21 deletions

View File

@@ -219,14 +219,14 @@ export const Drawer: React.FC<DrawerProps> = ({ isOpen, onClose, title, classNam
<div className="fixed inset-0 bg-black/60 backdrop-blur-sm transition-opacity" onClick={onClose} /> <div className="fixed inset-0 bg-black/60 backdrop-blur-sm transition-opacity" onClick={onClose} />
{/* Drawer Content */} {/* Drawer Content */}
<div className={`relative ml-auto flex h-full w-full flex-col overflow-y-auto bg-background/95 border-l border-white/10 p-6 shadow-2xl animate-in slide-in-from-right ${className || 'max-w-md sm:max-w-lg'}`}> <div className={`relative ml-auto flex h-full w-full flex-col bg-background/95 border-l border-white/10 p-6 shadow-2xl animate-in slide-in-from-right ${className || 'max-w-md sm:max-w-lg'}`}>
<div className="flex items-center justify-between mb-4"> <div className="flex items-center justify-between mb-4 shrink-0">
<h2 className="text-lg font-semibold text-foreground">{title}</h2> <h2 className="text-lg font-semibold text-foreground">{title}</h2>
<Button variant="ghost" size="icon" onClick={onClose}> <Button variant="ghost" size="icon" onClick={onClose}>
<X className="h-4 w-4" /> <X className="h-4 w-4" />
</Button> </Button>
</div> </div>
<div className="flex-1"> <div className="flex-1 min-h-0 overflow-y-auto">
{children} {children}
</div> </div>
</div> </div>

View File

@@ -2379,7 +2379,7 @@ export const DebugDrawer: React.FC<{
const [inputText, setInputText] = useState(''); const [inputText, setInputText] = useState('');
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [callStatus, setCallStatus] = useState<'idle' | 'calling' | 'active'>('idle'); const [callStatus, setCallStatus] = useState<'idle' | 'calling' | 'active'>('idle');
const [agentState, setAgentState] = useState<'waiting' | 'listening' | 'thinking' | 'speaking'>('waiting'); const [agentState, setAgentState] = useState<'listening' | 'thinking' | 'speaking'>('listening');
const [textPromptDialog, setTextPromptDialog] = useState<DebugTextPromptDialogState>({ const [textPromptDialog, setTextPromptDialog] = useState<DebugTextPromptDialogState>({
open: false, open: false,
message: '', message: '',
@@ -2562,7 +2562,7 @@ export const DebugDrawer: React.FC<{
clearResponseTracking(); clearResponseTracking();
setMessages([]); setMessages([]);
setCallStatus('idle'); setCallStatus('idle');
setAgentState('waiting'); setAgentState('listening');
} }
} else { } else {
setMode('text'); setMode('text');
@@ -2586,7 +2586,7 @@ export const DebugDrawer: React.FC<{
setSettingsDrawerOpen(false); setSettingsDrawerOpen(false);
setIsSwapped(false); setIsSwapped(false);
setCallStatus('idle'); setCallStatus('idle');
setAgentState('waiting'); setAgentState('listening');
} }
}, [isOpen, assistant, mode]); }, [isOpen, assistant, mode]);
@@ -3112,7 +3112,7 @@ export const DebugDrawer: React.FC<{
console.error(e); console.error(e);
stopVoiceCapture(); stopVoiceCapture();
setCallStatus('idle'); setCallStatus('idle');
setAgentState('waiting'); setAgentState('listening');
const err = e as Error & { __dynamicVariables?: boolean }; const err = e as Error & { __dynamicVariables?: boolean };
if (err.__dynamicVariables) { if (err.__dynamicVariables) {
setWsStatus('disconnected'); setWsStatus('disconnected');
@@ -3138,7 +3138,7 @@ export const DebugDrawer: React.FC<{
stopMedia(); stopMedia();
closeWs(); closeWs();
setCallStatus('idle'); setCallStatus('idle');
setAgentState('waiting'); setAgentState('listening');
clearResponseTracking(); clearResponseTracking();
setMessages([]); setMessages([]);
setTextPromptDialog({ open: false, message: '', promptType: 'text' }); setTextPromptDialog({ open: false, message: '', promptType: 'text' });
@@ -3590,7 +3590,7 @@ export const DebugDrawer: React.FC<{
} }
if (type === 'output.audio.end') { if (type === 'output.audio.end') {
setAgentState('waiting'); setAgentState('listening');
return; return;
} }
@@ -4516,36 +4516,31 @@ export const DebugDrawer: React.FC<{
</div> </div>
<div className="text-center z-10"> <div className="text-center z-10">
<h3 className="text-xl font-bold text-white mb-2 tracking-tight"> <h3 className="text-xl font-bold text-white mb-2 tracking-tight">
{agentState === 'listening' ? '正在倾听...' : {agentState === 'thinking' ? '思考中...' :
agentState === 'thinking' ? '思考中...' :
agentState === 'speaking' ? '正在回复...' : agentState === 'speaking' ? '正在回复...' :
'待机中'} '正在倾听...'}
</h3> </h3>
<div className="flex items-center justify-center gap-2"> <div className="flex items-center justify-center gap-2">
<span className="relative flex h-2.5 w-2.5"> <span className="relative flex h-2.5 w-2.5">
<span className={`animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 ${ <span className={`animate-ping absolute inline-flex h-full w-full rounded-full opacity-75 ${
agentState === 'listening' ? 'bg-blue-400' :
agentState === 'thinking' ? 'bg-yellow-400' : agentState === 'thinking' ? 'bg-yellow-400' :
agentState === 'speaking' ? 'bg-green-400' : agentState === 'speaking' ? 'bg-green-400' :
'bg-gray-400' 'bg-blue-400'
}`}></span> }`}></span>
<span className={`relative inline-flex rounded-full h-2.5 w-2.5 ${ <span className={`relative inline-flex rounded-full h-2.5 w-2.5 ${
agentState === 'listening' ? 'bg-blue-500' :
agentState === 'thinking' ? 'bg-yellow-500' : agentState === 'thinking' ? 'bg-yellow-500' :
agentState === 'speaking' ? 'bg-green-500' : agentState === 'speaking' ? 'bg-green-500' :
'bg-gray-500' 'bg-blue-500'
}`}></span> }`}></span>
</span> </span>
<p className={`text-sm font-medium ${ <p className={`text-sm font-medium ${
agentState === 'listening' ? 'text-blue-400' :
agentState === 'thinking' ? 'text-yellow-400' : agentState === 'thinking' ? 'text-yellow-400' :
agentState === 'speaking' ? 'text-green-400' : agentState === 'speaking' ? 'text-green-400' :
'text-gray-400' 'text-blue-400'
}`}> }`}>
{agentState === 'listening' ? 'Listening' : {agentState === 'thinking' ? 'Thinking' :
agentState === 'thinking' ? 'Thinking' :
agentState === 'speaking' ? 'Speaking' : agentState === 'speaking' ? 'Speaking' :
'Waiting'} 'Listening'}
</p> </p>
</div> </div>
</div> </div>