Gilbra commited on
Commit
fd2cea0
·
1 Parent(s): 2b97c56

fix utils complete

Browse files
Files changed (1) hide show
  1. utils.py +147 -11
utils.py CHANGED
@@ -1,11 +1,41 @@
1
  import os
2
  import re
 
3
 
4
  from openai import OpenAI
5
  from groq import Groq
6
  import anthropic
7
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  # =====================================================
10
  # DEEPSEEK
11
  # =====================================================
@@ -130,25 +160,31 @@ def call_llm(
130
  max_tokens: int = 2000
131
  ):
132
 
 
 
133
  if provider == "deepseek":
 
134
  return call_deepseek(
135
  prompt,
136
  max_tokens=max_tokens
137
  )
138
 
139
  elif provider == "groq":
 
140
  return call_groq(
141
  prompt,
142
  max_tokens=max_tokens
143
  )
144
 
145
  elif provider == "claude":
 
146
  return call_claude(
147
  prompt,
148
  max_tokens=max_tokens
149
  )
150
 
151
  else:
 
152
  return "ERREUR: provider inconnu"
153
 
154
 
@@ -160,7 +196,8 @@ def smart_call(prompt: str):
160
 
161
  providers = [
162
  "deepseek",
163
- "groq"
 
164
  ]
165
 
166
  for provider in providers:
@@ -170,21 +207,28 @@ def smart_call(prompt: str):
170
  provider=provider
171
  )
172
 
173
- if not result.startswith("ERREUR"):
 
 
 
174
  return result
175
 
176
  return "ERREUR: tous les providers ont échoué"
177
 
178
 
179
  # =====================================================
180
- # EXTRACTION LATEX
181
  # =====================================================
182
 
183
  def extract_latex_blocks(text: str):
184
 
185
  pattern = r'\$\$([^\$]+)\$\$|\\\[(.*?)\\\]|\$([^\$]+)\$'
186
 
187
- matches = re.findall(pattern, text, re.DOTALL)
 
 
 
 
188
 
189
  equations = []
190
 
@@ -195,23 +239,30 @@ def extract_latex_blocks(text: str):
195
  if eq and eq.strip():
196
  equations.append(eq.strip())
197
 
198
- seen = set()
199
-
200
  unique = []
201
 
 
 
202
  for eq in equations:
203
 
204
  if eq not in seen:
 
205
  seen.add(eq)
 
206
  unique.append(eq)
207
 
208
  return unique
209
 
 
210
  # =====================================================
211
- # EXTRACTION EQUATIONS VIA LLM
212
  # =====================================================
213
 
214
- def extract_equations_with_llm(text: str):
 
 
 
215
 
216
  prompt = f"""
217
  Tu es un assistant scientifique.
@@ -219,12 +270,97 @@ Tu es un assistant scientifique.
219
  Extrais uniquement les équations mathématiques
220
  présentes dans ce texte.
221
 
222
- Retourne uniquement une liste brute.
 
 
 
 
 
 
 
223
 
224
  Texte :
225
  {text}
226
  """
227
 
228
- response = smart_call(prompt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
 
230
- return extract_latex_blocks(response)
 
 
 
 
 
 
1
  import os
2
  import re
3
+ import json
4
 
5
  from openai import OpenAI
6
  from groq import Groq
7
  import anthropic
8
 
9
 
10
+ # =====================================================
11
+ # JSON HELPERS
12
+ # =====================================================
13
+
14
+ def clean_json_text(text: str) -> str:
15
+
16
+ if not text:
17
+ return ""
18
+
19
+ text = text.strip()
20
+
21
+ # retire ```json
22
+ text = re.sub(r"^```json", "", text)
23
+ text = re.sub(r"^```", "", text)
24
+ text = re.sub(r"```$", "", text)
25
+
26
+ return text.strip()
27
+
28
+
29
+ def safe_json_loads(text: str):
30
+
31
+ try:
32
+ cleaned = clean_json_text(text)
33
+ return json.loads(cleaned)
34
+
35
+ except Exception:
36
+ return None
37
+
38
+
39
  # =====================================================
40
  # DEEPSEEK
41
  # =====================================================
 
160
  max_tokens: int = 2000
161
  ):
162
 
163
+ provider = provider.lower()
164
+
165
  if provider == "deepseek":
166
+
167
  return call_deepseek(
168
  prompt,
169
  max_tokens=max_tokens
170
  )
171
 
172
  elif provider == "groq":
173
+
174
  return call_groq(
175
  prompt,
176
  max_tokens=max_tokens
177
  )
178
 
179
  elif provider == "claude":
180
+
181
  return call_claude(
182
  prompt,
183
  max_tokens=max_tokens
184
  )
185
 
186
  else:
187
+
188
  return "ERREUR: provider inconnu"
189
 
190
 
 
196
 
197
  providers = [
198
  "deepseek",
199
+ "groq",
200
+ "claude"
201
  ]
202
 
203
  for provider in providers:
 
207
  provider=provider
208
  )
209
 
210
+ if (
211
+ isinstance(result, str)
212
+ and not result.startswith("ERREUR")
213
+ ):
214
  return result
215
 
216
  return "ERREUR: tous les providers ont échoué"
217
 
218
 
219
  # =====================================================
220
+ # EXTRACTION LATEX SIMPLE
221
  # =====================================================
222
 
223
  def extract_latex_blocks(text: str):
224
 
225
  pattern = r'\$\$([^\$]+)\$\$|\\\[(.*?)\\\]|\$([^\$]+)\$'
226
 
227
+ matches = re.findall(
228
+ pattern,
229
+ text,
230
+ re.DOTALL
231
+ )
232
 
233
  equations = []
234
 
 
239
  if eq and eq.strip():
240
  equations.append(eq.strip())
241
 
242
+ # remove duplicates
 
243
  unique = []
244
 
245
+ seen = set()
246
+
247
  for eq in equations:
248
 
249
  if eq not in seen:
250
+
251
  seen.add(eq)
252
+
253
  unique.append(eq)
254
 
255
  return unique
256
 
257
+
258
  # =====================================================
259
+ # EXTRACTION EQUATIONS AVEC LLM
260
  # =====================================================
261
 
262
+ def extract_equations_with_llm(
263
+ text: str,
264
+ provider: str = "deepseek"
265
+ ):
266
 
267
  prompt = f"""
268
  Tu es un assistant scientifique.
 
270
  Extrais uniquement les équations mathématiques
271
  présentes dans ce texte.
272
 
273
+ Retourne STRICTEMENT un JSON valide
274
+ sous cette forme :
275
+
276
+ [
277
+ {{
278
+ "latex": "E = mc^2"
279
+ }}
280
+ ]
281
 
282
  Texte :
283
  {text}
284
  """
285
 
286
+ response = call_llm(
287
+ prompt,
288
+ provider=provider,
289
+ max_tokens=2000
290
+ )
291
+
292
+ data = safe_json_loads(response)
293
+
294
+ if data is None:
295
+ return []
296
+
297
+ return data
298
+
299
+
300
+ # =====================================================
301
+ # VALIDATION IR
302
+ # =====================================================
303
+
304
+ def validate_ir(ir):
305
+
306
+ if not isinstance(ir, dict):
307
+ return False
308
+
309
+ if "nodes" not in ir:
310
+ return False
311
+
312
+ if "edges" not in ir:
313
+ return False
314
+
315
+ return True
316
+
317
+
318
+ # =====================================================
319
+ # NORMALISATION IR
320
+ # =====================================================
321
+
322
+ def normalize_ir(ir):
323
+
324
+ if not isinstance(ir, dict):
325
+ return {
326
+ "name": "Invalid IR",
327
+ "strategy": "fallback",
328
+ "nodes": [],
329
+ "edges": []
330
+ }
331
+
332
+ ir.setdefault("name", "Unnamed IR")
333
+ ir.setdefault("strategy", "fallback")
334
+ ir.setdefault("nodes", [])
335
+ ir.setdefault("edges", [])
336
+
337
+ return ir
338
+
339
+
340
+ # =====================================================
341
+ # GENERATION IR FALLBACK
342
+ # =====================================================
343
+
344
+ def build_fallback_ir(equations):
345
+
346
+ nodes = []
347
+
348
+ for i, eq in enumerate(equations):
349
+
350
+ if isinstance(eq, dict):
351
+ latex = eq.get("latex", "")
352
+ else:
353
+ latex = str(eq)
354
+
355
+ nodes.append({
356
+ "id": f"eq_{i}",
357
+ "type": "equation",
358
+ "latex": latex
359
+ })
360
 
361
+ return {
362
+ "name": "Fallback Variant 1",
363
+ "strategy": "fallback",
364
+ "nodes": nodes,
365
+ "edges": []
366
+ }