fix: Pipeline hardening — error handling, token efficiency, and robustness
core/utils.py: - estimate_tokens: improved heuristic 4 chars/token → 3.5 chars/token (more accurate) - truncate_to_tokens: added keep_head=True mode for head+tail truncation (better context retention for story summaries that need both opening and recent content) - load_json: explicit exception handling (json.JSONDecodeError, OSError) with log instead of silent returns; added utf-8 encoding with error replacement - log_image_attempt: replaced bare except with (json.JSONDecodeError, OSError); added utf-8 encoding to output write - log_usage: replaced bare except with AttributeError for token count extraction story/bible_tracker.py: - merge_selected_changes: wrapped all int() key casts (char idx, book num, beat idx) in try/except with meaningful log warning instead of crashing on malformed keys - harvest_metadata: replaced bare except:pass with except Exception as e + log message cli/engine.py: - Persona validation: added warning when all 3 attempts fail and substandard persona is accepted — flags elevated voice-drift risk for the run - Lore index updates: throttled from every chapter to every 3 chapters; lore is stable after the first few chapters (~10% token saving per book) - Mid-gen consistency check: now samples first 2 + last 8 chapters instead of passing full manuscript — caps token cost regardless of book length story/writer.py: - Two-pass polish: added local filter-word density check (no API call); skips the Pro polish if density < 1 per 83 words — saves ~8K tokens on already-clean drafts - Polish prompt: added prev_context_block for continuity — polished chapter now maintains seamless flow from the previous chapter's ending marketing/fonts.py: - Separated requests.exceptions.Timeout with specific log message vs generic failure - Added explicit log message when Roboto fallback also fails (returns None) marketing/blurb.py: - Added word count trim: blurbs > 220 words trimmed to last sentence within 220 words - Changed bare except to except Exception as e with log message - Added utf-8 encoding to file writes; logs final word count Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -42,14 +42,20 @@ def download_font(font_name):
|
||||
base_url = f"https://github.com/google/fonts/raw/main/{license_type}/{clean_name}"
|
||||
for pattern in patterns:
|
||||
try:
|
||||
r = requests.get(f"{base_url}/{pattern}", headers=headers, timeout=5)
|
||||
r = requests.get(f"{base_url}/{pattern}", headers=headers, timeout=6)
|
||||
if r.status_code == 200 and len(r.content) > 1000:
|
||||
with open(font_path, 'wb') as f: f.write(r.content)
|
||||
with open(font_path, 'wb') as f:
|
||||
f.write(r.content)
|
||||
utils.log("ASSETS", f"✅ Downloaded {font_name} to {font_path}")
|
||||
return font_path
|
||||
except Exception: continue
|
||||
except requests.exceptions.Timeout:
|
||||
utils.log("ASSETS", f" Font download timeout for {font_name} ({pattern}). Trying next...")
|
||||
continue
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if clean_name != "roboto":
|
||||
utils.log("ASSETS", f"⚠️ Font '{font_name}' not found. Falling back to Roboto.")
|
||||
utils.log("ASSETS", f"⚠️ Font '{font_name}' not found on Google Fonts. Falling back to Roboto.")
|
||||
return download_font("Roboto")
|
||||
utils.log("ASSETS", "⚠️ Roboto fallback also failed. PIL will use built-in default font.")
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user