From f39cffcb9a9dfb474e58c86e655cf53abb64a7de Mon Sep 17 00:00:00 2001 From: fengxiangdebaozi <10845145+fengxiangdebaozi@user.noreply.gitee.com> Date: Tue, 16 Jun 2026 15:51:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(qa-center):=20=E9=97=AE=E7=AD=94=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E5=B7=A6=E4=BE=A7=E6=A0=8F=E6=94=B9=E9=80=A0=EF=BC=88?= =?UTF-8?q?0616=20=E9=9C=80=E6=B1=82=202-5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 多智能体会商:Step1 落地左栏「业务链(public 前3) + 分析记录」;点链=勾选(autoChainResult),第一步澄清后点「进入研讨」才按链执行 - zzJC/zzXD:独立模块路由 /page/strategy/qa/{zzjc,zzxd},常驻左栏(按 agent 标签分组 + 仅本模块会话的聊天记录),点智能体模块内切换不跳页,默认落地配置类型下首个智能体 - zzJC/zzXD admin 设置:左栏齿轮→单选类型(TDesign)配置面板+智能体预览;后端 system_settings.agent_modules 持久化(GET 开放/PUT admin)+ test_agent_modules - 课题研究:左栏「研究模板(文章类型) + 笔记本」;模板点击预填表单,笔记本点击设为素材来源(selectedNotebookId 上提 WritingFormContext) - 通用问答:全量模式历史侧栏默认展开 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../agents/agent-module-settings-dialog.tsx | 174 +++++++++++ .../workspace/agents/agent-module-sidebar.tsx | 278 ++++++++++++++++++ .../src/core/page-layout/sidebar-menu.ts | 4 +- frontend-web/src/core/system-settings/api.ts | 39 +++ .../src/core/system-settings/hooks.ts | 25 ++ .../components/ai-writing/AIWritingForm.tsx | 19 +- .../components/ai-writing/ResearchSidebar.tsx | 128 ++++++++ .../contexts/WritingFormContext.tsx | 24 +- .../src/open-canvas/pages/AIWritingPage.tsx | 15 +- frontend-web/src/pages/AgentChatPage.tsx | 4 +- frontend-web/src/pages/AgentModulePage.tsx | 99 +++++++ frontend-web/src/pages/StrategyRoutes.tsx | 6 + frontend-web/src/pages/WorkspaceRoutes.tsx | 10 +- .../pages/RoundtablePlanningPage.tsx | 198 +++++++++++-- offline-backend-20260512/backend/CLAUDE.md | 4 + .../app/gateway/routers/system_settings.py | 35 ++- .../deerflow/config/system_settings.py | 32 ++ .../backend/tests/test_agent_modules.py | 60 ++++ 18 files changed, 1113 insertions(+), 41 deletions(-) create mode 100644 frontend-web/src/components/workspace/agents/agent-module-settings-dialog.tsx create mode 100644 frontend-web/src/components/workspace/agents/agent-module-sidebar.tsx create mode 100644 frontend-web/src/open-canvas/components/ai-writing/ResearchSidebar.tsx create mode 100644 frontend-web/src/pages/AgentModulePage.tsx create mode 100644 offline-backend-20260512/backend/tests/test_agent_modules.py diff --git a/frontend-web/src/components/workspace/agents/agent-module-settings-dialog.tsx b/frontend-web/src/components/workspace/agents/agent-module-settings-dialog.tsx new file mode 100644 index 00000000..b1e71d7e --- /dev/null +++ b/frontend-web/src/components/workspace/agents/agent-module-settings-dialog.tsx @@ -0,0 +1,174 @@ +"use client"; + +import { Bot, Loader2 } from "lucide-react"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { toast } from "sonner"; +import { Select } from "tdesign-react"; + +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { useAgents } from "@/core/agents"; +import type { Agent } from "@/core/agents"; +import { + useAgentModuleConfig, + useUpdateAgentModuleConfig, +} from "@/core/system-settings/hooks"; +import { useTags } from "@/core/tags"; +import { desensitize } from "@/lib/desensitize"; + +/** + * 模块(zzJC / zzXD)类型配置弹窗(需求 0616 #3/#4,admin)。 + * + * 单选一个「类型」(agent 标签,TDesign 下拉框)→ 下方实时预览该类型下的智能体(名称+描述)→ + * 确认后写入后端(``/api/system-settings/agent-modules/{key}``,单选即存单元素列表), + * 该模块左栏据此只展示选中类型的智能体。 + */ +export function AgentModuleSettingsDialog({ + open, + onOpenChange, + moduleKey, + moduleTitle, +}: { + open: boolean; + onOpenChange: (open: boolean) => void; + moduleKey: string; + moduleTitle: string; +}) { + const { data: tags = [] } = useTags("agent"); + const { agents } = useAgents(); + const { data: config } = useAgentModuleConfig(moduleKey); + const { mutate: save, isPending } = useUpdateAgentModuleConfig(moduleKey); + + const [selectedTagId, setSelectedTagId] = useState(); + // Radix Dialog(modal) 把 body 设为 pointer-events:none,TDesign 浮层默认挂到 body 上 + // 会点不动 —— 用 attach 把下拉浮层挂到弹窗内部容器(pointer-events 正常)。 + const selectWrapRef = useRef(null); + + // 每次打开同步当前已保存配置(取首个,单选语义)。 + useEffect(() => { + if (open) setSelectedTagId(config?.tag_ids?.[0]); + }, [open, config?.tag_ids]); + + const tagOptions = useMemo( + () => tags.map((t) => ({ label: t.name, value: t.id })), + [tags], + ); + + // 选中类型下的智能体(含名称 + 描述)。 + const previewAgents = useMemo(() => { + if (!selectedTagId) return []; + return agents.filter((agent) => + (agent.tags ?? []).some((t) => t.id === selectedTagId), + ); + }, [agents, selectedTagId]); + + const handleConfirm = () => { + save(selectedTagId ? [selectedTagId] : [], { + onSuccess: () => { + toast.success(`已更新「${moduleTitle}」展示的类型`); + onOpenChange(false); + }, + onError: (err) => + toast.error(err instanceof Error ? err.message : "保存失败,请重试"), + }); + }; + + return ( + + + + {moduleTitle} · 类型配置 + + 选择该模块左栏展示的智能体类型(标签);下方预览该类型下的智能体。 + + + +
+
+
+ 选择类型 +
+ {tags.length === 0 ? ( +

+ 暂无智能体标签,请先到「标签管理」创建。 +

+ ) : ( +
+