| """ |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| β NVIDIA Nemotron Nano VL via OpenRouter - Doc2GL v2.0 β |
| β β |
| β Description : GΓ©nΓ©ration de graphes Mermaid avec Nemotron Nano 12B VL β |
| β Auteur : YOUMBI CHATUE DANIELE β |
| ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| """ |
|
|
| import os |
| import base64 |
| import logging |
| import requests |
|
|
| |
| logging.basicConfig(level=logging.INFO) |
|
|
|
|
| |
| |
| |
|
|
| def generate_mermaid_from_nvidia(base64_image): |
| """ |
| Génère un diagramme Mermaid à partir d'une image en utilisant NVIDIA Nemotron via OpenRouter. |
| |
| Args: |
| base64_image (str): Image encodΓ©e en Base64 |
| |
| Returns: |
| str: Code Mermaid reprΓ©sentant le graphe de connaissances |
| |
| Raises: |
| EnvironmentError: Si la clΓ© API n'est pas dΓ©finie |
| Exception: Si l'appel au modèle échoue |
| |
| Note: |
| - Utilise NVIDIA Nemotron Nano 12B 2 VL via OpenRouter |
| - Pas de tΓ©lΓ©chargement, pas de GPU requis |
| - ClΓ© API requise : NVIDIA_API_KEY (clΓ© OpenRouter) |
| """ |
| |
| |
| |
| |
| api_key = os.environ.get("NVIDIA_API_KEY") or os.environ.get("QWEN_API_KEY") |
|
|
| if not api_key: |
| raise EnvironmentError( |
| "β Aucune clΓ© API OpenRouter trouvΓ©e.\n" |
| "DΓ©finis NVIDIA_API_KEY ou QWEN_API_KEY (mΓͺme clΓ© OpenRouter)\n" |
| "Format : sk-or-v1-xxxxxxxxxxxxxxxxxxxxx" |
| ) |
|
|
| try: |
| |
| |
| |
| OPENROUTER_API_URL = "https://openrouter.ai/api/v1/chat/completions" |
|
|
| headers = { |
| "Authorization": f"Bearer {api_key}", |
| "Content-Type": "application/json", |
| "HTTP-Referer": "https://doc2gl.app", |
| "X-Title": "Doc2GL v2.0" |
| } |
|
|
| |
| |
| |
| payload = { |
| |
| "model": "nvidia/nemotron-nano-12b-v2-vl:free", |
| "messages": [ |
| { |
| "role": "user", |
| "content": [ |
| { |
| "type": "image_url", |
| "image_url": { |
| "url": f"data:image/jpeg;base64,{base64_image}" |
| } |
| }, |
| { |
| "type": "text", |
| "text": ( |
| "Generate a Mermaid diagram of this mindmap image in the following " |
| "structured format: A main concept at the top connects to " |
| "several sub-concepts, which further branch into related " |
| "elements. Use a graph TD structure, and label each node " |
| "with meaningful names.\n\n" |
| "Example format:\n" |
| "graph TD\n" |
| "A[Main Topic] --> B[Subtopic 1]\n" |
| "A --> C[Subtopic 2]\n" |
| "B --> D[Detail 1]\n\n" |
| "Generate ONLY the Mermaid code, without any explanation or markdown formatting." |
| ) |
| } |
| ] |
| } |
| ], |
| "temperature": 0.7, |
| "max_tokens": 1024, |
| "top_p": 0.9 |
| } |
|
|
| |
| |
| |
| logging.info("π€ GΓ©nΓ©ration en cours avec NVIDIA Nemotron (via OpenRouter)...") |
|
|
| response = requests.post( |
| OPENROUTER_API_URL, |
| headers=headers, |
| json=payload, |
| timeout=60 |
| ) |
|
|
| |
| |
| |
| if response.status_code != 200: |
| error_msg = f"Erreur API OpenRouter : {response.status_code} - {response.text}" |
| logging.error(f"β {error_msg}") |
| raise Exception(error_msg) |
|
|
| result = response.json() |
| output_text = result["choices"][0]["message"]["content"] |
|
|
| logging.info("β
GΓ©nΓ©ration terminΓ©e avec NVIDIA Nemotron (OpenRouter)") |
|
|
| |
| |
| |
| clean_lines = [] |
| for line in output_text.split("\n"): |
| clean_line = line.replace("```mermaid", "").replace("```", "").strip() |
| clean_line = clean_line.split("'''")[0].strip() |
|
|
| if clean_line and not clean_line.startswith("style"): |
| clean_lines.append(clean_line) |
|
|
| mermaid_code = "\n".join(clean_lines) |
|
|
| if "graph" not in mermaid_code.lower() and "-->" not in mermaid_code: |
| logging.warning("β οΈ Le code gΓ©nΓ©rΓ© ne semble pas Γͺtre un diagramme Mermaid valide") |
|
|
| return mermaid_code |
|
|
| except Exception as e: |
| logging.error(f"β Erreur lors de l'appel Γ l'API NVIDIA (OpenRouter) : {e}") |
| raise |
|
|
|
|
| |
| |
| |
|
|
| if __name__ == "__main__": |
| import sys |
|
|
| test_image_path = "test_mindmap.png" |
|
|
| if not os.path.exists(test_image_path): |
| print(f"β Fichier {test_image_path} introuvable") |
| sys.exit(1) |
|
|
| with open(test_image_path, "rb") as f: |
| base64_image = base64.b64encode(f.read()).decode('utf-8') |
|
|
| print("π Test de gΓ©nΓ©ration avec NVIDIA Nemotron (OpenRouter)...") |
|
|
| try: |
| mermaid = generate_mermaid_from_nvidia(base64_image) |
| print("\n" + "="*80) |
| print("π DIAGRAMME MERMAID GΓNΓRΓ :") |
| print("="*80) |
| print(mermaid) |
| print("="*80) |
| print("\nβ
SUCCESS !") |
| except Exception as e: |
| print(f"β Erreur : {e}") |