v1.3.1: Remove rigidity from chapter counts, beats, word lengths, and bridge chapters

story.py — create_chapter_plan():
- TARGET_CHAPTERS is now a guideline (±15%) not a hard constraint; the AI
  can produce a count that fits the story rather than forcing a specific number
- Word scaling is now pacing-aware instead of uniform: Very Fast ≈ 60% of avg,
  Fast ≈ 80%, Standard ≈ 100%, Slow ≈ 125%, Very Slow ≈ 150%
- Two-pass normalisation: pacing weights applied first, then the total is
  nudged to the word target — natural variation preserved throughout
- Variance range tightened to ±8% (was ±10%) for more predictable totals
- Prompt now tells the AI that estimated_words should reflect pacing rhythm

story.py — expand():
- Added event ceiling (target_chapters × 1.5): if the outline already has
  enough beats, the pass switches from "add events" to "enrich descriptions"
  — prevents over-dense outlines for short stories and flash fiction
- Task instruction is dynamically chosen: add-events vs deepen-descriptions
- Clarified that original user beats must be preserved but new events must
  each be distinct and spread evenly (not front-loaded)

story.py — refinement loop:
- Word count constraint softened from hard "do not condense" to
  "~N words ±20% acceptable if the scene demands it" so action chapters
  can run short and introspective chapters can run long naturally

main.py — bridge chapter insertion:
- Removed hardcoded 1500-word estimate for dynamically inserted bridge
  chapters; now computes the average estimated_words from the current
  chapter plan so bridge chapters match the book's natural chapter length

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-20 10:42:51 -05:00
parent 1964c9c2a5
commit 958a6d0ea0
3 changed files with 74 additions and 37 deletions

View File

@@ -213,12 +213,17 @@ def process_book(bp, folder, context="", resume=False, interactive=False):
pacing = story.check_pacing(bp, summary, txt, ch, remaining, folder)
if pacing and pacing.get('status') == 'add_bridge':
new_data = pacing.get('new_chapter', {})
# Estimate bridge chapter length from current plan average (not hardcoded)
if chapters:
avg_words = int(sum(c.get('estimated_words', 1500) for c in chapters) / len(chapters))
else:
avg_words = 1500
new_ch = {
"chapter_number": ch['chapter_number'] + 1,
"title": new_data.get('title', 'Bridge Chapter'),
"pov_character": new_data.get('pov_character', ch.get('pov_character')),
"pacing": "Slow",
"estimated_words": 1500,
"estimated_words": avg_words,
"beats": new_data.get('beats', [])
}
chapters.insert(i+1, new_ch)