import rawMetadata from '@/tools/generated/tool-metadata' import { resolveToolId } from '@/tools/tool-ids' import type { OAuthConfig, ToolConfig } from '@/tools/types' /** * Serializable tool metadata, read without importing the executable registry. * * `@/tools/registry` is a barrel over 4,300+ tools whose `ToolConfig`s carry * closures (`request.headers`, `transformResponse`, `directExecution`), and * those closures drag ~4,700 modules into any graph that reaches them. Callers * that only need to know a tool's shape — its params, its outputs, or whether it * exists — read it from here instead, and stay off the registry entirely. * * The backing data is generated by `scripts/sync-tool-metadata.ts` and verified * in CI by `bun run tool-metadata:check`. Never hand-edit it. * * Outputs live in `@/tools/metadata-outputs`, not here: they are the larger half * of the data and have a single consumer, so keeping them in a separate module * means callers that only need params don't pay for them. Callers that need * neither should use `@/tools/tool-ids`, which is ~40x smaller again. * * Lookups resolve unversioned names the same way `getTool` does. */ export interface ToolMetadata { id: string name?: string description?: string version?: string params: ToolConfig['params'] oauth?: OAuthConfig } /** * Annotated rather than inferred: letting TypeScript infer a literal type for a * 4 MB JSON import makes every downstream file that touches it dramatically more * expensive to typecheck. */ const metadata: Record = rawMetadata as Record /** * Serializable metadata for a built-in tool, or `undefined` if unknown. * * `Object.hasOwn` rather than a bare lookup: `JSON.parse` yields an object with * the normal prototype, so a tool id colliding with `constructor`, `toString` or * `__proto__` would otherwise return an inherited function typed as tool * metadata. */ export function getToolMetadata(toolId: string): ToolMetadata | undefined { const resolved = resolveToolId(toolId) return Object.hasOwn(metadata, resolved) ? metadata[resolved] : undefined } /** Declared parameters for a built-in tool, or `undefined` if unknown. */ export function getToolParams(toolId: string): ToolConfig['params'] | undefined { return getToolMetadata(toolId)?.params }