// Tool handler for the review_code MCP tool. import { validateToolInput } from "./schemas.js"; import { checkContextBudget } from "../utils/context-budget.js"; import { buildReviewCodePrompt } from "../prompts/review-code.js"; /** * Handle the review_code MCP tool. * * Orchestration order: validate -> config -> budget -> prompt -> client -> response. * All external dependencies injected via deps. Internal utilities imported directly. * No throws escape — all paths return structured results. * * @param {unknown} input * Raw tool input per ARCHITECTURE.md §7 schema. * @param {{ * loadConfig: () => object, * createProvider: (config: object) => { send: (request: ProviderRequest, cfg: object) => Promise<{ content: string }> } * ProviderRequest = { prompt?: string, input?: object } * }} deps * Injected external dependencies. * @returns {Promise<{ ok: true, answer: string, warnings: string[] } | { ok: false, error: string, warnings: string[] }>} */ export async function handleReviewCode(input, deps) { // --- 1. Validate input (before anything else) --- const validation = validateToolInput(input); if (!validation.ok) { return { ok: false, error: validation.errors.join(" | "), warnings: [] }; } // --- 2. Load config --- let config; try { config = deps.loadConfig(); } catch (err) { return { ok: false, error: String(err), warnings: [] }; } // --- 3. Context budget check --- const budget = checkContextBudget(validation.data, config); if (!budget.ok) { return { ok: false, error: budget.error, warnings: budget.warnings }; } // --- 4. Build prompt --- const promptMessages = buildReviewCodePrompt(budget.input); // --- 5. Create chat provider --- let provider; try { provider = deps.createProvider(config); } catch (err) { return { ok: false, error: String(err), warnings: [] }; } // --- 5b. Package shared data for provider --- const reviewRequest = { prompt: promptMessages, input: budget.input }; // --- 6. Send via provider --- let aiResult; try { aiResult = await provider.send(reviewRequest, config); } catch (err) { return { ok: false, error: String(err), warnings: [] }; } // --- 7. Success --- return { ok: true, answer: aiResult.content, warnings: budget.warnings }; }