Persist generated outline state immediately after /generate_outline - #67
Conversation
Agent-Logs-Url: https://github.com/CyberSecDef/NovelForge/sessions/f3e84173-d86e-4bf5-a949-a80c7b27a43b Co-authored-by: CyberSecDef <[email protected]>
There was a problem hiding this comment.
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()viasave_session_state(). - Add tests asserting that
/generate_outlinecreates a session JSON file containing the expected fields and that the saved state can be restored. - Add a targeted test to ensure the
voice_seedis 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.
| from novelforge.session.persistence import get_session_id | ||
|
|
There was a problem hiding this comment.
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.
| from novelforge.session.persistence import get_session_id |
| with client.session_transaction() as sess: | ||
| session_id = sess.get("session_id") | ||
|
|
||
| session_file = Path(config.NOVELS_DIR) / f"{session_id}.json" |
There was a problem hiding this comment.
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.
| 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" |
/generate_outlinewrote 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_outlinesilently discarded all that expensive LLM work.Changes
novelforge/routes/outline.py— Callsave_session_state()after all session fields are populated ingenerate_outline(), matching the existing pattern inapprove_outline():tests/test_session.py— NewTestGenerateOutlinePersistenceclass with three tests:/generate_outlinerestore_session_from_state()can fully recover the session without ever hitting/approve_outlineWarning
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/usr/bin/python python -m pytest -q(dns block)/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: