import PyPDF2 import gradio as gr from groq import Groq # Function to extract PDF def extract_text_from_pdf(pdf_file_path): with open(pdf_file_path, 'rb') as file: reader = PyPDF2.PdfReader(file) extracted_text = "" for page in reader.pages: extracted_text += page.extract_text() return extracted_text # Function to generate different types of questions using Groq def generate_questions(api_key, paper_text): groq_client = Groq(api_key=api_key) # Use the provided API key prompts = [ f"Read this paper submitted by a student. Then, ask them to briefly summarize its outline. Ask the question directly. Do not comment on the paper or add anything else. Present this as a reflection exercise. Paper text: '{paper_text}'", f"Read this paper submitted by a student. Identify a key term that is central to the discussion. Then, ask the student to explain it in context (provide an excerpt from the paper). Do not comment on the paper or add anything else. Paper text: '{paper_text}'", f"Read this paper submitted by a student. Find a key concept or idea in the paper. Then, ask the student to explain how it can be applied to a different real-world scenario. Do not comment on the paper or add anything else. Paper text: '{paper_text}'", f"Read this paper submitted by a student. Create a true or false (but believable) statement about the content of the paper. Then, ask the student to determine if it's true or false. Do not comment on the paper or add anything else. Paper text: '{paper_text}'" ] questions = [] for prompt in prompts: response = groq_client.chat.completions.create( messages=[{"role": "user", "content": prompt}], model="llama-3.1-70b-versatile" ) questions.append(response.choices[0].message.content) return questions # Function to validate each student's answer def validate_answer(api_key, paper_text, question, student_answer): groq_client = Groq(api_key=api_key) # Use the provided API key prompt = ( f"The student was asked questions about a paper they submitted. Compare their answers to the content of the paper." f"Determine if the student's answer reflects an understanding of the paper's content. The goal is to determine whether there are reasons to believe or to doubt that they understand its content, and therefore that they are its author." f"You MUST return 'Flagged' if there is insufficient evidence that the student understands the paper and is its author, or if there is evidence that they might not understand its content or might not be its author." f"Paper text: '{paper_text}'\n\nQuestion: '{question}'\n\nStudent's answer: '{student_answer}'" ) response = groq_client.chat.completions.create( messages=[{"role": "user", "content": prompt}], model="llama-3.1-70b-versatile" ) return response.choices[0].message.content # Function to handle PDF upload and question generation def handle_pdf_upload(api_key, pdf_file): # Save the uploaded file and extract text from it pdf_file_path = pdf_file.name paper_text = extract_text_from_pdf(pdf_file_path) # Generate four types of questions based on the paper's content questions = generate_questions(api_key, paper_text) # Return the generated questions for display return questions # Function to handle answer submission and LLM's final judgment def handle_answer_submission(api_key, pdf_file, answer1, answer2, answer3, answer4): # Extract the paper text for validation pdf_file_path = pdf_file.name paper_text = extract_text_from_pdf(pdf_file_path) # Initialize answers summary answers_summary = "" # Loop over each question-answer pair and validate questions = generate_questions(api_key, paper_text) verification_status = "Thank you! " emoji = "🟢" answers = [answer1, answer2, answer3, answer4] for i in range(len(questions)): validation_result = validate_answer(api_key, paper_text, questions[i], answers[i]) answers_summary += f"Question {i+1}: {questions[i]}\nAnswer: {answers[i]}\nValidation: {validation_result}\n\n" if "Flagged" in validation_result: verification_status = "Please talk to your teacher about this submission 🟠" # Return final judgment summary return f"Final Judgment: {verification_status}\n\nAnswers Summary:\n{answers_summary}" # Gradio Blocks for the App with gr.Blocks() as app: with gr.Row(): # Seshat logo logo_url = "https://i.ibb.co/S7DCk3K/a-logo-design-with-a-stylized-egyptian-scribe-the-i-L59-Gh-Zn-QASp7v-TUazjdp-A-1-s-Ip-Qq-VRIif-VF5dn.png" gr.Image(logo_url, label="", show_label=False, height=200) # User input Groq API key api_key_input = gr.Textbox(label="Enter your Groq API Key", placeholder="Create a free key at https://console.groq.com/keys", type="password") # PDF upload Section pdf_file = gr.File(label="Upload PDF Paper") upload_btn = gr.Button("Upload and Generate Questions") # Q/A section with separate inputs for each question question1 = gr.Textbox(label="Question 1", interactive=False) answer1 = gr.Textbox(label="Answer to Question 1", placeholder="Your answer here...") question2 = gr.Textbox(label="Question 2", interactive=False) answer2 = gr.Textbox(label="Answer to Question 2", placeholder="Your answer here...") question3 = gr.Textbox(label="Question 3", interactive=False) answer3 = gr.Textbox(label="Answer to Question 3", placeholder="Your answer here...") question4 = gr.Textbox(label="Question 4", interactive=False) answer4 = gr.Textbox(label="Answer to Question 4", placeholder="Your answer here...") # Output for result output = gr.Textbox(label="Result", interactive=False) # Upload button upload_btn.click(fn=handle_pdf_upload, inputs=[api_key_input, pdf_file], outputs=[question1, question2, question3, question4]) submit_btn = gr.Button("Submit Answers") # Passing answers individually submit_btn.click(fn=handle_answer_submission, inputs=[api_key_input, pdf_file, answer1, answer2, answer3, answer4], outputs=output) # "Powered by Groq" badge with gr.Row(): groq_url = "https://i.ibb.co/FxPsxKF/PBG-mark1-color.png" gr.Image(groq_url, label="", show_label=False, height=50) # Launch the app app.launch()