From d9e8278028664c15a0859aa95af54b755dd584dd Mon Sep 17 00:00:00 2001 From: xiaoen <2768753269@qq.com> Date: Fri, 6 Mar 2026 12:49:41 +0800 Subject: [PATCH] feat(agent): wire JSONL session store into agent loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the concrete *SessionManager field with the SessionStore interface and initialize the JSONL backend by default. Legacy .json session files are auto-migrated on first startup. Falls back to SessionManager if the JSONL store cannot be initialized. The agent loop code (loop.go) requires zero changes — all method calls work identically through the interface. Closes #1169 --- pkg/agent/instance.go | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/pkg/agent/instance.go b/pkg/agent/instance.go index 599ea57fc..8ccd69de2 100644 --- a/pkg/agent/instance.go +++ b/pkg/agent/instance.go @@ -1,6 +1,7 @@ package agent import ( + "context" "fmt" "log" "os" @@ -9,6 +10,7 @@ import ( "strings" "github.com/sipeed/picoclaw/pkg/config" + "github.com/sipeed/picoclaw/pkg/memory" "github.com/sipeed/picoclaw/pkg/providers" "github.com/sipeed/picoclaw/pkg/routing" "github.com/sipeed/picoclaw/pkg/session" @@ -31,7 +33,7 @@ type AgentInstance struct { SummarizeMessageThreshold int SummarizeTokenPercent int Provider providers.LLMProvider - Sessions *session.SessionManager + Sessions session.SessionStore ContextBuilder *ContextBuilder Tools *tools.ToolRegistry Subagents *config.SubagentsConfig @@ -86,7 +88,7 @@ func NewAgentInstance( } sessionsDir := filepath.Join(workspace, "sessions") - sessionsManager := session.NewSessionManager(sessionsDir) + sessions := initSessionStore(sessionsDir) contextBuilder := NewContextBuilder(workspace) @@ -194,7 +196,7 @@ func NewAgentInstance( SummarizeMessageThreshold: summarizeMessageThreshold, SummarizeTokenPercent: summarizeTokenPercent, Provider: provider, - Sessions: sessionsManager, + Sessions: sessions, ContextBuilder: contextBuilder, Tools: toolsRegistry, Subagents: subagents, @@ -246,6 +248,25 @@ func compilePatterns(patterns []string) []*regexp.Regexp { return compiled } +// initSessionStore creates the session persistence backend. +// It uses the JSONL store by default and auto-migrates legacy JSON sessions. +// Falls back to SessionManager if the JSONL store cannot be initialized. +func initSessionStore(dir string) session.SessionStore { + store, err := memory.NewJSONLStore(dir) + if err != nil { + log.Printf("memory: init store: %v; using json sessions", err) + return session.NewSessionManager(dir) + } + + if n, merr := memory.MigrateFromJSON(context.Background(), dir, store); merr != nil { + log.Printf("memory: migration: %v", merr) + } else if n > 0 { + log.Printf("memory: migrated %d session(s) to jsonl", n) + } + + return session.NewJSONLBackend(store) +} + func expandHome(path string) string { if path == "" { return path