Files
goclaw/cmd/gateway_redis.go
T
viettranx 6595c0185a refactor: merge file writers into config permissions + agent hard delete
Migration 000023:
- Migrate group_file_writers data into agent_config_permissions (config_type='file_writer')
- Add FK CASCADE/SET NULL on 16 tables for agent hard delete
- Clean up soft-deleted zombie agents
- ALTER scope VARCHAR(100) → VARCHAR(255)
- Partial unique index on agent_key (allows reuse after delete)

Store layer:
- Remove GroupWriterCache, GroupFileWriterData, 5 AgentStore methods
- Add CheckFileWriterPermission (fail-open), ListFileWriters (cached)
- Add scope filter to ConfigPermissionStore.List()

Tools: Replace GroupWriterCache with ConfigPermissionStore in read_file,
write_file, edit, cron, context_file_interceptor

Agent loop: buildGroupWriterPrompt uses ListFileWriters + metadata parsing

Channels: Telegram commands rewritten to use configPermStore.Grant/Revoke/List
HTTP API: Writer endpoints rewired to configPermStore (same response shapes)

Hard delete: agents.go DELETE FROM instead of soft delete
2026-03-19 13:35:57 +07:00

54 lines
1.6 KiB
Go

//go:build redis
package cmd
import (
"log/slog"
"github.com/redis/go-redis/v9"
"github.com/nextlevelbuilder/goclaw/internal/cache"
"github.com/nextlevelbuilder/goclaw/internal/config"
"github.com/nextlevelbuilder/goclaw/internal/store"
)
// initRedisClient creates a Redis client when built with -tags redis.
// Returns nil (typed as any) if GOCLAW_REDIS_DSN is empty or connection fails.
func initRedisClient(cfg *config.Config) any {
dsn := cfg.Database.RedisDSN
if dsn == "" {
slog.Debug("Redis available but not configured (set GOCLAW_REDIS_DSN)")
return nil
}
client, err := cache.NewRedisClient(dsn)
if err != nil {
slog.Warn("Redis connection failed, falling back to in-memory cache", "error", err)
return nil
}
slog.Info("Redis cache connected")
return client
}
// makeCaches creates typed cache instances backed by Redis (or in-memory if client is nil).
func makeCaches(raw any) (
agentCtxCache cache.Cache[[]store.AgentContextFileData],
userCtxCache cache.Cache[[]store.AgentContextFileData],
) {
client, _ := raw.(*redis.Client)
if client == nil {
slog.Info("cache backend: in-memory (Redis not connected)")
return cache.NewInMemoryCache[[]store.AgentContextFileData](),
cache.NewInMemoryCache[[]store.AgentContextFileData]()
}
slog.Info("cache backend: redis")
return cache.NewRedisCache[[]store.AgentContextFileData](client, "ctx:agent"),
cache.NewRedisCache[[]store.AgentContextFileData](client, "ctx:user")
}
// shutdownRedis closes the Redis client connection.
func shutdownRedis(raw any) {
if client, ok := raw.(*redis.Client); ok && client != nil {
client.Close()
}
}