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:
@@ -184,11 +184,42 @@ def validate_persona(bp, persona_details, folder):
|
||||
return True, 7
|
||||
|
||||
|
||||
def refine_persona(bp, text, folder):
|
||||
def refine_persona(bp, text, folder, pov_character=None):
|
||||
utils.log("SYSTEM", "Refining Author Persona based on recent chapters...")
|
||||
ad = bp.get('book_metadata', {}).get('author_details', {})
|
||||
current_bio = ad.get('bio', 'Standard style.')
|
||||
|
||||
# If a POV character is given and has a voice_profile, refine that instead
|
||||
if pov_character:
|
||||
for char in bp.get('characters', []):
|
||||
if char.get('name') == pov_character and char.get('voice_profile'):
|
||||
vp = char['voice_profile']
|
||||
current_bio = vp.get('bio', 'Standard style.')
|
||||
prompt = f"""
|
||||
ROLE: Literary Stylist
|
||||
TASK: Refine a POV character's voice profile based on the text sample.
|
||||
|
||||
INPUT_DATA:
|
||||
- TEXT_SAMPLE: {text[:3000]}
|
||||
- CHARACTER: {pov_character}
|
||||
- CURRENT_VOICE_BIO: {current_bio}
|
||||
|
||||
GOAL: Ensure future chapters for this POV character sound exactly like the sample. Highlight quirks, patterns, vocabulary specific to this character's perspective.
|
||||
|
||||
OUTPUT_FORMAT (JSON): {{ "bio": "Updated voice bio..." }}
|
||||
"""
|
||||
try:
|
||||
response = ai_models.model_logic.generate_content(prompt)
|
||||
utils.log_usage(folder, ai_models.model_logic.name, response.usage_metadata)
|
||||
new_bio = json.loads(utils.clean_json(response.text)).get('bio')
|
||||
if new_bio:
|
||||
char['voice_profile']['bio'] = new_bio
|
||||
utils.log("SYSTEM", f" -> Voice profile bio updated for '{pov_character}'.")
|
||||
except Exception as e:
|
||||
utils.log("SYSTEM", f" -> Voice profile refinement failed for '{pov_character}': {e}")
|
||||
return ad # Return author_details unchanged
|
||||
|
||||
# Default: refine the main author persona bio
|
||||
current_bio = ad.get('bio', 'Standard style.')
|
||||
prompt = f"""
|
||||
ROLE: Literary Stylist
|
||||
TASK: Refine Author Bio based on text sample.
|
||||
|
||||
Reference in New Issue
Block a user