diff --git a/cmd/olliesrv/internal/session/session.go b/cmd/olliesrv/internal/session/session.go index a3c9c9a..4f36e41 100644 --- a/cmd/olliesrv/internal/session/session.go +++ b/cmd/olliesrv/internal/session/session.go @@ -119,15 +119,23 @@ func (s *Session) ToolsConn() *toolclient.ToolsrvConn { // Caller is responsible for closing the returned conn. func (s *Session) DialToolServer() *toolclient.ToolsrvConn { s.mu.RLock() + if s.paused { + s.mu.RUnlock() + return nil + } k := s.Keeper s.mu.RUnlock() if k == nil { + s.log.Debug("DialToolServer: no keeper") return nil } + s.log.Debug("DialToolServer: dialing keeper paused=%v", s.IsPaused()) conn, err := k.Dial() if err != nil { + s.log.Debug("DialToolServer: dial failed: %v", err) return nil } + s.log.Debug("DialToolServer: dial succeeded") return conn } @@ -351,24 +359,31 @@ func (s *Session) SetSessionID(newID string) error { // Pause stops the tool server to save resources. func (s *Session) Pause() error { + s.log.Debug("Pause: begin") s.mu.Lock() defer s.mu.Unlock() if s.paused { return fmt.Errorf("session already paused") } + s.paused = true + s.log.Debug("Pause: marked paused") if s.Cancel != nil { s.Cancel() } + s.log.Debug("Pause: context canceled") if s.Keeper != nil { + s.log.Debug("Pause: closing keeper") s.Keeper.Close() } else if s.Proc != nil { s.Proc.Close() } if s.toolsConn != nil { + s.log.Debug("Pause: closing tools connection") s.toolsConn.Close() s.toolsConn = nil } s.paused = true + s.log.Debug("Pause: complete") go s.saveSession() PublishEvent("session."+s.ID+".pause", "") return nil @@ -376,26 +391,31 @@ func (s *Session) Pause() error { // Resume restarts the tool server after a Pause. func (s *Session) Resume() error { + s.log.Debug("Resume: begin") s.mu.Lock() - defer s.mu.Unlock() if !s.paused { + s.mu.Unlock() return fmt.Errorf("session not paused") } ctx, cancel := context.WithCancel(serverCtx) s.Ctx = ctx s.Cancel = cancel + s.log.Debug("Resume: context created") // Ensure we always have a Keeper. If the session was restored from disk // without infra, spawn a new tool server now. if s.Keeper == nil { - cwd := "" - if len(s.agents) > 0 { - cwd = s.agents[0].Cwd() - } + s.log.Info("Resume: no keeper, starting toolsrv") + cwd := s.cwd if cwd == "" { cwd, _ = os.Getwd() } + if s.Remote != "" { + s.log.Info("Resume: spawning remote toolsrv target=%s cwd=%s", s.Remote, cwd) + } else { + s.log.Info("Resume: spawning local toolsrv cwd=%s", cwd) + } infra, err := SetupToolServer(ToolServerConfig{ Ctx: ctx, CWD: cwd, @@ -404,8 +424,12 @@ func (s *Session) Resume() error { Yolo: pkgYolo, }) if err != nil { + s.log.Error("Resume: toolsrv startup failed: %v", err) + cancel() + s.mu.Unlock() return fmt.Errorf("resume: %w", err) } + s.log.Info("Resume: toolsrv started") s.Proc = infra.Proc s.Keeper = infra.Keeper s.toolsConn = infra.ToolsConn @@ -415,12 +439,14 @@ func (s *Session) Resume() error { } } else { // Keeper exists — just re-dial. + s.log.Debug("Resume: dialing existing keeper") s.Keeper.SetContext(ctx) conn, err := s.Keeper.Dial() if err != nil { return fmt.Errorf("resume failed: %w", err) } s.toolsConn = conn + s.log.Debug("Resume: existing keeper dial succeeded") // Update agent connections with fresh dials for _, ag := range s.agents { agConn, err := s.Keeper.Dial() @@ -436,6 +462,13 @@ func (s *Session) Resume() error { } s.paused = false + s.mu.Unlock() + s.log.Debug("Resume: marked active") + + // Start bypass approval loop for the new session context. + if pkgBypassNotify != nil { + s.StartBypassLoop(pkgBypassNotify) + } // Rebuild full runtimes for restored agents (they have stub runtimes from persist). for _, ag := range s.agents { @@ -450,6 +483,7 @@ func (s *Session) Resume() error { } go s.saveSession() PublishEvent("session."+s.ID+".resume", "") + s.log.Debug("Resume: complete") return nil }