/** * compose_prompt — the canonical happy-path pipeline. * * ┌──────────────┐ ┌──────────────────────┐ ┌──────────────┐ * │ pre_clarify │ → │ ground_prompt OR │ → │ post_critique│ * │ (optional) │ │ optimize_prompt │ │ (optional) │ * └──────────────┘ └──────────────────────┘ └──────────────┘ * * One MCP call gets you the entire flow. Designed so callers can pipeline * the four tools without orchestrating five round-trips themselves, and so * the canonical "clarify → optimize → critique" pattern is discoverable * straight from the tool list. * * Short-circuit semantics: * - pre_clarify=true AND clarify returns questions → STOP. Return only * the questions. Caller answers, re-calls with pre_clarify=false. * - sources provided → goes through ground_prompt (strict mode). * - sources empty/absent → goes through optimize_prompt (auto-curated). * - post_critique=true → runs critique against the optimized prompt. * - auto_revise=true AND critique verdict !== 'accept' AND there's an * improvedPrompt → finalPrompt is the rewritten version, not the raw * optimization. The caller uses finalPrompt regardless. * * The output also includes a `stages` audit so the caller can see exactly * what ran, in what order, and how long each stage took. */ import { type ClarifyResult } from '../clarification/clarify.js'; import { type GroundResult } from '../grounding/ground.js'; import { type CritiqueResult, type CritiqueCriterion } from '../critique/critique.js'; import type { OptimizationResult, UserProvidedSource } from '../optimization/types.js'; import type { Category, Mode } from '../config/categories.js'; export interface ComposeInputs { prompt: string; /** * 'auto' — default: run clarify ONLY if the analyzer's confidence is * low or the prompt is short. If clarification is needed, * stop and return the questions (caller must answer + re-call). * 'always' — always run clarify; stop if questions surface. * 'never' — skip the clarify pre-stage entirely. */ preClarify?: 'auto' | 'always' | 'never'; /** Cap on clarify questions (passed through). */ maxQuestions?: number; /** When non-empty, the chain takes the ground_prompt branch (strict). */ sources?: UserProvidedSource[]; /** Run the critique judge against the optimized output. */ postCritique?: boolean; /** Score threshold below which a rewrite pass is attempted. */ reviseThreshold?: number; /** Override the default critique criteria. */ critiqueCriteria?: CritiqueCriterion[]; /** * When true: if critique produced an improvedPrompt and verdict !== 'accept', * `finalPrompt` becomes the improved version instead of the raw optimization. */ autoRevise?: boolean; /** * Max revise-loop iterations. Each iteration re-runs ground/optimize + critique * on the previously-improved prompt. Stops at verdict=accept, no improvedPrompt * to feed back, or this cap. Default 1 (single-shot, current behavior). Hard * max 5 to prevent cost runaways on pathological prompts. * * Only meaningful with `postCritique: true` AND `autoRevise: true`. Without * autoRevise there's no rewritten prompt to feed back; the loop short-circuits * after iteration 1. */ maxIterations?: number; /** Override the LLM model for the clarify pre-stage. Default: env LLM_MODEL. */ clarifyModel?: string; /** Override the LLM model for the optimize/ground core stage. */ optimizeModel?: string; /** Override the LLM model for the critique judge + rewrite. */ critiqueModel?: string; category?: Category; platform?: string; mode?: Mode; modeExplicit?: boolean; enrichContext?: boolean; sessionId?: string; filePath?: string; fileLanguage?: string; fileExcerpt?: string; cwd?: string; userLocale?: string; userPinnedInstructions?: string; skipIntentResolution?: boolean; includeBundle?: boolean; /** * Cancellation signal. Propagated to every stage's LLM call so a client * cancel aborts work in flight; also checked between iterations so a long * revise loop stops promptly. */ signal?: AbortSignal; /** * Progress callback, invoked at the start of each stage. The MCP handler maps * these to `notifications/progress` so hosts can show a live status on a long * compose. Pure-data; safe to ignore. */ onProgress?: (update: ComposeProgress) => void; } export interface ComposeProgress { stage: ComposeStage['name'] | 'analyze'; iteration: number; maxIterations: number; message: string; } export interface ComposeStage { name: 'clarify' | 'ground' | 'optimize' | 'critique' | 'revise'; ranAt: string; durationMs: number; summary: string; } export interface ComposeResult { stages: ComposeStage[]; /** * The prompt the caller should send downstream. Equals * `optimization.optimizedPrompt` unless auto_revise replaced it with * `critique.improvedPrompt`. */ finalPrompt: string; /** * Set only when the chain stopped early because clarification was needed. * The caller MUST answer the questions and re-call (with preClarify='never' * or by editing the prompt to incorporate the answers). */ clarificationRequired?: boolean; /** clarify result. Always present when clarify ran. */ clarification?: ClarifyResult; /** ground result. Present iff the chain took the ground branch. */ grounding?: GroundResult; /** optimize result. Present iff the chain took the optimize branch. */ optimization?: OptimizationResult; /** critique result. Present iff post_critique=true. */ critique?: CritiqueResult; /** Whether finalPrompt was replaced by critique.improvedPrompt. */ revised?: boolean; /** * How many optimize+critique iterations ran. Equals 1 for the default * single-shot flow; only >1 when maxIterations > 1 AND the engine actually * fed the rewrite back through another iteration. */ iterations?: number; } export declare function composePrompt(inputs: ComposeInputs): Promise;