package toolbox import ( "fmt" "os" "path/filepath" "strings" toolutil "git.mlow.ca/mlow/lmcli/pkg/agent/toolbox/util" "git.mlow.ca/mlow/lmcli/pkg/api" ) const READ_DIR_DESCRIPTION = `Return the contents of the CWD (current working directory). Example result: { "message": "success", "result": [ {"name": "a_file.txt", "type": "file", "size": 123}, {"name": "a_directory/", "type": "dir", "size": 11}, ... ] } For files, size represents the size of the file, in bytes. For directories, size represents the number of entries in that directory.` var ReadDirTool = api.ToolSpec{ Name: "read_dir", Description: READ_DIR_DESCRIPTION, Parameters: []api.ToolParameter{ { Name: "relative_dir", Type: "string", Description: "If set, read the contents of a directory relative to the current one.", }, }, Impl: func(tool *api.ToolSpec, args map[string]interface{}) (string, error) { var relativeDir string tmp, ok := args["relative_dir"] if ok { relativeDir, ok = tmp.(string) if !ok { return "", fmt.Errorf("Invalid relative_dir in function arguments: %v", tmp) } } result := readDir(relativeDir) ret, err := result.ToJson() if err != nil { return "", fmt.Errorf("Could not serialize result: %v", err) } return ret, nil }, } func readDir(path string) api.CallResult { if path == "" { path = "." } ok, reason := toolutil.IsPathWithinCWD(path) if !ok { return api.CallResult{Message: reason} } files, err := os.ReadDir(path) if err != nil { return api.CallResult{ Message: err.Error(), } } var dirContents []map[string]interface{} for _, f := range files { info, _ := f.Info() name := f.Name() if strings.HasPrefix(name, ".") { // skip hidden files continue } entryType := "file" size := info.Size() if info.IsDir() { name += "/" entryType = "dir" subdirfiles, _ := os.ReadDir(filepath.Join(".", path, info.Name())) size = int64(len(subdirfiles)) } dirContents = append(dirContents, map[string]interface{}{ "name": name, "type": entryType, "size": size, }) } return api.CallResult{Result: dirContents} }