Spaces:
Sleeping
Sleeping
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.") | |