Blueprint v2.4-2.6: Style Rules UI, Lore RAG, Thread Tracking, Redo Book
v2.4 — Item 7: Refresh Style Guidelines - web/routes/admin.py: Added /admin/refresh-style-guidelines route (AJAX-aware) - templates/system_status.html: Added 'Refresh Style Rules' button with spinner v2.5 — Item 8: Lore & Location RAG-Lite - story/bible_tracker.py: Added update_lore_index() — extracts location/item descriptions from chapters into tracking_lore.json - story/writer.py: Reads chapter locations/key_items, builds LORE_CONTEXT block injected into the prompt (graceful degradation if no tags) - cli/engine.py: Loads tracking_lore.json on resume, calls update_lore_index after each chapter, saves tracking_lore.json v2.5 — Item 9: Structured Story State (Thread Tracking) - story/state.py (new): load_story_state, update_story_state (extracts active_threads, immediate_handoff, resolved_threads via model_logic), format_for_prompt (structured context replacing the prev_sum blob) - cli/engine.py: Loads story_state.json on resume, uses format_for_prompt as summary_ctx for write_chapter, updates state after each chapter accepted v2.6 — Item 10: Redo Book - templates/consistency_report.html: Added 'Redo Book' form with instruction input and confirmation dialog - web/routes/run.py: Added revise_book route — creates new Run, queues generate_book_task with user instruction as feedback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import json
|
||||
import markdown
|
||||
from datetime import datetime
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, session, send_from_directory
|
||||
from flask_login import login_required, current_user
|
||||
from web.db import db, Run, LogEntry
|
||||
@@ -315,6 +316,39 @@ def get_task_status(task_id):
|
||||
return {"status": "completed", "success": task_result}
|
||||
|
||||
|
||||
@run_bp.route('/project/<int:run_id>/revise_book/<string:book_folder>', methods=['POST'])
|
||||
@login_required
|
||||
def revise_book(run_id, book_folder):
|
||||
run = db.session.get(Run, run_id) or Run.query.get_or_404(run_id)
|
||||
if run.project.user_id != current_user.id:
|
||||
flash("Unauthorized.")
|
||||
return redirect(url_for('run.view_run', id=run_id))
|
||||
|
||||
if run.status == 'running':
|
||||
flash("A run is already active. Please wait for it to finish.")
|
||||
return redirect(url_for('run.view_run', id=run_id))
|
||||
|
||||
instruction = request.form.get('instruction', '').strip()
|
||||
if not instruction:
|
||||
flash("Please provide an instruction describing what to fix.")
|
||||
return redirect(url_for('run.check_consistency', run_id=run_id, book_folder=book_folder))
|
||||
|
||||
bible_path = os.path.join(run.project.folder_path, "bible.json")
|
||||
if not os.path.exists(bible_path):
|
||||
flash("Bible file not found. Cannot start revision.")
|
||||
return redirect(url_for('run.view_run', id=run_id))
|
||||
|
||||
new_run = Run(project_id=run.project_id, status='queued', start_time=datetime.utcnow())
|
||||
db.session.add(new_run)
|
||||
db.session.commit()
|
||||
|
||||
from web.tasks import generate_book_task
|
||||
generate_book_task(new_run.id, run.project.folder_path, bible_path, feedback=instruction, source_run_id=run.id)
|
||||
|
||||
flash(f"Book revision queued. Instruction: '{instruction[:80]}...' — a new run has been started.")
|
||||
return redirect(url_for('run.view_run', id=new_run.id))
|
||||
|
||||
|
||||
@run_bp.route('/project/<int:run_id>/regenerate_artifacts', methods=['POST'])
|
||||
@login_required
|
||||
def regenerate_artifacts(run_id):
|
||||
|
||||
Reference in New Issue
Block a user