From e00a4a8e72b43dfdde16f3fc635c9282c9aef61b Mon Sep 17 00:00:00 2001 From: Autumn-27 <53844290+Autumn-27@users.noreply.github.com> Date: Sun, 9 Aug 2026 04:49:57 -0400 Subject: [PATCH] =?UTF-8?q?refactor(asset):=20delete=5Fassets=5Fby=5Fhost?= =?UTF-8?q?=20=E6=94=B9=E4=B8=BA=E5=B9=B3=E5=8F=B0=E5=B7=A5=E5=85=B7(?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E7=BB=91=20Auto)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前作为任务域工具挂在 worker/mainagent 列表里;移除绑定后它也从 BuiltinToolSeeds 自动生成的 seed 清单里消失,导致从未写入 tools 表、UI 看不到。改到平台工具层 (platformTools),由 seedOrchestrationTools 每次启动独立 seed 并默认绑内置 Auto agent, 不属于任务 agent。db 层 DeleteByHost 不变。 Co-Authored-By: Claude Opus 4.8 --- agent/tools_insert.go | 39 ------------------------------------ server/platform_tools.go | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/agent/tools_insert.go b/agent/tools_insert.go index c1a9973..d442bf2 100644 --- a/agent/tools_insert.go +++ b/agent/tools_insert.go @@ -521,45 +521,6 @@ func (t *ToolSet) listAssets() actool.CoreTool { ) } -// deleteAssetsByHost hard-deletes every asset tied to one host (exact match). -func (t *ToolSet) deleteAssetsByHost() actool.CoreTool { - return writeTool( - "delete_assets_by_host", - "按 host 精确删除资产:删掉该 host 的域名/子域名,以及其下的服务(service)、接口(endpoint)。\n"+ - "host 完全匹配(小写、去空格),不是模糊/通配。\n"+ - "传根域名(如 example.com)会连带删除它的子域名及其服务/接口;传子域名(如 a.example.com)或 IP 只删该 host 自身及其服务/接口。\n"+ - "⚠️ 硬删除且作用于全局资产库(跨任务共享),不可撤销;请先用 list_assets 确认范围再删。", - obj(map[string]any{ - "host": str("要删除的 host:域名/子域名/IP。完全匹配,如 example.com 或 a.example.com 或 1.2.3.4"), - }, "host"), - func(_ context.Context, in json.RawMessage) (actool.Result, error) { - if t.as == nil { - return actool.Errorf("delete_assets_by_host 未启用: AssetStore 未初始化"), nil - } - var a struct { - Host string `json:"host"` - } - _ = json.Unmarshal(in, &a) - if strings.TrimSpace(a.Host) == "" { - return actool.Errorf("host 不能为空"), nil - } - counts, err := t.as.DeleteByHost(a.Host) - if err != nil { - return actool.Errorf("删除失败: " + err.Error()), nil - } - var total int64 - for _, n := range counts { - total += n - } - return jsonResult(map[string]any{ - "host": a.Host, - "deleted": total, - "deleted_by_type": counts, - }) - }, - ) -} - // listCompanies lets an agent enumerate companies (企业) with their scope + asset count. func (t *ToolSet) listCompanies() actool.CoreTool { return readTool( diff --git a/server/platform_tools.go b/server/platform_tools.go index face7d8..1dacf56 100644 --- a/server/platform_tools.go +++ b/server/platform_tools.go @@ -23,6 +23,7 @@ func (s *Server) platformTools() []actool.CoreTool { s.toolUpdateCustomTool(), s.toolCreateMCP(), s.toolUpdateMCP(), + s.toolDeleteAssetsByHost(), } } @@ -31,6 +32,48 @@ var platformToolKeys = []string{ "create_skill", "update_skill_file", "create_custom_tool", "update_custom_tool", "create_mcp", "update_mcp", + "delete_assets_by_host", +} + +// ---- assets ---- + +// toolDeleteAssetsByHost hard-deletes every asset tied to one host (exact match). +// Platform-level (not a per-task tool): operates on the global, cross-task asset库. +func (s *Server) toolDeleteAssetsByHost() actool.CoreTool { + return wrTool("delete_assets_by_host", + "按 host 精确删除资产:删掉该 host 的域名/子域名,以及其下的服务(service)、接口(endpoint)。\n"+ + "host 完全匹配(小写、去空格),不是模糊/通配。\n"+ + "传根域名(如 example.com)会连带删除它的子域名及其服务/接口;传子域名(如 a.example.com)或 IP 只删该 host 自身及其服务/接口。\n"+ + "⚠️ 硬删除、作用于全局资产库(跨任务共享)、不可撤销。", + objSchema(map[string]any{ + "host": strParam("要删除的 host:域名/子域名/IP。完全匹配,如 example.com 或 a.example.com 或 1.2.3.4"), + }, "host"), + func(_ context.Context, in json.RawMessage) (actool.Result, error) { + as := s.assetStore() + if as == nil { + return actool.Errorf("资产库未初始化"), nil + } + var a struct { + Host string `json:"host"` + } + _ = json.Unmarshal(in, &a) + if strings.TrimSpace(a.Host) == "" { + return actool.Errorf("host 不能为空"), nil + } + counts, err := as.DeleteByHost(a.Host) + if err != nil { + return actool.Errorf("删除失败: " + err.Error()), nil + } + var total int64 + for _, n := range counts { + total += n + } + return jsonResult(map[string]any{ + "host": a.Host, + "deleted": total, + "deleted_by_type": counts, + }) + }) } // ---- skills ----