Skip to main content

Chapter Writer Agent

The Chapter Writer Agent generates the first draft of each chapter scene by scene, with automatic narrative constraint injection and an inline prose quality loop.

Overview​

This agent transforms the outline into fully-written chapters. For each scene it:

  1. Checks narrative invariants (dead characters, injured limbs, destroyed locations) and prepends any violations as hard constraints in the prompt.
  2. Injects style hints from the prior chapter's quality report to prevent recurring clichés and tell-not-show patterns.
  3. Generates the scene prose via the configured LLM.
  4. Scores the generated prose across 5 quality axes; if the overall score is below 0.65, fires one targeted rewrite pass preserving all plot facts.
  5. After all scenes are written, triggers NarrativeGraphBuilder to extract and persist new narrative facts.

Quality Pipeline​

Option A — Preventive Style Injection​

Before writing chapter N, the agent reads quality_chapter_{N-1}.json. Any quality axis scoring below 0.70 contributes a line to a STYLE CONSTRAINTS: block that is prepended to every scene prompt in the chapter. This costs zero extra LLM calls.

Example injected block:

STYLE CONSTRAINTS (patterns to avoid from prior chapter quality analysis):
- [cliche_density] Replace opening atmospheric sentences with a concrete sensory detail or action.
Avoid phrases like: "The air was thick with tension"
Avoid phrases like: "he let out a breath he didn't know he was holding"

Option B — Reactive Rewrite Loop​

After each scene is generated, ContentQualityAgent.score_prose() evaluates it. If overall_score < 0.65:

  • All axes scoring below the threshold are collected (not just the lowest three).
  • A rewrite prompt is built listing only the specific problems to fix, with strict instructions to preserve all character names, locations, events, and injuries.
  • One rewrite pass fires against the LLM (max 2 000 tokens).
  • If the rewrite fails or returns output shorter than half the original, the original scene is kept without error.

The threshold is configurable via _QUALITY_REWRITE_THRESHOLD in chapter_writer.py (default 0.65).

Narrative Graph Update​

After all scenes in the chapter are written, the agent calls NarrativeGraphBuilder.extract_from_chapter(). Failure is caught and logged; existing facts in narrative_graph.json are never lost.

Input Requirements​

  1. Chapter outline (scenes, characters, setting, goal, emotional beat)
  2. Character profiles from the knowledge base
  3. Worldbuilding information
  4. Project metadata (title, genre, language)
  5. narrative_graph.json (auto-created if missing)
  6. quality_chapter_{N-1}.json (used for Option A; silently skipped if missing)

Output Files​

FileDescription
chapter_{N}.mdWritten chapter in Markdown
narrative_graph.jsonUpdated with facts extracted from this chapter

CLI Usage​

The chapter writer is invoked automatically during guided setup. It can also be triggered directly:

libriscribe write --chapter-number 1

Error Handling​

  • Missing chapter in knowledge base: a default chapter is created and logged.
  • Empty LLM response for a scene: placeholder text is inserted; chapter writing continues.
  • Narrative graph update failure: existing graph is preserved; chapter writing is not aborted.
  • Quality scoring or rewrite failure: original scene content is kept; chapter writing continues.

Pipeline Context Propagation​

These behaviours were added to ensure every user answer reaches each scene.

Character Profiles in Scene Prompts​

For each scene, _write_scene() looks up the full character profile for every character listed in scene.characters. If found in the PKB, a CHARACTER PROFILES (keep consistent): block is prepended to the scene prompt containing name, role, personality traits, background (first 120 chars), and character arc (first 80 chars).

Worldbuilding Context in Scene Prompts​

If project_knowledge_base.worldbuilding is set, a WORLD CONTEXT (maintain consistency): block is built from these fields (each truncated to 200 chars):

geography, key_locations, magic_system, culture_and_society, technology_level, setting_context, key_concepts, industry_overview

Dynamic Questions in Scene Prompts​

Genre-specific Q&A from Advanced setup (pkb.dynamic_questions) is included as a GENRE-SPECIFIC AUTHOR DETAILS: block prepended to every scene prompt.

Chapter 1 Narrative Graph Seeding​

When writing chapter 1 and the narrative graph is empty, character trait facts are seeded into the graph before the first scene is generated. This gives InvariantChecker character context from scene 1 instead of starting blind.

Tone and Target Audience​

SCENE_PROMPT.format(...) now passes tone and target_audience from the PKB so the LLM respects the author's intended register from the first scene.

Research Context in Scene Prompts​

If research_results.md exists in the project directory (produced by the Researcher Agent), its first 1 200 characters are injected as a RESEARCH CONTEXT (relevant background for this scene): block prepended to every scene prompt. The content is truncated to avoid displacing other context blocks. If the file is absent, the block is silently skipped.

Run the Researcher before starting chapter writing to give every scene factual grounding:

libriscribe research "your research topic here"

Pacing Guidance in Editor Prompt​

After all scenes for a chapter are written, the AI-review pipeline runs the Pacing Agent across all chapters written so far. Any axes scoring below 0.70 produce a PACING GUIDANCE: block prepended to the Editor Agent's prompt, directing it to address cross-chapter arc problems during this editing pass. See Pacing Agent for full details.

Output Format​

## Chapter 1: Chapter Title

**Scene 1: Scene summary...**

[Scene prose...]

**Scene 2: Scene summary...**

[Scene prose...]