UNPKG

scai

Version:

> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** > **100% local • No token cost • Private by design • GDPR-friendly** — made in Denmark/EU with ❤️.

100 lines (88 loc) 3.13 kB
// File: src/modules/contextReviewStep.ts import { generate } from "../lib/generate.js"; import { logInputOutput } from "../utils/promptLogHelper.js"; export async function contextReviewStep(context) { const analysis = context.analysis; if (!analysis) { throw new Error("[contextReviewStep] No analysis state available."); } const intent = analysis.intent ?? { intent: "", intentCategory: "", normalizedQuery: "", confidence: 0, }; const focus = analysis.focus ?? { relevantFiles: [], missingFiles: [], rationale: "", }; const fileAnalysis = analysis.fileAnalysis ?? {}; const planDecision = analysis.planSuggestion?.plan ? "planExists" : "needsPlan"; // ------------------------------ // Compress file-level analysis to high-signal summaries // ------------------------------ const summarizedFiles = Object.entries(fileAnalysis) .filter(([, fa]) => fa.intent === "relevant") .map(([filePath, fa]) => ({ file: filePath, role: fa.role ?? "unspecified", relevance: fa.relevance, proposedChangeScope: fa.proposedChanges?.scope ?? "none", })); // ------------------------------ // Build prompt using distilled conclusions only // ------------------------------ const prompt = ` You are a meta-reasoning agent. Your job is to determine whether enough relevant information has been collected to directly answer the user's intent, or whether more data must be gathered first. Decision meanings: - "executeOnQuery": The collected analysis and files are sufficient to answer the user's question. - "gatherData": The current analysis is insufficient; more files or analysis are required. User Intent: ${JSON.stringify(intent, null, 2)} Relevant Files (paths only): ${JSON.stringify(focus.relevantFiles, null, 2)} Missing Files: ${JSON.stringify(focus.missingFiles, null, 2)} Why these files were selected: ${focus.rationale ?? "No rationale provided."} Relevant File Summaries (high-signal only): ${JSON.stringify(summarizedFiles, null, 2)} Plan Suggestion Status: ${planDecision} Question: Based on the above, is there enough information to answer the user's question directly? Output STRICT JSON with shape: { "decision": "gatherData" | "executeOnQuery", "reason": "concise explanation", "missing": string[] } `.trim(); logInputOutput("contextReviewStep", "output", prompt); const ai = await generate({ query: context.initContext?.userQuery ?? "", content: prompt, }); const text = typeof ai.data === "string" ? ai.data : JSON.stringify(ai.data); logInputOutput("contextReviewStep", "output", text); // ------------------------------ // Parse JSON or fallback // ------------------------------ try { return JSON.parse(text); } catch { return { decision: text.toLowerCase().includes("gather") ? "gatherData" : "executeOnQuery", reason: text, missing: [], }; } }