Auto-commit: v2.7 Series Continuity & Book Number Awareness
- story/planner.py: enrich() and plan_structure() now extract series_metadata and inject a SERIES_CONTEXT block (Book X of Y in series Z, with position-aware guidance) into prompts when is_series is true. - story/writer.py: write_chapter() builds and injects the same SERIES_CONTEXT into the chapter draft prompt; passes series_context to evaluate_chapter_quality(). - story/editor.py: evaluate_chapter_quality() accepts optional series_context parameter and injects it into METADATA so arc pacing is evaluated relative to the book's position in the series. - ai_blueprint.md: Section 11 marked complete (v2.7), summary updated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -223,6 +223,18 @@ def write_chapter(chap, bp, folder, prev_sum, tracking=None, prev_content=None,
|
||||
|
||||
genre_mandates = get_genre_instructions(genre)
|
||||
|
||||
series_meta = bp.get('series_metadata', {})
|
||||
series_block = ""
|
||||
if series_meta.get('is_series'):
|
||||
series_title = series_meta.get('series_title', 'this series')
|
||||
book_num = series_meta.get('book_number', '?')
|
||||
total_books = series_meta.get('total_books', '?')
|
||||
series_block = (
|
||||
f"\n - SERIES_CONTEXT: This is Book {book_num} of {total_books} in the '{series_title}' series. "
|
||||
f"Pace character arcs and emotional resolution to reflect this book's position in the series: "
|
||||
f"{'establish foundations, plant seeds, avoid premature resolution of series-level stakes' if str(book_num) == '1' else 'escalate the overarching conflict, deepen character arcs, end on a compelling hook that carries into the next book' if str(book_num) != str(total_books) else 'resolve all major character arcs and series-level conflicts with earned, satisfying payoffs'}."
|
||||
)
|
||||
|
||||
total_chapters = ls.get('chapters', '?')
|
||||
prompt = f"""
|
||||
ROLE: Fiction Writer
|
||||
@@ -234,7 +246,7 @@ def write_chapter(chap, bp, folder, prev_sum, tracking=None, prev_content=None,
|
||||
- POSITION: Chapter {chap['chapter_number']} of {total_chapters} — calibrate narrative tension accordingly (early = setup/intrigue, middle = escalation, final third = payoff/climax)
|
||||
- PACING: {pacing} — see PACING_GUIDE below
|
||||
- TARGET_WORDS: ~{est_words} (write to this length; do not summarise to save space)
|
||||
- POV: {pov_char if pov_char else 'Protagonist'}
|
||||
- POV: {pov_char if pov_char else 'Protagonist'}{series_block}
|
||||
|
||||
PACING_GUIDE:
|
||||
- 'Very Fast': Pure action/dialogue. Minimal description. Short punchy paragraphs.
|
||||
@@ -326,7 +338,7 @@ def write_chapter(chap, bp, folder, prev_sum, tracking=None, prev_content=None,
|
||||
|
||||
for attempt in range(1, max_attempts + 1):
|
||||
utils.log("WRITER", f" -> Evaluating Ch {chap['chapter_number']} (Attempt {attempt}/{max_attempts})...")
|
||||
score, critique = evaluate_chapter_quality(current_text, chap['title'], meta.get('genre', 'Fiction'), ai_models.model_writer, folder)
|
||||
score, critique = evaluate_chapter_quality(current_text, chap['title'], meta.get('genre', 'Fiction'), ai_models.model_writer, folder, series_context=series_block.strip())
|
||||
|
||||
past_critiques.append(f"Attempt {attempt}: {critique}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user