- "backend/pipeline/quality/voice_dial.py" - "backend/pipeline/quality/scorer.py" - "backend/pipeline/quality/__main__.py" GSD-Task: S02/T02
91 lines
3.8 KiB
Python
91 lines
3.8 KiB
Python
"""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"
|