UNPKG

scai

Version:

> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** 100% local, private, GDPR-friendly, made in Denmark/EU with ❤️.

105 lines (96 loc) 3.75 kB
// File: src/modules/contextReviewStep.ts import { generate } from "../lib/generate.js"; import { logInputOutput } from "../utils/promptLogHelper.js"; export async function contextReviewStep(context) { if (!context.plan?.targetFiles || context.plan.targetFiles.length === 0) { throw new Error("[contextReviewStep] No targetFiles defined in plan."); } // ------------------------------ // Authoritative view: only target files // ------------------------------ const authoritativeFiles = (context.workingFiles ?? []) .filter(f => context.plan.targetFiles.includes(f.path)) .map((f) => ({ path: f.path, hasCode: Boolean(f.code), code: f.code ?? null, summary: f.summary ?? null, })); // ------------------------------ // Structural verification: only target files // ------------------------------ const structuralProof = context.analysis?.structure ? { fileCount: context.analysis.structure.files.filter(f => context.plan.targetFiles.includes(f.path)).length, files: context.analysis.structure.files .filter(f => context.plan.targetFiles.includes(f.path)) .map(f => ({ path: f.path, hasCode: Boolean(authoritativeFiles.find(af => af.path === f.path)?.code), })), } : null; // ------------------------------ // Include combined architecture analysis // ------------------------------ const combinedAnalysis = context.analysis?.combinedAnalysis ?? {}; const architectureSummary = combinedAnalysis.architectureSummary ?? ""; const hotspots = combinedAnalysis.hotspots ?? []; // ------------------------------ // Build prompt // ------------------------------ const prompt = ` You are a meta-reasoning agent responsible for determining whether the agent has sufficient information to proceed. IMPORTANT CONTRACT: - Any file listed below with a non-null "code" field MUST be treated as the complete and authoritative source code for that file. - Do NOT request file contents again if "code" is present. User intent: ${JSON.stringify(context.analysis?.intent ?? {}, null, 2)} Authoritative source files: ${JSON.stringify(authoritativeFiles, null, 2)} Structural verification: ${JSON.stringify(structuralProof, null, 2)} Combined architecture analysis: { "architectureSummary": ${JSON.stringify(architectureSummary, null, 2)} } Your task: 1. Determine whether the available information is sufficient to fulfill the user intent. 2. If NOT sufficient, explicitly list what is missing. 3. Output STRICT JSON with the following shape: { "decision": "loopAgain" | "stop", "reason": "string", "missing": string[] } Rules: - If the intent involves modifying, commenting, refactoring, or analyzing code, and at least one relevant file includes full source code, the context SHOULD be considered sufficient. - Do NOT request information that is already present in the authoritative files. `.trim(); // ------------------------------ // Call LLM // ------------------------------ const ai = await generate({ query: context.initContext?.userQuery ?? '', content: prompt, }); const text = typeof ai.data === "string" ? ai.data : JSON.stringify(ai.data); logInputOutput("contextReviewHelper", "output", text); // ------------------------------ // Parse JSON or fallback // ------------------------------ try { return JSON.parse(text); } catch { return { decision: text.toLowerCase().includes("loop") ? "loopAgain" : "stop", reason: text, missing: [], }; } }