feat(planner): finding 当场唤醒 + planner N 秒心跳触发(任务参数,默认5min)
触发机制补两条(见 docs/planner-trigger-impl-plan.md): 1) finding 当场唤醒:worker 飞行中 report_finding 落库即唤醒本任务 planner, 不再等 worker 整趟收工才反应。 - worker.Execute 加 notify 入参并 SetNotify(补上 worker toolset 之前缺失的接线) - addFinding 写 KindFinding 成功后调 notify(只对 finding,不对 fact) - engine 两处 worker.Execute 调用传 t.Notify 2) planner N 秒心跳:距上轮规划结束/任务开始满 N 秒且期间无触发 → 触发一轮, 兜底卡死 + 唤醒去监督飞行中的 worker(steer/kill) + 周期复查。 - plannerLoop 重构为 runRound 闭包 + 三臂 select(ctx/notify/heartbeat) - 心跳在 loop 入口臂 = 从任务 start 计时(覆盖 seed 跳过首轮),每轮结束重臂 - 新增任务参数 plan_heartbeat_seconds,下限=默认=300(5min),低于自动抬到300 - DB 迁移:schema.sql 加列 + ALTER ADD COLUMN IF NOT EXISTS 补旧库 - 全链路接线:db.CreateTask/manager/server HTTP/orchestration spawn_task - 前端:api.createTask 传参 + 建任务表单新增"planner 心跳(分钟)"字段
This commit is contained in:
1 parent
06c1ac748f
commit
47ba58bda6
11 files changed
+168
-82
No files matched your search
+8
-6
@@ -36,9 +36,10 @@ type Task struct {
|
||||
LLMProfileID *int64 `json:"llm_profile_id,omitempty"` // 指定运行本任务 planner/worker 的 LLM 配置;nil=用全局激活配置
|
||||
Status string `json:"status"` // persisted lifecycle status (done/failed/timeout 为终态;空/其它则由运行态推导)
|
||||
// 任务级超时(见 docs/任务级超时与收尾设计.md)。DeadlineAt/FirstRunAt 为 unix 秒,0=未设/未运行。
|
||||
TimeoutSeconds int `json:"timeout_seconds"`
|
||||
FirstRunAt int64 `json:"first_run_at,omitempty"`
|
||||
DeadlineAt int64 `json:"deadline_at,omitempty"`
|
||||
TimeoutSeconds int `json:"timeout_seconds"`
|
||||
PlanHeartbeatSeconds int `json:"plan_heartbeat_seconds"` // planner 心跳触发间隔(秒)
|
||||
FirstRunAt int64 `json:"first_run_at,omitempty"`
|
||||
DeadlineAt int64 `json:"deadline_at,omitempty"`
|
||||
Store *pgdb.ExplorationStore `json:"-"`
|
||||
Guard *guard.Guard `json:"-"`
|
||||
notify chan struct{}
|
||||
@@ -459,15 +460,16 @@ func taskFromPG(pt *pgdb.Task, store *pgdb.ExplorationStore, ic *intercept.Inter
|
||||
Description: pt.Description, Goal: pt.Goal, CreatedAt: pt.CreatedAt.Unix(), Paused: pt.Paused,
|
||||
CompletedAt: unixOrZero(pt.CompletedAt), Status: pt.Status, ParentRef: pt.ParentRef,
|
||||
LLMProfileID: pt.LLMProfileID,
|
||||
TimeoutSeconds: pt.TimeoutSeconds, FirstRunAt: unixOrZero(pt.FirstRunAt), DeadlineAt: unixOrZero(pt.DeadlineAt),
|
||||
TimeoutSeconds: pt.TimeoutSeconds, PlanHeartbeatSeconds: pt.PlanHeartbeatSeconds,
|
||||
FirstRunAt: unixOrZero(pt.FirstRunAt), DeadlineAt: unixOrZero(pt.DeadlineAt),
|
||||
Store: store, Guard: guard.NewWithInterceptor(ic), notify: make(chan struct{}, 1),
|
||||
}
|
||||
}
|
||||
|
||||
// CreateTask creates a task + its exploration and makes it active.
|
||||
// timeoutSeconds is the task-level wall-clock budget (0 = 不限时).
|
||||
func (m *Manager) CreateTask(description, goal string, llmProfileID *int64, timeoutSeconds int) (*Task, error) {
|
||||
pt, err := m.pg.CreateTask(description, goal, llmProfileID, timeoutSeconds)
|
||||
func (m *Manager) CreateTask(description, goal string, llmProfileID *int64, timeoutSeconds, planHeartbeatSeconds int) (*Task, error) {
|
||||
pt, err := m.pg.CreateTask(description, goal, llmProfileID, timeoutSeconds, planHeartbeatSeconds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user