feat: storage.base_path configurable para aislar datos de runtime

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/<id> > agents/<id>/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 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 19:49:02 +00:00
parent b4db953211
commit 536fa0bc54
2 changed files with 23 additions and 5 deletions
+19 -2
View File
@@ -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/<id> > agents/<id>/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/<id> > agents/<id>/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,
+4 -3
View File
@@ -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/<id> or agents/<id>/data
State StateStorageCfg `yaml:"state"`
Cache CacheStorageCfg `yaml:"cache"`
History HistoryStorageCfg `yaml:"history"`
}
type StateStorageCfg struct {