File size: 5,018 Bytes
21a4c2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e9a3e3
 
 
21a4c2b
6e9a3e3
 
 
21a4c2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3a22488
21a4c2b
 
 
 
 
 
 
 
 
 
8d389fb
21a4c2b
cde5b9b
21a4c2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
import openai
import streamlit as st
from dotenv import load_dotenv
import boto3
import base64
import datetime
import json

load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
client = openai.OpenAI(api_key=OPENAI_API_KEY)

dynamodb = boto3.resource(
    'dynamodb',
    aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID'), 
    aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY'),
    region_name='ap-northeast-2'  # ์›ํ•˜๋Š” ๋ฆฌ์ „์œผ๋กœ ๋ณ€๊ฒฝ
)
table = dynamodb.Table('ChatbotConversations')

#original_allowed_usernames = os.getenv('ALLOWED_NAMES')
#allowed_usernames = json.loads(original_allowed_usernames)

original_allowed_usernames = os.getenv('ALLOWED_NAMES')
original_allowed_usernames = original_allowed_usernames.strip()

# JSON ํŒŒ์‹ฑ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
allowed_usernames = json.loads(original_allowed_usernames)

def is_valid_username(username):
    return username in allowed_usernames

st.title(':male-teacher: AI ROBLOX Tutor - Feedback')
st.header(':two: Tutor for Feedack: Get feedbacks and suggestions on your own Roblox game codes!')

user_id = st.text_input(label='Assigned ID.')


if is_valid_username(user_id):
    st.write(f'ID: :violet[{user_id}]')

    purpose = st.text_input(
        label='Write the purpose of the code that you want to get feedback on.',
        placeholder='purpose of your code'
    )

    st.write(f'Purpose: :violet[{purpose}]')

    eval = st.text_input(
        label='Write the code that you want to get feedback on.',
        placeholder='copy and paste syntax-based code script'
    )

    st.write(f'Codes: :violet[{eval}]')

    query2 = "purpose: " + purpose + ". texted codes: " + eval

    query_2 = 'AT_TUTOR_2: ' + query2

    # ์ด๋ฏธ์ง€ ์ž…๋ ฅ
    image_uploaded2 = st.file_uploader("OPTIONAL: Upload an image of the code that you want to get feedback on", type=["png", "jpg", "jpeg"])

    def evaluator_persona_query(eval, purpose, image_data=None):
        import openai
        openai.api_key = OPENAI_API_KEY

        VISION_PROMPT_MESSAGES = [
            {
                "role": "system",
                "content": "Your role: You are a tutor who gives feedback about the Roblox code made with a Roblox plugin called Blocklua. Situation: A student is using a plugin called Blocklua to program using block-based code. The student ask for corrective and explanatory feedback of their own code of the Roblox games of their own, sometimes including images. What to do: If they ask you to give feedback and suggestion about the code they uploaded or the code in the image, give them the corrective or explanatory feedback and suggestion based on the aspect of Algorithm & procedures, Automation logic, perfection. PERCEIVE the code the user enetered as it is, and NEVER change it until the code suggestion. " 
                ##CSTA & ISTE (2011). Computational Thinking in K-12 education โ€“ teacher resources, 2nd edition, CSTA & ISTE
            },
            {"role": "user", "content": "Read and find the meaning of the code in the image and text and evaluate the code. purpose of the code: "+ purpose + "code to be analysed: " + eval},
        ]

        if image_data is not None:
            encoded_image = base64.b64encode(image_data).decode("utf-8")
            VISION_PROMPT_MESSAGES.append({"role": "user", "content": encoded_image})

        params = {
            "model": "gpt-4o-mini",
            "messages": VISION_PROMPT_MESSAGES,
            "max_tokens": 3000, # 1024,
        }

        trimmed_answer = ""  # trimmed_answer ์ดˆ๊ธฐํ™”
        try:
            full_answer = openai.chat.completions.create(**params)
            trimmed_answer = full_answer.choices[0].message.content
        except Exception as e:
            print(f"Error: {e}")
            trimmed_answer = f"Error: {e}"  # ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ trimmed_answer์— ํ• ๋‹น

        return trimmed_answer

    # ๋ฒ„ํŠผ ํด๋ฆญ
    button2 = st.button(':sparkles: suggestions :sparkles:')

    def save_message(user_id, message, timestamp=None):
        if timestamp is None:
            timestamp = datetime.datetime.now()

        # datetime ๊ฐ์ฒด๋ฅผ DynamoDB ์ง€์› ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜
        if isinstance(timestamp, datetime.datetime):
            timestamp = int(timestamp.timestamp())  # Unix ํƒ€์ž„์Šคํƒฌํ”„(์ดˆ ๋‹จ์œ„ ์ •์ˆ˜)๋กœ ๋ณ€ํ™˜

        table.put_item(
            Item={
                'UserID': user_id,
                'Timestamp': timestamp,
                'Message': message
            }
        )


    if button2:
        eval = eval
        save_message(user_id, query_2) 

        if image_uploaded2 is not None:
            image_data = image_uploaded2.read()
            answer = evaluator_persona_query(eval, purpose, image_data)
        else:
            answer = evaluator_persona_query(eval, purpose)
        
        answer_2 = 'AT_TUTOR_2: ' + answer
        save_message(user_id, answer_2)
        st.write(f'{answer}')

else:
    st.warning("Invalid username. Please enter a valid username.")