File size: 4,870 Bytes
dc1da67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da60aad
dc1da67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import os
import json

from flask import Flask, request
from flask_cors import CORS

import google.generativeai
google.generativeai.configure(
    api_key=os.environ.get("GEMINI_API_KEY"))

app = Flask(__name__)
CORS(app)


def output_sanitizer(prompt: str) -> dict:
    """
    return dictionary from llm output
    """
    begin = prompt.find("{")
    end = prompt.find("}")
    output = prompt[begin: end + 1]
    
    try:
        output = json.loads(output)
    except json.JSONDecodeError:
        return {}
    
    return output


def dict_style_changer(file: dict) -> dict: 
    """
    parses it in such a way so that mermaid won't crash due to semicolons and such
    """
    """
    {"1[a]" : ["2[b]", "3[c]"], "4[d]" : ["5[e]", "6[f]"]}
    """
    new = {}
    count = 1

    for k, v in file.items():
        new_key = f"{count}[{k}]"
        count += 1
        temp = []

        for i in v:
            new_value = f"{count}[{i}]"
            count += 1
            temp.append(new_value)
        
        new[new_key] = temp

    return new


def dict_to_mermaid(file: dict) -> str:
    """
    returns a mermaid.js syntax to be rendered for the roadmap
    """
    file = dict_style_changer(file)
    output = """
    flowchart TB\n\t
    """
    arrow = " --> "
    thick_arrow = " ==> "

    for k, v in file.items():
        output += f"subgraph {k}\n\t{arrow.join(v)}\n\tend\n\t"
    
    output += thick_arrow.join(list(file.keys()))

    return output


def get_completion(message: str, current_knowledge: str) -> str:
    """
    Returns a string with mermaid syntax.
    """
    sys_message = f"""
You are required to provide a learning roadmap for the given topic. The learner profile is provided. Use these data to give a very detailed learning roadmap. Use the output format shown below. Remember to optimize the roadmap as per the learners profile.

Return the output in JSON format.
Example:
{{
    "<Topic>": [
        "<sub topic 1>", 
        "<sub topic 2>"
    ],
    "<Topic>": [
        "<sub topic 1>", 
        "<sub topic 2>"
    ]
}}

Topic name: {message}
Learner profile: {current_knowledge}
"""
    llm_model = google.generativeai.GenerativeModel('gemini-1.5-flash')
    chat_completion = llm_model.generate_content(sys_message)
    print(chat_completion)
    chat_completion_text = chat_completion.to_dict()['candidates'][0]['content']['parts'][0]['text']
    chat_completion_text = chat_completion_text.replace("(", "")
    chat_completion_text = chat_completion_text.replace(")", "")

    print(dict_to_mermaid(output_sanitizer(chat_completion_text)))
    return dict_to_mermaid(output_sanitizer(chat_completion_text))



@app.route("/gemini_output", methods=['POST'])
def gemini_output():
    message = request.get_json()
    print(message)
    if message['prompt'] == "chess":
        return {'response': """flowchart TB

    subgraph 1[Fundamentals]
        2[Objective of the game] --> 3[Chessboard setup] --> 4[Piece movement King, Queen, Rook, Bishop, Knight, Pawn] --> 5[Special moves Castling, En Passant] --> 6[Check, Checkmate, and Stalemate]
        end
        subgraph 7[Basic Tactics]
        8[Piece value and development] --> 9[Controlling the center] --> 10[Forks] --> 11[Pins] --> 12[Skewers] --> 13[Discovered attacks] --> 14[Double attacks] --> 15[Traps]
        end
        subgraph 16[Openings]
        17[Principles of opening theory] --> 18[Common opening traps to avoid] --> 19[Learning a few standard openings e.g., Italian Game, Ruy Lopez, Sicilian Defense] --> 20[Understanding opening goals control of the center, piece development, king safety]
        end
        subgraph 21[Middlegame Strategy]
        22[Planning and evaluating positions] --> 23[Pawn structures and their weaknesses] --> 24[Identifying tactical opportunities] --> 25[Positional play improving piece placement, creating weaknesses] --> 26[Attacking and defending techniques]
        end
        subgraph 27[Endgames]
        28[Basic checkmates King and Queen, King and Rook] --> 29[Theoretical endgames King and Pawn vs King, Rook and Pawn vs Rook] --> 30[Key endgame principles opposition, triangulation, key squares] --> 31[Practice common endgame patterns]
        end
        subgraph 32[Beyond the Basics]
        33[Studying annotated master games] --> 34[Analyzing your own games] --> 35[Solving chess puzzles and tactics] --> 36[Participating in tournaments and online play] --> 37[Utilizing chess software and engines for analysis and training] --> 38[Exploring advanced concepts e.g., prophylaxis, positional sacrifice]
        end
        1[Fundamentals] ==> 7[Basic Tactics] ==> 16[Openings] ==> 21[Middlegame Strategy] ==> 27[Endgames] ==> 32[Beyond the Basics]"""}
    # return {"prompt": "hi " + message['prompt']}
    return {"response": get_completion(message['prompt'], message['current_knowledge'])}