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