package knowledgetools import ( "context" "testing" "github.com/enmanuel/agents/pkg/knowledge" ) func TestNewSharedKnowledgeTools(t *testing.T) { store := newMockKnowledgeStore() tools := NewSharedKnowledgeTools(store) if len(tools) != 4 { t.Errorf("expected 4 tools, got %d", len(tools)) } names := make(map[string]bool) for _, tool := range tools { names[tool.Def.Name] = true } expected := []string{ "shared_knowledge_search", "shared_knowledge_read", "shared_knowledge_write", "shared_knowledge_list", } for _, name := range expected { if !names[name] { t.Errorf("expected tool %q not found", name) } } } func TestSharedKnowledgeSearchTool(t *testing.T) { store := newMockKnowledgeStore() store.docs["shared-doc"] = knowledge.Document{ Slug: "shared-doc", Title: "Shared Doc", Content: "This is shared knowledge", } tools := NewSharedKnowledgeTools(store) tool := tools[0] // shared_knowledge_search is first // Missing query r := tool.Exec(context.Background(), map[string]any{}) if r.Err == nil { t.Error("expected error for missing query") } // Valid search r = tool.Exec(context.Background(), map[string]any{"query": "shared"}) if r.Err != nil { t.Errorf("unexpected error: %v", r.Err) } if r.Output == "" { t.Error("expected non-empty output") } // Empty results store2 := newMockKnowledgeStore() tools2 := NewSharedKnowledgeTools(store2) r = tools2[0].Exec(context.Background(), map[string]any{"query": "nothing"}) if r.Err != nil { t.Errorf("unexpected error: %v", r.Err) } if r.Output != "no documents found in shared knowledge base matching your query" { t.Errorf("expected empty message, got %q", r.Output) } } func TestSharedKnowledgeReadTool(t *testing.T) { store := newMockKnowledgeStore() store.docs["shared-doc"] = knowledge.Document{ Slug: "shared-doc", Title: "Shared", Content: "Shared content", } tools := NewSharedKnowledgeTools(store) tool := tools[1] // shared_knowledge_read is second // Missing slug r := tool.Exec(context.Background(), map[string]any{}) if r.Err == nil { t.Error("expected error for missing slug") } // Valid read r = tool.Exec(context.Background(), map[string]any{"slug": "shared-doc"}) if r.Err != nil { t.Errorf("unexpected error: %v", r.Err) } if r.Output != "Shared content" { t.Errorf("output = %q, want %q", r.Output, "Shared content") } // Not found r = tool.Exec(context.Background(), map[string]any{"slug": "nope"}) if r.Err == nil { t.Error("expected error for nonexistent doc") } } func TestSharedKnowledgeWriteTool(t *testing.T) { store := newMockKnowledgeStore() tools := NewSharedKnowledgeTools(store) tool := tools[2] // shared_knowledge_write is third // Missing params r := tool.Exec(context.Background(), map[string]any{"slug": "test"}) if r.Err == nil { t.Error("expected error for missing content") } // Valid write r = tool.Exec(context.Background(), map[string]any{ "slug": "shared-doc", "content": "# Shared Doc\nShared by agent A", }) if r.Err != nil { t.Errorf("unexpected error: %v", r.Err) } if _, ok := store.docs["shared-doc"]; !ok { t.Error("document was not stored") } // Verify the output message mentions "shared" if r.Output != "shared document saved: shared-doc (30 bytes)" { t.Errorf("output = %q, want mention of shared", r.Output) } } func TestSharedKnowledgeListTool(t *testing.T) { store := newMockKnowledgeStore() tools := NewSharedKnowledgeTools(store) tool := tools[3] // shared_knowledge_list is fourth // Empty r := tool.Exec(context.Background(), map[string]any{}) if r.Err != nil { t.Errorf("unexpected error: %v", r.Err) } if r.Output != "shared knowledge base is empty" { t.Errorf("expected empty message, got %q", r.Output) } // With docs store.docs["shared-doc1"] = knowledge.Document{Slug: "shared-doc1", Title: "Shared 1"} r = tool.Exec(context.Background(), map[string]any{}) if r.Err != nil { t.Errorf("unexpected error: %v", r.Err) } if r.Output == "shared knowledge base is empty" { t.Error("expected non-empty output after adding docs") } } // TestSharedAndPrivateCoexist verifies that shared and private tools can coexist // with different stores and don't interfere with each other. func TestSharedAndPrivateCoexist(t *testing.T) { privateStore := newMockKnowledgeStore() sharedStore := newMockKnowledgeStore() // Write to private store privateStore.docs["private-doc"] = knowledge.Document{ Slug: "private-doc", Title: "Private", Content: "Private content", } // Write to shared store sharedStore.docs["shared-doc"] = knowledge.Document{ Slug: "shared-doc", Title: "Shared", Content: "Shared content", } // Verify private has only private doc privateDocs, _ := privateStore.List(context.Background()) if len(privateDocs) != 1 || privateDocs[0].Slug != "private-doc" { t.Error("private store should only have private doc") } // Verify shared has only shared doc sharedDocs, _ := sharedStore.List(context.Background()) if len(sharedDocs) != 1 || sharedDocs[0].Slug != "shared-doc" { t.Error("shared store should only have shared doc") } // Verify tools from different stores don't mix data privateTool := NewKnowledgeRead(privateStore) sharedTools := NewSharedKnowledgeTools(sharedStore) sharedTool := sharedTools[1] // shared_knowledge_read // Private tool can't read shared doc r := privateTool.Exec(context.Background(), map[string]any{"slug": "shared-doc"}) if r.Err == nil { t.Error("private tool should not be able to read shared doc") } // Shared tool can't read private doc r = sharedTool.Exec(context.Background(), map[string]any{"slug": "private-doc"}) if r.Err == nil { t.Error("shared tool should not be able to read private doc") } }