From fbbb2e0fee1ef9320bfdc5076613607aaa2b3c57 Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Thu, 26 Feb 2026 14:13:47 +0800 Subject: [PATCH] Add assistant snapshot management to track unsaved changes and enhance debug handling --- web/pages/Assistants.tsx | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/web/pages/Assistants.tsx b/web/pages/Assistants.tsx index 7c3a648..0e2c9b5 100644 --- a/web/pages/Assistants.tsx +++ b/web/pages/Assistants.tsx @@ -106,8 +106,14 @@ export const AssistantsPage: React.FC = () => { const [copySuccess, setCopySuccess] = useState(false); const [saveLoading, setSaveLoading] = useState(false); const [isLoading, setIsLoading] = useState(true); + const [persistedAssistantSnapshotById, setPersistedAssistantSnapshotById] = useState>({}); const selectedAssistant = assistants.find(a => a.id === selectedId) || null; + const serializeAssistant = (assistant: Assistant) => JSON.stringify(assistant); + const selectedAssistantHasUnsavedChanges = Boolean( + selectedAssistant + && persistedAssistantSnapshotById[selectedAssistant.id] !== serializeAssistant(selectedAssistant) + ); const filteredAssistants = assistants.filter(a => a.name.toLowerCase().includes(searchTerm.toLowerCase()) @@ -131,6 +137,12 @@ export const AssistantsPage: React.FC = () => { setLlmModels(llmList); setAsrModels(asrList); setTools(toolList); + setPersistedAssistantSnapshotById( + assistantList.reduce>((acc, item) => { + acc[item.id] = serializeAssistant(item); + return acc; + }, {}) + ); if (assistantList.length > 0) { setSelectedId(assistantList[0].id); } @@ -166,6 +178,7 @@ export const AssistantsPage: React.FC = () => { try { const created = await createAssistant(newAssistantPayload); setAssistants((prev) => [created, ...prev]); + setPersistedAssistantSnapshotById((prev) => ({ ...prev, [created.id]: serializeAssistant(created) })); setSelectedId(created.id); setActiveTab(TabValue.GLOBAL); } catch (error) { @@ -180,6 +193,7 @@ export const AssistantsPage: React.FC = () => { try { const updated = await updateAssistantApi(selectedAssistant.id, selectedAssistant); setAssistants((prev) => prev.map((item) => (item.id === updated.id ? { ...item, ...updated } : item))); + setPersistedAssistantSnapshotById((prev) => ({ ...prev, [updated.id]: serializeAssistant(updated) })); } catch (error) { console.error(error); alert('保存失败,请稍后重试。'); @@ -218,6 +232,11 @@ export const AssistantsPage: React.FC = () => { try { await deleteAssistant(deleteId); setAssistants(prev => prev.filter(a => a.id !== deleteId)); + setPersistedAssistantSnapshotById((prev) => { + const next = { ...prev }; + delete next[deleteId]; + return next; + }); if (selectedId === deleteId) setSelectedId(null); setDeleteId(null); } catch (error) { @@ -240,6 +259,15 @@ export const AssistantsPage: React.FC = () => { } }; + const handleOpenDebug = () => { + if (!selectedAssistant) return; + if (selectedAssistantHasUnsavedChanges) { + const proceed = window.confirm('当前助手配置尚未保存。是否继续打开调试窗口?'); + if (!proceed) return; + } + setDebugOpen(true); + }; + const toggleTool = (toolId: string) => { if (!selectedAssistant) return; const currentTools = selectedAssistant.tools || []; @@ -393,7 +421,7 @@ export const AssistantsPage: React.FC = () => {