File size: 10,589 Bytes
9d3a830
86c0d78
9d3a830
bbd8ccb
 
226e05d
fdd046d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
df52de7
fdd046d
 
9d3a830
bbd8ccb
9e9d244
bbd8ccb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9d3a830
 
 
 
 
 
 
 
 
 
 
bbd8ccb
9d3a830
bbd8ccb
 
 
 
 
9d3a830
bbd8ccb
9d3a830
 
 
 
 
 
bbd8ccb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9d3a830
 
 
bbd8ccb
 
 
 
 
 
 
9d3a830
bbd8ccb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9d3a830
 
 
bbd8ccb
9d3a830
bbd8ccb
9d3a830
 
bbd8ccb
 
 
 
 
 
 
 
 
 
 
 
9d3a830
 
bbd8ccb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9d3a830
 
bbd8ccb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
import gradio as gr
import os
from huggingface_hub import InferenceClient
from datasets import load_dataset
import random
import secrets
# Fix for SessionMiddleware error in HF Spaces
def configure_gradio_session():
    """Configure session middleware for Gradio in HF Spaces"""
    try:
        from starlette.middleware.sessions import SessionMiddleware
        import gradio.routes
        
        # Store original create_app function
        if hasattr(gradio.routes, 'App') and hasattr(gradio.routes.App, 'create_app'):
            original_create_app = gradio.routes.App.create_app
            
            def patched_create_app(self, *args, **kwargs):
                app = original_create_app(self, *args, **kwargs)
                # Add session middleware
                app.add_middleware(
                    SessionMiddleware,
                    secret_key=os.getenv("HF_SESSION_SECRET", secrets.token_hex(32))
                )
                return app
            
            gradio.routes.App.create_app = patched_create_app
            
    except (ImportError, AttributeError) as e:
        print(f"Warning: Could not configure session middleware: {e}")

# Call the configuration function
configure_gradio_session()

# Load math datasets for sample problems
ds = load_dataset("HuggingFaceH4/ultrachat_200k", streaming=True)
def load_sample_problems():
    """Load sample problems from math datasets"""
    try:
        # Load GSM8K for sample problems
        gsm8k = load_dataset("openai/gsm8k", "main", streaming=True)
        samples = []
        for i, item in enumerate(gsm8k["train"]):
            samples.append(item["question"])
            if i >= 50:  # Load 50 samples
                break
        return samples
    except:
        return [
            "What is the derivative of f(x) = 3x² + 2x - 1?",
            "A triangle has sides of length 5, 12, and 13. What is its area?",
            "If log₂(x) + log₂(x+6) = 4, find the value of x.",
            "Find the limit: lim(x→0) (sin(x)/x)",
            "Solve the system: x + 2y = 7, 3x - y = 4"
        ]

# Initialize sample problems
math_samples = load_sample_problems()

def create_math_system_message():
    """Create specialized system prompt for mathematics"""
    return """You are Mathetics AI, an advanced mathematics tutor and problem solver. 

🧮 **Your Expertise:**
- Step-by-step problem solving with clear explanations
- Multiple solution approaches when applicable
- Proper mathematical notation and terminology
- Verification of answers through different methods

📐 **Problem Domains:**
- Arithmetic, Algebra, and Number Theory
- Geometry, Trigonometry, and Coordinate Geometry
- Calculus (Limits, Derivatives, Integrals)
- Statistics, Probability, and Data Analysis
- Competition Mathematics (AMC, AIME level)

💡 **Teaching Style:**
1. **Understand the Problem** - Identify what's being asked
2. **Plan the Solution** - Choose the appropriate method
3. **Execute Step-by-Step** - Show all work clearly
4. **Verify the Answer** - Check if the result makes sense
5. **Alternative Methods** - Mention other possible approaches

Always be precise, educational, and encourage mathematical thinking."""

def respond(
    message,
    history: list[dict[str, str]],
    system_message,
    max_tokens,
    temperature,
    top_p,
    hf_token: gr.OAuthToken,
):
    """
    Enhanced response function for mathematical problem solving
    """
    # Use Qwen Math model for better mathematical reasoning
    client = InferenceClient(
        token=hf_token.token if hf_token else None,
        model="Qwen/Qwen2.5-Math-7B-Instruct"  # Specialized math model
    )

    # Build message history
    messages = [{"role": "system", "content": system_message}]
    messages.extend(history)
    messages.append({"role": "user", "content": message})

    response = ""

    try:
        for message_chunk in client.chat_completion(
            messages,
            max_tokens=max_tokens,
            stream=True,
            temperature=temperature,
            top_p=top_p,
        ):
            choices = message_chunk.choices
            token = ""
            if len(choices) and choices[0].delta.content:
                token = choices[0].delta.content

            response += token
            yield response
            
    except Exception as e:
        error_msg = f"❌ **Error**: {str(e)}\n\n💡 **Troubleshooting**:\n- Make sure you're logged in with Hugging Face\n- Check if the model is accessible\n- Try a simpler problem first"
        yield error_msg

def get_random_sample():
    """Get a random sample problem"""
    if math_samples:
        return random.choice(math_samples)
    return "Solve for x: 2x² + 5x - 3 = 0"

def set_difficulty_preset(difficulty):
    """Set temperature and other params based on difficulty"""
    presets = {
        "Elementary": (0.2, 0.8, 512),    # Low temp for accuracy
        "High School": (0.3, 0.85, 768),  # Balanced
        "College": (0.4, 0.9, 1024),      # More exploration
        "Competition": (0.3, 0.8, 1536)   # Detailed solutions
    }
    return presets.get(difficulty, (0.3, 0.85, 768))

# Create the enhanced ChatInterface
chatbot = gr.ChatInterface(
    respond,
    type="messages",
    title="🧮 **Mathetics AI** - Advanced Mathematics Solver",
    description="""
    **Powered by Qwen 2.5-Math** | **Specialized for Mathematical Problem Solving**
    
    ✨ **Capabilities**: Algebra • Geometry • Calculus • Statistics • Competition Math
    📚 **Features**: Step-by-step solutions • Multiple approaches • Clear explanations
    """,
    additional_inputs=[
        gr.Textbox(
            value=create_math_system_message(), 
            label="🧠 System Message (Math Tutor Personality)",
            lines=3,
            max_lines=10
        ),
        gr.Slider(
            minimum=256, 
            maximum=2048, 
            value=768, 
            step=64, 
            label="📝 Max Tokens (Solution Length)"
        ),
        gr.Slider(
            minimum=0.1, 
            maximum=1.0, 
            value=0.3, 
            step=0.1, 
            label="🎯 Temperature (Creativity vs Precision)"
        ),
        gr.Slider(
            minimum=0.1,
            maximum=1.0,
            value=0.85,
            step=0.05,
            label="🔍 Top-p (Response Diversity)",
        ),
    ],
    examples=[
        ["What is the derivative of f(x) = 3x² + 2x - 1?"],
        ["A triangle has sides of length 5, 12, and 13. What is its area?"],
        ["If log₂(x) + log₂(x+6) = 4, find the value of x."],
        ["A bag contains 5 red balls and 7 blue balls. What's the probability of drawing 2 red balls without replacement?"],
        ["Find the limit: lim(x→0) (sin(x)/x)"],
        ["Solve the system of equations: x + 2y = 7 and 3x - y = 4"],
        ["What is the integral of ∫(2x³ - 5x + 3)dx?"],
        ["In a right triangle, if one angle is 30° and the hypotenuse is 10, find the lengths of the other two sides."]
    ],
    cache_examples=False,  # Don't cache for dynamic math problems
    concurrency_limit=10,
)

# Enhanced interface with additional features
with gr.Blocks(
    title="🧮 Mathetics AI", 
    theme=gr.themes.Soft(),
    css="""
    .math-highlight {
        background-color: #f0f8ff;
        padding: 10px;
        border-left: 4px solid #4CAF50;
        margin: 10px 0;
        border-radius: 5px;
    }
    .difficulty-selector {
        background-color: #fff3e0;
        padding: 15px;
        border-radius: 10px;
        margin: 10px 0;
    }
    """
) as demo:
    
    gr.Markdown("""
    # 🧮 **Mathetics AI** - Advanced Mathematics Solver
    
    **Your Personal AI Math Tutor** | Specialized in step-by-step problem solving across all mathematical domains
    """)
    
    with gr.Row():
        with gr.Column(scale=4):
            # Main chat interface
            chatbot.render()
            
        with gr.Column(scale=1):
            # Sidebar with additional features
            with gr.Accordion("🎲 **Quick Actions**", open=True):
                
                difficulty_preset = gr.Dropdown(
                    choices=["Elementary", "High School", "College", "Competition"],
                    value="High School",
                    label="🎯 Problem Difficulty",
                    elem_classes=["difficulty-selector"]
                )
                
                sample_btn = gr.Button("🎯 Get Sample Problem", variant="secondary", size="sm")
                help_btn = gr.Button("❓ Math Help Tips", variant="secondary", size="sm")
                
                # Quick math tools
                gr.Markdown("### 🔧 **Quick Tools**")
                gr.Markdown("""
                - **Algebra**: Equations, inequalities, factoring
                - **Geometry**: Area, volume, trigonometry  
                - **Calculus**: Derivatives, integrals, limits
                - **Statistics**: Probability, distributions
                - **Number Theory**: Prime factorization, GCD/LCM
                """)
    
    # Footer with information
    gr.Markdown("""
    ---
    **🔧 Technical Details:**
    - **Model**: Qwen/Qwen2.5-Math-7B-Instruct (Specialized for Mathematics)
    - **Authentication**: Automatic via Hugging Face OAuth
    - **Features**: Real-time streaming responses, step-by-step solutions
    
    **💡 Usage Tips:**
    - Be specific about what you want to find or solve
    - Mention if you want step-by-step solutions
    - Ask for alternative solution methods
    - Request verification of your own solutions
    """)
    
    # Event handlers for additional functionality
    def insert_sample(difficulty):
        sample = get_random_sample()
        return sample
    
    def show_help():
        return """**Math Help Tips:**
        
        1. **Be Specific**: "Find the derivative of..." instead of "Help with calculus"
        2. **Show Your Work**: "I got x=5, is this correct?"
        3. **Ask for Steps**: "Show me step-by-step how to solve..."
        4. **Request Verification**: "Check my solution to this problem"
        5. **Alternative Methods**: "What's another way to solve this?"
        """
    
    # Connect sample button (this would need to be integrated with the chat properly)
    sample_btn.click(
        lambda x: get_random_sample(),
        inputs=[difficulty_preset],
        outputs=[]  # Would need proper integration with chat input
    )

if __name__ == "__main__":
    demo.launch()