package knowledgetools import ( "context" "fmt" "strings" "github.com/enmanuel/agents/pkg/knowledge" "github.com/enmanuel/agents/tools" ) // NewSharedKnowledgeTools creates all shared knowledge tools backed by the given store. // These tools provide access to the shared knowledge base accessible by all agents. func NewSharedKnowledgeTools(store KnowledgeStore) []tools.Tool { return []tools.Tool{ newSharedKnowledgeSearch(store), newSharedKnowledgeRead(store), newSharedKnowledgeWrite(store), newSharedKnowledgeList(store), } } // newSharedKnowledgeSearch creates a tool that searches the shared knowledge base. func newSharedKnowledgeSearch(store KnowledgeStore) tools.Tool { return tools.Tool{ Def: tools.Def{ Name: "shared_knowledge_search", Description: "Search the shared knowledge base accessible by all agents. Use this to find information other agents have recorded.", Parameters: []tools.Param{ {Name: "query", Type: "string", Description: "Search terms or phrase", Required: true}, {Name: "limit", Type: "integer", Description: "Max results (default 5)", Required: false}, }, }, Exec: func(ctx context.Context, args map[string]any) tools.Result { query := tools.GetString(args, "query") if query == "" { return tools.Result{Err: fmt.Errorf("shared_knowledge_search: query is required")} } limit := tools.GetInt(args, "limit") if limit <= 0 { limit = 5 } results, err := store.Search(ctx, query, limit) if err != nil { return tools.Result{Err: fmt.Errorf("shared_knowledge_search: %w", err)} } if len(results) == 0 { return tools.Result{Output: "no documents found in shared knowledge base matching your query"} } var sb strings.Builder for i, r := range results { fmt.Fprintf(&sb, "%d. **%s** (`%s`)\n %s\n", i+1, r.Title, r.Slug, r.Snippet) } return tools.Result{Output: sb.String()} }, } } // newSharedKnowledgeRead creates a tool that reads a shared knowledge document. func newSharedKnowledgeRead(store KnowledgeStore) tools.Tool { return tools.Tool{ Def: tools.Def{ Name: "shared_knowledge_read", Description: "Read the full content of a shared knowledge document by its slug. This document is accessible by all agents.", Parameters: []tools.Param{ {Name: "slug", Type: "string", Description: "Document slug (e.g. \"go-patterns\")", Required: true}, }, }, Exec: func(ctx context.Context, args map[string]any) tools.Result { slug := tools.GetString(args, "slug") if slug == "" { return tools.Result{Err: fmt.Errorf("shared_knowledge_read: slug is required")} } doc, err := store.Get(ctx, slug) if err != nil { return tools.Result{Err: fmt.Errorf("shared_knowledge_read: %w", err)} } return tools.Result{Output: doc.Content} }, } } // newSharedKnowledgeWrite creates a tool that writes a shared knowledge document. func newSharedKnowledgeWrite(store KnowledgeStore) tools.Tool { return tools.Tool{ Def: tools.Def{ Name: "shared_knowledge_write", Description: "Create or update a shared knowledge document accessible by all agents. Use this to share knowledge with other agents.", Parameters: []tools.Param{ {Name: "slug", Type: "string", Description: "Document slug (lowercase, hyphens, e.g. \"matrix-tips\")", Required: true}, {Name: "content", Type: "string", Description: "Full markdown content of the document", Required: true}, }, }, Exec: func(ctx context.Context, args map[string]any) tools.Result { slug := tools.GetString(args, "slug") content := tools.GetString(args, "content") if slug == "" || content == "" { return tools.Result{Err: fmt.Errorf("shared_knowledge_write: slug and content are required")} } err := store.Put(ctx, knowledge.Document{ Slug: slug, Content: content, }) if err != nil { return tools.Result{Err: fmt.Errorf("shared_knowledge_write: %w", err)} } return tools.Result{Output: fmt.Sprintf("shared document saved: %s (%d bytes)", slug, len(content))} }, } } // newSharedKnowledgeList creates a tool that lists all shared knowledge documents. func newSharedKnowledgeList(store KnowledgeStore) tools.Tool { return tools.Tool{ Def: tools.Def{ Name: "shared_knowledge_list", Description: "List all documents in the shared knowledge base accessible by all agents.", Parameters: []tools.Param{}, }, Exec: func(ctx context.Context, args map[string]any) tools.Result { docs, err := store.List(ctx) if err != nil { return tools.Result{Err: fmt.Errorf("shared_knowledge_list: %w", err)} } if len(docs) == 0 { return tools.Result{Output: "shared knowledge base is empty"} } var sb strings.Builder for _, d := range docs { fmt.Fprintf(&sb, "- `%s`: %s (updated %s)\n", d.Slug, d.Title, d.UpdatedAt.Format("2006-01-02")) } return tools.Result{Output: sb.String()} }, } }