-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathwriter.py
More file actions
96 lines (78 loc) · 2.39 KB
/
Copy pathwriter.py
File metadata and controls
96 lines (78 loc) · 2.39 KB
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
import re
import time
from core.llm_client import ask_llm
class WriterAgent:
"""
Writes clean academic content.
- No references
- No citations
- No markdown
- One coherent paragraph per section
"""
def write_section(
self,
sub_question: str,
search_results: list,
retries: int = 3
) -> str:
for attempt in range(retries):
try:
return self._generate(sub_question, search_results)
except Exception:
if attempt == retries - 1:
return self._fallback(sub_question)
time.sleep(2)
def _generate(self, sub_question: str, search_results: list) -> str:
information = ""
for r in search_results:
summary = r.get("summary", "").strip()
if summary:
information += f"{summary}\n"
if information:
prompt = f"""
You are an academic research writer.
Write ONE well-structured academic paragraph that answers the
research question below using ONLY the provided information.
Research Question:
{sub_question}
Background Information:
{information}
Strict Rules:
- One paragraph only
- Formal academic tone
- No headings
- No citations
- No references
- No markdown
- No bullet points
- Neutral and objective style
"""
else:
prompt = f"""
You are an academic research writer.
Write ONE well-structured academic paragraph that answers the
research question below based on general academic knowledge.
Research Question:
{sub_question}
Strict Rules:
- One paragraph only
- Formal academic tone
- No headings
- No citations
- No references
- No markdown
- No bullet points
- Neutral and objective style
"""
response = ask_llm(prompt)
if not response or not response.strip():
raise RuntimeError("Empty LLM response")
# Remove any hidden chain-of-thought
cleaned = re.sub(r"<think>.*?</think>", "", response, flags=re.DOTALL)
return cleaned.strip()
def _fallback(self, sub_question: str) -> str:
return (
f"This section discusses {sub_question.lower()} by examining its "
"fundamental concepts, relevance, and implications within the "
"broader academic and practical context."
)