package agents import ( "context" "embed" "encoding/json" "fmt" "io/fs" "strings" "g.fc.run/ai/byre/internal/mcp" ) //go:embed kb/*.md var kbFiles embed.FS var kb, kbIndex = loadKB() func loadKB() (map[string]string, string) { entries, err := fs.ReadDir(kbFiles, "kb") if err != nil { panic(err) } articles := map[string]string{} index := "" for _, e := range entries { b, err := kbFiles.ReadFile("kb/" + e.Name()) if err != nil { panic(err) } summary, body, _ := strings.Cut(string(b), "\n") topic := strings.TrimSuffix(e.Name(), ".md") articles[topic] = strings.TrimSpace(body) index += fmt.Sprintf("\n- %s: %s", topic, summary) } return articles, index } func (m *Manager) readKnowledgeTool() mcp.Tool { return mcp.Tool{ Name: "read_knowledge", Description: "Read an article from byre's knowledge base: how byre features work that agents need only now and then. " + "Read the matching article before working on or answering about one of these topics:" + kbIndex, InputSchema: json.RawMessage(`{ "type": "object", "properties": { "topic": {"type": "string", "description": "The article's topic, as listed."} }, "required": ["topic"] }`), Handler: func(ctx context.Context, raw json.RawMessage) (string, error) { args := struct { Topic string `json:"topic"` }{} err := json.Unmarshal(raw, &args) if err != nil { return "", fmt.Errorf("malformed read_knowledge call: %w", err) } body, ok := kb[args.Topic] if !ok { return "", fmt.Errorf("no article %q; the topics are:%s", args.Topic, kbIndex) } return body, nil }, } }