diff --git a/frontend/app/app/assistant.tsx b/frontend/app/app/assistant.tsx index 0f70b42..065c74c 100644 --- a/frontend/app/app/assistant.tsx +++ b/frontend/app/app/assistant.tsx @@ -329,15 +329,32 @@ function AssistantWorkspace() { closeActivityPanel(); }, [showPipeline, closeActivityPanel]); - // Skill 开关联动 applied:开 → 立刻展开面板;关 → 收起。 - // 面板只在用户显式点击 skill 按钮时展开,不再从消息/pipeline 自动推断。 + // Skill 开关联动 applied:只有用户在本次页面会话中「主动点击」开启 skill + // 才展开面板。页面加载时 skill 已经是 enabled 的情况不自动展开(避免闪烁)。 + // 判断依据:skill.loading 从 true→false 是初始加载完成,之后 enabled 变化 + // 才是用户主动操作。 + const skillLoadedOnce = useRef(false); + const prevSkillEnabled = useRef(null); useEffect(() => { - if (skill.enabled && !applied) { + if (skill.loading) return; + if (!skillLoadedOnce.current) { + // 初始加载完成,记录当前状态,不触发 applied + skillLoadedOnce.current = true; + prevSkillEnabled.current = skill.enabled; + // 关掉时清理 localStorage 残留 + if (!skill.enabled && applied) { + setApplied(false); + } + return; + } + // 初始加载之后的变化 = 用户主动操作 + if (skill.enabled && !prevSkillEnabled.current) { setApplied(true); - } else if (!skill.enabled && applied) { + } else if (!skill.enabled && prevSkillEnabled.current) { setApplied(false); } - }, [skill.enabled, applied, setApplied]); + prevSkillEnabled.current = skill.enabled; + }, [skill.enabled, skill.loading, applied, setApplied]); // 注意:用同一棵树 + 条件渲染,保证 在 // pipeline 切换前后都保持挂载,否则它们会 remount,