feat: Add FastGPT interactive voice toggle to DebugDrawer and state management

This commit is contained in:
Xin Wang
2026-03-11 13:59:34 +08:00
parent 9b9fbf432f
commit 3b9ee80c8f
2 changed files with 37 additions and 2 deletions

View File

@@ -2534,6 +2534,8 @@ export const DebugDrawer: React.FC<{
const setNsEnabled = useDebugPrefsStore((state) => state.setNsEnabled);
const agcEnabled = useDebugPrefsStore((state) => state.agcEnabled);
const setAgcEnabled = useDebugPrefsStore((state) => state.setAgcEnabled);
const fastgptInteractiveVoiceEnabled = useDebugPrefsStore((state) => state.fastgptInteractiveVoiceEnabled);
const setFastgptInteractiveVoiceEnabled = useDebugPrefsStore((state) => state.setFastgptInteractiveVoiceEnabled);
const clientToolEnabledMap = useDebugPrefsStore((state) => state.clientToolEnabledMap);
const setClientToolEnabled = useDebugPrefsStore((state) => state.setClientToolEnabled);
const hydrateClientToolDefaults = useDebugPrefsStore((state) => state.hydrateClientToolDefaults);
@@ -2752,6 +2754,12 @@ export const DebugDrawer: React.FC<{
fastgptInteractiveDialogRef.current = fastgptInteractiveDialog;
}, [fastgptInteractiveDialog]);
useEffect(() => {
if (!fastgptInteractiveVoiceEnabled && fastgptInteractiveDialog.open) {
stopPromptVoicePlayback();
}
}, [fastgptInteractiveVoiceEnabled, fastgptInteractiveDialog.open]);
useEffect(() => {
dynamicVariableSeqRef.current = 0;
setDynamicVariables([]);
@@ -3088,7 +3096,7 @@ export const DebugDrawer: React.FC<{
submitLabel: item.payload.submitLabel,
cancelLabel: item.payload.cancelLabel,
});
if (nextVoiceText) {
if (nextVoiceText && fastgptInteractiveVoiceEnabled) {
void playPromptVoice(nextVoiceText);
}
return;
@@ -3163,6 +3171,10 @@ export const DebugDrawer: React.FC<{
const fieldValues = snapshot.fieldValues;
const interactionType = snapshot.interactionType;
stopPromptVoicePlayback();
// Stop only local playback so the resumed FastGPT response can take over
// without cancelling the active server-side turn.
stopPlaybackImmediately();
setAgentState('waiting');
setFastgptInteractiveDialog({
open: false,
interactionType: 'userSelect',
@@ -4605,6 +4617,23 @@ export const DebugDrawer: React.FC<{
Auto Gain Control (AGC)
</label>
</div>
<div className="rounded-md border border-white/10 bg-black/20 p-2 space-y-2">
<p className="text-[10px] uppercase tracking-widest text-muted-foreground">Prompt Voice</p>
<div className="flex items-center justify-between gap-3 rounded-md border border-white/10 bg-black/20 px-2 py-1.5">
<div className="min-w-0">
<div className="text-[11px] font-mono text-foreground truncate">FastGPT Interactive</div>
<div className="text-[10px] text-muted-foreground">
Play the interactive description or prompt voice when the popup opens.
</div>
</div>
<Switch
checked={fastgptInteractiveVoiceEnabled}
onCheckedChange={setFastgptInteractiveVoiceEnabled}
title={fastgptInteractiveVoiceEnabled ? 'Click to mute FastGPT interactive prompt voice' : 'Click to enable FastGPT interactive prompt voice'}
aria-label={`FastGPT interactive prompt voice ${fastgptInteractiveVoiceEnabled ? 'enabled' : 'disabled'}`}
/>
</div>
</div>
<div className="rounded-md border border-white/10 bg-black/20 p-2 space-y-2">
<p className="text-[10px] uppercase tracking-widest text-muted-foreground">Client Tools</p>
<p className="text-[11px] text-muted-foreground"></p>
@@ -5086,7 +5115,7 @@ export const DebugDrawer: React.FC<{
)}
{fastgptInteractiveDialog.open && (
<div className="absolute inset-0 z-40 flex items-center justify-center bg-black/55 backdrop-blur-[1px]">
<div className="relative w-[92%] max-w-lg rounded-xl border border-white/15 bg-card/95 p-4 shadow-2xl animate-in zoom-in-95 duration-200">
<div className="relative flex max-h-[82vh] w-[92%] max-w-lg flex-col rounded-xl border border-white/15 bg-card/95 p-4 shadow-2xl animate-in zoom-in-95 duration-200">
{!fastgptInteractiveDialog.required && (
<button
type="button"
@@ -5122,6 +5151,7 @@ export const DebugDrawer: React.FC<{
</p>
)}
</div>
<div className="min-h-0 overflow-y-auto pr-1 custom-scrollbar">
{fastgptInteractiveDialog.interactionType === 'userSelect' ? (
<div className="space-y-2">
{fastgptInteractiveDialog.options.map((option) => {
@@ -5202,6 +5232,7 @@ export const DebugDrawer: React.FC<{
})}
</div>
)}
</div>
<div className="mt-4 flex items-center justify-end gap-2">
<Button
size="sm"