From 3a048876bd335dea8e40a3a1090195e6b5456a38 Mon Sep 17 00:00:00 2001 From: tinkle-community Date: Thu, 11 Jun 2026 01:12:36 +0800 Subject: [PATCH] fix(agent): keep suspended-task snapshots on the legacy stack suspendActiveContexts clears all active contexts after parking a task on the snapshot stack, so the active-context guard alone let the agentic loop hijack resume requests and strand suspended tasks. Check the snapshot stack in shouldUseAgenticTurn. --- agent/agentic_loop.go | 5 +++++ agent/agentic_loop_test.go | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/agent/agentic_loop.go b/agent/agentic_loop.go index fa98e3fc..537724e6 100644 --- a/agent/agentic_loop.go +++ b/agent/agentic_loop.go @@ -46,6 +46,11 @@ func (a *Agent) shouldUseAgenticTurn(userID int64) bool { if _, ok := a.getPendingProposalSession(userID); ok { return false } + // Suspended tasks are parked on the snapshot stack with all active + // contexts cleared; only the legacy router knows how to resume them. + if len(a.SnapshotManager(userID).Stack()) > 0 { + return false + } return true } diff --git a/agent/agentic_loop_test.go b/agent/agentic_loop_test.go index 7e9eb138..093222f6 100644 --- a/agent/agentic_loop_test.go +++ b/agent/agentic_loop_test.go @@ -274,6 +274,26 @@ func TestShouldUseAgenticTurn(t *testing.T) { } }) + t.Run("suspended task snapshot stays on legacy stack", func(t *testing.T) { + st, err := store.New(filepath.Join(t.TempDir(), "agentic-snapshot.db")) + if err != nil { + t.Fatalf("create store: %v", err) + } + b := New(nil, st, DefaultConfig(), slog.Default()) + b.SetAIClient(&scriptedAIClient{}) + if !b.shouldUseAgenticTurn(12) { + t.Fatal("fresh conversation should use the agentic turn") + } + b.SnapshotManager(12).Save(SuspendedTask{ + SnapshotID: "snap_test", + Kind: "skill", + ResumeHint: "continue strategy create", + }) + if b.shouldUseAgenticTurn(12) { + t.Fatal("suspended task snapshot must stay on the legacy stack so it can be resumed") + } + }) + t.Run("active legacy session stays on legacy stack", func(t *testing.T) { st, err := store.New(filepath.Join(t.TempDir(), "agentic-guard.db")) if err != nil {