package io import ( "errors" "testing" "git.yeij.top/AskaEth/Cyrene_v2/internal/capability/registry" "git.yeij.top/AskaEth/Cyrene_v2/internal/config" "git.yeij.top/AskaEth/Cyrene_v2/pkg/plugins/sdk" ) func TestTools_ReturnsEveryTool(t *testing.T) { t.Parallel() set, err := New(&config.Config{DataDir: t.TempDir()}) if err != nil { t.Fatalf("New: %v", err) } if len(set) != 7 { t.Fatalf("expected 7 tools, got %d", len(set)) } want := []string{"file", "image-crop", "http", "web-search", "web-fetch", "knowledge", "document-read"} seen := map[string]bool{} for _, tool := range set { seen[tool.Name()] = true if tool.Description() == "" { t.Errorf("tool %q has an empty description", tool.Name()) } params, err := tool.Parameters() if err != nil { t.Errorf("tool %q Parameters error: %v", tool.Name(), err) } if params == nil { t.Errorf("tool %q has nil parameters", tool.Name()) } } for _, name := range want { if !seen[name] { t.Errorf("missing tool %q", name) } } } func TestNew_NilConfigErrors(t *testing.T) { t.Parallel() if _, err := New(nil); err == nil { t.Fatal("expected error for nil config") } } func TestRegister_RegistersEveryTool(t *testing.T) { t.Parallel() reg := registry.New() if err := Register(reg); err != nil { t.Fatalf("Register: %v", err) } for _, name := range []string{"file", "image-crop", "http", "web-search", "web-fetch", "knowledge", "document-read"} { c, err := reg.Get(name) if err != nil { t.Fatalf("Get(%q): %v", name, err) } if c.Kind != registry.KindTool { t.Errorf("kind of %q = %q, want tool", name, c.Kind) } } } func TestRegister_NilRegistrar(t *testing.T) { t.Parallel() if err := Register(nil); !errors.Is(err, sdk.ErrNilRegistrar) { t.Fatalf("expected sdk.ErrNilRegistrar, got %v", err) } } func TestRegister_DuplicateErrors(t *testing.T) { t.Parallel() reg := registry.New() if err := Register(reg); err != nil { t.Fatalf("first Register: %v", err) } if err := Register(reg); !errors.Is(err, registry.ErrDuplicate) { t.Fatalf("expected registry.ErrDuplicate, got %v", err) } } func TestTools_ConcurrentDescribe(t *testing.T) { t.Parallel() set, err := New(&config.Config{DataDir: t.TempDir()}) if err != nil { t.Fatalf("New: %v", err) } // Exercise the read-only contract concurrently to catch any shared-state // mutation (the dispatcher may call Parameters from many goroutines). for _, tool := range set { tool := tool t.Run(tool.Name(), func(t *testing.T) { t.Parallel() for i := 0; i < 10; i++ { if _, err := tool.Parameters(); err != nil { t.Fatalf("Parameters: %v", err) } if tool.Name() == "" || tool.Description() == "" { t.Fatalf("empty identity for %v", tool) } } }) } }