From 536fa0bc542f0a68b1a833d254a8512fbe33581a Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Sat, 7 Mar 2026 19:49:02 +0000 Subject: [PATCH] feat: storage.base_path configurable para aislar datos de runtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Añade BasePath a StorageCfg y resolveDataBase() en runtime.go para centralizar la resolucion del directorio base de datos del agente. Prioridad: config storage.base_path > $AGENTS_DATA_DIR/ > agents//data Esto permite mover los datos de runtime fuera del arbol del proyecto, evitando que herramientas de desarrollo lean bases de datos, logs o crypto stores por accidente. Los paths de memory.db y knowledge.db ahora usan el base resuelto. Los configs existentes no se rompen (fallback al path original). Tareas 1.1 y 1.2 del issue 0019. Co-Authored-By: Claude Opus 4.6 --- agents/runtime.go | 21 +++++++++++++++++++-- internal/config/schema.go | 7 ++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/agents/runtime.go b/agents/runtime.go index e8f7a75..4739e7f 100644 --- a/agents/runtime.go +++ b/agents/runtime.go @@ -175,6 +175,11 @@ func New(cfg *config.AgentConfig, rules []decision.Rule, logger *slog.Logger) (* // Effects runner runner := effects.NewRunner(matrixClient, sshExec, logger) + // Resolve base data path for this agent. + // Priority: config storage.base_path > $AGENTS_DATA_DIR/ > agents//data + dataBase := resolveDataBase(cfg) + logger.Debug("data base path", "path", dataBase) + // Memory subsystem var memStore memory.Store windowSize := defaultWindowSize @@ -188,7 +193,7 @@ func New(cfg *config.AgentConfig, rules []decision.Rule, logger *slog.Logger) (* dbPath := cfg.Memory.DBPath if dbPath == "" { - dbPath = filepath.Join("agents", cfg.Agent.ID, "data", "memory.db") + dbPath = filepath.Join(dataBase, "memory.db") } store, err := shellmem.New(dbPath, logger) if err != nil { @@ -205,7 +210,7 @@ func New(cfg *config.AgentConfig, rules []decision.Rule, logger *slog.Logger) (* if knowledgeDir == "" { knowledgeDir = filepath.Join("agents", cfg.Agent.ID, "knowledge") } - knowledgeDBPath := filepath.Join("agents", cfg.Agent.ID, "data", "knowledge.db") + knowledgeDBPath := filepath.Join(dataBase, "knowledge.db") var kErr error kStore, kErr = shellknowledge.New(knowledgeDir, knowledgeDBPath, logger) if kErr != nil { @@ -902,6 +907,18 @@ func (a *Agent) sanitizeInput(content, roomID, senderID string) (string, bool) { return result.Output, result.Rejected } +// resolveDataBase returns the base directory for agent runtime data. +// Priority: config storage.base_path > $AGENTS_DATA_DIR/ > agents//data +func resolveDataBase(cfg *config.AgentConfig) string { + if cfg.Storage.BasePath != "" { + return cfg.Storage.BasePath + } + if envDir := os.Getenv("AGENTS_DATA_DIR"); envDir != "" { + return filepath.Join(envDir, cfg.Agent.ID) + } + return filepath.Join("agents", cfg.Agent.ID, "data") +} + // buildToolRegistry creates a Registry with tools enabled in the agent's config. func buildToolRegistry( cfg *config.AgentConfig, diff --git a/internal/config/schema.go b/internal/config/schema.go index 37876c8..cd05d9f 100644 --- a/internal/config/schema.go +++ b/internal/config/schema.go @@ -413,9 +413,10 @@ type QueueCfg struct { // ── Storage ─────────────────────────────────────────────────────────────── type StorageCfg struct { - State StateStorageCfg `yaml:"state"` - Cache CacheStorageCfg `yaml:"cache"` - History HistoryStorageCfg `yaml:"history"` + BasePath string `yaml:"base_path"` // root for all data; default $AGENTS_DATA_DIR/ or agents//data + State StateStorageCfg `yaml:"state"` + Cache CacheStorageCfg `yaml:"cache"` + History HistoryStorageCfg `yaml:"history"` } type StateStorageCfg struct {