AniseF commited on
Commit
bc63458
·
verified ·
1 Parent(s): 7575aa9

Delete question_runner.py

Browse files
Files changed (1) hide show
  1. question_runner.py +0 -226
question_runner.py DELETED
@@ -1,226 +0,0 @@
1
- # question_runner.py
2
-
3
- import tempfile
4
- import re
5
- from router_client import query_model
6
- from doc_utils import get_questions_from_doc
7
- from config import SYNTAX_DOC_URL, MORPHOLOGY_DOC_URL, SEMANTICS_DOC_URL
8
-
9
-
10
- def detect_language(passage):
11
- """
12
- Detect whether the passage is in Latin or Greek based on character analysis.
13
-
14
- Returns:
15
- str: 'latin', 'greek', or 'unknown'
16
- """
17
- # Remove whitespace, punctuation, and numbers for analysis
18
- import string
19
- punctuation_and_whitespace = set(string.punctuation + string.whitespace + string.digits)
20
- cleaned = ''.join(char for char in passage if char not in punctuation_and_whitespace)
21
-
22
- # Greek alphabet ranges (Unicode)
23
- greek_chars = re.findall(r'[\u0370-\u03FF\u1F00-\u1FFF]', cleaned)
24
-
25
- # Latin alphabet - look for standard Latin letters
26
- # Greek text might have some Latin, so we check for Greek-specific patterns
27
- latin_chars = re.findall(r'[a-zA-Z]', cleaned)
28
-
29
- if not cleaned:
30
- return 'unknown'
31
-
32
- # If we find Greek characters, it's Greek
33
- if greek_chars and len(greek_chars) > len(cleaned) * 0.3: # At least 30% Greek chars
34
- return 'greek'
35
-
36
- # Otherwise assume Latin if it has Latin characters
37
- if latin_chars and len(latin_chars) > len(cleaned) * 0.3:
38
- return 'latin'
39
-
40
- return 'unknown'
41
-
42
-
43
- def get_language_specific_instructions(language, doc_type):
44
- """
45
- Generate language-specific instructions to prevent AI hallucinations
46
- and incorrect application of grammatical rules.
47
-
48
- Args:
49
- language: 'latin' or 'greek'
50
- doc_type: 'syntax', 'morphology', or 'semantics'
51
-
52
- Returns:
53
- str: Language-specific instruction text
54
- """
55
- if language == 'latin':
56
- if doc_type.lower() == 'morphology':
57
- return """You are a Latin morphology expert. When analyzing Latin:
58
- - Focus ONLY on Latin grammatical categories: tense, mood, voice, person, number, case, gender
59
- - Use traditional Latin grammatical terminology
60
- - Do NOT apply Greek-specific concepts like the dual number (which does not exist in Latin)
61
- - Do NOT apply Greek-specific mood distinctions
62
- - Remember Latin has 6 cases (nominative, genitive, dative, accusative, ablative, vocative)
63
- - Remember Latin verb system: 6 tenses, 3 moods (indicative, subjunctive, imperative), 3 voices"""
64
- elif doc_type.lower() == 'syntax':
65
- return """You are a Latin syntax expert. When analyzing Latin:
66
- - Apply ONLY Latin syntactic rules and conventions
67
- - Focus on Latin clause structure, agreement patterns, and word order principles
68
- - Do NOT assume Greek syntactic conventions (e.g., Greek subjunctive/optative patterns may differ)
69
- - Remember Latin typically uses SVO/SOV word order with flexible positioning
70
- - Apply Roman conventions for subordination and clause relationships
71
- - Do NOT apply Modern Greek or Koine Greek-specific syntax patterns"""
72
- else: # semantics
73
- return """You are a Latin semantics expert. When analyzing Latin meaning:
74
- - Focus on etymological and semantic fields relevant to Latin
75
- - Use Roman cultural context to interpret meaning
76
- - Do NOT apply Greek philosophical or semantic frameworks that may not apply to Latin texts
77
- - Consider the historical period of the text (Classical, Silver Age, etc.)
78
- - Remember Latin word meanings evolved differently from their Greek cognates"""
79
-
80
- elif language == 'greek':
81
- if doc_type.lower() == 'morphology':
82
- return """You are an Ancient Greek morphology expert. When analyzing Ancient Greek:
83
- - Focus ONLY on Ancient Greek grammatical categories: tense, mood, voice, person, number, case, gender, dual
84
- - Use Attic/Ionic Greek conventions as appropriate to the text
85
- - Remember Greek HAS the dual number (in addition to singular and plural)
86
- - Remember Greek has 3 moods: indicative, subjunctive, optative
87
- - Remember Greek has 5 cases (nominative, genitive, dative, accusative, vocative)
88
- - Do NOT apply Latin-specific grammatical categories (Latin lacks dual, has different mood system)"""
89
- elif doc_type.lower() == 'syntax':
90
- return """You are an Ancient Greek syntax expert. When analyzing Ancient Greek:
91
- - Apply ONLY Ancient Greek syntactic rules and conventions
92
- - Focus on Greek clause structure, participle usage, and optative/subjunctive patterns
93
- - Do NOT assume Latin syntactic conventions (Latin lacks Greek optative, uses subjunctive differently)
94
- - Remember Greek favors parataxis and uses participles extensively
95
- - Apply Greek conventions for indirect discourse and optative in conditional sentences
96
- - Do NOT apply Latin syntax patterns"""
97
- else: # semantics
98
- return """You are an Ancient Greek semantics expert. When analyzing Greek meaning:
99
- - Focus on etymological and semantic fields relevant to Ancient Greek
100
- - Use Hellenic cultural and philosophical context to interpret meaning
101
- - Do NOT apply Roman cultural frameworks that may not apply to Greek texts
102
- - Consider whether the text is Attic, Ionic, or another Greek dialect
103
- - Remember Greek philosophical terminology has specific meanings distinct from Latin usage"""
104
-
105
- else: # unknown language
106
- return """You are a classical language expert analyzing a passage of unknown classical language.
107
- - First identify whether the text is in Latin or Greek
108
- - Then apply only the grammatical and syntactic rules appropriate to that language
109
- - Be careful not to mix grammatical conventions between Latin and Greek
110
- - If unable to determine, ask for clarification"""
111
-
112
-
113
- def create_language_aware_prompt(passage, question, language):
114
- """
115
- Create a prompt that is aware of the language and specific doc type.
116
-
117
- Args:
118
- passage: The text to analyze
119
- question: The question to answer
120
- language: 'latin', 'greek', or 'unknown'
121
-
122
- Returns:
123
- str: The complete prompt
124
- """
125
- language_context = {
126
- 'latin': 'Latin',
127
- 'greek': 'Ancient Greek',
128
- 'unknown': 'Latin or Greek'
129
- }[language]
130
-
131
- prompt = f"""You are a classical language expert specializing in {language_context}.
132
-
133
- LANGUAGE IDENTIFIED: {language.upper()}
134
-
135
- Given the following {language_context} passage:
136
-
137
- {passage}
138
-
139
- Answer the following question concisely and directly:
140
-
141
- {question}
142
-
143
- IMPORTANT GUIDELINES:
144
- - Only apply grammatical and syntactic rules specific to {language_context}
145
- - Do not confuse or mix conventions from Latin and Greek
146
- - If the question asks about a grammatical feature that doesn't exist in {language_context}, note that explicitly
147
- - Be precise about which language's conventions you are applying
148
- - Provide ONLY your direct answer without explanation of your reasoning process
149
- - Do NOT repeat the question or reiterate the principles you're using
150
- - Keep your answer brief and focused
151
-
152
- Answer:"""
153
-
154
- return prompt
155
-
156
-
157
- def run_tool(passage, doc_type):
158
- if not passage.strip():
159
- return "Please enter a passage to analyze.", None, None
160
- if not doc_type:
161
- return "Please select 'Syntax', 'Morphology', or 'Semantics'.", None, None
162
-
163
- try:
164
- # Detect the language of the passage
165
- language = detect_language(passage)
166
-
167
- if doc_type.lower() == "syntax":
168
- doc_url = SYNTAX_DOC_URL
169
- elif doc_type.lower() == "morphology":
170
- doc_url = MORPHOLOGY_DOC_URL
171
- else: # semantics
172
- doc_url = SEMANTICS_DOC_URL
173
- questions = get_questions_from_doc(doc_url)
174
-
175
- if not questions or questions[0].startswith("Error"):
176
- return questions[0], None, None
177
-
178
- est_seconds = round(len(questions) * 2.5, 1)
179
- estimated_time_message = f"Estimated generation time: ~{est_seconds} seconds"
180
-
181
- responses = []
182
- for idx, question in enumerate(questions):
183
- # Get language-specific instructions
184
- language_instructions = get_language_specific_instructions(language, doc_type)
185
-
186
- # Create language-aware prompt
187
- base_prompt = create_language_aware_prompt(passage, question, language)
188
-
189
- # Combine with language-specific instructions
190
- prompt = f"""{language_instructions}
191
-
192
- ---
193
-
194
- {base_prompt}"""
195
-
196
- raw_response, model_used = query_model(prompt)
197
-
198
- if not raw_response or not model_used:
199
- formatted_block = f"""Question: {question.strip()}
200
- Answer:
201
- <No answer – all models failed or quota exceeded.>
202
- Language Detected: {language.upper()}
203
- ===
204
- """
205
- else:
206
- answer = raw_response.split("Answer:")[-1].strip()
207
- formatted_block = f"""Question: {question.strip()}
208
- Answer:
209
- {answer}
210
- Language Detected: {language.upper()}
211
- Model used: {model_used}
212
- ===""" # Separator for logic tree parsing
213
-
214
- responses.append(formatted_block)
215
-
216
- result = "\n\n".join(responses)
217
-
218
- with tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode="w", encoding="utf-8") as f:
219
- f.write(result)
220
- file_path = f.name
221
-
222
- return result, file_path, estimated_time_message
223
-
224
- except Exception as e:
225
- return f"An error occurred: {str(e)}", None, None
226
-