feat(agent): node_detail 也默认给 worker,并随回看工具一起补绑

worker 已能通过 search_all_worker_traces / get_worker_trace 拿到 intent_id/
节点 id,配套把 node_detail 也下放给 worker,便于就地查节点完整详情。

- WorkerTools() 增加 node_detail
- 从 seedWorkerReadToolsUnbind 解绑清单去掉 node_detail(保留 list_facts/
  list_companies/list_worker_traces)
- 原 seedWorkerCrossTraceRebind 泛化为 seedWorkerReadbackRebind,补绑清单追加
  node_detail,flag 升到 v2 让已跑过旧迁移的库也补上
This commit is contained in:
Autumn-27 committed 2026-09-13 09:35:18 -04:00
1 parent 2ba395856d
commit c9bfa35113
2 files changed
+23 -22

No files matched your search

+3 -2
View File
@@ -579,9 +579,10 @@ func (t *ToolSet) WorkerTools() []actool.CoreTool {
// search_all_worker_traces:不必先知道 intent_id,按关键字全局捞命中步骤;
// get_worker_trace:锁定某条 work 后列步骤/就地搜/取完整内容。
t.searchAllWorkerTraces(), t.getWorkerTrace(),
// node_detail:worker 拿到 intent_id/节点 id 后可查该节点完整详情(配合上面的回看)。
t.nodeDetail(),
// 以下工具仍【不给】worker,只留给 planner/main(读上下文、跨 work 复盘是规划职责,
// worker 只做单条意图的执行与写回):list_facts / node_detail / list_companies /
// list_worker_traces。
// worker 只做单条意图的执行与写回):list_facts / list_companies / list_worker_traces。
}
}
+20 -20
View File
@@ -490,8 +490,8 @@ func (s *Server) seedOrchestrationTools() {
s.seedPlannerDefaultBindings()
s.seedPlannerListAssetsBinding()
s.seedCompanyScopeRebind()
s.seedWorkerReadToolsUnbind() // list_facts/node_detail/list_companies/list_worker_traces 从 worker 默认解绑(一次性)
s.seedWorkerCrossTraceRebind() // 修复旧 v1 迁移误删:把 search_all_worker_traces/get_worker_trace 补绑回 worker(一次性)
s.seedWorkerReadToolsUnbind() // list_facts/list_companies/list_worker_traces 从 worker 默认解绑(一次性)
s.seedWorkerReadbackRebind() // 修复旧迁移误删:把 search_all_worker_traces/get_worker_trace/node_detail 补绑回 worker(一次性)
s.seedAutoReportFindingBinding()
s.unbindGoalMetDefault()
s.reseedGoalsPrompt() // goals 提示词加入「抽操作约束」步 → 旧库追加一版新默认(一次性)
@@ -849,23 +849,23 @@ func (s *Server) seedCompanyScopeRebind() {
// seedWorkerReadToolsUnbind strips the read-context tools off worker's default
// binding ONCE on existing DBs (guarded by a settings flag): a worker executes one
// intent and writes back — reading facts/nodes/companies and listing all workers'
// traces is a planning/main concern, not the executor's. Fresh DBs already lack these
// via WorkerTools(); this only backfills old rows without overriding a user who
// intent and writes back — reading facts/companies and listing all workers' traces is
// a planning/main concern, not the executor's. Fresh DBs already lack these via
// WorkerTools(); this only backfills old rows without overriding a user who
// deliberately re-binds worker. Each RemoveAgentFromTool is per-tool +
// membership-guarded, so planner/mainagent bindings of the same tool are untouched.
//
// NOTE: search_all_worker_traces / get_worker_trace are intentionally NOT unbound —
// worker owns them for cross-work look-back (see WorkerTools). They used to be in this
// list back when worker lacked them; seedWorkerCrossTraceRebind repairs DBs whose old
// v1 run stripped them.
// NOTE: search_all_worker_traces / get_worker_trace / node_detail are intentionally NOT
// unbound — worker owns them for cross-work look-back + node drill-down (see WorkerTools).
// They used to be in this list back when worker lacked them; seedWorkerReadbackRebind
// repairs DBs whose old run stripped them.
func (s *Server) seedWorkerReadToolsUnbind() {
const flag = "worker_readtools_unbind_v1"
if v, _, _ := s.m.pg.GetSetting(flag); v == "true" {
return
}
for _, k := range []string{
"list_facts", "node_detail", "list_companies", "list_worker_traces",
"list_facts", "list_companies", "list_worker_traces",
} {
if err := s.m.pg.RemoveAgentFromTool("worker", k); err != nil {
log.Printf("[worker] %s 从 worker 解绑失败: %v", k, err)
@@ -875,21 +875,21 @@ func (s *Server) seedWorkerReadToolsUnbind() {
_ = s.m.pg.SetSetting(flag, "true")
}
// seedWorkerCrossTraceRebind re-binds the cross-work look-back tools onto worker ONCE
// (guarded by a settings flag): an earlier seedWorkerReadToolsUnbind (v1) wrongly
// stripped search_all_worker_traces / get_worker_trace from worker after they had been
// added to WorkerTools(), so any DB that ran that migration lost them. Fresh DBs already
// have them via WorkerTools() and this is a harmless no-op there. One-shot + flag-guarded
// so a user who later deliberately unbinds them isn't overridden.
func (s *Server) seedWorkerCrossTraceRebind() {
const flag = "worker_crosstrace_rebind_v1"
// seedWorkerReadbackRebind re-binds the cross-work look-back / drill-down tools onto
// worker ONCE (guarded by a settings flag): an earlier seedWorkerReadToolsUnbind wrongly
// stripped search_all_worker_traces / get_worker_trace / node_detail from worker after
// they had been added to WorkerTools(), so any DB that ran that migration lost them.
// Fresh DBs already have them via WorkerTools() and this is a harmless no-op there.
// One-shot + flag-guarded so a user who later deliberately unbinds them isn't overridden.
func (s *Server) seedWorkerReadbackRebind() {
const flag = "worker_readback_rebind_v2" // v2: 追加 node_detail
if v, _, _ := s.m.pg.GetSetting(flag); v == "true" {
return
}
if err := s.m.pg.AddAgentToToolBinding("worker", []string{
"search_all_worker_traces", "get_worker_trace",
"search_all_worker_traces", "get_worker_trace", "node_detail",
}); err != nil {
log.Printf("[worker] 跨 work 回看工具补绑失败: %v", err)
log.Printf("[worker] 回看/详情工具补绑失败: %v", err)
return // 出错则不落 flag,下次启动重试
}
_ = s.m.pg.SetSetting(flag, "true")