Docfile commited on
Commit
18b4b14
·
verified ·
1 Parent(s): 78cb1ca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -53
app.py CHANGED
@@ -1,5 +1,6 @@
1
  from flask import Flask, render_template, request, send_file, jsonify
2
  from google import genai
 
3
  from PIL import Image
4
  import subprocess
5
  import tempfile
@@ -10,7 +11,7 @@ import base64
10
 
11
  app = Flask(__name__)
12
 
13
- # --- Convstantes ---
14
  MODEL_SINGLE_GENERATION = "gemini-2.5-pro-exp-03-25" # Modèle avec "thinking" pour la génération complète
15
  LATEX_MENTION = r"\vspace{1cm}\noindent\textit{Ce devoir a été généré par Mariam AI. \url{https://mariam-241.vercel.app}}"
16
 
@@ -78,11 +79,44 @@ def clean_latex(raw_latex_text):
78
 
79
  return cleaned.strip() # Retourne le résultat nettoyé
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  # --- Fonction Principale (API GenAI) ---
82
 
83
  def generate_complete_latex(client, image_bytes):
84
  """
85
- Génère une solution complète en LaTeX à partir de l'image en utilisant l'exécution de code.
 
86
  """
87
  try:
88
  # Convertir les bytes en image PIL
@@ -90,17 +124,44 @@ def generate_complete_latex(client, image_bytes):
90
 
91
  prompt = f"""
92
  # ROLE & OBJECTIF
93
- Agis en tant qu'expert en mathématiques et tuteur pédagogue. Ton objectif est de créer une correction détaillée et
94
- irréprochable pour l'exercice mathématique présenté dans l'image fournie.
95
-
96
- # TÂCHE PRINCIPALE
97
- 1. Analyse l'image pour comprendre l'énoncé de l'exercice.
98
- 2. Utilise Python pour effectuer des calculs complexes si nécessaire.
99
- 3. Résous l'exercice mathématique étape par étape.
100
- 4. Génère ensuite la solution complète en LaTeX.
101
-
102
- # SPÉCIFICATIONS TECHNIQUES DU CODE LATEX
103
- [vos spécifications LaTeX actuelles...]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  """
105
 
106
  response = client.models.generate_content(
@@ -108,57 +169,34 @@ def generate_complete_latex(client, image_bytes):
108
  contents=[image, prompt],
109
  config=genai.types.GenerateContentConfig(
110
  temperature=0.3,
111
- tools=[genai.types.Tool(
112
- code_execution=genai.types.ToolCodeExecution()
113
- )]
114
  )
115
  )
116
 
117
- # Traitement de la réponse avec gestion de l'exécution de code
118
- latex_content_raw = None
119
- thinking_content = None
120
- code_execution_results = []
121
-
122
- if response.candidates and response.candidates[0].content and response.candidates[0].content.parts:
123
- for part in response.candidates[0].content.parts:
124
- if getattr(part, 'thought', None):
125
- thinking_content = part.text
126
- elif getattr(part, 'executable_code', None):
127
- # Capture le code exécutable et son résultat
128
- code = part.executable_code.code
129
- result = getattr(part, 'code_execution_result', None)
130
- result_output = result.output if result else "Pas de résultat d'exécution"
131
- code_execution_results.append({
132
- 'code': code,
133
- 'result': result_output
134
- })
135
- elif part.text:
136
- # Le contenu texte contient probablement le LaTeX
137
- if '\\documentclass' in part.text:
138
- latex_content_raw = part.text
139
-
140
- # Si aucun contenu LaTeX n'a été trouvé dans les parties, chercher dans le texte global
141
- if not latex_content_raw and response.text:
142
- if '\\documentclass' in response.text:
143
- latex_content_raw = response.text
144
 
145
  if latex_content_raw:
146
  latex_content_cleaned = clean_latex(latex_content_raw)
147
 
148
- # Vérifier et ajouter la mention obligatoire
149
  if LATEX_MENTION not in latex_content_cleaned:
 
150
  end_doc_tag = "\\end{document}"
151
  if end_doc_tag in latex_content_cleaned:
152
  latex_content_cleaned = latex_content_cleaned.replace(end_doc_tag, f"{LATEX_MENTION}\n{end_doc_tag}")
153
  else:
 
154
  latex_content_cleaned += f"\n{LATEX_MENTION}\n{end_doc_tag}"
155
 
156
- return latex_content_cleaned, thinking_content, None, code_execution_results
157
  else:
158
- return None, thinking_content, "Aucun contenu LaTeX n'a été généré par le modèle.", code_execution_results
159
 
 
 
160
  except Exception as e:
161
- return None, None, f"❌ Erreur lors de la génération du LaTeX: {str(e)}", []
 
162
  # --- Fonction de Compilation LaTeX ---
163
 
164
  def compile_latex_to_pdf(latex_content):
@@ -285,8 +323,8 @@ def process():
285
  if client is None:
286
  return jsonify({'success': False, 'message': message})
287
 
288
- # Générer le LaTeX avec exécution de code
289
- latex_content, thinking_content, error, code_execution_results = generate_complete_latex(client, image_bytes)
290
  if error:
291
  return jsonify({'success': False, 'message': error})
292
 
@@ -297,8 +335,7 @@ def process():
297
  'success': False,
298
  'message': message,
299
  'latex': latex_content,
300
- 'thinking': thinking_content,
301
- 'code_execution': code_execution_results
302
  })
303
 
304
  # Encoder le PDF en base64 pour le retourner au front-end
@@ -310,11 +347,9 @@ def process():
310
  'message': 'PDF généré avec succès',
311
  'latex': latex_content,
312
  'thinking': thinking_content,
313
- 'code_execution': code_execution_results,
314
  'pdf_base64': pdf_base64
315
  })
316
 
317
-
318
  @app.route('/download-pdf', methods=['POST'])
319
  def download_pdf():
320
  if 'pdf_data' not in request.json:
 
1
  from flask import Flask, render_template, request, send_file, jsonify
2
  from google import genai
3
+ from google.genai import types
4
  from PIL import Image
5
  import subprocess
6
  import tempfile
 
11
 
12
  app = Flask(__name__)
13
 
14
+ # --- Constantes ---
15
  MODEL_SINGLE_GENERATION = "gemini-2.5-pro-exp-03-25" # Modèle avec "thinking" pour la génération complète
16
  LATEX_MENTION = r"\vspace{1cm}\noindent\textit{Ce devoir a été généré par Mariam AI. \url{https://mariam-241.vercel.app}}"
17
 
 
79
 
80
  return cleaned.strip() # Retourne le résultat nettoyé
81
 
82
+ def extract_content_from_response(response):
83
+ """
84
+ Extrait le contenu LaTeX et le raisonnement (thought) de la réponse Gemini.
85
+ Prend également en compte les résultats d'exécution de code.
86
+ """
87
+ latex_content_raw = None
88
+ thinking_content = []
89
+ code_execution_results = []
90
+
91
+ if response.candidates and response.candidates[0].content and response.candidates[0].content.parts:
92
+ for part in response.candidates[0].content.parts:
93
+ # Extraire le thinking
94
+ if getattr(part, 'thought', None):
95
+ thinking_content.append(part.text)
96
+
97
+ # Extraire le code et les résultats d'exécution
98
+ if getattr(part, 'executable_code', None):
99
+ thinking_content.append(f"Code généré:\n{part.executable_code.code}")
100
+
101
+ if getattr(part, 'code_execution_result', None):
102
+ code_execution_results.append(part.code_execution_result.output)
103
+ thinking_content.append(f"Résultat d'exécution:\n{part.code_execution_result.output}")
104
+
105
+ # Extraire le texte (contenu LaTeX)
106
+ if getattr(part, 'text', None) and not latex_content_raw:
107
+ latex_content_raw = part.text
108
+
109
+ # Combiner les éléments de thinking_content
110
+ thinking_content = "\n\n".join(thinking_content)
111
+
112
+ return latex_content_raw, thinking_content, code_execution_results
113
+
114
  # --- Fonction Principale (API GenAI) ---
115
 
116
  def generate_complete_latex(client, image_bytes):
117
  """
118
+ Génère une solution complète en LaTeX à partir de l'image en une seule étape.
119
+ Utilise l'exécution de code pour améliorer les réponses mathématiques.
120
  """
121
  try:
122
  # Convertir les bytes en image PIL
 
124
 
125
  prompt = f"""
126
  # ROLE & OBJECTIF
127
+ Agis en tant qu'expert en mathématiques et tuteur pédagogue. Ton objectif est de créer une correction détaillée et irréprochable pour l'exercice mathématique présenté dans l'image fournie. La correction doit être sous forme de document LaTeX complet et directement compilable.
128
+
129
+ # CONTEXTE
130
+ - **Input:** Une image contenant un exercice de mathématiques.
131
+ - **Niveau Cible:** Élève de Terminale S (Lycée, filière scientifique française).
132
+ - **Output Attendu:** Un fichier source LaTeX (.tex) autonome.
133
+
134
+ # TÂCHE PRINCIPALE
135
+ 1. Analyse l'image pour comprendre parfaitement l'énoncé de l'exercice.
136
+ 2. Résous l'exercice de manière rigoureuse, étape par étape.
137
+ 3. Utilise l'exécution de code Python quand nécessaire pour vérifier tes calculs, résoudre des équations ou générer des visualisations.
138
+ 4. Rédige la solution complète directement en code LaTeX, en respectant **toutes** les spécifications ci-dessous.
139
+
140
+ # SPÉCIFICATIONS TECHNIQUES DU CODE LATEX
141
+ 1. **Structure du Document:** Commence **strictement** par `\\documentclass{{article}}` et se termine **strictement** par `\\end{{document}}`.
142
+ 2. **Packages Requis:** Inclus impérativement les packages suivants via `\\usepackage{{...}}`: `amsmath`, `amssymb`, `geometry`, `hyperref`, `url`. Assure-toi qu'ils sont déclarés dans le préambule.
143
+ 3. **Compilabilité:** Le code généré doit être valide et compilable sans erreur avec `pdflatex`.
144
+ 4. **Formatage du Code:** Produis un code LaTeX propre, bien indenté et lisible.
145
+ 5. **Environnements Mathématiques:** Utilise les environnements LaTeX appropriés (`align`, `equation`, `gather`, etc.) pour présenter les calculs et les équations de manière claire et standard.
146
+ 6. **AUCUN Marqueur de Code:** Le résultat doit être **uniquement** le code LaTeX brut. N'inclus **JAMAIS** de marqueurs de code comme ```latex ... ``` ou ``` ... ``` au début ou à la fin.
147
+
148
+ # STYLE & CONTENU DE LA SOLUTION
149
+ 1. **Pédagogie:** La correction doit être claire, aérée et facile à comprendre pour un élève de Terminale S.
150
+ 2. **Justifications:** Justifie **chaque** étape clé du raisonnement mathématique. Explique *pourquoi* une certaine méthode est utilisée ou *comment* on passe d'une étape à l'autre.
151
+ 3. **Rigueur:** Assure l'exactitude mathématique complète de la solution.
152
+ 4. **Structure Logique:** Organise la solution de manière logique. Utilise des sections (`\\section*{{...}}`, `\\subsection*{{...}}`) si cela améliore la clarté pour des problèmes longs ou multi-parties.
153
+ 5. **Mention Obligatoire:** Insère la ligne suivante **exactement** telle quelle, juste avant la ligne `\\end{{document}}`:
154
+ {LATEX_MENTION}
155
+
156
+ # UTILISATION DU CODE PYTHON
157
+ 1. Utilise Python pour vérifier tes calculs, résoudre des équations complexes ou générer des visualisations.
158
+ 2. Lorsque tu utilises l'exécution de code, assure-toi que les résultats sont correctement intégrés dans ta solution LaTeX.
159
+ 3. N'affiche pas le code Python lui-même dans le document LaTeX final, utilise-le uniquement comme outil pour améliorer la qualité de ta correction.
160
+
161
+ # PROCESSUS INTERNE RECOMMANDÉ (Pour l'IA)
162
+ 1. **Analyse Approfondie:** Décompose le problème en sous-étapes logiques.
163
+ 2. **Résolution Étape par Étape:** Effectue la résolution mathématique complète en interne.
164
+ 3. **Traduction en LaTeX:** Convertis ta résolution raisonnée en code LaTeX, en appliquant méticuleusement toutes les spécifications de formatage et de style demandées
165
  """
166
 
167
  response = client.models.generate_content(
 
169
  contents=[image, prompt],
170
  config=genai.types.GenerateContentConfig(
171
  temperature=0.3,
172
+ tools=[types.Tool(code_execution=types.ToolCodeExecution)]
 
 
173
  )
174
  )
175
 
176
+ latex_content_raw, thinking_content, code_execution_results = extract_content_from_response(response)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
  if latex_content_raw:
179
  latex_content_cleaned = clean_latex(latex_content_raw)
180
 
181
+ # Vérification supplémentaire : est-ce que la mention obligatoire est présente ?
182
  if LATEX_MENTION not in latex_content_cleaned:
183
+ # Tente de l'insérer avant \end{document}
184
  end_doc_tag = "\\end{document}"
185
  if end_doc_tag in latex_content_cleaned:
186
  latex_content_cleaned = latex_content_cleaned.replace(end_doc_tag, f"{LATEX_MENTION}\n{end_doc_tag}")
187
  else:
188
+ # Si \end{document} n'est pas là, ajoute les deux à la fin
189
  latex_content_cleaned += f"\n{LATEX_MENTION}\n{end_doc_tag}"
190
 
191
+ return latex_content_cleaned, thinking_content, None
192
  else:
193
+ return None, thinking_content, "Aucun contenu LaTeX n'a été généré par le modèle."
194
 
195
+ except genai.types.StopCandidateException as e:
196
+ return None, None, "❌ Génération stoppée (possible contenu inapproprié)"
197
  except Exception as e:
198
+ return None, None, f"❌ Erreur lors de la génération du LaTeX: {str(e)}"
199
+
200
  # --- Fonction de Compilation LaTeX ---
201
 
202
  def compile_latex_to_pdf(latex_content):
 
323
  if client is None:
324
  return jsonify({'success': False, 'message': message})
325
 
326
+ # Générer le LaTeX
327
+ latex_content, thinking_content, error = generate_complete_latex(client, image_bytes)
328
  if error:
329
  return jsonify({'success': False, 'message': error})
330
 
 
335
  'success': False,
336
  'message': message,
337
  'latex': latex_content,
338
+ 'thinking': thinking_content
 
339
  })
340
 
341
  # Encoder le PDF en base64 pour le retourner au front-end
 
347
  'message': 'PDF généré avec succès',
348
  'latex': latex_content,
349
  'thinking': thinking_content,
 
350
  'pdf_base64': pdf_base64
351
  })
352
 
 
353
  @app.route('/download-pdf', methods=['POST'])
354
  def download_pdf():
355
  if 'pdf_data' not in request.json: