From 785fe0996fee618810d87eaac04e4a71523699a5 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Fri, 14 Aug 2026 08:45:54 +0200 Subject: [PATCH] fix: rebuild full agent runtime on session resume Paused sessions restored agents with stub Runtime (nil Backend, nil Preamble). On resume, now rebuilds the complete runtime: loads config, builds preamble, creates backend, loads tools. Added Agent.SetRuntime for this path. --- cmd/olliesrv/internal/agent/agent.go | 5 +++++ cmd/olliesrv/internal/session/session.go | 27 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/cmd/olliesrv/internal/agent/agent.go b/cmd/olliesrv/internal/agent/agent.go index 61e5478..00c098e 100644 --- a/cmd/olliesrv/internal/agent/agent.go +++ b/cmd/olliesrv/internal/agent/agent.go @@ -634,6 +634,11 @@ func (ag *Agent) ToolServer() *toolsrv.Conn { return ag.runtime.ToolServer } +// SetRuntime replaces the agent's runtime (used on session resume). +func (ag *Agent) SetRuntime(rt *Runtime) { + ag.runtime = rt +} + // Queue pushes a prompt onto the agent's FIFO. func (ag *Agent) Queue(prompt string) { ag.fifo.Push(prompt) diff --git a/cmd/olliesrv/internal/session/session.go b/cmd/olliesrv/internal/session/session.go index 47ef5e9..410f4a6 100644 --- a/cmd/olliesrv/internal/session/session.go +++ b/cmd/olliesrv/internal/session/session.go @@ -10,6 +10,7 @@ import ( "time" "ollie/cmd/olliesrv/internal/agent" + "ollie/cmd/olliesrv/internal/backend" "ollie/cmd/olliesrv/internal/toolclient" olog "ollie/log" "ollie/paths" @@ -334,6 +335,32 @@ func (s *Session) Resume() error { } s.paused = false + + // Rebuild full runtimes for restored agents (they have stub runtimes from persist). + for _, ag := range s.agents { + cfg := agent.LoadConfig(pkgAgentsDir, ag.Profile(), os.Open) + layers := BuildPromptLayers(cfg, ag.Cwd(), s.ID, ag.ID(), "linux", false, "") + env := []string{"OLLIE_SESSION_ID=" + s.ID, "OLLIE_UNAME=" + ag.ID()} + rt := agent.BuildRuntime(cfg, ag.ToolServer(), ag.Cwd(), env, layers.SystemPrompt, layers.EnvBlock) + beName := "" + if cfg != nil { + beName = cfg.Backend + } + be, err := backend.NewWithName(beName) + if err != nil { + pkgLog.Error("resume agent %s: backend: %v", ag.ID(), err) + continue + } + if cfg != nil && cfg.Model != "" { + be.SetModel(cfg.Model) + } + rt.Backend = be + ag.SetRuntime(rt) + LoadAutoLoadTools(cfg, ag.ToolServer(), s.ID, ag.ID(), func(f string, a ...any) { + pkgLog.Error("resume agent %s: "+f, append([]any{ag.ID()}, a...)...) + }) + } + // Start feed consumers for restored agents (context now available). for _, ag := range s.agents { go agent.ConsumeFeed(ctx, ag)