UNPKG

@autobe/agent

Version:

AI backend server code generator

132 lines (111 loc) 4.15 kB
import { AutoBePhase } from "@autobe/interface"; import { StringUtil } from "@autobe/utils"; import { AutoBeState } from "../context/AutoBeState"; /** * Validates pipeline state before executing a phase, returning user-friendly * error message if prerequisites are missing or outdated. * * Enforces the waterfall dependency structure: each phase requires all previous * phases to be completed with matching step counters. When requirements change * (analyze step increments), downstream phases become invalid through step * mismatch, and this function generates clear messages guiding users to * regenerate affected phases. * * This is the gatekeeper preventing users from executing phases out of order or * with stale dependencies, ensuring generated artifacts always reflect current * requirements. Without this validation, users could generate API * implementations based on outdated database schemas, causing subtle bugs. * * @param state Current pipeline state * @param future Phase attempting to execute * @returns Error message if validation fails, null if valid to proceed */ export const predicateStateMessage = ( state: AutoBeState, future: AutoBePhase, ): string | null => { if (future === "analyze") return null; if (future === "database") return predicateDatabase(state); const futureIndex: number = STEP_ORDER.indexOf(future); for (const key of STEP_ORDER.slice(0, futureIndex)) if (state[key] === null) return buildMissingStepsMessage(future, key); const prevStepName: AutoBePhase = STEP_ORDER[futureIndex - 1]; if (state.analyze!.step !== state[prevStepName]!.step) return buildOutdatedMessage(prevStepName, "analyze", state); return null; }; /** Generates error message listing steps needed to reach current phase. */ const buildMissingStepsMessage = ( current: AutoBePhase, missing: AutoBePhase, ): string => { const currentIndex: number = STEP_ORDER.indexOf(current); const missingIndex: number = STEP_ORDER.indexOf(missing); const remainingSteps: string = STEP_ORDER.slice( missingIndex, currentIndex + 1, ) .map((step, index) => `${index + 1}. ${STEP_DESCRIPTIONS[step]}`) .join("\n "); const currentAction = ACTION_NAMES[current]; return StringUtil.trim` ${STEP_DESCRIPTIONS[missing]} not completed yet. To ${currentAction}, complete these steps: ${remainingSteps} Start with step ${missingIndex + 1}. `; }; /** * Generates error message indicating phase is outdated due to requirements * change. */ const buildOutdatedMessage = ( outdatedStep: AutoBePhase, currentStep: AutoBePhase, state: AutoBeState, ): string => { const outdatedVersion = state[outdatedStep]?.step; const currentVersion = state[currentStep]?.step; return StringUtil.trim` ${STEP_NAMES[outdatedStep]} is outdated (step ${outdatedVersion}). Requirements are now at step ${currentVersion}. Please update ${outdatedStep} to match current requirements. `; }; /** Special validation for Database phase requiring only analyze completion. */ const predicateDatabase = (state: AutoBeState): string | null => { if (state.analyze !== null) return null; return StringUtil.trim` Requirements analysis not started. Discuss your project with AI to generate requirements analysis. Database design will follow after requirements are ready. `; }; const STEP_DESCRIPTIONS: Record<AutoBePhase, string> = { analyze: "Requirements analysis", database: "Database design", interface: "API interface design", test: "E2E test creation", realize: "Implementation", }; const STEP_NAMES: Record<AutoBePhase, string> = { analyze: "Requirements analysis", database: "Database schema", interface: "API interface", test: "Test functions", realize: "Implementation", }; const ACTION_NAMES: Record<AutoBePhase, string> = { analyze: "analyze requirements", database: "design database", interface: "design API interface", test: "create tests", realize: "implement the program", }; const STEP_ORDER: AutoBePhase[] = [ "analyze", "database", "interface", "test", "realize", ];