Spaces:
Configuration error
Configuration error
| """ | |
| Gradio Interactive Chat App for Educational Information Collection. | |
| """ | |
| # Imports | |
| import gradio as gr | |
| import openai | |
| import json | |
| from datetime import datetime | |
| from typing import List, Optional, Dict | |
| from pydantic import BaseModel, Field | |
| # Constants | |
| SYSTEM_PROMPT = """You are an educational information collection assistant. Your task is to systematically collect the following information in a conversational manner: | |
| Required Information (collect in this order): | |
| 1. Institution Details: | |
| - Name | |
| - Type (e.g., university, college, etc.) | |
| - Location | |
| 2. Degree Information: | |
| - Type (e.g., Bachelor's, Master's, etc.) | |
| - Field of Study | |
| - Status (e.g., completed, ongoing) | |
| 3. Attendance Dates (start and end) | |
| 4. Academic Performance: | |
| - GPA (if provided) | |
| - Honors or awards | |
| 5. Activities: | |
| - Extracurricular activities, roles, and durations | |
| Always maintain a friendly, professional tone while systematically collecting this information.""" | |
| # Data Models | |
| class Institution(BaseModel): | |
| name: str | |
| type: str | |
| location: str | |
| class Degree(BaseModel): | |
| type: str | |
| field: str | |
| status: str | |
| class Dates(BaseModel): | |
| start: str | |
| end: str | |
| class Activity(BaseModel): | |
| name: str | |
| description: str | |
| duration: str | |
| class Academic(BaseModel): | |
| gpa: Optional[float] = None | |
| honors: List[str] = Field(default_factory=list) | |
| achievements: List[str] = Field(default_factory=list) | |
| class Education(BaseModel): | |
| institution: Institution | |
| degree: Degree | |
| dates: Dates | |
| academic: Academic | |
| activities: List[Activity] = Field(default_factory=list) | |
| class EducationRecord(BaseModel): | |
| education: List[Education] = Field(default_factory=list) | |
| metadata: Dict[str, str] | |
| # Assistant Logic | |
| class EducationAssistant: | |
| """ | |
| Handles conversation state, chat interactions, and JSON generation. | |
| """ | |
| def __init__(self): | |
| self.conversation_history = [] | |
| self.client = None | |
| self.system_prompt = SYSTEM_PROMPT | |
| def initialize_chat(self, api_key: str) -> str: | |
| """Initializes OpenAI client and provides the first prompt.""" | |
| try: | |
| openai.api_key = api_key | |
| return "Hello! Let's record your educational history. What is the name of your most recent educational institution?" | |
| except Exception as e: | |
| return f"Error initializing chat: {str(e)}" | |
| def chat(self, message: str, api_key: str) -> Dict[str, str]: | |
| """Processes user messages and generates responses.""" | |
| if not self.client: | |
| first_message = self.initialize_chat(api_key) | |
| self.conversation_history.append({"role": "assistant", "content": first_message}) | |
| return {"role": "assistant", "content": first_message} | |
| try: | |
| # Append user message to history | |
| self.conversation_history.append({"role": "user", "content": message}) | |
| # Generate response | |
| response = openai.ChatCompletion.create( | |
| model="gpt-4o-mini", | |
| messages=[{"role": "system", "content": self.system_prompt}] + self.conversation_history, | |
| temperature=0.7, | |
| max_tokens=300 | |
| ) | |
| # Parse and store assistant response | |
| assistant_message = {"role": "assistant", "content": response.choices[0].message.content} | |
| self.conversation_history.append(assistant_message) | |
| return assistant_message | |
| except Exception as e: | |
| return {"role": "assistant", "content": f"Error: {str(e)}"} | |
| def generate_json(self) -> Optional[str]: | |
| """Generates structured JSON from the conversation history.""" | |
| try: | |
| json_prompt = """Based on our conversation, generate a structured JSON containing the educational information shared. Format it as follows: | |
| { | |
| "education": [ | |
| { | |
| "institution": { | |
| "name": string, | |
| "type": string, | |
| "location": string | |
| }, | |
| "degree": { | |
| "type": string, | |
| "field": string, | |
| "status": string | |
| }, | |
| "dates": { | |
| "start": string, | |
| "end": string | |
| }, | |
| "academic": { | |
| "gpa": float (if provided), | |
| "honors": [string], | |
| "achievements": [string] | |
| }, | |
| "activities": [ | |
| { | |
| "name": string, | |
| "description": string, | |
| "duration": string | |
| } | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "timestamp": string, | |
| "source": "Education Information Assistant" | |
| } | |
| } | |
| Respond ONLY with the JSON.""" | |
| # Generate JSON based on the conversation history | |
| response = openai.ChatCompletion.create( | |
| model="gpt-4o-mini", | |
| messages=[{"role": "system", "content": self.system_prompt}] + self.conversation_history + | |
| [{"role": "user", "content": json_prompt}], | |
| temperature=0.1, | |
| max_tokens=1500 | |
| ) | |
| # Parse response and write JSON file | |
| json_data = json.loads(response.choices[0].message.content) | |
| filename = f"education_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" | |
| with open(filename, "w") as f: | |
| json.dump(json_data, f, indent=2) | |
| return filename | |
| except Exception as e: | |
| print(f"Error generating JSON: {str(e)}") | |
| return None | |
| # Gradio Interface | |
| def create_interface(): | |
| assistant = EducationAssistant() | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# 📘 Educational Information Collection Assistant") | |
| with gr.Row(): | |
| api_key = gr.Textbox( | |
| label="OpenAI API Key", | |
| type="password", | |
| placeholder="Enter your OpenAI API Key", | |
| info="Required for using OpenAI's GPT model." | |
| ) | |
| chatbot = gr.Chatbot(label="Assistant", height=400) | |
| with gr.Row(): | |
| user_input = gr.Textbox( | |
| label="Your Message", | |
| placeholder="Type your message here...", | |
| lines=2 | |
| ) | |
| send_button = gr.Button("Send", variant="primary") | |
| generate_button = gr.Button("Generate JSON") | |
| download_file = gr.File(label="Generated JSON") | |
| # Event Handlers | |
| def handle_send(message, history, api_key): | |
| if not api_key.strip(): | |
| return history + [{"role": "assistant", "content": "Please provide your OpenAI API key to continue."}] | |
| if not message.strip(): | |
| return history | |
| response = assistant.chat(message, api_key) | |
| return history + [{"role": "user", "content": message}, response] | |
| def handle_generate(): | |
| filename = assistant.generate_json() | |
| if filename: | |
| return filename | |
| return "Error generating JSON. Please ensure all required information is collected." | |
| # Button Actions | |
| send_button.click( | |
| handle_send, | |
| inputs=[user_input, chatbot, api_key], | |
| outputs=[chatbot] | |
| ) | |
| user_input.submit( | |
| handle_send, | |
| inputs=[user_input, chatbot, api_key], | |
| outputs=[chatbot] | |
| ) | |
| generate_button.click( | |
| handle_generate, | |
| outputs=[download_file] | |
| ) | |
| return demo | |
| # Main Execution | |
| if __name__ == "__main__": | |
| demo = create_interface() | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=True | |
| ) | |