File size: 2,813 Bytes
1fcafa8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import base64
import json
import mimetypes
import re
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage


model = init_chat_model("gemini-2.0-flash", model_provider="google_genai")


def _encode_file(file_path: str) -> str:
    with open(file_path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")


def extract_json(response: str) -> dict:
    # Match inside ```json ... ```
    match = re.search(r"```(?:json)?\s*({.*?})\s*```", response, re.DOTALL)
    
    if match:
        json_str = match.group(1)
    else:
        # Fallback if no code block
        json_str = response.strip()
    
    try:
        return json.loads(json_str)
    except json.JSONDecodeError as e:
        return {"error": "Failed to parse JSON", "raw": response, "details": str(e)}



def analyze_media_structured(file_path: str) -> str:
    """
    Analyze the uploaded image or video of a craft project.

    Focus the analysis on general craft quality dimensions:
    - Structure: Alignment, balance, symmetry
    - Technique: Precision of folds, stitches, lines, etc.
    - Neatness: Clean execution, absence of wrinkles or gaps
    - Materials: Appropriate use, clarity, or consistency (if visible)
    - Areas for improvement: Clear, actionable suggestions

    Return a structured dictionary with specific observations.
    Avoid general encouragement or introductions.
    Do not refer to yourself or the tool.
    """
    mime_type, _ = mimetypes.guess_type(file_path)
    if not mime_type:
        return {"error": "Unsupported file type."}

    encoded = _encode_file(file_path)
    prompt = f"""
    You are a craft analysis assistant. The user uploaded a {mime_type} of their craft project.
    Please return your observations on the following points:

    - Structure: comment on balance, alignment, or symmetry.
    - Technique: precision of folds, stitches, or construction.
    - Neatness: how polished or clean the work appears.
    - Materials: if visible, comment on appropriateness or consistency.
    - Recommendations: a list of 2–3 actionable improvements.

    Return the comments as a string.
    """

    if mime_type.startswith("video"):
        content = [
            {"type": "text", "text": prompt},
            {"type": "media", "data": encoded, "mime_type": mime_type},
        ]
    elif mime_type.startswith("image"):
        content = [
            {"type": "text", "text": prompt},
            {"type": "image_url", "image_url": f"data:{mime_type};base64,{encoded}"},
        ]
    else:
        return {"error": "Unsupported media type."}

    response = model.invoke([HumanMessage(content=content)]).content

    try:
        return response
    except Exception:
        return "Failed to load response from media analysis"