fix(core): exact-resume saved session on workspace reconnect (#315)
This commit is contained in:
2 files changed
+53
-5
No files matched your search
+11
-5
@@ -1932,16 +1932,22 @@ func (e *Engine) getOrCreateInteractiveStateWith(sessionKey string, p Platform,
|
||||
return state
|
||||
}
|
||||
|
||||
// On first real-user connection after engine startup (or workspace re-creation
|
||||
// after idle reap), use --continue to pick up the most recent CLI session.
|
||||
// Subsequent connections respect the stored session ID (or "" for fresh).
|
||||
// On first real-user connection after engine startup, use --continue to pick
|
||||
// up the most recent CLI session. For workspace-scoped reconnects after idle
|
||||
// reap, keep that behavior only when we do not already have a concrete saved
|
||||
// agent session ID; otherwise exact resume is more precise than continuing
|
||||
// whatever the CLI considers "latest" in that workspace.
|
||||
startSessionID := session.GetAgentSessionID()
|
||||
once := &e.hasConnectedOnce
|
||||
if connectedOnce != nil {
|
||||
once = connectedOnce
|
||||
}
|
||||
if consumeFirstUserContinueBridge && !once.Swap(true) {
|
||||
startSessionID = ContinueSession
|
||||
if consumeFirstUserContinueBridge {
|
||||
if connectedOnce != nil && startSessionID != "" {
|
||||
once.Store(true)
|
||||
} else if !once.Swap(true) {
|
||||
startSessionID = ContinueSession
|
||||
}
|
||||
}
|
||||
|
||||
isResume := startSessionID != ""
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -4450,6 +4451,47 @@ func TestFreshSessionRespectedAfterFirstConnection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorkspaceReconnectWithSavedSessionIDSkipsContinueBridge(t *testing.T) {
|
||||
agent := &stubStartSessionAgent{}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
e := &Engine{
|
||||
agent: agent,
|
||||
sessions: NewSessionManager(""),
|
||||
ctx: ctx,
|
||||
i18n: NewI18n("en"),
|
||||
interactiveStates: make(map[string]*interactiveState),
|
||||
display: DisplayCfg{},
|
||||
}
|
||||
|
||||
session := e.sessions.GetOrCreateActive("test:user3")
|
||||
session.SetAgentSessionID("saved-session-id", "stub")
|
||||
|
||||
var wsConnectedOnce atomic.Bool
|
||||
p := &stubPlatformEngine{n: "test"}
|
||||
state := e.getOrCreateInteractiveStateWith("test:user3", p, "ctx", session, e.sessions, nil, "", true, &wsConnectedOnce)
|
||||
|
||||
if state.agentSession == nil {
|
||||
t.Fatal("expected agentSession to be non-nil")
|
||||
}
|
||||
if !wsConnectedOnce.Load() {
|
||||
t.Fatal("workspace connectedOnce flag should be marked after exact resume")
|
||||
}
|
||||
|
||||
agent.mu.Lock()
|
||||
calls := append([]string{}, agent.calls...)
|
||||
agent.mu.Unlock()
|
||||
|
||||
if len(calls) != 1 {
|
||||
t.Fatalf("expected 1 StartSession call, got %d: %v", len(calls), calls)
|
||||
}
|
||||
if calls[0] != "saved-session-id" {
|
||||
t.Fatalf("StartSession call = %q, want saved session id", calls[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSelfReportedCtx(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
|
||||
Reference in new issue
Block a user