From 43edb86720f54f7afbef1da9edafd1808908ac87 Mon Sep 17 00:00:00 2001 From: Autumn-27 <53844290+Autumn-27@users.noreply.github.com> Date: Mon, 24 Aug 2026 11:57:28 -0400 Subject: [PATCH] =?UTF-8?q?revert(tasks):=20=E4=BB=8E=20main=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E8=AF=AF=E5=B9=B6=E5=85=A5=204cf36c7=20=E7=9A=84=20go?= =?UTF-8?q?alless=20=E7=9B=B4=E6=8A=95=E6=84=8F=E5=9B=BE=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 这几处 goalless(目标完成后主 agent 直投意图执行)改动被打包进了「任务列表 按 id 降序」提交(4cf36c7),与该提交主题无关,且尚在评审阶段不应留在 main。 此处仅做正向移除,不改写历史;功能改由独立分支 feat/goalless-intent-execution 承载,评审通过后再合入。 --- agent/mainagent.go | 3 +-- agent/tools.go | 10 ---------- db/exploration.go | 10 ---------- server/engine.go | 18 ------------------ server/orchestration.go | 31 ------------------------------- 5 files changed, 1 insertion(+), 71 deletions(-) diff --git a/agent/mainagent.go b/agent/mainagent.go index 99531df..be9e573 100644 --- a/agent/mainagent.go +++ b/agent/mainagent.go @@ -62,8 +62,7 @@ const mainAgentDefaultTmpl = `你是一个授权渗透测试系统的"主 agent" 1. 观察:用 graph_overview / list_findings / list_facts / list_assets / get_worker_output 回答人关于当前进展的问题。 2. 操舵(把人的意图落到系统): - 人想"改方向/强调某类漏洞/重点某区域" → 用 add_hint 写提示(规划者下次会读到)。 - - 人想"立刻测某个具体目标" → 用 add_intent 直接注入一条高优先级意图(priority 8-10)。系统会自动把已完成的任务拉回运行态、让 worker 领这条意图执行,跑完即回到已完成状态。 - **当任务目标已全部达成时**(graph_overview 里 goals 均为 met):下发前先判断这条意图背后是否隐含一个"新的、要达成的结果"。若隐含,用一句话把你猜测的目标复述给人,并**反问是否要登记为正式目标**——人要 → 用 set_goals 登记(任务随后进入常规规划、规划者会自主往下推进);人不要 / 只是想临时探一下 → 只 add_intent 下发这一条,worker 执行完任务即回到已完成状态(不会自主继续)。若这条意图明显只是一次性查证、不隐含新目标,直接 add_intent 即可,不必每次都问。 + - 人想"立刻测某个具体目标" → 用 add_intent 直接注入一条高优先级意图(priority 8-10)。 - 人想"对某条正在运行的意图(work)实时纠偏(别再走 X、聚焦 Y)" → 用 steer_work(不打断、不丢已有进展,worker 下一步动作前生效);先用 get_worker_output 看它在干嘛。方向整个错了则改用 add_intent 另下新意图。 - 人想"新增一个要达成的最终目标" → 用 set_goals 增补目标。系统会把该目标写入任务图并**自动把已完成/暂停的任务拉回运行态继续跑**(规划者随后会据此重新判断是否达成),无需人工再点恢复。 - 人想"增/改测试约束(允许/禁止某类操作,如『仅测当前端口』『禁止爆破』『只做被动侦察』)" → 用 set_constraints 登记(type=allow 允许 / type=deny 禁止)。约束会在下一轮规划时注入 planner/worker 的提示词以框定探索边界;也可在总览「约束管理」里增删改。 diff --git a/agent/tools.go b/agent/tools.go index f8493ab..3f211cb 100644 --- a/agent/tools.go +++ b/agent/tools.go @@ -1016,7 +1016,6 @@ func (t *ToolSet) addIntent() actool.CoreTool { ids := make([]int64, len(items)) errs := map[string]string{} - createdAny := false for i, it := range items { id, err := t.addOneIntent(it) if err != nil { @@ -1024,15 +1023,6 @@ func (t *ToolSet) addIntent() actool.CoreTool { continue } ids[i] = id - createdAny = true - } - - // 人经主 agent 直投意图 → 若任务已 done(无 open 目标的 goalless 分支),把它 - // 拉回 running,worker 才能领这条意图执行。resumeTask 仅由主 agent 的 Chat 接入 - // (SetResumeTask);planner 的 ToolSet 为 nil,故 planner 自己调 add_intent 时此段 - // no-op,不影响其正常产意图。意图节点已在上面建好(open),复活时不会被误判抽干。 - if createdAny && t.resumeTask != nil { - t.resumeTask() } if !batch { // 单条:保持原返回 diff --git a/db/exploration.go b/db/exploration.go index 3a8c563..8747fa6 100644 --- a/db/exploration.go +++ b/db/exploration.go @@ -857,16 +857,6 @@ WHERE exploration_id=$1 AND kind='intent' AND state IN ('open','running'))`, s.e return exists, err } -// HasOpenGoal reports whether this exploration still has any goal in state 'open'. -// false ⇒ 所有目标已 met/abandoned(或本任务无目标)⇒ 进入 goalless(人工直投)分支: -// planner 停跑,任务是否结束改由 frontier 是否抽干决定。met 与 abandoned 都算"已了结"。 -func (s *ExplorationStore) HasOpenGoal() (bool, error) { - var exists bool - err := s.db.QueryRow(`SELECT EXISTS(SELECT 1 FROM exploration_nodes -WHERE exploration_id=$1 AND kind='goal' AND state='open')`, s.expID).Scan(&exists) - return exists, err -} - // ClaimIntent atomically moves an open intent to running. Returns true if claimed. func (s *ExplorationStore) ClaimIntent(id int64, owner string) (bool, error) { res, err := s.db.Exec(`UPDATE exploration_nodes SET state='running', owner=$1 diff --git a/server/engine.go b/server/engine.go index f3c7074..551aa0a 100644 --- a/server/engine.go +++ b/server/engine.go @@ -792,24 +792,6 @@ func (e *Engine) plannerLoop(ctx context.Context, t *Task) { if e.isSettling(t.ID) { return } - // goalless(人工直投)分支:任务已无 open 目标时 planner 不跑——跑了会重判 - // met→cancelExec 杀掉用户经主 agent 直投的意图。是否结束改由 frontier 决定: - // 还有 open/running 意图 → 保持 running、静默等待;意图已全部跑干 → 落 done。 - // 整段纯 Go、不触发任何 LLM 调用,也不打规划轮 marker。 - if open, err := t.Store.HasOpenGoal(); err == nil && !open { - t.drainTriggers() // 丢弃累积的 done/finding 触发,避免 goalless 长会话里无界增长 - if active, err := t.Store.HasActiveIntent(); err == nil && !active { - // frontier 抽干且无在跑意图 → 收尾。用 Guarded 版做 CAS,避免踩到并发的 - // pause/delete/超时收尾的状态转换。 - if won, err := e.m.SetTaskStatusGuarded(t.ID, "done"); err != nil { - log.Printf("[goalless] task %s 收尾落 done 失败: %v", t.ID, err) - } else if won { - e.emitActivity(t, db.Activity{Worker: "system", Kind: "text", - Summary: "目标已全部达成,直投意图已执行完毕,任务结束"}) - } - } - return // goalless 分支永不进入 planner.Plan - } if !e.beginTaskOperation(t.ID) { return } diff --git a/server/orchestration.go b/server/orchestration.go index 9057ea7..ae08953 100644 --- a/server/orchestration.go +++ b/server/orchestration.go @@ -451,7 +451,6 @@ func (s *Server) seedOrchestrationTools() { s.seedAutoReportFindingBinding() s.unbindGoalMetDefault() s.reseedGoalsPrompt() // goals 提示词加入「抽操作约束」步 → 旧库追加一版新默认(一次性) - s.reseedMainAgentPrompt() // mainagent 提示词加入「目标达成后 add_intent 反问是否建目标」(一次性) s.seedReporterAgent() // 预置「报告撰写」agent + 工具绑定 + finding 触发器(一次性) // 注:pentest 的默认工具绑定无需迁移——BuiltinToolSeeds 在全新初始化时就把 // list_assets/insert_assets/report_finding/list_findings/list_companies 连同 @@ -541,36 +540,6 @@ func (s *Server) reseedGoalsPrompt() { log.Printf("[prompts] goals 提示词已追加新默认版本(加入抽操作约束步,一次性)") } -// reseedMainAgentPrompt 把 mainagent 提示词刷成【当前代码默认】——默认正文新增了「目标全部 -// 达成后 add_intent 直投意图时,反问人是否登记为正式目标」这段引导,而 SeedPromptIfEmpty 首插入 -// only,旧库已有版本收不到。用版本管理【追加一个新版本】并切过去(ResetPromptToDefault),旧版本仍 -// 保留在历史里,用户若自定义过可从版本记录找回。settings flag 守卫 → 只做一次。全新库无需处理 -// (SeedPromptIfEmpty 已 seed 最新默认)。与 reseedGoalsPrompt 完全同构。 -func (s *Server) reseedMainAgentPrompt() { - const flag = "mainagent_prompt_goalless_intent_v1" - if v, _, _ := s.m.pg.GetSetting(flag); v == "true" { - return - } - defer func() { _ = s.m.pg.SetSetting(flag, "true") }() // 无论成功与否只尝试一次 - a, err := s.m.pg.GetAgentByKey("mainagent") - if err != nil || a == nil { - return // 全新库尚未建 agent 行时,seedPrompts 会直接 seed 最新默认,无需此迁移 - } - tmpl := agent.BuiltinPromptSeeds()["mainagent"] - if tmpl == "" { - return - } - // 全新库 seedPrompts 已 seed 最新默认 → 当前版本已等于代码默认,不必再追加重复版本。 - if cur, err := s.m.pg.CurrentPrompt(a.ID); err == nil && cur == tmpl { - return - } - if _, err := s.m.pg.ResetPromptToDefault(a.ID, tmpl); err != nil { - log.Printf("[prompts] mainagent 提示词重刷为新默认失败: %v", err) - return - } - log.Printf("[prompts] mainagent 提示词已追加新默认版本(加入目标达成后反问建目标,一次性)") -} - // seedReporterAgent 预置一个「报告撰写」自定义 agent(builtin=false,可在 UI 编辑/删除): // 绑定 update_finding_report + 任务查询工具,并挂一个「report_finding 被调用即触发」的 // 触发器 —— 每登记一个漏洞就唤起它写详细报告。一次性(settings flag 守卫):用户删掉后不再重建。