diff --git a/web/app/dashboard/ai-agents/_components/config-workbench.tsx b/web/app/dashboard/ai-agents/_components/config-workbench.tsx index cd8f393..ca63476 100644 --- a/web/app/dashboard/ai-agents/_components/config-workbench.tsx +++ b/web/app/dashboard/ai-agents/_components/config-workbench.tsx @@ -25,6 +25,14 @@ import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table" import { Textarea } from "@/components/ui/textarea" import { createAIAgent, @@ -32,6 +40,7 @@ import { fetchAIAgentWorkflow, fetchAIConfigsAll, fetchAIWorkflowNodeSpecs, + fetchAIWorkflowVersions, fetchAgentTeamsAll, fetchKnowledgeBasesAll, fetchMCPCatalog, @@ -45,6 +54,7 @@ import { type AIWorkflow, type AIWorkflowDefinition, type AIWorkflowNodeSpec, + type AIWorkflowVersion, type AIWorkflowValidationResult, type AdminAgentTeam, type CreateAIAgentPayload, @@ -162,6 +172,7 @@ export function AIAgentConfigWorkbench({ 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) @@ -234,6 +245,7 @@ export function AIAgentConfigWorkbench({ if (!currentAgentId || currentAgentId <= 0) { setAgent(null) setWorkflow(null) + setWorkflowVersions([]) setName("") setDescription("") setAIConfigId("") @@ -260,6 +272,12 @@ export function AIAgentConfigWorkbench({ setAgent(agentDetail) setWorkflow(workflowDetail) + if (workflowDetail?.id > 0) { + const versionPage = await fetchAIWorkflowVersions({ workflowId: workflowDetail.id, limit: 20 }) + setWorkflowVersions(versionPage.results ?? []) + } else { + setWorkflowVersions([]) + } setName(agentDetail.name) setDescription(agentDetail.description || "") setAIConfigId(toText(agentDetail.aiConfigId)) @@ -600,7 +618,7 @@ export function AIAgentConfigWorkbench({ ) : (
{activeSection === "basic" ? ( - +
setName(event.target.value)} /> @@ -621,7 +639,7 @@ export function AIAgentConfigWorkbench({ ) : null} {activeSection === "model" ? ( - +
+ !selectedKnowledgeIds.includes(Number(option.value)))} @@ -703,7 +721,7 @@ export function AIAgentConfigWorkbench({ ) : null} {activeSection === "skills" ? ( - + !selectedSkillIds.includes(Number(option.value)))} @@ -723,7 +741,7 @@ export function AIAgentConfigWorkbench({ ) : null} {activeSection === "tools" ? ( - +
+
@@ -812,14 +830,76 @@ export function AIAgentConfigWorkbench({ ) : null} {activeSection === "publish" ? ( - -
- - - + +
+
+ Agent 状态 + {agent?.statusName || "-"} +
+
+ 运行模式 + {agent?.runtimeModeName || "-"} +
+
+ 生效流程版本 + + {agent?.workflowVersionId ? `#${agent.workflowVersionId}` : "未发布"} + +
+
+ 发布会保存草稿、生成不可变版本,并绑定为当前生效流程。 +
-
- 发布会先保存当前流程草稿,再生成不可变版本,并将该版本绑定为 Agent 当前生效流程。 +
+
+

版本记录

+

+ 仅展示已发布的不可变流程版本,当前页面暂不支持切换或回滚版本。 +

+
+
+ {workflowVersions.length > 0 ? ( + + + + 版本 + 发布时间 + 发布人 + 状态 + 定义指纹 + + + + {workflowVersions.map((version) => ( + + +
+ v{version.version} + {agent?.workflowVersionId === version.id ? ( + 当前生效 + ) : null} +
+
+ + {version.publishedAt || version.createdAt || "-"} + + {version.publishedByName || "-"} + + + {version.status === Status.Ok ? "启用" : "禁用"} + + + + {version.definitionHash ? version.definitionHash.slice(0, 8) : "-"} + +
+ ))} +
+
+ ) : ( +
暂无已发布版本。
+ )} +
) : null} @@ -833,20 +913,12 @@ export function AIAgentConfigWorkbench({ } function ConfigSection({ - title, - description, children, }: { - title: string - description: string children: ReactNode }) { return (
-
-

{title}

-

{description}

-
{children}
) @@ -911,12 +983,3 @@ function BadgeList({
) } - -function StatusTile({ label, value }: { label: string; value: string }) { - return ( -
-
{label}
-
{value}
-
- ) -} diff --git a/web/app/dashboard/ai-agents/page.tsx b/web/app/dashboard/ai-agents/page.tsx index 01c14d6..e270c5d 100644 --- a/web/app/dashboard/ai-agents/page.tsx +++ b/web/app/dashboard/ai-agents/page.tsx @@ -311,8 +311,8 @@ export default function DashboardAIAgentsPage() { }} title={t("aiAgent.configure")} size="xxl" + defaultFullscreen bodyScrollable={false} - contentClassName="top-5 left-5 h-[calc(100vh-40px)] max-h-[calc(100vh-40px)] w-[calc(100vw-40px)] max-w-[calc(100vw-40px)] translate-x-0 translate-y-0 sm:max-w-[calc(100vw-40px)]" headerClassName="sr-only" > {configOpen ? ( diff --git a/web/lib/api/admin.ts b/web/lib/api/admin.ts index ec229e0..47f3b5c 100644 --- a/web/lib/api/admin.ts +++ b/web/lib/api/admin.ts @@ -815,6 +815,12 @@ export function fetchAIWorkflowNodeSpecs() { return request("/api/dashboard/ai-workflow/node-spec/list") } +export function fetchAIWorkflowVersions(query?: Record) { + return request>( + `/api/dashboard/ai-workflow/version/list${toQueryString(query)}` + ) +} + export function validateAIWorkflow(definition: AIWorkflowDefinition) { return request("/api/dashboard/ai-agent/workflow/validate", { method: "POST",