Skip to content

Persist generated outline state immediately after /generate_outline - #67

Merged
CyberSecDef merged 2 commits into
mainfrom
copilot/persist-generated-outline-state
Apr 3, 2026
Merged

Persist generated outline state immediately after /generate_outline#67
CyberSecDef merged 2 commits into
mainfrom
copilot/persist-generated-outline-state

Conversation

Copilot AI commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

/generate_outline wrote all generated state (title, chapter list, characters, planning artifacts, voice seed) into the Flask session but never persisted it to disk — so a crash or restart before /approve_outline silently discarded all that expensive LLM work.

Changes

  • novelforge/routes/outline.py — Call save_session_state() after all session fields are populated in generate_outline(), matching the existing pattern in approve_outline():
session["pov_focal_character_plan"] = pov_focal_character_plan

# Auto-save session state after outline generation for crash recovery
save_session_state()  # ← added

return jsonify({...})
  • tests/test_session.py — New TestGenerateOutlinePersistence class with three tests:
    • Session file exists on disk with correct fields after a successful /generate_outline
    • All planning artifacts and voice seed are present in the persisted file, and restore_session_from_state() can fully recover the session without ever hitting /approve_outline
    • Voice seed is included in the persisted state

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.openai.com
    • Triggering command: /usr/bin/python python -m pytest -q (dns block)
    • Triggering command: /usr/bin/python python -m pytest --tb=short (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title [WIP] Persist generated outline state after outline generation Persist generated outline state immediately after /generate_outline Apr 2, 2026
Copilot AI requested a review from CyberSecDef April 2, 2026 21:05
@CyberSecDef
CyberSecDef marked this pull request as ready for review April 3, 2026 12:33
Copilot AI review requested due to automatic review settings April 3, 2026 12:33
@CyberSecDef
CyberSecDef merged commit e1921a1 into main Apr 3, 2026
3 checks passed
@CyberSecDef
CyberSecDef deleted the copilot/persist-generated-outline-state branch April 3, 2026 12:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ensures the expensive state generated by /generate_outline (title, outline, characters, planning artifacts, and voice seed) is persisted to disk immediately, improving crash/restart recovery without requiring a subsequent /approve_outline.

Changes:

  • Persist session state to disk at the end of generate_outline() via save_session_state().
  • Add tests asserting that /generate_outline creates a session JSON file containing the expected fields and that the saved state can be restored.
  • Add a targeted test to ensure the voice_seed is included in the persisted state.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
novelforge/routes/outline.py Saves generated outline/planning state to disk immediately after populating the Flask session.
tests/test_session.py Adds tests validating persistence and restorability of /generate_outline session state (including voice_seed).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/test_session.py
Comment on lines +420 to +421
from novelforge.session.persistence import get_session_id

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import: get_session_id is imported but never referenced in this test. Removing it will keep the test focused and avoid accumulating dead imports as the suite grows.

Suggested change
from novelforge.session.persistence import get_session_id

Copilot uses AI. Check for mistakes.
Comment thread tests/test_session.py
with client.session_transaction() as sess:
session_id = sess.get("session_id")

session_file = Path(config.NOVELS_DIR) / f"{session_id}.json"

Copilot AI Apr 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test reads the persisted JSON file without first asserting it exists. Adding an explicit assert session_file.exists() (as done in the other tests in this class) will yield a clearer assertion failure if persistence breaks.

Suggested change
session_file = Path(config.NOVELS_DIR) / f"{session_id}.json"
session_file = Path(config.NOVELS_DIR) / f"{session_id}.json"
assert session_file.exists(), "Session file must be created after /generate_outline"

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Persist generated outline state immediately after /generate_outline to improve crash recovery

3 participants