diff --git a/web/app/dashboard/ai-agents/_components/config-workbench.tsx b/web/app/dashboard/ai-agents/_components/config-workbench.tsx index 61f6da7..fe73f7b 100644 --- a/web/app/dashboard/ai-agents/_components/config-workbench.tsx +++ b/web/app/dashboard/ai-agents/_components/config-workbench.tsx @@ -5,16 +5,11 @@ import { ArrowDownIcon, ArrowUpIcon, BotMessageSquareIcon, - BrainCircuitIcon, - DatabaseIcon, GitBranchIcon, HistoryIcon, - LifeBuoyIcon, PlugIcon, SaveIcon, - SendIcon, SettingsIcon, - ShieldCheckIcon, Trash2Icon, } from "lucide-react" import { toast } from "sonner" @@ -23,6 +18,12 @@ import { ContentEditor } from "@/components/content-editor" import { OptionCombobox } from "@/components/option-combobox" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { @@ -52,11 +53,9 @@ import { validateAIWorkflow, type AIAgent, type AIConfig, - type AIWorkflow, type AIWorkflowDefinition, type AIWorkflowNodeSpec, type AIWorkflowVersion, - type AIWorkflowValidationResult, type AdminAgentTeam, type CreateAIAgentPayload, type KnowledgeBase, @@ -85,13 +84,8 @@ type DirectToolOption = { type SectionKey = | "basic" - | "model" - | "knowledge" - | "skills" - | "tools" + | "capabilities" | "workflow" - | "handoff" - | "versions" const fallbackDefinition: AIWorkflowDefinition = { schemaVersion: 1, @@ -140,13 +134,12 @@ export function AIAgentConfigWorkbench({ const [currentAgentId, setCurrentAgentId] = useState(agentId ?? null) const [activeSection, setActiveSection] = useState("basic") const [agent, setAgent] = useState(null) - const [workflow, setWorkflow] = useState(null) const [workflowVersions, setWorkflowVersions] = useState([]) const [nodeSpecs, setNodeSpecs] = useState([]) - const [validation, setValidation] = useState(null) const [loading, setLoading] = useState(true) const [savingAgent, setSavingAgent] = useState(false) const [savingWorkflow, setSavingWorkflow] = useState(false) + const [versionDialogOpen, setVersionDialogOpen] = useState(false) const [name, setName] = useState("") const [description, setDescription] = useState("") @@ -216,7 +209,6 @@ export function AIAgentConfigWorkbench({ if (!currentAgentId || currentAgentId <= 0) { setAgent(null) - setWorkflow(null) setWorkflowVersions([]) setName("") setDescription("") @@ -233,7 +225,6 @@ export function AIAgentConfigWorkbench({ setSelectedSkillIds([]) setDirectTools([]) replaceWorkflowDefinition(defaultDefinition ?? fallbackDefinition) - setValidation(null) return } @@ -243,7 +234,6 @@ export function AIAgentConfigWorkbench({ ]) setAgent(agentDetail) - setWorkflow(workflowDetail) if (workflowDetail?.id > 0) { const versionPage = await fetchAIWorkflowVersions({ workflowId: workflowDetail.id, limit: 20 }) setWorkflowVersions(versionPage.results ?? []) @@ -265,7 +255,6 @@ export function AIAgentConfigWorkbench({ setSelectedSkillIds(agentDetail.skillIds ?? []) setDirectTools(agentDetail.directTools ?? []) replaceWorkflowDefinition(workflowDetail.draftDefinition ?? defaultDefinition ?? fallbackDefinition) - setValidation(null) } catch (error) { toast.error(error instanceof Error ? error.message : "Failed to load Agent config") } finally { @@ -438,13 +427,12 @@ export function AIAgentConfigWorkbench({ if (!currentAgentId) return setSavingWorkflow(true) try { - const saved = await saveAIAgentWorkflow({ + await saveAIAgentWorkflow({ agentId: currentAgentId, name: "", description: "", definition, }) - setWorkflow(saved) toast.success("Workflow draft saved") } catch (error) { toast.error(error instanceof Error ? error.message : "Failed to save workflow draft") @@ -457,7 +445,6 @@ export function AIAgentConfigWorkbench({ setSavingWorkflow(true) try { const result = await validateAIWorkflow(definition) - setValidation(result) toast[result.valid ? "success" : "error"]( result.valid ? "Workflow is valid" : "Workflow has validation errors" ) @@ -474,7 +461,6 @@ export function AIAgentConfigWorkbench({ try { const defaultDefinition = await fetchAIWorkflowDefaultDefinition() replaceWorkflowDefinition(defaultDefinition ?? fallbackDefinition) - setValidation(null) toast.success("已恢复默认流程,保存草稿或发布后生效") } catch (error) { toast.error(error instanceof Error ? error.message : "恢复默认流程失败") @@ -493,15 +479,11 @@ export function AIAgentConfigWorkbench({ description: "", definition, }) - setWorkflow(saved) const version = await publishAIAgentWorkflow(currentAgentId, definition) toast.success(`Published version ${version.version}`) setAgent((current) => current ? { ...current, workflowVersionId: version.id } : current ) - setWorkflow((current) => - current ? { ...current, publishedVersionId: version.id } : saved - ) if (saved.id > 0) { const versionPage = await fetchAIWorkflowVersions({ workflowId: saved.id, @@ -523,13 +505,8 @@ export function AIAgentConfigWorkbench({ const sections: { key: SectionKey; title: string; icon: ReactNode }[] = [ { key: "basic", title: "基础信息", icon: }, - { key: "model", title: "模型与 Prompt", icon: }, - { key: "knowledge", title: "知识库", icon: }, - { key: "skills", title: "Skills", icon: }, - { key: "tools", title: "MCP Tools", icon: }, + { key: "capabilities", title: "能力来源", icon: }, { key: "workflow", title: "会话流程", icon: }, - { key: "handoff", title: "转人工与兜底", icon: }, - { key: "versions", title: "版本记录", icon: }, ] const selectedKnowledgeOptions = selectedOptions(selectedKnowledgeIds, knowledgeOptions) @@ -569,15 +546,7 @@ export function AIAgentConfigWorkbench({ onClick={saveAgentSettings} > - 保存 - - )} @@ -624,7 +593,7 @@ export function AIAgentConfigWorkbench({ 加载中... ) : ( -
+
{activeSection === "basic" ? (
@@ -646,7 +615,7 @@ export function AIAgentConfigWorkbench({ ) : null} - {activeSection === "model" ? ( + {activeSection === "basic" ? (
@@ -683,7 +652,38 @@ export function AIAgentConfigWorkbench({ ) : null} - {activeSection === "knowledge" ? ( + {activeSection === "basic" ? ( + +
+ + + + + + +
+ !selectedTeamIds.includes(Number(option.value)))} + placeholder="选择客服组" + onValueChange={setTeamToAdd} + onAdd={() => { + addSelected(teamToAdd, selectedTeamIds, setSelectedTeamIds) + setTeamToAdd("") + }} + /> + setSelectedTeamIds((current) => current.filter((item) => item !== id))} + /> + +