Spaces:
Runtime error
Runtime error
File size: 4,131 Bytes
aad7814 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | """Proofread and enhance modes for legacy UI compatibility."""
from __future__ import annotations
from backend.core.note_bullets import format_bullets_for_prompt
from backend.core.paragraph_merge import merge_observations_into_paragraph
from backend.core.style_profile import StyleProfile
from backend.llm import openai_client
from backend.models.schema import TemplateSchema
PROOFREAD_SYSTEM = """\
You are a professional RICS survey report editor and proofreader. \
Fix grammar, clarity, and British English spellings. Do not add new facts. \
Output plain text only.\
"""
ENHANCE_SYSTEM = """\
You are an expert RICS surveyor and technical writer. \
Expand the section using supplied evidence only — do not invent facts. \
Use British English. Output plain text only.\
"""
def _profile_fields(profile: StyleProfile) -> dict[str, str]:
return {
"tone": profile.tone,
"formality_level": profile.formality_level,
"avg_sentence_complexity": profile.avg_sentence_complexity,
"vocabulary_level": profile.vocabulary_level,
"writing_style_summary": profile.writing_style_summary,
}
def proofread_text(
text: str,
bullets: list[str],
*,
style_profile: StyleProfile | None = None,
) -> str:
clean = text.split("\n\n[Editor notes:")[0].strip()
if not clean:
return text
profile = style_profile or StyleProfile()
pf = _profile_fields(profile)
bullets_text = format_bullets_for_prompt(bullets)
if not openai_client.is_available():
return clean
user = f"""AUTHOR'S WRITING STYLE PROFILE:
- Tone: {pf['tone']}
- Formality: {pf['formality_level']}
- Sentence complexity: {pf['avg_sentence_complexity']}
- Vocabulary: {pf['vocabulary_level']}
- Style summary: {pf['writing_style_summary']}
ORIGINAL FACT BULLETS:
{bullets_text}
TEXT TO PROOFREAD:
{clean}
TASK: Proofread and improve the text. Do NOT add new facts.
Return corrected text, then "---NOTES---" and 1–3 brief editor notes."""
out = openai_client.chat_text(
[{"role": "system", "content": PROOFREAD_SYSTEM}, {"role": "user", "content": user}],
temperature=0.15,
max_tokens=max(700, min(2400, len(clean.split()) * 3)),
)
if "---NOTES---" in out:
corrected, notes = out.split("---NOTES---", 1)
corrected = corrected.strip()
notes_block = f"\n\n[Editor notes: {notes.strip()}]"
else:
corrected = out.strip()
notes_block = ""
return corrected + notes_block
def enhance_text(
text: str,
bullets: list[str],
snippets: list[str],
*,
style_profile: StyleProfile | None = None,
schema: TemplateSchema | None = None,
) -> str:
base = text.split("\n\n[Editor notes:")[0].strip()
if not base:
base = text.strip()
profile = style_profile or StyleProfile()
pf = _profile_fields(profile)
bullets_text = format_bullets_for_prompt(bullets)
examples = "\n\n---\n\n".join(s.strip() for s in snippets if s.strip())[:3500]
if openai_client.is_available():
user = f"""AUTHOR'S WRITING STYLE PROFILE:
- Tone: {pf['tone']}
- Formality: {pf['formality_level']}
- Vocabulary: {pf['vocabulary_level']}
- Style summary: {pf['writing_style_summary']}
ORIGINAL FACT BULLETS:
{bullets_text}
ADDITIONAL EVIDENCE:
{examples or '(No additional evidence available.)'}
CURRENT TEXT:
{base}
TASK: Rewrite and expand the current text using evidence only. Aim for 80–200 words.
Output only the enhanced text."""
out = openai_client.chat_text(
[{"role": "system", "content": ENHANCE_SYSTEM}, {"role": "user", "content": user}],
temperature=0.2,
max_tokens=max(900, min(2400, len(base.split()) + 800)),
)
enhanced = (out or "").strip()
if enhanced:
return enhanced
sch = schema or TemplateSchema()
merged = merge_observations_into_paragraph(base, bullets, sch)
if snippets and snippets[0].strip() not in merged:
extra = snippets[0].strip()
if len(extra) > 40:
merged = f"{merged.rstrip()} {extra}"
return merged
|