-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ba06ad2
commit e72d09e
Showing
5 changed files
with
245 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import openai | ||
import logging | ||
import boto3 | ||
from botocore.exceptions import ClientError | ||
import json | ||
|
||
logger = logging.getLogger() | ||
logger.setLevel(logging.INFO) | ||
|
||
|
||
def get_secret(): | ||
secret_name = "Hakaton" | ||
region_name = "eu-central-1" | ||
|
||
# Create a Secrets Manager client | ||
session = boto3.session.Session() | ||
client = session.client(service_name="secretsmanager", region_name=region_name) | ||
|
||
try: | ||
get_secret_value_response = client.get_secret_value(SecretId=secret_name) | ||
# Assume the secret is stored as a JSON object | ||
secret = json.loads(get_secret_value_response["SecretString"]) | ||
logger.info("Successfully retrieved secret for OpenAI API key") | ||
return secret["OPENAI_API_KEY"] | ||
except ClientError as e: | ||
logger.exception(f"Unable to retrieve secret: {e}") | ||
raise e | ||
|
||
|
||
# Set the OpenAI API key from the Secrets Manager | ||
openai.api_key = get_secret() | ||
|
||
|
||
def get_gpt_answer(messages): | ||
if not messages: | ||
logger.warning("Messages list is empty.") | ||
return "Pitanje ne može biti prazno." | ||
|
||
logger.info("Calling OpenAI for Q&A") | ||
try: | ||
response = openai.chat.completions.create( | ||
model="gpt-3.5-turbo", | ||
messages=messages, | ||
temperature=0, | ||
) | ||
logger.info("Received response from OpenAI") | ||
return response.choices[0].message.content | ||
except Exception as e: | ||
logger.exception("Error calling OpenAI API: %s", str(e)) | ||
return "Došlo je do greške prilikom pozivanja OpenAI API-ja. Pokušajte ponovo kasnije." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import json | ||
import boto3 | ||
import uuid | ||
import os | ||
from datetime import datetime | ||
from pytz import timezone | ||
from ai_response import get_gpt_answer | ||
import logging | ||
|
||
# Initialize DynamoDB resources | ||
DYNAMODB_QUESTIONS_TABLE = os.getenv("QUESTION_TABLE") | ||
DYNAMODB_CHATS_TABLE = os.getenv("CHATS_TABLE") | ||
dynamodb = boto3.resource("dynamodb") | ||
questions_table = dynamodb.Table(DYNAMODB_QUESTIONS_TABLE) | ||
chats_table = dynamodb.Table(DYNAMODB_CHATS_TABLE) | ||
|
||
# Configure logging | ||
logger = logging.getLogger() | ||
logger.setLevel(logging.INFO) | ||
|
||
|
||
def lambda_handler(event, context): | ||
logger.info("Received event: %s", event) | ||
try: | ||
body = json.loads(event.get("body", "{}")) | ||
user_id = body.get("UserID") | ||
chat_id = body.get("ChatID") | ||
question = body.get("Question") | ||
|
||
if not user_id or not question or not chat_id: | ||
logger.error("Missing UserID, ChatID or Question in the request") | ||
return { | ||
"statusCode": 400, | ||
"body": json.dumps( | ||
{"error": "UserID, ChatID and Question are required"} | ||
), | ||
} | ||
|
||
logger.info("Processing question for user: %s", user_id) | ||
|
||
# Get chat topic from Chats table | ||
chat_response = chats_table.get_item(Key={"ChatID": chat_id}) | ||
if "Item" not in chat_response: | ||
logger.error("ChatID not found in Chats table") | ||
return { | ||
"statusCode": 404, | ||
"body": json.dumps({"error": "ChatID not found"}), | ||
} | ||
|
||
chat_topic = chat_response["Item"]["ChatTopic"] | ||
|
||
# Get the last 10 questions and responses for the chat | ||
response = questions_table.query( | ||
IndexName="ChatID-index", | ||
KeyConditionExpression=boto3.dynamodb.conditions.Key("ChatID").eq(chat_id), | ||
Limit=10, | ||
ScanIndexForward=False, # Get the latest items first | ||
) | ||
|
||
osnovna_skola = "Odgovaras uceniku osnovne skole. Potrudi se da odgovor bude zanimljiv i postavi dodatno pitanje da zainteresujes ucenika." | ||
srednja_skola = "Odgovaras uceniku srednje skole. Potrudi se da odgovor bude na nivou znanja srednjoskolca." | ||
fakultet = "Odgovaras studentu na fakultetu. Daj kompletan odgovor sa referencama. Pretrazi internet za najnovije clanke koji mu mogu pomoci u daljem istrazivanju." | ||
nivo_znanja = fakultet | ||
|
||
SYSPROMPT = f""" | ||
Ti si ekspert za pravljenje testova. Tvoj zadatak je da osnovu teme koja je data izmedju ''' i | ||
pitanja koje je student imao naprvis test od 10 pitanja za studenta. | ||
{nivo_znanja} | ||
Test treba da bude sa 4 ponudjena odgovora od koji je samo jedan tacan. Sve pises na sprpskom jeziku. | ||
Ispisi svih 10 pitanja u json formatu: "pitanje", "ponudjeni odgovori", "slovo za tacan odgovor". | ||
'''{chat_topic}''' | ||
""" | ||
|
||
messages = [{"role": "system", "content": SYSPROMPT}] | ||
for item in reversed( | ||
response["Items"] | ||
): # Reverse to maintain chronological order | ||
messages.append({"role": "user", "content": item["Question"]}) | ||
messages.append({"role": "assistant", "content": item["AIResponse"]}) | ||
|
||
# Add the current question to the messages | ||
messages.append({"role": "user", "content": question}) | ||
|
||
ai_response = get_gpt_answer(messages) | ||
|
||
# Generate UUID for QuestionID | ||
question_id = str(uuid.uuid4()) | ||
|
||
# Get current time in Central European Time (CET) | ||
cet = timezone("Europe/Belgrade") | ||
current_time = datetime.now(cet).isoformat() | ||
|
||
# Save question and AI response to DynamoDB | ||
questions_table.put_item( | ||
Item={ | ||
"QuestionID": question_id, | ||
"UserID": user_id, | ||
"ChatID": chat_id, | ||
"Question": question, | ||
"Timestamp": current_time, | ||
"AIResponse": ai_response, | ||
} | ||
) | ||
|
||
logger.info("Successfully processed question for user: %s", user_id) | ||
return { | ||
"statusCode": 200, | ||
"headers": { | ||
"Content-Type": "application/json", | ||
"Access-Control-Allow-Origin": "*", | ||
"Access-Control-Allow-Methods": "POST", | ||
}, | ||
"body": json.dumps({"Response": ai_response}), | ||
} | ||
except Exception as e: | ||
logger.exception("Error processing request: %s", str(e)) | ||
return { | ||
"statusCode": 500, | ||
"body": json.dumps({"error": "An error occurred. Please try again later."}), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
openai == 1.30.3 | ||
pytz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters