(toolName: string)
| 2503 | } |
| 2504 | |
| 2505 | async function getToolInfo(toolName: string): Promise<{ |
| 2506 | description: string |
| 2507 | params: Array<{ name: string; type: string; required: boolean; description: string }> |
| 2508 | outputs: Record<string, any> |
| 2509 | } | null> { |
| 2510 | try { |
| 2511 | const parts = toolName.split('_') |
| 2512 | |
| 2513 | let toolPrefix = '' |
| 2514 | let toolSuffix = '' |
| 2515 | |
| 2516 | for (let i = parts.length - 1; i >= 1; i--) { |
| 2517 | const possiblePrefix = parts.slice(0, i).join('_') |
| 2518 | const possibleSuffix = parts.slice(i).join('_') |
| 2519 | |
| 2520 | const toolDirPath = path.join(rootDir, `apps/sim/tools/${possiblePrefix}`) |
| 2521 | |
| 2522 | if (fs.existsSync(toolDirPath) && fs.statSync(toolDirPath).isDirectory()) { |
| 2523 | toolPrefix = possiblePrefix |
| 2524 | toolSuffix = possibleSuffix |
| 2525 | break |
| 2526 | } |
| 2527 | } |
| 2528 | |
| 2529 | if (!toolPrefix) { |
| 2530 | toolPrefix = parts[0] |
| 2531 | toolSuffix = parts.slice(1).join('_') |
| 2532 | } |
| 2533 | |
| 2534 | // Check if this is a versioned tool (e.g., _v2, _v3) |
| 2535 | const isVersionedTool = isVersionedType(toolSuffix) |
| 2536 | const strippedToolSuffix = stripVersionSuffix(toolSuffix) |
| 2537 | |
| 2538 | const possibleLocations: Array<{ path: string; priority: 'exact' | 'fallback' }> = [] |
| 2539 | |
| 2540 | // For versioned tools, prioritize the exact versioned file first |
| 2541 | // This handles cases like google_sheets where V2 is in a separate file (read_v2.ts) |
| 2542 | if (isVersionedTool) { |
| 2543 | // First priority: exact versioned file (e.g., read_v2.ts) |
| 2544 | possibleLocations.push({ |
| 2545 | path: path.join(rootDir, `apps/sim/tools/${toolPrefix}/${toolSuffix}.ts`), |
| 2546 | priority: 'exact', |
| 2547 | }) |
| 2548 | // Second priority: stripped file that contains both V1 and V2 (e.g., pr.ts for github) |
| 2549 | possibleLocations.push({ |
| 2550 | path: path.join(rootDir, `apps/sim/tools/${toolPrefix}/${strippedToolSuffix}.ts`), |
| 2551 | priority: 'fallback', |
| 2552 | }) |
| 2553 | } else { |
| 2554 | // Non-versioned tool: try the direct file |
| 2555 | possibleLocations.push({ |
| 2556 | path: path.join(rootDir, `apps/sim/tools/${toolPrefix}/${toolSuffix}.ts`), |
| 2557 | priority: 'exact', |
| 2558 | }) |
| 2559 | } |
| 2560 | |
| 2561 | // Also try camelCase versions |
| 2562 | const camelCaseSuffix = strippedToolSuffix |
no test coverage detected