Spaces:
Sleeping
Sleeping
| # app/services/mindmap_service.py | |
| import asyncio | |
| import json | |
| import logging | |
| from app.config import GEMINI_API_KEY | |
| import google.genai as genai | |
| from google.api_core.exceptions import GoogleAPIError | |
| _MINDMAP_MODEL = "gemini-1.5-flash" | |
| _gemini_client = None | |
| if GEMINI_API_KEY: | |
| try: | |
| _gemini_client = genai.Client(api_key=GEMINI_API_KEY) | |
| logging.info(f"[mindmap_service] Initialized google.genai client with model={_MINDMAP_MODEL}") | |
| except Exception as e: | |
| logging.exception(f"[mindmap_service] Failed to init google.genai client: {e}") | |
| _gemini_client = None | |
| else: | |
| logging.warning("[mindmap_service] GEMINI_API_KEY is not set, mindmap generation will be disabled") | |
| async def generate_mindmap(text: str) -> dict: | |
| """ | |
| Sinh cấu trúc mindmap JSON từ văn bản. | |
| Fallback: trả {} nếu không có model hoặc lỗi. | |
| """ | |
| if not _gemini_client: | |
| return {} | |
| prompt = f""" | |
| Bạn là chuyên gia tạo Sơ đồ tư duy. Hãy phân tích văn bản sau và tạo CẤU TRÚC JSON Mindmap. | |
| Yêu cầu: | |
| 1. Xác định Ý chính làm Root. | |
| 2. Phân tách ý phụ thành nhánh con (tối đa 3 cấp). | |
| 3. Nhãn (label) ngắn gọn (< 7 từ). | |
| 4. Màu sắc (colorHex): | |
| - Root: "#6200EE" | |
| - Các nhánh con: sử dụng một trong các màu: "#F59E2B", "#2ECF9A", "#2F9BFF" | |
| 5. CHỈ TRẢ VỀ JSON, không giải thích thêm. | |
| Cấu trúc JSON bắt buộc: | |
| {{ | |
| "root": {{ | |
| "label": "Chủ đề", | |
| "colorHex": "#6200EE", | |
| "children": [ | |
| {{ | |
| "label": "Ý 1", | |
| "colorHex": "#F59E2B", | |
| "children": [] | |
| }} | |
| ] | |
| }} | |
| }} | |
| Văn bản: | |
| \"\"\"{text}\"\"\" | |
| """ | |
| loop = asyncio.get_event_loop() | |
| def call(): | |
| resp = _gemini_client.models.generate_content( | |
| model=_MINDMAP_MODEL, | |
| contents=prompt, | |
| ) | |
| return resp.text or "" | |
| try: | |
| raw = await loop.run_in_executor(None, call) | |
| start = raw.find("{") | |
| end = raw.rfind("}") | |
| if start != -1 and end != -1: | |
| try: | |
| return json.loads(raw[start:end + 1]) | |
| except Exception as e: | |
| logging.warning(f"[mindmap_service] Failed to parse mindmap JSON: {e}") | |
| else: | |
| logging.warning("[mindmap_service] Mindmap response has no JSON block") | |
| except GoogleAPIError as e: | |
| logging.error(f"[mindmap_service] Gemini API error: {e}") | |
| except Exception as e: | |
| logging.exception(f"[mindmap_service] generate_mindmap failed: {e}") | |
| return {} | |