// Tool handler for the debug_issue MCP tool. import { validateToolInput } from "./schemas.js"; import { checkContextBudget } from "../utils/context-budget.js"; import { buildDebugIssuePrompt } from "../prompts/debug-issue.js"; /** * Handle the debug_issue 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, * createOpenAIClient: (config: object) => any, * sendOpenAIResponse: (client: any, params: object) => Promise * }} deps * Injected external dependencies. * @returns {Promise<{ ok: true, answer: string, warnings: string[] } | { ok: false, error: string, warnings: string[] }>} */ export async function handleDebugIssue(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 = buildDebugIssuePrompt(budget.input); // --- 5. Create OpenAI client --- let client; try { client = deps.createOpenAIClient(config); } catch (err) { return { ok: false, error: String(err), warnings: [] }; } // --- 6. Send to OpenAI --- let aiResult; try { aiResult = await deps.sendOpenAIResponse(client, { input: [{ role: "system", content: promptMessages }], model: config.openaiModel, temperature: config.temperature, maxOutputTokens: config.maxOutputTokens, }); } catch (err) { return { ok: false, error: String(err), warnings: [] }; } // --- 7. Success --- return { ok: true, answer: aiResult.content, warnings: budget.warnings }; }