From 57114a2994eed776f3d536edda2fa6aa21fffbfc Mon Sep 17 00:00:00 2001 From: Autumn-27 <53844290+Autumn-27@users.noreply.github.com> Date: Tue, 18 Aug 2026 12:38:14 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=A6=E5=8F=91=E5=99=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=BC=96=E8=BE=91(=E5=89=8D=E7=AB=AF=E8=A1=A5?= =?UTF-8?q?=E9=BD=90,=E5=90=8E=E7=AB=AF=E6=97=A9=E5=B7=B2=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20PATCH)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 触发器 Tab 之前只能新增/删除/启停。改造「新增」表单为「新增/编辑」双模式: - 每条触发器加「编辑」按钮 → 灌入表单进入编辑态(高亮该行),改完点「保存修改」 调 api.updateTrigger;可「取消编辑」 - 编辑时保留该触发器原有启用状态;删除正在编辑的触发器会自动退出编辑态 后端 PATCH /api/triggers/{id} 与 api.updateTrigger 早已存在,本次仅补前端 UI。 --- web/src/components/agent-editor.tsx | 136 +++++++++++++++++++--------- 1 file changed, 95 insertions(+), 41 deletions(-) diff --git a/web/src/components/agent-editor.tsx b/web/src/components/agent-editor.tsx index a678fda..ac9208e 100644 --- a/web/src/components/agent-editor.tsx +++ b/web/src/components/agent-editor.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { toast } from "sonner"; -import { EyeIcon, GitCompareIcon, InfoIcon, RotateCcwIcon, SaveIcon, Trash2Icon } from "lucide-react"; +import { EyeIcon, GitCompareIcon, InfoIcon, PencilIcon, RotateCcwIcon, SaveIcon, Trash2Icon, XIcon } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; @@ -768,6 +768,8 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent const [taskCreateMsg, setTaskCreateMsg] = React.useState(""); const [toolNames, setToolNames] = React.useState([]); const [saving, setSaving] = React.useState(false); + // null = 新增模式;非 null = 正在编辑该 id 的触发器。 + const [editingId, setEditingId] = React.useState(null); const reload = React.useCallback(() => { api.agentTriggers(agentKey).then(setTriggers).catch(() => setTriggers([])); @@ -783,7 +785,46 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent setToolNames((prev) => (prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key])); } - async function create() { + // resetForm 清空表单并回到「新增」模式。 + function resetForm() { + setEditingId(null); + setOnInterval(false); + setIntervalSec("60"); + setOnFinding(false); + setOnGoalMet(false); + setOnTaskTimeout(false); + setOnToolCall(false); + setOnTaskCreate(false); + setIntervalMsg(""); + setFindingMsg(""); + setGoalMsg(""); + setTaskTimeoutMsg(""); + setToolCallMsg(""); + setTaskCreateMsg(""); + setToolNames([]); + } + + // startEdit 把某条已有触发器灌进表单,进入「编辑」模式。 + function startEdit(t: AgentTrigger) { + setEditingId(t.id); + setOnInterval(t.interval_sec > 0); + setIntervalSec(t.interval_sec > 0 ? String(t.interval_sec) : "60"); + setOnFinding(t.on_finding); + setOnGoalMet(t.on_goal_met); + setOnTaskTimeout(t.on_task_timeout); + setOnToolCall(t.on_tool_call); + setOnTaskCreate(t.on_task_create); + setIntervalMsg(t.interval_message); + setFindingMsg(t.finding_message); + setGoalMsg(t.goal_message); + setTaskTimeoutMsg(t.task_timeout_message); + setToolCallMsg(t.tool_call_message); + setTaskCreateMsg(t.task_create_message); + setToolNames(t.tool_names ?? []); + } + + // submit 依 editingId 走「新增」或「保存修改」;编辑时保留该触发器的启用状态。 + async function submit() { const n = onInterval ? Math.max(1, Math.floor(Number(intervalSec) || 0)) : 0; if (n === 0 && !onFinding && !onGoalMet && !onTaskTimeout && !onToolCall && !onTaskCreate) { toast.error("至少选择一种触发条件"); @@ -793,42 +834,35 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent toast.error("工具调用触发至少选择一个工具"); return; } + const body = { + interval_sec: n, + on_finding: onFinding, + on_goal_met: onGoalMet, + on_task_timeout: onTaskTimeout, + on_tool_call: onToolCall, + on_task_create: onTaskCreate, + interval_message: intervalMsg.trim(), + finding_message: findingMsg.trim(), + goal_message: goalMsg.trim(), + task_timeout_message: taskTimeoutMsg.trim(), + tool_call_message: toolCallMsg.trim(), + task_create_message: taskCreateMsg.trim(), + tool_names: onToolCall ? toolNames : [], + }; setSaving(true); try { - await api.createTrigger(agentKey, { - enabled: true, - interval_sec: n, - on_finding: onFinding, - on_goal_met: onGoalMet, - on_task_timeout: onTaskTimeout, - on_tool_call: onToolCall, - on_task_create: onTaskCreate, - interval_message: intervalMsg.trim(), - finding_message: findingMsg.trim(), - goal_message: goalMsg.trim(), - task_timeout_message: taskTimeoutMsg.trim(), - tool_call_message: toolCallMsg.trim(), - task_create_message: taskCreateMsg.trim(), - tool_names: onToolCall ? toolNames : [], - }); - toast.success("已添加触发器"); - setOnInterval(false); - setIntervalSec("60"); - setOnFinding(false); - setOnGoalMet(false); - setOnTaskTimeout(false); - setOnToolCall(false); - setOnTaskCreate(false); - setIntervalMsg(""); - setFindingMsg(""); - setGoalMsg(""); - setTaskTimeoutMsg(""); - setToolCallMsg(""); - setTaskCreateMsg(""); - setToolNames([]); + if (editingId != null) { + const cur = triggers.find((x) => x.id === editingId); + await api.updateTrigger(editingId, { ...body, enabled: cur?.enabled ?? true }); + toast.success("已保存修改"); + } else { + await api.createTrigger(agentKey, { ...body, enabled: true }); + toast.success("已添加触发器"); + } + resetForm(); reload(); } catch (e) { - toast.error("添加失败:" + (e as Error).message); + toast.error((editingId != null ? "保存失败:" : "添加失败:") + (e as Error).message); } finally { setSaving(false); } @@ -859,6 +893,7 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent async function del(id: number) { try { await api.deleteTrigger(id); + if (editingId === id) resetForm(); reload(); } catch (e) { toast.error("删除失败:" + (e as Error).message); @@ -959,9 +994,13 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent

- {/* 新增触发器 */} + {/* 新增 / 编辑触发器 */}
- + {/* 定时 */}
@@ -1057,10 +1096,15 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent )}
-
- + {editingId != null && ( + + )}
@@ -1069,7 +1113,13 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent {triggers.length === 0 && (暂无)} {triggers.map((t) => ( -
+
toggleEnabled(t)} className="mt-0.5" />
@@ -1092,8 +1142,12 @@ function AgentTriggersTab({ agentKey, agent }: { agentKey: string; agent?: Agent )}
+