diff --git a/packages/api/src/llm/fo-blog-pipeline.ts b/packages/api/src/llm/fo-blog-pipeline.ts index 31a9517..efa7218 100644 --- a/packages/api/src/llm/fo-blog-pipeline.ts +++ b/packages/api/src/llm/fo-blog-pipeline.ts @@ -396,6 +396,12 @@ Write the flow plan (3-4 beats, as prose):`; export const STEP4_MASTER_DRAFT = `Write the full technical blog article based on the outline below. +═══════════════════════════════════════════════════════ +LENGTH: HARD LIMIT — 800–1,100 WORDS. STOP AT 1,100. +═══════════════════════════════════════════════════════ +Target: 800–1,100 words. If you hit 1,100 words, stop immediately and end the article. +This is not negotiable. Longer is not better. Dense and focused beats exhaustive. + ═══════════════════════════════════════════════════════ FORMAT: CONTINUOUS PROSE — NO EXCEPTIONS ═══════════════════════════════════════════════════════ diff --git a/packages/api/src/routes/blog.ts b/packages/api/src/routes/blog.ts index be409e7..a6a26fb 100644 --- a/packages/api/src/routes/blog.ts +++ b/packages/api/src/routes/blog.ts @@ -1017,8 +1017,8 @@ async function runLlmPipeline( withCalibration, } = await import("../llm/fo-blog-pipeline"); - const LLM_OPTS = { temperature: 0.7, maxTokens: 8192, timeoutMs: 480000 }; - const LLM_REFINE = { temperature: 0.4, maxTokens: 6144, timeoutMs: 480000 }; + const LLM_OPTS = { temperature: 0.7, maxTokens: 1600, timeoutMs: 480000 }; + const LLM_REFINE = { temperature: 0.4, maxTokens: 1800, timeoutMs: 480000 }; const TOTAL_STEPS = 16; // 10 original + 4b Narrative Control + 8b Reduction + 8c Style Lock + 8d Auto-Kill + Auto-Kill Score + LinkedIn let stepsCompleted = 0; @@ -1083,6 +1083,12 @@ async function runLlmPipeline( } } + if (additionalContext) { + contextLines.unshift( + `[HOT TOPIC BRIEFING — editorial direction, do not copy verbatim]\n${additionalContext.slice(0, 4000)}` + ); + } + const contextData = contextLines.length > 0 ? contextLines.join("\n") : "[NO PRODUCT DATA AVAILABLE — do NOT invent product names, part numbers, or prices]"; @@ -1131,7 +1137,7 @@ async function runLlmPipeline( STEP4_MASTER_DRAFT .replace("{{OUTLINE}}", step3.text) .replace("{{CONTEXT_DATA}}", contextData), - { ...LLM_OPTS, maxTokens: 8192 } + { ...LLM_OPTS, maxTokens: 1600 } ); stepsCompleted = 4; console.log(` Draft: ${step4.text.split(/\s+/).length} words`); @@ -1343,8 +1349,8 @@ async function runLlmPipeline( await pool.query( `UPDATE blog_drafts SET title = $9, draft_content = $1, word_count = $2, - generated_by = 'fo-blog-engine-v5-autokill', - pipeline_version = 'v5-auto-kill-layer', + generated_by = 'fo-blog-engine-v6-length-fix', + pipeline_version = 'v6-length-capped', pipeline_steps_completed = $3, auto_qa_score = $4, outline = $5,