"""Voice preservation dial — modifies Stage 5 synthesis prompt by intensity band. Three bands control how much of the creator's original voice is preserved: - Low (0.0–0.33): Clinical, encyclopedic tone — suppress direct quotes - Mid (0.34–0.66): Base prompt unchanged (already ~0.6 voice preservation) - High (0.67–1.0): Maximum voice — prioritize exact words, strong opinions """ from __future__ import annotations # ── Band modifier text ──────────────────────────────────────────────────────── _LOW_BAND_MODIFIER = """ ## Voice Suppression Override IMPORTANT — override the voice/tone guidelines above. For this synthesis: - Do NOT include any direct quotes from the creator. Rephrase all insights in neutral third-person encyclopedic style. - Do NOT attribute opinions or preferences to the creator by name (avoid "he recommends", "she prefers"). - Remove all personality markers, humor, strong opinions, and conversational tone. - Write as a reference manual: factual, impersonal, technically precise. - Replace phrases like "he warns against" with neutral statements like "this approach is generally avoided because." - Suppress colloquialisms and informal language entirely. """ _HIGH_BAND_MODIFIER = """ ## Maximum Voice Preservation Override IMPORTANT — amplify the voice/tone guidelines above. For this synthesis: - Maximize the use of direct quotes from the transcript. Every memorable phrase, vivid metaphor, or strong opinion should be quoted verbatim with quotation marks. - Attribute all insights, preferences, and techniques to the creator by name — use their name frequently. - Preserve personality, humor, strong opinions, and conversational tone. If the creator is emphatic, the prose should feel emphatic. - Prioritize the creator's exact words over paraphrase. When a transcript excerpt contains a usable phrase, quote it rather than summarizing it. - Include warnings, caveats, and opinionated asides in the creator's own voice. - The resulting page should feel like the creator is speaking directly to the reader through the text. """ # ── VoiceDial class ─────────────────────────────────────────────────────────── class VoiceDial: """Modifies a Stage 5 synthesis prompt based on a voice_level parameter. Parameters ---------- base_prompt: The original stage5_synthesis.txt system prompt content. """ # Band boundaries LOW_UPPER = 0.33 HIGH_LOWER = 0.67 def __init__(self, base_prompt: str) -> None: self.base_prompt = base_prompt def modify(self, voice_level: float) -> str: """Return the system prompt modified for the given voice_level. Parameters ---------- voice_level: Float 0.0–1.0. Values outside this range are clamped. Returns ------- str Modified system prompt with band-appropriate instructions appended. """ voice_level = max(0.0, min(1.0, voice_level)) if voice_level <= self.LOW_UPPER: return self.base_prompt + _LOW_BAND_MODIFIER elif voice_level >= self.HIGH_LOWER: return self.base_prompt + _HIGH_BAND_MODIFIER else: # Mid band — base prompt is already moderate voice preservation return self.base_prompt @staticmethod def band_name(voice_level: float) -> str: """Return the human-readable band name for a voice_level value.""" voice_level = max(0.0, min(1.0, voice_level)) if voice_level <= VoiceDial.LOW_UPPER: return "low" elif voice_level >= VoiceDial.HIGH_LOWER: return "high" return "mid"