diff --git a/src/lib/llm/prompts.ts b/src/lib/llm/prompts.ts index 77ace34..f05462e 100644 --- a/src/lib/llm/prompts.ts +++ b/src/lib/llm/prompts.ts @@ -1,14 +1,114 @@ +import type { + ArticleInput, + ConfirmedFactCard, + OptimizedArticle, + PublishPlatform, + QaCheck, +} from "../domain/types"; + export const JSON_ONLY_PROMPT = "Return valid JSON only. Do not include markdown fences or commentary."; export const ARTICLE_OPTIMIZER_SYSTEM_PROMPT = [ "You optimize GEO-related articles under a confirmed fact card.", "Never invent numbers, cases, qualifications, company names, products, or years.", + "Use only facts present in the confirmed fact card or source article.", JSON_ONLY_PROMPT, ].join(" "); export const QUALITY_INSPECTOR_SYSTEM_PROMPT = [ "Evaluate article quality against the confirmed fact card and target platform.", - "Return one structured check per required quality gate.", + "Return one structured check per required quality gate when asked.", + "Do not downgrade deterministic hard failures supplied by the application.", JSON_ONLY_PROMPT, ].join(" "); + +export const FACT_EXTRACTOR_SYSTEM_PROMPT = [ + "Extract a candidate fact card from the source article.", + "Do not mark uncertain facts as confirmed.", + "Put missing or conflicting facts in uncertain_items.", + JSON_ONLY_PROMPT, +].join(" "); + +export const TARGETED_REWRITER_SYSTEM_PROMPT = [ + "Rewrite only the fields needed to resolve the provided failed QA checks.", + "Keep confirmed facts unchanged.", + "Preserve sections that are unrelated to failed checks.", + JSON_ONLY_PROMPT, +].join(" "); + +export function buildFactExtractorPrompt(input: ArticleInput) { + return [ + "Return a CandidateFactCard JSON object with these exact keys:", + "company_full_name, company_short_names, brand_names, product_names, target_industry, target_audience, experience_years, core_claims, forbidden_claims, image_topics, uncertain_items.", + "Do not include confirmed_by_user.", + "", + "Article input:", + JSON.stringify(input, null, 2), + ].join("\n"); +} + +export function buildArticleOptimizerPrompt( + input: ArticleInput, + factCard: ConfirmedFactCard, +) { + return [ + "Return an OptimizedArticle JSON object with these exact keys:", + "title, summary, body_markdown, image_suggestions, changed_sections, requires_user_confirmation.", + "Use Markdown in body_markdown.", + "If the user instruction asks for unsupported facts, omit them from the article and add them to requires_user_confirmation.", + "", + "Confirmed fact card:", + JSON.stringify(factCard, null, 2), + "", + "Article input:", + JSON.stringify(input, null, 2), + ].join("\n"); +} + +export function buildQualityInspectorPrompt(input: { + article: OptimizedArticle; + factCard: ConfirmedFactCard; + platform: PublishPlatform; + deterministicChecks: QaCheck[]; +}) { + return [ + "Return a JSON object with a checks array.", + "Each check must include rule_id, status, evidence, reason, suggested_fix, and target_agent.", + "Only use rule_id values already present in deterministicChecks.", + "If a deterministic check has status fail, keep it fail.", + "", + "Target platform:", + input.platform, + "", + "Confirmed fact card:", + JSON.stringify(input.factCard, null, 2), + "", + "Optimized article:", + JSON.stringify(input.article, null, 2), + "", + "Deterministic checks:", + JSON.stringify(input.deterministicChecks, null, 2), + ].join("\n"); +} + +export function buildTargetedRewritePrompt(input: { + article: OptimizedArticle; + factCard: ConfirmedFactCard; + failedChecks: QaCheck[]; +}) { + return [ + "Return an OptimizedArticle JSON object.", + "Rewrite only the fields needed for failedChecks.", + "Do not add unconfirmed numbers, customer names, qualifications, awards, or capabilities.", + "", + "Confirmed fact card:", + JSON.stringify(input.factCard, null, 2), + "", + "Current optimized article:", + JSON.stringify(input.article, null, 2), + "", + "Failed checks:", + JSON.stringify(input.failedChecks, null, 2), + ].join("\n"); +}