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.")