feat(agent): add_hint 触发的规划轮显式播报「本轮由新增 hint 触发」

此前 add_hint 走裸 notify,触发的规划轮 triggers 为空,开场白说"无具体变动",
hint 只折在 graph_overview 里让 planner 自己发现。仿照 set_goals/NotifyGoal,
让 add_hint 记一条 hint 触发事件并带上提示文本。

- TriggerEvent 增加 Hints 字段;renderTriggers 增加 hint 分支,播报「人新增了
  N 条战略提示:…」
- ToolSet 增加 notifyHint 回调 + SetNotifyHint;add_hint 整批写完统一唤醒一次
  (优先 notifyHint,未接则退回裸 notify),notify 从 addOneHint 上移到 handler
- 主 agent(server.go) 与跨任务编排(orchestration.go) 均接上 Task.NotifyHint
This commit is contained in:
Autumn-27 committed 2026-09-13 11:36:31 -04:00
1 parent 0b9341ac8b
commit edbc296e29
6 files changed
+55 -9

No files matched your search

+15
View File
@@ -1776,6 +1776,21 @@ func (t *Task) NotifyGoal(texts []string) {
t.Notify()
}
// NotifyHint records that one OR MORE hints were added in a single add_hint call —
// by the human via the main agent, or by cross-task orchestration — then wakes the
// planner, so the next round is told "人新增了 N 条战略提示:…" and looks at them
// directly instead of having to spot the new hint folded into the graph overview.
// One call → one trigger event (a batched add_hint counts as one, not one per hint).
func (t *Task) NotifyHint(texts []string) {
if len(texts) == 0 {
return
}
t.trigMu.Lock()
t.pendingTriggers = append(t.pendingTriggers, agent.TriggerEvent{Kind: "hint", Hints: texts})
t.trigMu.Unlock()
t.Notify()
}
// NotifyGoalDeleted records that the human deleted a goal (via 总览的目标管理), then
// wakes the planner so the next round spells out which goal was removed. The event
// survives an early-returning terminal round (drain happens after the gate).
+2 -1
View File
@@ -166,7 +166,8 @@ func (s *Server) delegateToTask(ctx context.Context, in json.RawMessage, pick fu
if s.m.Assets() != nil {
tsx.SetAssetStore(s.m.Assets(), s.m.Assets().Companies())
}
tsx.SetNotify(t.Notify) // hint writes wake this task's planner (no-op for read tools)
tsx.SetNotify(t.Notify) // 通用唤醒(无专用回调的写操作走它;读工具为 no-op)
tsx.SetNotifyHint(t.NotifyHint) // add_hint → 记一条「人新增了 N 条战略提示:…」触发并唤醒 planner
return pick(tsx).Call(ctx, inner, nil)
}
+1 -1
View File
@@ -3571,7 +3571,7 @@ func (s *Server) chat(w http.ResponseWriter, r *http.Request) {
taskDir := filepath.Join(s.m.dir, "tasks", t.ID)
agentMsg := composeAgentMessage(req.Message, req.Attachments, taskDir)
s.engine.BeginLLMCall(t.ID)
_, err := ma.Chat(ctx, maTaskID, mainSeg, s.m.Assets(), t.Store, t.Goal, agentMsg, emit, t.Notify, resume, t.NotifyGoal)
_, err := ma.Chat(ctx, maTaskID, mainSeg, s.m.Assets(), t.Store, t.Goal, agentMsg, emit, t.Notify, resume, t.NotifyGoal, t.NotifyHint)
s.engine.EndLLMCall(t.ID)
if err != nil && ctx.Err() == nil {
s.engine.emitActivity(t, db.Activity{Worker: "mainagent", Kind: "text", IsError: true, Summary: "(主 Agent 出错:" + err.Error() + ")", MainSeg: segPtr})