Add debug mode functionality to AssistantPage with text and voice testing options
Introduced a DebugDrawer component to allow users to switch between text and voice testing modes. Enhanced the AssistantPage layout for better organization and added a debug interface for testing AI responses. This update improves usability by providing clear options for debugging and testing the assistant's capabilities.
This commit is contained in:
@@ -20,6 +20,8 @@ import {
|
|||||||
Save,
|
Save,
|
||||||
Mic,
|
Mic,
|
||||||
Volume2,
|
Volume2,
|
||||||
|
Send,
|
||||||
|
MessageCircle,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
@@ -190,6 +192,8 @@ const mockAssistants: AssistantListItem[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
type DebugMode = "text" | "voice";
|
||||||
|
|
||||||
type TypeFilter = "全部" | AssistantType;
|
type TypeFilter = "全部" | AssistantType;
|
||||||
|
|
||||||
const typeFilters: TypeFilter[] = ["全部", ...assistantTypes];
|
const typeFilters: TypeFilter[] = ["全部", ...assistantTypes];
|
||||||
@@ -214,6 +218,8 @@ export function AssistantPage() {
|
|||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
const [typeFilter, setTypeFilter] = useState<TypeFilter>("全部");
|
const [typeFilter, setTypeFilter] = useState<TypeFilter>("全部");
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
// 右侧调试 drawer 的当前模式
|
||||||
|
const [debugMode, setDebugMode] = useState<DebugMode>("text");
|
||||||
// choose 步骤的草稿:名称与已选类型,确认后才决定进入哪个构建页
|
// choose 步骤的草稿:名称与已选类型,确认后才决定进入哪个构建页
|
||||||
const [draftName, setDraftName] = useState("");
|
const [draftName, setDraftName] = useState("");
|
||||||
const [draftType, setDraftType] = useState<AssistantType | null>(null);
|
const [draftType, setDraftType] = useState<AssistantType | null>(null);
|
||||||
@@ -667,21 +673,18 @@ export function AssistantPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto flex w-full max-w-[1180px] flex-col gap-6">
|
<div className="-mt-6 flex h-full flex-col gap-4">
|
||||||
<div className="flex items-start justify-between gap-6">
|
<div className="flex shrink-0 items-center justify-between gap-6 border-b border-hairline pb-3 pt-1">
|
||||||
<div>
|
<div className="flex items-baseline gap-3">
|
||||||
<h1 className="font-display display-lg text-ink">
|
<h1 className="font-display display-sm text-ink">创建助手</h1>
|
||||||
创建助手
|
<p className="hidden text-sm text-muted-foreground lg:block">
|
||||||
</h1>
|
|
||||||
<p className="mt-3 text-[15px] text-muted-foreground">
|
|
||||||
通过提示词、模型、语音和知识库快速创建 AI 视频助手
|
通过提示词、模型、语音和知识库快速创建 AI 视频助手
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex shrink-0 gap-3">
|
<div className="flex shrink-0 gap-2">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="lg"
|
|
||||||
className="gap-2 border-hairline-strong text-muted-foreground hover:text-foreground"
|
className="gap-2 border-hairline-strong text-muted-foreground hover:text-foreground"
|
||||||
onClick={() => setView("list")}
|
onClick={() => setView("list")}
|
||||||
>
|
>
|
||||||
@@ -689,14 +692,15 @@ export function AssistantPage() {
|
|||||||
返回
|
返回
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button size="lg" className="gap-2">
|
<Button className="gap-2">
|
||||||
<Save size={16} />
|
<Save size={16} />
|
||||||
保存
|
保存
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-5">
|
<div className="flex min-h-0 flex-1 gap-6">
|
||||||
|
<div className="min-w-0 flex-1 space-y-5 overflow-y-auto pr-1">
|
||||||
<SectionCard>
|
<SectionCard>
|
||||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<button
|
<button
|
||||||
@@ -868,6 +872,119 @@ export function AssistantPage() {
|
|||||||
onChange={(checked) => updateForm("enableInterrupt", checked)}
|
onChange={(checked) => updateForm("enableInterrupt", checked)}
|
||||||
/>
|
/>
|
||||||
</SectionCard>
|
</SectionCard>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DebugDrawer mode={debugMode} onModeChange={setDebugMode} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DebugDrawer({
|
||||||
|
mode,
|
||||||
|
onModeChange,
|
||||||
|
}: {
|
||||||
|
mode: DebugMode;
|
||||||
|
onModeChange: (mode: DebugMode) => void;
|
||||||
|
}) {
|
||||||
|
const modeTabs: { key: DebugMode; label: string; icon: React.ReactNode }[] = [
|
||||||
|
{ key: "text", label: "文字测试", icon: <MessageCircle size={15} /> },
|
||||||
|
{ key: "voice", label: "语音测试", icon: <Mic size={15} /> },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<aside className="hidden min-w-0 flex-1 flex-col overflow-hidden rounded-2xl border border-hairline bg-card shadow-sm lg:flex">
|
||||||
|
<div className="shrink-0 border-b border-hairline p-4">
|
||||||
|
<div className="mb-3 text-sm font-medium text-foreground">调试</div>
|
||||||
|
<div className="flex gap-1 rounded-full bg-surface-strong p-1">
|
||||||
|
{modeTabs.map((tab) => (
|
||||||
|
<button
|
||||||
|
key={tab.key}
|
||||||
|
type="button"
|
||||||
|
onClick={() => onModeChange(tab.key)}
|
||||||
|
className={[
|
||||||
|
"flex flex-1 items-center justify-center gap-1.5 rounded-full px-3 py-1.5 text-sm transition-colors",
|
||||||
|
mode === tab.key
|
||||||
|
? "bg-card text-foreground shadow-sm"
|
||||||
|
: "text-muted-foreground hover:text-foreground",
|
||||||
|
].join(" ")}
|
||||||
|
>
|
||||||
|
{tab.icon}
|
||||||
|
{tab.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{mode === "text" ? <DebugTextPanel /> : <DebugVoicePanel />}
|
||||||
|
</aside>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DebugTextPanel() {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-0 flex-1 flex-col">
|
||||||
|
<div className="flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4">
|
||||||
|
<div className="flex max-w-[85%] flex-col gap-1">
|
||||||
|
<div className="rounded-2xl rounded-tl-sm bg-surface-strong px-4 py-2.5 text-sm leading-6 text-foreground">
|
||||||
|
您好,我是 AI 视频助手,请问有什么可以帮您?
|
||||||
|
</div>
|
||||||
|
<span className="px-1 text-xs text-muted-soft">助手</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex max-w-[85%] flex-col items-end gap-1 self-end">
|
||||||
|
<div className="rounded-2xl rounded-tr-sm bg-primary px-4 py-2.5 text-sm leading-6 text-primary-foreground">
|
||||||
|
我想咨询一下社保卡的办理流程。
|
||||||
|
</div>
|
||||||
|
<span className="px-1 text-xs text-muted-soft">我</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex max-w-[85%] flex-col gap-1">
|
||||||
|
<div className="rounded-2xl rounded-tl-sm bg-surface-strong px-4 py-2.5 text-sm leading-6 text-foreground">
|
||||||
|
社保卡可通过线上或线下渠道办理。线上可在政务服务 App
|
||||||
|
提交申请,线下可前往社保经办网点……
|
||||||
|
</div>
|
||||||
|
<span className="px-1 text-xs text-muted-soft">助手</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="shrink-0 border-t border-hairline p-3">
|
||||||
|
<div className="flex items-end gap-2">
|
||||||
|
<Textarea
|
||||||
|
rows={1}
|
||||||
|
placeholder="输入测试消息…"
|
||||||
|
className="max-h-28 min-h-10 flex-1 resize-none border-hairline-strong bg-background text-sm text-foreground placeholder:text-muted-soft"
|
||||||
|
/>
|
||||||
|
<Button size="icon" className="shrink-0" aria-label="发送">
|
||||||
|
<Send size={16} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DebugVoicePanel() {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-6 p-6 text-center">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex h-24 w-24 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-transform hover:scale-105"
|
||||||
|
aria-label="开始语音测试"
|
||||||
|
>
|
||||||
|
<Mic size={32} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div className="text-sm font-medium text-foreground">点击开始语音测试</div>
|
||||||
|
<p className="mt-1.5 text-sm leading-6 text-muted-foreground">
|
||||||
|
点击麦克风后开始录音,实时识别结果将显示在下方。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full rounded-xl border border-hairline bg-canvas-soft p-4 text-left">
|
||||||
|
<div className="caption-label mb-2 text-muted-soft">实时转写</div>
|
||||||
|
<p className="text-sm leading-6 text-muted-soft">等待语音输入…</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user