UNPKG

@agentforce/adk

Version:

AgentForce Agent Development Kit - A powerful framework for building AI agents and servers

181 lines (173 loc) 7.14 kB
import { readdirSync, statSync } from "fs"; import { join, isAbsolute, basename } from "path"; import type { ToolImplementation } from "../types"; /** * File system get file tree tool * Recursively generates a file tree from a given path in various output formats */ export const fs_get_file_tree: ToolImplementation = { definition: { type: "function", function: { name: "fs_get_file_tree", description: "Recursively generates a file tree from a given directory path in various output formats (array, json, yaml)", parameters: { type: "object", properties: { path: { type: "string", description: "The root directory to start from (must be absolute path)", }, output_format: { type: "string", description: "The output format for the file tree", enum: ["array", "json", "yaml"], }, excludes: { type: "array", description: "Directory names to exclude (e.g., ['node_modules', '.git'])", }, }, required: ["path", "output_format"], }, }, }, execute: async (args: Record<string, any>) => { const path = args.path; const outputFormat = args.output_format || "array"; const excludes = args.excludes || []; try { if (!isAbsolute(path)) { return { success: false, error: "The path must be absolute.", path: path, }; } if (!["array", "json", "yaml"].includes(outputFormat)) { return { success: false, error: "Invalid outputFormat. Use 'array', 'json', or 'yaml'.", output_format: outputFormat, }; } // Helper for array output const walkArray = (dir: string, arr: string[]) => { let stats; try { stats = statSync(dir); } catch { return; } if (stats.isDirectory()) { if (excludes.includes(basename(dir))) return; arr.push(dir); try { const entries = readdirSync(dir, { withFileTypes: true }); entries.sort((a, b) => { if (a.isDirectory() && !b.isDirectory()) return -1; if (!a.isDirectory() && b.isDirectory()) return 1; return a.name.localeCompare(b.name); }); for (const entry of entries) { walkArray(join(dir, entry.name), arr); } } catch { return; } } else if (stats.isFile()) { arr.push(dir); } }; // Helper for JSON tree const walkJson = (dir: string): any => { let stats; try { stats = statSync(dir); } catch { return null; } if (stats.isDirectory()) { if (excludes.includes(basename(dir))) return null; const children: any[] = []; try { const entries = readdirSync(dir, { withFileTypes: true }); entries.sort((a, b) => { if (a.isDirectory() && !b.isDirectory()) return -1; if (!a.isDirectory() && b.isDirectory()) return 1; return a.name.localeCompare(b.name); }); for (const entry of entries) { const child = walkJson(join(dir, entry.name)); if (child) children.push(child); } } catch { // On error, we will fall through and return the directory with empty children, which is fine. } return { name: basename(dir), path: dir, type: "directory", children }; } else if (stats.isFile()) { return { name: basename(dir), path: dir, type: "file" }; } return null; }; // Helper for YAML indentation list const walkYaml = (dir: string, indent: number, lines: string[]) => { let stats; try { stats = statSync(dir); } catch { return; } const prefix = " ".repeat(indent); if (stats.isDirectory()) { if (excludes.includes(basename(dir))) return; lines.push(`${prefix}${basename(dir)}/`); try { const entries = readdirSync(dir, { withFileTypes: true }); entries.sort((a, b) => { if (a.isDirectory() && !b.isDirectory()) return -1; if (!a.isDirectory() && b.isDirectory()) return 1; return a.name.localeCompare(b.name); }); for (const entry of entries) { walkYaml(join(dir, entry.name), indent + 1, lines); } } catch { return; } } else if (stats.isFile()) { lines.push(`${prefix}${basename(dir)}`); } }; let result; if (outputFormat === "array") { const arr: string[] = []; walkArray(path, arr); result = arr; } else if (outputFormat === "json") { result = walkJson(path); } else if (outputFormat === "yaml") { const lines: string[] = []; walkYaml(path, 0, lines); result = lines.join("\n"); } else { result = []; } return { success: true, path: path, output_format: outputFormat, excludes: excludes, result: result, count: Array.isArray(result) ? result.length : (typeof result === "string" ? result.split("\n").length : 1), }; } catch (error: any) { return { success: false, error: error.message, path: path, output_format: outputFormat, }; } }, };