import gradio as gr import os import re import time from openai import OpenAI from together import Together # Function to generate math solution using the Phi-4-reasoning-plus model via OpenRouter def generate_math_solution_openrouter(api_key, problem_text, history=None): if not api_key.strip(): return "Please enter your OpenRouter API key.", history if not problem_text.strip(): return "Please enter a math problem.", history try: client = OpenAI( base_url="https://openrouter.ai/api/v1", api_key=api_key, ) messages = [ {"role": "system", "content": """You are an expert math tutor who explains concepts clearly and thoroughly. Analyze the given math problem and provide a detailed step-by-step solution. For each step: 1. Show the mathematical operation 2. Explain why this step is necessary 3. Connect it to relevant mathematical concepts Format your response with clear section headers using markdown. Begin with an "Initial Analysis" section, follow with numbered steps, and conclude with a "Final Answer" section."""}, ] # Add conversation history if it exists if history: for exchange in history: messages.append({"role": "user", "content": exchange[0]}) if exchange[1]: # Check if there's a response messages.append({"role": "assistant", "content": exchange[1]}) # Add the current problem messages.append({"role": "user", "content": f"Solve this math problem step-by-step: {problem_text}"}) # Create the completion completion = client.chat.completions.create( model="microsoft/phi-4-reasoning-plus:free", messages=messages, extra_headers={ "HTTP-Referer": "https://advancedmathtutor.edu", "X-Title": "Advanced Math Tutor", } ) solution = completion.choices[0].message.content # Update history if history is None: history = [] history.append((problem_text, solution)) return solution, history except Exception as e: error_message = f"Error: {str(e)}" return error_message, history # Function to generate math solution using Together AI with support for images def generate_math_solution_together(api_key, problem_text, image=None, history=None): if not api_key.strip(): return "Please enter your Together AI API key.", history if not problem_text.strip() and image is None: return "Please enter a math problem or upload an image of a math problem.", history try: client = Together(api_key=api_key) system_message = { "role": "system", "content": """You are an expert math tutor who explains concepts clearly and thoroughly. Analyze the given math problem and provide a detailed step-by-step solution. For each step: 1. Show the mathematical operation 2. Explain why this step is necessary 3. Connect it to relevant mathematical concepts Format your response with clear section headers using markdown. Begin with an "Initial Analysis" section, follow with numbered steps, and conclude with a "Final Answer" section.""" } # Start with text content user_content = [{"type": "text", "text": f"Solve this math problem: {problem_text}"}] # Add image if provided if image is not None: user_content.append({ "type": "image_url", "image_url": {"url": image} }) messages = [system_message] # Add conversation history if it exists if history: for exchange in history: # For simplicity, we're assuming text-only history here messages.append({"role": "user", "content": exchange[0]}) if exchange[1]: # Check if there's a response messages.append({"role": "assistant", "content": exchange[1]}) # Add the current problem messages.append({"role": "user", "content": user_content}) # Create the completion response = client.chat.completions.create( model="meta-llama/Llama-Vision-Free", messages=messages, stream=False ) solution = response.choices[0].message.content # Update history - for simplicity, just store the text problem if history is None: history = [] history.append((problem_text, solution)) return solution, history except Exception as e: error_message = f"Error: {str(e)}" return error_message, history # Function to verify API key format def validate_openrouter_key(api_key): # This is a simple check - OpenRouter keys typically start with "sk-or-" if api_key.startswith("sk-or-") and len(api_key) > 20: return True return False # Function to validate Together AI API key (basic format check) def validate_together_key(api_key): # Together API keys usually have a specific format # This is just a simple length check for now if len(api_key) > 20: return True return False # Function to process LaTeX in the solution def process_solution(solution): # Replace $...$ with $$...$$ for better rendering in Gradio markdown solution = re.sub(r'(?