Skip to content

Extract chapter draft content-rejection retry into _draft_with_content_retry helper#157

Merged
CyberSecDef merged 3 commits into
mainfrom
copilot/fix-draft-retry-block-logic
Apr 8, 2026
Merged

Extract chapter draft content-rejection retry into _draft_with_content_retry helper#157
CyberSecDef merged 3 commits into
mainfrom
copilot/fix-draft-retry-block-logic

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

The draft step in chapters.py was the only pipeline step with an inline retry loop — 37 lines mixing prompt construction with retry/backoff logic — instead of using the _call_with_content_retry / _safe() pattern used everywhere else.

Changes

  • _helpers.py: Adds _draft_with_content_retry(build_prompt_fn, *, action, special_instructions, chapter_num, max_attempts=3) and the _DRAFT_CONTENT_NOTE constant it injects on retry. Unlike _call_with_content_retry (which sanitizes existing chapter text), this helper appends a content-guidance note to special_instructions and rebuilds the prompt from scratch via build_prompt_fn.

  • chapters.py: Replaces the inline 37-line retry loop with a single call:

    text = _draft_with_content_retry(
        lambda instr: build_chapter_draft_prompt(..., instr, ...),
        action=f"Chapter {chapter_num}: drafting",
        special_instructions=special_instructions,
        chapter_num=chapter_num,
    )
  • __init__.py: Re-exports _draft_with_content_retry and _DRAFT_CONTENT_NOTE.

  • test_progress_snapshot.py: Four terminal-state force-write tests were patching chapters.call_llm; draft calls now go through _helpers.call_llm, so patch targets updated accordingly.

  • test_draft_with_content_retry.py: New unit tests covering first-attempt success, content-note injection with/without special_instructions, retry exhaustion, exact attempt count, and warning logging.

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 tests/ -q --tb=short (dns block)
    • Triggering command: /usr/bin/python python -m pytest tests/ -q --tb=short -j DROP (dns block)
    • Triggering command: /usr/bin/python python -m pytest tests/ -q (dns block)

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

Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 21:31
Copilot AI linked an issue Apr 8, 2026 that may be closed by this pull request
Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 21:43
Copilot AI changed the title [WIP] Refactor draft retry block to separate prompt construction Extract chapter draft content-rejection retry into _draft_with_content_retry helper Apr 8, 2026
Copilot AI requested a review from CyberSecDef April 8, 2026 21:46
@CyberSecDef CyberSecDef marked this pull request as ready for review April 8, 2026 22:50
Copilot AI review requested due to automatic review settings April 8, 2026 22:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors chapter drafting to use a shared helper for content-rejection retry behavior, aligning the draft step with the retry patterns used elsewhere in the pipeline.

Changes:

  • Added _draft_with_content_retry (and _DRAFT_CONTENT_NOTE) to centralize draft-time content rejection retry logic.
  • Replaced the inline retry loop in chapters.py with a single helper call that rebuilds prompts on retry.
  • Updated and added tests to reflect the new call path and to cover the helper’s retry behavior.

Reviewed changes

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

Show a summary per file
File Description
novelforge/agents/chapter/_helpers.py Introduces _DRAFT_CONTENT_NOTE and _draft_with_content_retry to handle draft retries on ContentRejectionError.
novelforge/routes/generation/chapters.py Uses _draft_with_content_retry instead of an inline retry loop during drafting.
novelforge/agents/chapter/__init__.py Re-exports _draft_with_content_retry and _DRAFT_CONTENT_NOTE.
tests/test_progress_snapshot.py Updates patch targets to the new draft call path (_helpers.call_llm).
tests/test_draft_with_content_retry.py Adds unit coverage for success, retry note injection, exhaustion behavior, and warning logging.
Comments suppressed due to low confidence (1)

novelforge/routes/generation/chapters.py:45

  • After switching draft calls to _draft_with_content_retry, this module no longer appears to reference call_llm or parse_llm_json directly (no call_llm( / parse_llm_json( usages found). Consider dropping those imports from novelforge.llm.client to avoid unused-import warnings.
from novelforge.agents.chapter import (
    _format_characters,
    _draft_with_content_retry,
    build_chapter_draft_prompt,
    run_continuity_gatekeeper, run_chapter_rhythm_classifier,
    run_character_state_updater, run_per_chapter_compression_check,
    _run_all_chapter_agents, ChapterContext,
)

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

Comment thread novelforge/agents/chapter/_helpers.py Outdated
Comment thread tests/test_draft_with_content_retry.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 8, 2026 22:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.


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

Comment on lines +175 to +182
def _draft_with_content_retry(
build_prompt_fn: Callable[[str], list[dict]],
*,
action: str,
special_instructions: str,
chapter_num: int,
max_attempts: int = 3,
) -> str:
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

max_attempts can be set to 0 (or a negative value) and the loop will perform zero attempts, falling through to the final raise ContentRejectionError(...) with a misleading message and without ever calling the LLM. Add a guard (e.g., raise ValueError) when max_attempts < 1 so the helper’s behavior is well-defined.

Copilot uses AI. Check for mistakes.
@CyberSecDef CyberSecDef merged commit d4b0f0e into main Apr 8, 2026
13 checks passed
@CyberSecDef CyberSecDef deleted the copilot/fix-draft-retry-block-logic branch April 8, 2026 23:02
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.

Draft Retry Block Mixes Prompt Construction with Retry Logic

3 participants