From dd2fa05f87bb7bc1720d9ce62359eb22d67a4cd4 Mon Sep 17 00:00:00 2001 From: Enmanuel Date: Wed, 8 Apr 2026 23:19:07 +0000 Subject: [PATCH] test: tests para buildToolRegistry con configs parciales Agrega 8 tests para buildToolRegistry() que verifican: - Config minima: solo tools always-on (current_time, get_weather, matrix_send) - HTTP habilitado/deshabilitado: http_get y http_post - FileOps read-only: registra read_file y list_directory pero NO write/append/delete - FileOps read-write: registra todas las 5 file tools - IMDb habilitado: imdb_search - SSH habilitado: ssh_command - Conteo total: 12 tools con todo habilitado (sin deps externas) Estos tests validan la logica condicional de registro que ahora vive en registry_build.go, separada del runtime principal. --- agents/registry_build_test.go | 173 ++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 agents/registry_build_test.go diff --git a/agents/registry_build_test.go b/agents/registry_build_test.go new file mode 100644 index 0000000..5a3c9a5 --- /dev/null +++ b/agents/registry_build_test.go @@ -0,0 +1,173 @@ +package agents + +import ( + "log/slog" + "os" + "testing" + + "github.com/enmanuel/agents/internal/config" + toolmemory "github.com/enmanuel/agents/tools/memorytools" +) + +func TestBuildToolRegistry_MinimalConfig(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + } + roomCtx := &toolmemory.RoomContext{} + + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + // Always-registered tools: current_time, weather, matrix_send + names := reg.Names() + if len(names) < 3 { + t.Fatalf("expected at least 3 always-on tools, got %d: %v", len(names), names) + } + assertToolRegistered(t, reg, "current_time") + assertToolRegistered(t, reg, "get_weather") + assertToolRegistered(t, reg, "matrix_send") +} + +func TestBuildToolRegistry_HTTPEnabled(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + Tools: config.ToolsCfg{ + HTTP: config.HTTPToolCfg{Enabled: true, AllowedDomains: []string{"example.com"}}, + }, + } + roomCtx := &toolmemory.RoomContext{} + + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + assertToolRegistered(t, reg, "http_get") + assertToolRegistered(t, reg, "http_post") +} + +func TestBuildToolRegistry_HTTPDisabled(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + } + roomCtx := &toolmemory.RoomContext{} + + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + assertToolNotRegistered(t, reg, "http_get") + assertToolNotRegistered(t, reg, "http_post") +} + +func TestBuildToolRegistry_FileOpsReadOnly(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + Tools: config.ToolsCfg{ + FileOps: config.FileOpsCfg{Enabled: true, ReadOnly: true, AllowedPaths: []string{"/tmp"}}, + }, + } + roomCtx := &toolmemory.RoomContext{} + + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + assertToolRegistered(t, reg, "read_file") + assertToolRegistered(t, reg, "list_directory") + assertToolNotRegistered(t, reg, "write_file") + assertToolNotRegistered(t, reg, "append_file") + assertToolNotRegistered(t, reg, "delete_file") +} + +func TestBuildToolRegistry_FileOpsReadWrite(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + Tools: config.ToolsCfg{ + FileOps: config.FileOpsCfg{Enabled: true, ReadOnly: false, AllowedPaths: []string{"/tmp"}}, + }, + } + roomCtx := &toolmemory.RoomContext{} + + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + assertToolRegistered(t, reg, "read_file") + assertToolRegistered(t, reg, "list_directory") + assertToolRegistered(t, reg, "write_file") + assertToolRegistered(t, reg, "append_file") + assertToolRegistered(t, reg, "delete_file") +} + +func TestBuildToolRegistry_IMDbEnabled(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + Tools: config.ToolsCfg{ + IMDb: config.IMDbToolCfg{Enabled: true}, + }, + } + roomCtx := &toolmemory.RoomContext{} + + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + assertToolRegistered(t, reg, "imdb_search") +} + +func TestBuildToolRegistry_SSHEnabled(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + Tools: config.ToolsCfg{ + SSH: config.SSHToolCfg{Enabled: true}, + }, + } + roomCtx := &toolmemory.RoomContext{} + + // SSH tool requires an executor; passing nil is fine for registration (only used at exec time) + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + assertToolRegistered(t, reg, "ssh_command") +} + +func TestBuildToolRegistry_ToolCount(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + + // Enable everything that doesn't need external deps + cfg := &config.AgentConfig{ + Agent: config.AgentMeta{ID: "test-agent"}, + Tools: config.ToolsCfg{ + HTTP: config.HTTPToolCfg{Enabled: true}, + SSH: config.SSHToolCfg{Enabled: true}, + FileOps: config.FileOpsCfg{Enabled: true, AllowedPaths: []string{"/tmp"}}, + IMDb: config.IMDbToolCfg{Enabled: true}, + }, + } + roomCtx := &toolmemory.RoomContext{} + + reg := buildToolRegistry(cfg, nil, nil, nil, nil, nil, nil, nil, nil, roomCtx, logger) + + // 3 always-on + 2 HTTP + 1 SSH + 5 file + 1 IMDb = 12 + expected := 12 + if got := reg.Len(); got != expected { + t.Errorf("expected %d tools, got %d: %v", expected, got, reg.Names()) + } +} + +// ── Test helpers ──────────────────────────────────────────────────────────── + +func assertToolRegistered(t *testing.T, reg interface{ Names() []string }, name string) { + t.Helper() + for _, n := range reg.Names() { + if n == name { + return + } + } + t.Errorf("expected tool %q to be registered, but it was not. Registered: %v", name, reg.Names()) +} + +func assertToolNotRegistered(t *testing.T, reg interface{ Names() []string }, name string) { + t.Helper() + for _, n := range reg.Names() { + if n == name { + t.Errorf("expected tool %q NOT to be registered, but it was", name) + return + } + } +}