feat(agent): wire memory config, factory, and session migration into loop

Agent loop now respects Memory.Enabled toggle, uses NewFromConfig factory
for delegate construction, reads OffloadThresholdTokens from config, and
runs one-time file session migration on startup.
This commit is contained in:
ZanzyTHEbar 2026-02-18 13:06:10 +00:00
parent 5e0319f54b
commit b6ed552089

View file

@ -24,6 +24,7 @@ import (
"github.com/sipeed/picoclaw/pkg/constants" "github.com/sipeed/picoclaw/pkg/constants"
picofantasy "github.com/sipeed/picoclaw/pkg/fantasy" picofantasy "github.com/sipeed/picoclaw/pkg/fantasy"
"github.com/sipeed/picoclaw/pkg/logger" "github.com/sipeed/picoclaw/pkg/logger"
"github.com/sipeed/picoclaw/pkg/memory"
"github.com/sipeed/picoclaw/pkg/memory/delegate" "github.com/sipeed/picoclaw/pkg/memory/delegate"
memstore "github.com/sipeed/picoclaw/pkg/memory/store" memstore "github.com/sipeed/picoclaw/pkg/memory/store"
"github.com/sipeed/picoclaw/pkg/messages" "github.com/sipeed/picoclaw/pkg/messages"
@ -148,33 +149,52 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, model fantasy.Lang
// Initialize 3-tier MemGPT memory system // Initialize 3-tier MemGPT memory system
var ms *memstore.MemoryStore var ms *memstore.MemoryStore
memDBPath := filepath.Join(workspace, "memory", "picoclaw.db") if cfg.Memory.Enabled {
os.MkdirAll(filepath.Dir(memDBPath), 0755) memDBPath := filepath.Join(workspace, "memory", "picoclaw.db")
os.MkdirAll(filepath.Dir(memDBPath), 0755)
del, err := delegate.NewLibSQLDelegate(memDBPath) del, err := delegate.NewFromConfig(cfg.Memory, memDBPath)
if err != nil { if err != nil {
logger.WarnCF("agent", "Failed to create memory delegate, memory system disabled", logger.WarnCF("agent", "Failed to create memory delegate, memory system disabled",
map[string]interface{}{"error": err.Error()})
} else {
if err := del.Init(context.Background()); err != nil {
logger.WarnCF("agent", "Failed to init memory schema, memory system disabled",
map[string]interface{}{"error": err.Error()}) map[string]interface{}{"error": err.Error()})
del.Close()
} else { } else {
chunker := memstore.NewMarkdownChunker(memstore.DefaultMarkdownChunkerConfig()) if err := del.Init(context.Background()); err != nil {
ms = memstore.New(del, chunker, nil, memstore.Config{ logger.WarnCF("agent", "Failed to init memory schema, memory system disabled",
ContextWindowTokens: cfg.Agents.Defaults.MaxTokens, map[string]interface{}{"error": err.Error()})
OffloadThresholdTokens: 4000, del.Close()
}) } else {
contextBuilder.SetMemoryStore(ms) offloadThreshold := cfg.Memory.OffloadThresholdTokens
if offloadThreshold <= 0 {
offloadThreshold = 4000
}
chunker := memstore.NewMarkdownChunker(memstore.DefaultMarkdownChunkerConfig())
// Register the memory tool // Create embedding provider from config (nil = FTS5-only search)
memTool := NewMemGPTTool(ms, "picoclaw", "default") embedder, embErr := memstore.NewEmbedderFromConfig(cfg.Memory.Embedding, cfg.Providers)
toolsRegistry.Register(memTool) if embErr != nil {
logger.WarnCF("agent", "Failed to create embedding provider, archival search will use FTS5 only",
map[string]interface{}{"error": embErr.Error()})
}
logger.InfoCF("agent", "3-tier memory system initialized", ms = memstore.New(del, chunker, embedder, memstore.Config{
map[string]interface{}{"db_path": memDBPath}) ContextWindowTokens: cfg.Agents.Defaults.MaxTokens,
OffloadThresholdTokens: offloadThreshold,
})
contextBuilder.SetMemoryStore(ms)
memTool := NewMemGPTTool(ms, "picoclaw", "default")
toolsRegistry.Register(memTool)
// One-time migration of file-based sessions into recall memory
sessionsDir := filepath.Join(workspace, "sessions")
if _, migErr := memory.MigrateFileSessions(context.Background(), del, "picoclaw", sessionsDir); migErr != nil {
logger.WarnCF("agent", "Session migration failed (non-fatal)",
map[string]interface{}{"error": migErr.Error()})
}
}
} }
} else {
logger.InfoCF("agent", "Memory system disabled by config", nil)
} }
// Register meta-tools for progressive disclosure (tool_search + tool_call) // Register meta-tools for progressive disclosure (tool_search + tool_call)