feat: Implement ai_blueprint.md Steps 1 & 2 — bible-tracking merge and character voice profiles
Step 1 (Bible-Tracking Merge):
- Added merge_tracking_to_bible() to story/bible_tracker.py — merges character
tracking state and lore back into bible dict after each chapter, making
blueprint_initial.json the single persistent source of truth.
- Integrated in cli/engine.py after each chapter's update_tracking + update_lore_index
calls so the persisted bible is always up-to-date.
Step 2 (Character-Specific Voice Profiles):
- story/writer.py: write_chapter now checks bp['characters'] for a voice_profile on
the POV character before falling back to the prebuilt_persona cache.
- story/style_persona.py: refine_persona() accepts pov_character=None; when a POV
character with a voice_profile is supplied it refines that profile's bio instead of
the global author_details bio.
- cli/engine.py: refine_persona call now passes ch.get('pov_character') so per-chapter
persona refinement targets the correct voice.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -141,6 +141,30 @@ def update_lore_index(folder, chapter_text, current_lore):
|
||||
return current_lore
|
||||
|
||||
|
||||
def merge_tracking_to_bible(bible, tracking):
|
||||
"""Merge dynamic tracking state back into the bible dict.
|
||||
|
||||
Makes bible.json the single persistent source of truth by updating
|
||||
character data and lore from the in-memory tracking object.
|
||||
Returns the modified bible dict.
|
||||
"""
|
||||
for name, data in tracking.get('characters', {}).items():
|
||||
matched = False
|
||||
for char in bible.get('characters', []):
|
||||
if char.get('name') == name:
|
||||
char.update(data)
|
||||
matched = True
|
||||
break
|
||||
if not matched:
|
||||
utils.log("TRACKER", f" -> Character '{name}' in tracking not found in bible. Skipping.")
|
||||
|
||||
if 'lore' not in bible:
|
||||
bible['lore'] = {}
|
||||
bible['lore'].update(tracking.get('lore', {}))
|
||||
|
||||
return bible
|
||||
|
||||
|
||||
def harvest_metadata(bp, folder, full_manuscript):
|
||||
utils.log("HARVESTER", "Scanning for new characters...")
|
||||
full_text = "\n".join([c.get('content', '') for c in full_manuscript])[:500000]
|
||||
|
||||
Reference in New Issue
Block a user