feat(worker): 暂停/重跑续接先前 LLM 对话,不再从头开始
Worker 的 Execute 在创建 session 后尝试 Resume 先前的 transcript, 如果存在则续接对话而非重建全新会话,避免浪费已积累的 LLM 上下文。 Claude-Session: https://claude.ai/code/session_014TfZWeVGhjXqZD3vcj44mz
This commit is contained in:
1 parent
06a8f64b5e
commit
56101b46e8
3 files changed
+19
-6
No files matched your search
@@ -360,6 +360,18 @@ func (w *Worker) Execute(ctx context.Context, name string, taskID int64, as *db.
|
||||
s := agentcore.NewSession(opts)
|
||||
defer s.Close() // release the session's background-task manager (temp dir + processes)
|
||||
|
||||
// Resume prior conversation if this intent was paused/blocked/exhausted and is
|
||||
// being re-run. The transcript ID is deterministic per intent, so if a prior
|
||||
// session exists the worker continues from where it left off instead of
|
||||
// restarting from scratch.
|
||||
if w.tx != nil {
|
||||
_ = s.Resume(opts.SessionID)
|
||||
if len(s.Messages()) > 0 {
|
||||
seedUnlockFromHistory(s.Messages(), def.UnlockSkill)
|
||||
input = "继续执行。"
|
||||
}
|
||||
}
|
||||
|
||||
// Budgets + settlement are owned by the SDK (MaxTurns/MaxDuration + Settlement):
|
||||
// on hit it runs a wrap-up turn and finishes with ReasonMaxTurns/ReasonTimeout.
|
||||
// We only add a HARD ctx backstop past the soft wall-clock budget, for the rare
|
||||
|
||||
+5
-5
@@ -215,7 +215,7 @@ func (s *ExplorationStore) SetNodeState(id int64, state string) error {
|
||||
// ResetRunningIntents returns any intent left in 'running' back to 'open' so it
|
||||
// is re-claimed. Called on startup: a 'running' intent with no live worker (a
|
||||
// backend restart or crashed worker goroutine left it stuck) would otherwise spin
|
||||
// forever in the UI. Workers re-run an intent from scratch, so reopening is safe.
|
||||
// forever in the UI. Workers resume from their transcript, so reopening is safe.
|
||||
func (s *ExplorationStore) ResetRunningIntents() (int64, error) {
|
||||
res, err := s.db.Exec(`UPDATE exploration_nodes SET state='open', completed_at=NULL, blocked_reason=NULL
|
||||
WHERE exploration_id=$1 AND kind='intent' AND state='running'`, s.expID)
|
||||
@@ -227,9 +227,9 @@ WHERE exploration_id=$1 AND kind='intent' AND state='running'`, s.expID)
|
||||
}
|
||||
|
||||
// ReopenIntent flips ONE not-successfully-finished intent (blocked/exhausted/stopped)
|
||||
// back to 'open' so a worker re-claims and re-runs it from scratch (graph writes it
|
||||
// already produced stay). done/open/running are left untouched. Returns whether a row
|
||||
// changed (false = intent absent or not in a rerunnable state). Used by the "重跑" button.
|
||||
// back to 'open' so a worker re-claims it (graph writes it already produced stay).
|
||||
// The worker resumes from its prior LLM transcript instead of restarting from scratch.
|
||||
// done/open/running are left untouched. Returns whether a row changed. Used by "重跑".
|
||||
func (s *ExplorationStore) ReopenIntent(id int64) (bool, error) {
|
||||
res, err := s.db.Exec(`UPDATE exploration_nodes
|
||||
SET state='open', completed_at=NULL, blocked_reason=NULL
|
||||
@@ -244,7 +244,7 @@ WHERE id=$1 AND exploration_id=$2 AND kind='intent'
|
||||
|
||||
// ReopenBlockedIntents flips EVERY 'blocked' intent in this exploration back to 'open'
|
||||
// (batch rerun after e.g. an LLM/network outage that blocked many at once). Returns the
|
||||
// number reopened. Workers re-run each from scratch; kept graph writes remain.
|
||||
// number reopened. Workers resume from their transcripts; kept graph writes remain.
|
||||
func (s *ExplorationStore) ReopenBlockedIntents() (int64, error) {
|
||||
res, err := s.db.Exec(`UPDATE exploration_nodes SET state='open', completed_at=NULL, blocked_reason=NULL
|
||||
WHERE exploration_id=$1 AND kind='intent' AND state='blocked'`, s.expID)
|
||||
|
||||
+2
-1
@@ -926,7 +926,8 @@ func (e *Engine) runWorkerStep(ctx context.Context, t *Task, name string, worker
|
||||
return true
|
||||
}
|
||||
// if a pause cancelled this run mid-flight, return the intent to the frontier
|
||||
// so it is re-claimed (and re-run from scratch) on resume — not marked done.
|
||||
// so it is re-claimed on resume — the worker will resume the prior LLM
|
||||
// conversation from its transcript instead of restarting from scratch.
|
||||
if ectx.Err() != nil && e.IsPaused(t.ID) {
|
||||
_ = t.Store.SetIntentState(intent.ID, "open")
|
||||
return true
|
||||
|
||||
Reference in new issue
Block a user