UNPKG

@iqai/adk-cli

Version:

CLI tool for creating, running, and testing ADK-TS agents

159 lines 7.55 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AgentScanner = exports.DIRECTORIES_TO_SKIP = void 0; const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const common_1 = require("@nestjs/common"); const find_project_root_1 = require("../../common/find-project-root"); exports.DIRECTORIES_TO_SKIP = [ "node_modules", ".adk-cache", ".git", ".next", "dist", "build", ".turbo", "coverage", ".vscode", ".idea", ]; const AGENT_FILENAMES = ["agent.ts", "agent.js"]; let AgentScanner = class AgentScanner { quiet; logger; constructor(quiet = false) { this.quiet = quiet; this.logger = new common_1.Logger("agent-scanner"); } /** * Find the project root by traversing up from the given directory * looking for package.json, tsconfig.json, or .env files */ findProjectRoot(startDir) { return (0, find_project_root_1.findProjectRoot)(startDir); } scanAgents(agentsDir, loadedAgents) { const agents = new Map(); // Use current directory if agentsDir doesn't exist or is empty const scanDir = !agentsDir || !(0, node_fs_1.existsSync)(agentsDir) ? process.cwd() : (0, node_path_1.normalize)((0, node_path_1.resolve)(agentsDir)); // Find the actual project root (where tsconfig.json, package.json live) const projectRoot = this.findProjectRoot(scanDir); if (!this.quiet) { this.logger.log(`Scan directory: ${scanDir}`); this.logger.log(`Project root: ${projectRoot}`); } const shouldSkipDirectory = (dirName) => { return exports.DIRECTORIES_TO_SKIP.includes(dirName); }; const scanDirectory = (dir) => { try { const items = (0, node_fs_1.readdirSync)(dir); for (const item of items) { const fullPath = (0, node_path_1.normalize)((0, node_path_1.join)(dir, item)); const stat = (0, node_fs_1.statSync)(fullPath); if (stat.isDirectory()) { // Skip common build/dependency directories if (!shouldSkipDirectory(item)) { scanDirectory(fullPath); } } else if (AGENT_FILENAMES.includes(item)) { // Calculate relative path from PROJECT ROOT to agent directory // Normalize to use forward slashes for consistency across platforms let relativePath = (0, node_path_1.relative)(projectRoot, dir).replace(/\\/g, "/"); // Handle case where agent is directly in the project root if (!relativePath || relativePath === ".") { const rootDirName = projectRoot.split(/[\\/]/).pop() || "root"; relativePath = rootDirName; } // Remove any leading "./" from the path relativePath = relativePath.replace(/^\.\//, ""); // Try to get the actual agent name if it's already loaded const loadedAgent = loadedAgents.get(relativePath); let agentName = relativePath.split(/[/\\]/).pop() || "unknown"; if (loadedAgent?.agent?.name) { agentName = loadedAgent.agent.name; } else { // Try to quickly extract name from agent file if not loaded try { const agentFilePath = (0, node_path_1.normalize)((0, node_path_1.join)(dir, item)); agentName = this.extractAgentNameFromFile(agentFilePath) || agentName; } catch (error) { if (!this.quiet) { this.logger.warn(`Failed to extract agent name from ${(0, node_path_1.join)(dir, item)}: ${error instanceof Error ? error.message : String(error)}`); } } } // Store the agent with consistent keys if (relativePath) { agents.set(relativePath, { relativePath, name: agentName, absolutePath: (0, node_path_1.normalize)((0, node_path_1.resolve)(dir)), projectRoot, instance: loadedAgent?.agent, }); if (!this.quiet) { this.logger.log(`Found agent: ${relativePath} -> ${dir}`); } } else { this.logger.warn(`Skipping agent with invalid relativePath at ${dir}`); } } } } catch (error) { this.logger.warn(`Error reading directory ${dir}: ${error instanceof Error ? error.message : String(error)}`); } }; if (!this.quiet) { this.logger.log("Starting agent scan..."); } scanDirectory(scanDir); this.logger.log(`Agent scan complete. Found ${agents.size} agents.`); if (!this.quiet && agents.size > 0) { this.logger.log("Found agents:"); for (const [key, agent] of agents.entries()) { this.logger.log(` ${key} -> ${agent.absolutePath}`); } } return agents; } extractAgentNameFromFile(filePath) { try { const content = (0, node_fs_1.readFileSync)(filePath, "utf-8"); // Look for agent name in export statements // Match patterns like: name: "agent_name" or name:"agent_name" const nameMatch = content.match(/name\s*:\s*["']([^"']+)["']/); if (nameMatch?.[1]) { return nameMatch[1]; } return null; } catch (_error) { // Return null instead of throwing to allow fallback to directory name return null; } } }; exports.AgentScanner = AgentScanner; exports.AgentScanner = AgentScanner = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", [Object]) ], AgentScanner); //# sourceMappingURL=agent-scanner.service.js.map