import gradio as gr import PyPDF2 import openai from config import OPENAI_API_KEY import pandas as pd import json import re import os openai.api_key = os.getenv("OPENAI_API_KEY") class PDFChat: def __init__(self): self.pdf_text = "" self.chat_history = [] self.system_prompt = """You are a knowledgeable assistant specializing in microcontrollers from Renesas, TI, and STM. When comparing microcontrollers, always provide structured data in a JSON format that can be converted to a table. Focus on key specifications like CPU frequency, memory, peripherals, ADC Resolution , Flash Memory ,temperature range, and special features.""" def extract_text_from_pdf(self, pdf_file): if not pdf_file: return "Please upload a PDF file first." try: self.pdf_text = "" with open(pdf_file.name, "rb") as file: reader = PyPDF2.PdfReader(file) for page in reader.pages: self.pdf_text += page.extract_text() + "\n" return "PDF loaded successfully! You can now ask questions." except Exception as e: return f"Error loading PDF: {str(e)}" def clear_pdf(self): self.pdf_text = "" return "PDF content cleared." def clear_chat_history(self): self.chat_history = [] return "", None def extract_json_from_text(self, text): """Extract JSON data from the response text""" # Find JSON pattern between ```json and ``` json_match = re.search(r'```json\s*(.*?)\s*```', text, re.DOTALL) if json_match: json_str = json_match.group(1) else: # Try to find JSON pattern between { and } json_match = re.search(r'({[\s\S]*})', text) if json_match: json_str = json_match.group(1) else: return None try: return json.loads(json_str) except json.JSONDecodeError: return None def answer_question(self, question): if not question: return "", None structured_prompt = """ If the question is asking for a comparison or suggestion of microcontrollers, provide your response in the following JSON format wrapped in ```json ```: { "explanation": "Your textual explanation here", "comparison_table": [ { "Feature": "feature name", "Controller1_Name": "value", "Controller2_Name": "value", ... }, ... ] } """ messages = [ {"role": "system", "content": self.system_prompt}, {"role": "system", "content": structured_prompt} ] if self.pdf_text: messages.append({"role": "system", "content": f"PDF Content: {self.pdf_text}"}) for human, assistant in self.chat_history: messages.append({"role": "user", "content": human}) messages.append({"role": "assistant", "content": assistant}) messages.append({"role": "user", "content": question}) try: response = openai.ChatCompletion.create( model="gpt-4-turbo", messages=messages ) response_text = response.choices[0].message['content'] json_data = self.extract_json_from_text(response_text) if json_data and "comparison_table" in json_data: df = pd.DataFrame(json_data["comparison_table"]) explanation = json_data.get('explanation', response_text) self.chat_history.append((question, explanation)) return explanation, df else: self.chat_history.append((question, response_text)) return response_text, None except Exception as e: error_message = f"Error generating response: {str(e)}" return error_message, None pdf_chat = PDFChat() with gr.Blocks() as demo: gr.Markdown("# Renasus Chatbot") with gr.Row(): with gr.Column(scale=1): gr.Markdown("### PDF Controls") pdf_input = gr.File( label="Upload PDF", file_types=[".pdf"] ) with gr.Row(): load_button = gr.Button("Load PDF") clear_pdf_button = gr.Button("Clear PDF") status_text = gr.Textbox( label="Status", interactive=False ) with gr.Column(scale=2): gr.Markdown("### Microcontroller Selection Interface") question_input = gr.Textbox( label="Ask about microcontroller selection", placeholder="Describe your requirements or ask for comparisons...", lines=3 ) explanation_text = gr.Textbox( label="Explanation", interactive=False, lines=4 ) table_output = gr.DataFrame( label="Comparison Table", interactive=False, wrap=True ) with gr.Row(): submit_button = gr.Button("Send") clear_history_button = gr.Button("Clear Chat History") with gr.Group(): gr.Markdown("### Example Questions") gr.Examples( examples=[ ["Suggest controller suitable for water level monitoring system comparing RA4M1 and STM32L4"], ["Recommend controller for centralized vehicle lighting and door control systems comparing RA6M3 and STM32F4"], ["Suggest best suited controller for a Solar Inverter Design comparing RA6T1 and TMS320F28379D"], ["Compare RA6M5 and STM32G4 series for building automation applications"], ], inputs=[question_input], label="Example Questions" ) load_button.click( pdf_chat.extract_text_from_pdf, inputs=[pdf_input], outputs=[status_text] ) clear_pdf_button.click( pdf_chat.clear_pdf, outputs=[status_text] ) clear_history_button.click( pdf_chat.clear_chat_history, outputs=[explanation_text, table_output] ) def handle_question(question): explanation, df = pdf_chat.answer_question(question) return explanation, df, "" question_input.submit( handle_question, inputs=[question_input], outputs=[explanation_text, table_output, question_input] ) submit_button.click( handle_question, inputs=[question_input], outputs=[explanation_text, table_output, question_input] ) if __name__ == "__main__": demo.launch(debug=True)