File size: 2,557 Bytes
a6d62e8
 
 
 
 
983ffca
a6d62e8
 
 
 
 
 
0785301
 
a6d62e8
 
 
 
 
 
0785301
a6d62e8
0785301
 
 
a6d62e8
 
 
 
 
0785301
 
 
a6d62e8
 
0785301
 
 
 
a6d62e8
 
 
 
0785301
a6d62e8
0785301
a6d62e8
 
 
 
 
 
 
 
 
 
 
0785301
 
 
a6d62e8
0785301
 
 
 
 
a6d62e8
 
 
 
 
0785301
a6d62e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0785301
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 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 {}