Spaces:
Running
Running
Update app.py
Browse filesAdded Wolfram API Integration
app.py
CHANGED
@@ -2,59 +2,55 @@
|
|
2 |
import os
|
3 |
import gradio as gr
|
4 |
from anthropic import Anthropic
|
|
|
5 |
from datetime import datetime, timedelta
|
6 |
from collections import deque
|
7 |
|
8 |
-
# Initialize
|
9 |
-
anthropic = Anthropic(
|
10 |
-
|
11 |
-
)
|
12 |
-
|
13 |
-
# Request tracking
|
14 |
-
MAX_REQUESTS_PER_DAY = 25 # Conservative limit to start
|
15 |
-
request_history = deque(maxlen=1000)
|
16 |
-
|
17 |
-
def check_api_key():
|
18 |
-
"""Verify API key is configured"""
|
19 |
-
if not os.environ.get('ANTHROPIC_API_KEY'):
|
20 |
-
raise ValueError("Anthropic API key not found. Please configure it in HuggingFace Spaces settings.")
|
21 |
-
|
22 |
-
def check_rate_limit():
|
23 |
-
"""Check if we're within rate limits"""
|
24 |
-
now = datetime.now()
|
25 |
-
# Remove requests older than 24 hours
|
26 |
-
while request_history and (now - request_history[0]) > timedelta(days=1):
|
27 |
-
request_history.popleft()
|
28 |
-
return len(request_history) < MAX_REQUESTS_PER_DAY
|
29 |
|
30 |
-
def
|
31 |
-
"""
|
32 |
-
text = text.replace('\n', '\n\n')
|
33 |
-
return text
|
34 |
-
|
35 |
-
def generate_test(subject):
|
36 |
-
"""Generate a math test with error handling and rate limiting"""
|
37 |
try:
|
38 |
-
#
|
39 |
-
|
|
|
40 |
|
41 |
-
#
|
42 |
-
|
43 |
-
return "Daily request limit reached. Please try again tomorrow."
|
44 |
|
45 |
-
#
|
46 |
-
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
message = anthropic.messages.create(
|
60 |
model="claude-3-opus-20240229",
|
@@ -66,37 +62,48 @@ def generate_test(subject):
|
|
66 |
}]
|
67 |
)
|
68 |
|
69 |
-
# Extract
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
total_cost = input_cost + output_cost
|
75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
usage_stats = f"""
|
77 |
\n---\nUsage Statistics:
|
78 |
-
• Input Tokens: {input_tokens:,}
|
79 |
-
• Output Tokens: {output_tokens:,}
|
80 |
-
•
|
81 |
|
82 |
Cost Breakdown:
|
83 |
-
•
|
84 |
-
•
|
85 |
-
• Total Cost: ${total_cost:.4f}
|
86 |
"""
|
87 |
|
88 |
-
|
89 |
-
response_text = message.content[0].text
|
90 |
-
formatted_response = clean_latex(response_text) + usage_stats
|
91 |
-
return formatted_response
|
92 |
-
else:
|
93 |
-
return "Error: No content in response"
|
94 |
|
95 |
-
except ValueError as e:
|
96 |
-
return f"Configuration Error: {str(e)}"
|
97 |
except Exception as e:
|
98 |
return f"Error: {str(e)}"
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
# Subject choices
|
101 |
subjects = [
|
102 |
"Single Variable Calculus",
|
|
|
2 |
import os
|
3 |
import gradio as gr
|
4 |
from anthropic import Anthropic
|
5 |
+
import wolframalpha
|
6 |
from datetime import datetime, timedelta
|
7 |
from collections import deque
|
8 |
|
9 |
+
# Initialize clients
|
10 |
+
anthropic = Anthropic(api_key=os.environ.get('ANTHROPIC_API_KEY'))
|
11 |
+
wolfram_client = wolframalpha.Client(os.environ.get('WOLFRAM_APPID'))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
+
def verify_solution(problem, claimed_solution):
|
14 |
+
"""Verify a mathematical solution using Wolfram Alpha"""
|
|
|
|
|
|
|
|
|
|
|
15 |
try:
|
16 |
+
# Clean up the problem and solution for Wolfram Alpha
|
17 |
+
query = f"Solve {problem}"
|
18 |
+
result = wolfram_client.query(query)
|
19 |
|
20 |
+
# Extract the solution from Wolfram Alpha
|
21 |
+
wolfram_solution = next(result.results).text
|
|
|
22 |
|
23 |
+
# Compare solutions (needs sophisticated parsing based on your problem types)
|
24 |
+
solutions_match = compare_solutions(wolfram_solution, claimed_solution)
|
25 |
|
26 |
+
return {
|
27 |
+
'verified': solutions_match,
|
28 |
+
'wolfram_solution': wolfram_solution,
|
29 |
+
'match': solutions_match
|
30 |
+
}
|
31 |
+
except Exception as e:
|
32 |
+
return {
|
33 |
+
'verified': False,
|
34 |
+
'error': str(e),
|
35 |
+
'wolfram_solution': None
|
36 |
+
}
|
37 |
+
|
38 |
+
def compare_solutions(wolfram_sol, claude_sol):
|
39 |
+
"""Compare two solutions for mathematical equivalence"""
|
40 |
+
# This would need sophisticated parsing based on your problem types
|
41 |
+
# Basic example:
|
42 |
+
return abs(float(wolfram_sol) - float(claude_sol)) < 0.001
|
43 |
+
|
44 |
+
def generate_test(subject):
|
45 |
+
"""Generate and verify a math test"""
|
46 |
+
try:
|
47 |
+
# Generate the test using Claude
|
48 |
+
system_prompt = """Generate 3 university-level math questions with numerical solutions that can be verified.
|
49 |
+
For each question:
|
50 |
+
1. State the problem clearly
|
51 |
+
2. Provide your step-by-step solution
|
52 |
+
3. Give the final answer in a format that can be verified
|
53 |
+
Use simple $$ for all math expressions."""
|
54 |
|
55 |
message = anthropic.messages.create(
|
56 |
model="claude-3-opus-20240229",
|
|
|
62 |
}]
|
63 |
)
|
64 |
|
65 |
+
# Extract questions and solutions
|
66 |
+
content = message.content[0].text
|
67 |
+
|
68 |
+
# Add verification results
|
69 |
+
verification_results = []
|
|
|
70 |
|
71 |
+
# For each question/solution pair (you'll need to parse the content)
|
72 |
+
# Example structure:
|
73 |
+
verification_note = "\n\n## Solution Verification:\n"
|
74 |
+
for i, (problem, solution) in enumerate(parse_questions(content)):
|
75 |
+
result = verify_solution(problem, solution)
|
76 |
+
verification_note += f"\nQuestion {i+1}:\n"
|
77 |
+
if result['verified']:
|
78 |
+
verification_note += "✅ Solution verified by Wolfram Alpha\n"
|
79 |
+
else:
|
80 |
+
verification_note += "⚠️ Solution needs verification\n"
|
81 |
+
if result['wolfram_solution']:
|
82 |
+
verification_note += f"Wolfram Alpha got: {result['wolfram_solution']}\n"
|
83 |
+
|
84 |
+
# Add usage statistics
|
85 |
usage_stats = f"""
|
86 |
\n---\nUsage Statistics:
|
87 |
+
• Input Tokens: {message.usage.input_tokens:,}
|
88 |
+
• Output Tokens: {message.usage.output_tokens:,}
|
89 |
+
• Wolfram Alpha calls: {len(verification_results)}
|
90 |
|
91 |
Cost Breakdown:
|
92 |
+
• Claude Cost: ${((message.usage.input_tokens / 1000) * 0.015) + ((message.usage.output_tokens / 1000) * 0.075):.4f}
|
93 |
+
• Wolfram API calls: {len(verification_results)}
|
|
|
94 |
"""
|
95 |
|
96 |
+
return content + verification_note + usage_stats
|
|
|
|
|
|
|
|
|
|
|
97 |
|
|
|
|
|
98 |
except Exception as e:
|
99 |
return f"Error: {str(e)}"
|
100 |
|
101 |
+
# Update requirements.txt to include:
|
102 |
+
# wolframalpha==5.0.0
|
103 |
+
# Update environment variables to include WOLFRAM_APPID
|
104 |
+
|
105 |
+
# Rest of your Gradio interface code remains the same...
|
106 |
+
|
107 |
# Subject choices
|
108 |
subjects = [
|
109 |
"Single Variable Calculus",
|