| from flask import Flask, request, jsonify |
| from flask_cors import CORS |
| import requests |
| import os |
| import json |
|
|
| app = Flask(__name__) |
| CORS(app) |
|
|
| |
| API_KEY = os.environ.get("etape_calcul_markdown") |
|
|
| |
| ALBERT_URL = "https://albert.api.etalab.gouv.fr/v1/chat/completions" |
|
|
| @app.route('/') |
| def home(): |
| return "Serveur Albert Proxy en ligne (Mode Analyse Markdown v3.1) !" |
|
|
| @app.route('/verify', methods=['POST']) |
| def verify_math(): |
| |
| data = request.json |
| user_latex = data.get('userLatex', '') |
| expected_latex = data.get('expectedLatex', '') |
| problem_expression = data.get('problemExpression', '') |
| mode = data.get('mode', 'simple') |
|
|
| |
| if not API_KEY: |
| return jsonify({"error": "Clé API etape_calcul_markdown manquante dans les Settings"}), 500 |
|
|
| |
| if mode == "steps_analysis": |
| system_prompt = ( |
| "Tu es un professeur de mathématiques bienveillant pour des élèves de Seconde/Première. " |
| "L'élève doit simplifier une expression. Il doit détailler ses étapes de calcul. " |
| "TON RÔLE : Analyser la démarche ligne par ligne." |
| "\n\nCONSIGNES DE FORMATAGE (MARKDOWN & LATEX) :" |
| "1. Utilise le Markdown pour la structure (listes à puces '-', gras '**')." |
| "2. IMPORTANT : Ne commence JAMAIS une ligne par des espaces ou des tabulations. L'indentation est INTERDITE car elle crée des blocs de code qui bloquent le rendu mathématique." |
| "3. Utilise $...$ pour les formules dans le texte et $$...$$ pour les formules centrées." |
| "4. NE JAMAIS précéder le symbole dollar d'un anti-slash (n'écris jamais \\$). Écris simplement $." |
| "5. IMPORTANT : Utilise EXCLUSIVEMENT '\\times' pour le symbole de multiplication. " |
| "NE JAMAIS utiliser un autre symbole que '\\times' comme signe de multiplication." |
| "4. Ne jamais utiliser \\[ ou \\]." |
| "\n\nPOINTS DE VIGILANCE ET RÈGLES DE VALIDATION :" |
| "1. RÈGLE DE NON-RECOPIE : Si la réponse de l'élève est identique ou mathématiquement équivalente à l'énoncé SANS développement " |
| "(par exemple, s'il a juste recopié l'expression au carré), tu DOIS mettre isCorrect: false. " |
| "Explique-lui qu'il a simplement recopié l'énoncé et qu'il doit commencer le développement." |
| "2. L'identité remarquable : L'élève doit utiliser (a-b)^2 = a^2 - 2ab + b^2." |
| "3. Le calcul des carrés et du double produit." |
| "\n\nCONSIGNES DE RÉPONSE :" |
| "- Si tout est juste et abouti : Félicite l'élève." |
| "- Si une erreur est détectée : Indique la ligne et explique pourquoi." |
| "- Ne donne pas la solution brute immédiatement, guide l'élève vers la correction." |
| "\n\nFORMAT DE SORTIE : Réponds EXCLUSIVEMENT en JSON : " |
| "{\"isCorrect\": boolean, \"feedback\": \"ton_message_markdown\"}." |
| ) |
| else: |
| system_prompt = "Vérifie l'égalité. Réponds en JSON: {\"isCorrect\": boolean, \"feedback\": \"...\"}." |
| |
| |
| user_prompt = f"ÉNONCÉ D'ORIGINE : {problem_expression}. ATTENDU FINAL : {expected_latex}. RÉPONSE DE L'ÉLÈVE : {user_latex}." |
|
|
| payload = { |
| "model": "openai/gpt-oss-120b", |
| "temperature": 0.1, |
| "messages": [ |
| {"role": "system", "content": system_prompt}, |
| {"role": "user", "content": user_prompt} |
| ] |
| } |
|
|
| headers = { |
| "Authorization": f"Bearer {API_KEY}", |
| "Content-Type": "application/json" |
| } |
|
|
| try: |
| response = requests.post(ALBERT_URL, json=payload, headers=headers) |
| response.raise_for_status() |
| albert_data = response.json() |
| content = albert_data['choices'][0]['message']['content'] |
| |
| try: |
| start_index = content.find('{') |
| end_index = content.rfind('}') + 1 |
| if start_index != -1 and end_index > start_index: |
| json_content = content[start_index:end_index] |
| return jsonify(json.loads(json_content)) |
| return jsonify({"raw_content": content}) |
| except: |
| return jsonify({"raw_content": content}) |
|
|
| except Exception as e: |
| return jsonify({"error": str(e)}), 500 |
|
|
| if __name__ == '__main__': |
| app.run(host='0.0.0.0', port=7860) |