Blueprint v2.0: Pre-Flight Beat Expansion (Director's Treatment)
Implement Section 3 of the AI Context Optimization Blueprint: before each chapter draft, model_logic expands sparse scene_beats into a structured Director's Treatment covering staging, sensory anchors, emotional shifts, and subtext per beat. This treatment is injected into the writer prompt, giving the model a detailed scene blueprint to dramatize rather than infer, reducing rewrite attempts and improving first-draft quality scores. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,38 @@ from story.style_persona import get_style_guidelines
|
||||
from story.editor import evaluate_chapter_quality
|
||||
|
||||
|
||||
def expand_beats_to_treatment(beats, pov_char, genre, folder):
|
||||
"""Expand sparse scene beats into a Director's Treatment using a fast model.
|
||||
This pre-flight step gives the writer detailed staging and emotional direction,
|
||||
reducing rewrites by preventing skipped beats and flat pacing."""
|
||||
if not beats:
|
||||
return None
|
||||
prompt = f"""
|
||||
ROLE: Story Director
|
||||
TASK: Expand the following sparse scene beats into a concise "Director's Treatment".
|
||||
|
||||
GENRE: {genre}
|
||||
POV_CHARACTER: {pov_char or 'Protagonist'}
|
||||
SCENE_BEATS: {json.dumps(beats)}
|
||||
|
||||
For EACH beat, provide 3-4 sentences covering:
|
||||
1. STAGING: Where are characters physically? How do they enter/exit the scene?
|
||||
2. SENSORY ANCHOR: One specific sensory detail (sound, smell, texture) to ground the beat.
|
||||
3. EMOTIONAL SHIFT: What is the POV character's internal state at the START vs END of this beat?
|
||||
4. SUBTEXT: What does the POV character want vs. what they actually do or say?
|
||||
|
||||
OUTPUT: Prose treatment only. Do NOT write the chapter prose itself.
|
||||
"""
|
||||
try:
|
||||
response = ai_models.model_logic.generate_content(prompt)
|
||||
utils.log_usage(folder, ai_models.model_logic.name, response.usage_metadata)
|
||||
utils.log("WRITER", " -> Beat expansion complete.")
|
||||
return response.text
|
||||
except Exception as e:
|
||||
utils.log("WRITER", f" -> Beat expansion failed: {e}. Using raw beats.")
|
||||
return None
|
||||
|
||||
|
||||
def write_chapter(chap, bp, folder, prev_sum, tracking=None, prev_content=None, next_chapter_hint=""):
|
||||
pacing = chap.get('pacing', 'Standard')
|
||||
est_words = chap.get('estimated_words', 'Flexible')
|
||||
@@ -101,6 +133,10 @@ def write_chapter(chap, bp, folder, prev_sum, tracking=None, prev_content=None,
|
||||
trunc_content = utils.truncate_to_tokens(prev_content, 1000)
|
||||
prev_context_block = f"\nPREVIOUS CHAPTER TEXT (Last ~1000 Tokens — For Immediate Continuity):\n{trunc_content}\n"
|
||||
|
||||
utils.log("WRITER", f" -> Expanding beats to Director's Treatment...")
|
||||
treatment = expand_beats_to_treatment(chap.get('beats', []), pov_char, genre, folder)
|
||||
treatment_block = f"\n DIRECTORS_TREATMENT (Staged expansion of the beats — use this as your scene blueprint; DRAMATIZE every moment, do NOT summarize):\n{treatment}\n" if treatment else ""
|
||||
|
||||
total_chapters = ls.get('chapters', '?')
|
||||
prompt = f"""
|
||||
ROLE: Fiction Writer
|
||||
@@ -168,6 +204,7 @@ def write_chapter(chap, bp, folder, prev_sum, tracking=None, prev_content=None,
|
||||
- CHARACTERS: {json.dumps(chars_for_writer)}
|
||||
{char_visuals}
|
||||
- SCENE_BEATS: {json.dumps(chap['beats'])}
|
||||
{treatment_block}
|
||||
|
||||
OUTPUT: Markdown text.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user