AITUTOR / app.py
lugiiing's picture
Update app.py
a066775 verified
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')
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')
st.header(':one: Tutor: Ask questions for programming your own Roblox game!')
user_id = st.text_input(label='Assigned ID.')
if is_valid_username(user_id):
st.write(f'ID: :violet[{user_id}]')
query = st.text_input(
label='Write your question.',
placeholder='ex. What properties should I adjust to change the transparency of a Roblox Part?'
)
st.write(f'Query: :violet[{query}]')
query_1 = 'AT_TUTOR_1: ' + query
# ์ด๋ฏธ์ง€ ์ž…๋ ฅ
image_uploaded1 = st.file_uploader("OPTIONAL: Upload an image", type=["png", "jpg", "jpeg"])
def tutor_persona_query(query, image_data=None):
import openai
openai.api_key = OPENAI_API_KEY
VISION_PROMPT_MESSAGES = [
{
"role": "system",
"content": "Your role: You are an AI tutor providing interactive learning support for students engaged in constructionist gaming. Your goal is to offer personalized assistance that aligns with the learnerโ€™s objectives. Context: - The learner is building a game using [Roblox/Lua-based scripting]. - The learner is a pre-service teacher in a digital literacy course. - The learner is engaged in design-based, constructionist learning, working on ill-structured problems. - The learner may need help with computational thinking (CT) concepts such as decomposition, abstraction, algorithmic thinking, and pattern recognition. User Input: - The learner describes a challenge related to game design, programming logic, or debugging. - The learner may request alternative approaches, idea generation, or clarification of CT principles. Expected AI Response: 1. **Restate the learner's problem** in a concise and structured way to confirm understanding. 2. **Provide step-by-step guidance** for solving the problem (e.g., break it into subtasks, suggest a debugging strategy). 3. **Generate alternative approaches** if applicable. 4. **Explain relevant computational thinking concepts** (e.g., if the learner is struggling with loops, explain iteration and suggest a simplified example). 5. **Encourage self-reflection** by prompting the learner to apply the solution to their project. 6. If applicable, **provide a relevant external resource or documentation link**."
},
{"role": "user", "content": query},
]
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
# ๋ฒ„ํŠผ ํด๋ฆญ
button1 = st.button(':sparkles: ask :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 button1:
query_1 = query_1
save_message(user_id, query_1)
if image_uploaded1 is not None:
image_data = image_uploaded1.read()
answer = tutor_persona_query(query, image_data)
else:
answer = tutor_persona_query(query)
answer_1 = 'AT_TUTOR_1: ' + answer
save_message(user_id, answer_1)
st.write(f'{answer}')
else:
st.warning("Invalid username. Please enter a valid username.")