From 9a1e645c9fb2e390a266d37a0302ea43603b3dd7 Mon Sep 17 00:00:00 2001 From: alejandro-angulo Date: Tue, 3 Jun 2025 22:26:05 -0700 Subject: [PATCH] Add list files tool --- main.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index f01db02..522ae16 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" "os" + "path/filepath" + "strings" "github.com/anthropics/anthropic-sdk-go" "github.com/invopop/jsonschema" @@ -21,7 +23,7 @@ func main() { } return scanner.Text(), true } - tools := []ToolDefinition{ReadFileDefinition} + tools := []ToolDefinition{ReadFileDefinition, ListFilesDefinition} agent := NewAgent(&client, getUserMessage, tools) err := agent.Run(context.TODO()) @@ -179,3 +181,67 @@ func GenerateSchema[T any]() anthropic.ToolInputSchemaParam { Properties: schema.Properties, } } + +var ListFilesDefinition = ToolDefinition{ + Name: "list_files", + Description: "List files and directories at a given path. If no path is provided, lists files in the current directory.", + InputSchema: ListFilesInputSchema, + Function: ListFiles, +} + +type ListFilesInput struct { + Path string `json:"path,omitempty" jsonschema_description:"Optional relative path to list files from. Defaults to current directory if not provided."` +} + +var ListFilesInputSchema = GenerateSchema[ListFilesInput]() + +func ListFiles(input json.RawMessage) (string, error) { + listFilesInput := ListFilesInput{} + err := json.Unmarshal(input, &listFilesInput) + if err != nil { + panic(err) + } + + dir := "." + if listFilesInput.Path != "" { + dir = listFilesInput.Path + } + + var files []string + err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + // Ignore devenv folder because it blows up the list of files (too many + // tokens) + if strings.Contains(path, ".devenv") { + return nil + } + + relPath, err := filepath.Rel(dir, path) + if err != nil { + return err + } + + if relPath != "." { + if info.IsDir() { + files = append(files, relPath+"/") + } else { + files = append(files, relPath) + } + } + return nil + }) + + if err != nil { + return "", err + } + + result, err := json.Marshal(files) + if err != nil { + return "", err + } + + return string(result), nil +}