Upload app.py
Browse files
app.py
CHANGED
|
@@ -338,94 +338,133 @@ class UltimateTopcoderMCPEngine:
|
|
| 338 |
sort_by: str = None,
|
| 339 |
sort_order: str = None,
|
| 340 |
) -> List[Challenge]:
|
| 341 |
-
"""FIXED:
|
| 342 |
|
| 343 |
# Always try to connect
|
| 344 |
print(f"π Attempting to fetch REAL challenges (limit: {limit})")
|
|
|
|
| 345 |
connection_success = await self.initialize_connection()
|
| 346 |
|
| 347 |
if not connection_success:
|
| 348 |
print("β Could not establish MCP connection, using fallback")
|
| 349 |
return []
|
| 350 |
|
| 351 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
skill_keywords = self.extract_technologies_from_query(
|
| 353 |
query + " " + " ".join(user_profile.skills + user_profile.interests)
|
| 354 |
)
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
"
|
| 358 |
-
|
| 359 |
|
| 360 |
-
#
|
|
|
|
| 361 |
if status:
|
| 362 |
-
|
| 363 |
-
else:
|
| 364 |
-
mcp_query["status"] = "Active" # Default to active
|
| 365 |
-
|
| 366 |
-
if prize_min is not None:
|
| 367 |
-
mcp_query["totalPrizesFrom"] = prize_min
|
| 368 |
-
if prize_max is not None:
|
| 369 |
-
mcp_query["totalPrizesTo"] = prize_max
|
| 370 |
-
if challenge_type:
|
| 371 |
-
mcp_query["type"] = challenge_type
|
| 372 |
-
if track:
|
| 373 |
-
mcp_query["track"] = track
|
| 374 |
-
if skill_keywords:
|
| 375 |
-
mcp_query["tags"] = skill_keywords
|
| 376 |
if query.strip():
|
| 377 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 378 |
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
if "structuredContent" in result:
|
| 398 |
-
structured = result["structuredContent"]
|
| 399 |
-
if isinstance(structured, dict) and "data" in structured:
|
| 400 |
-
challenge_data_list = structured["data"]
|
| 401 |
-
print(f"β
Found {len(challenge_data_list)} challenges in structuredContent")
|
| 402 |
-
elif "data" in result:
|
| 403 |
-
challenge_data_list = result["data"]
|
| 404 |
-
print(f"β
Found {len(challenge_data_list)} challenges in data")
|
| 405 |
-
elif "content" in result and len(result["content"]) > 0:
|
| 406 |
-
content_item = result["content"][0]
|
| 407 |
-
if isinstance(content_item, dict) and content_item.get("type") == "text":
|
| 408 |
-
try:
|
| 409 |
-
text_content = content_item.get("text", "")
|
| 410 |
-
parsed_data = json.loads(text_content)
|
| 411 |
-
if "data" in parsed_data:
|
| 412 |
-
challenge_data_list = parsed_data["data"]
|
| 413 |
-
print(f"β
Found {len(challenge_data_list)} challenges in parsed content")
|
| 414 |
-
except json.JSONDecodeError:
|
| 415 |
-
pass
|
| 416 |
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 426 |
|
| 427 |
-
print(
|
| 428 |
-
return
|
| 429 |
|
| 430 |
def calculate_advanced_compatibility_score(self, challenge: Challenge, user_profile: UserProfile, query: str) -> tuple:
|
| 431 |
score = 0.0
|
|
@@ -1279,6 +1318,72 @@ def check_mcp_status():
|
|
| 1279 |
|
| 1280 |
return "\n".join(results)
|
| 1281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1282 |
def create_ultimate_interface():
|
| 1283 |
"""Create the ULTIMATE Gradio interface combining all features"""
|
| 1284 |
print("π¨ Creating ULTIMATE Gradio interface...")
|
|
@@ -1491,7 +1596,7 @@ def create_ultimate_interface():
|
|
| 1491 |
outputs=[enhanced_chatbot, enhanced_chat_input]
|
| 1492 |
)
|
| 1493 |
|
| 1494 |
-
# Tab 3: FIXED ULTIMATE Performance - ALL OPTIONS RESTORED
|
| 1495 |
with gr.TabItem("β‘ ULTIMATE Performance"):
|
| 1496 |
gr.Markdown("""
|
| 1497 |
### π§ͺ ULTIMATE System Performance & Real MCP Integration
|
|
@@ -1504,6 +1609,7 @@ def create_ultimate_interface():
|
|
| 1504 |
ultimate_test_btn = gr.Button("π§ͺ Run ULTIMATE Performance Test", variant="secondary", size="lg", elem_classes="ultimate-btn")
|
| 1505 |
quick_benchmark_btn = gr.Button("β‘ Quick Benchmark", variant="secondary")
|
| 1506 |
mcp_status_btn = gr.Button("π₯ Check Real MCP Status", variant="secondary")
|
|
|
|
| 1507 |
|
| 1508 |
with gr.Column():
|
| 1509 |
ultimate_test_output = gr.Textbox(
|
|
@@ -1512,10 +1618,11 @@ def create_ultimate_interface():
|
|
| 1512 |
show_label=True
|
| 1513 |
)
|
| 1514 |
|
| 1515 |
-
# FIXED: Connect all test functions
|
| 1516 |
ultimate_test_btn.click(run_ultimate_performance_test, outputs=ultimate_test_output)
|
| 1517 |
quick_benchmark_btn.click(quick_benchmark, outputs=ultimate_test_output)
|
| 1518 |
mcp_status_btn.click(check_mcp_status, outputs=ultimate_test_output)
|
|
|
|
| 1519 |
|
| 1520 |
# Tab 4: ULTIMATE About & Documentation
|
| 1521 |
with gr.TabItem("βΉοΈ ULTIMATE About"):
|
|
|
|
| 338 |
sort_by: str = None,
|
| 339 |
sort_order: str = None,
|
| 340 |
) -> List[Challenge]:
|
| 341 |
+
"""FIXED: Debug version - shows exactly what MCP is doing"""
|
| 342 |
|
| 343 |
# Always try to connect
|
| 344 |
print(f"π Attempting to fetch REAL challenges (limit: {limit})")
|
| 345 |
+
print(f"π― Query: '{query}' | Skills: {user_profile.skills}")
|
| 346 |
connection_success = await self.initialize_connection()
|
| 347 |
|
| 348 |
if not connection_success:
|
| 349 |
print("β Could not establish MCP connection, using fallback")
|
| 350 |
return []
|
| 351 |
|
| 352 |
+
# Try multiple query strategies to see what works
|
| 353 |
+
query_strategies = []
|
| 354 |
+
|
| 355 |
+
# Strategy 1: Simple query with minimal parameters
|
| 356 |
+
simple_query = {"perPage": min(limit, 20)}
|
| 357 |
+
if query.strip():
|
| 358 |
+
simple_query["search"] = query.strip()
|
| 359 |
+
query_strategies.append(("Simple Search", simple_query))
|
| 360 |
+
|
| 361 |
+
# Strategy 2: Skills-based query
|
| 362 |
skill_keywords = self.extract_technologies_from_query(
|
| 363 |
query + " " + " ".join(user_profile.skills + user_profile.interests)
|
| 364 |
)
|
| 365 |
+
if skill_keywords:
|
| 366 |
+
skills_query = {"perPage": min(limit, 20)}
|
| 367 |
+
skills_query["tags"] = skill_keywords[:3] # Limit to 3 skills
|
| 368 |
+
query_strategies.append(("Skills Query", skills_query))
|
| 369 |
|
| 370 |
+
# Strategy 3: Your comprehensive query
|
| 371 |
+
comprehensive_query = {"perPage": min(limit, 20)}
|
| 372 |
if status:
|
| 373 |
+
comprehensive_query["status"] = status
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 374 |
if query.strip():
|
| 375 |
+
comprehensive_query["search"] = query.strip()
|
| 376 |
+
if sort_by:
|
| 377 |
+
comprehensive_query["sortBy"] = sort_by
|
| 378 |
+
if sort_order:
|
| 379 |
+
comprehensive_query["sortOrder"] = sort_order
|
| 380 |
+
query_strategies.append(("Comprehensive", comprehensive_query))
|
| 381 |
+
|
| 382 |
+
# Try each strategy until one works
|
| 383 |
+
for strategy_name, mcp_query in query_strategies:
|
| 384 |
+
print(f"\nπ§ͺ Trying {strategy_name} strategy:")
|
| 385 |
+
print(f"π§ Query parameters: {mcp_query}")
|
| 386 |
+
|
| 387 |
+
# Call the MCP tool
|
| 388 |
+
result = await self.call_tool("query-tc-challenges", mcp_query)
|
| 389 |
|
| 390 |
+
if not result:
|
| 391 |
+
print(f"β {strategy_name} failed - no result")
|
| 392 |
+
continue
|
| 393 |
+
|
| 394 |
+
print(f"π {strategy_name} result type: {type(result)}")
|
| 395 |
+
if isinstance(result, dict):
|
| 396 |
+
print(f"π Result keys: {list(result.keys())}")
|
| 397 |
+
|
| 398 |
+
# Show first few characters of each field for debugging
|
| 399 |
+
for key, value in result.items():
|
| 400 |
+
if isinstance(value, str):
|
| 401 |
+
print(f" {key}: {str(value)[:100]}...")
|
| 402 |
+
elif isinstance(value, dict):
|
| 403 |
+
print(f" {key}: dict with keys {list(value.keys())}")
|
| 404 |
+
elif isinstance(value, list):
|
| 405 |
+
print(f" {key}: list with {len(value)} items")
|
| 406 |
+
else:
|
| 407 |
+
print(f" {key}: {type(value)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 408 |
|
| 409 |
+
# Try to parse the response
|
| 410 |
+
challenge_data_list = []
|
| 411 |
+
|
| 412 |
+
# Check all possible data locations
|
| 413 |
+
data_sources = [
|
| 414 |
+
("structuredContent.data", result.get("structuredContent", {}).get("data", [])),
|
| 415 |
+
("data", result.get("data", [])),
|
| 416 |
+
("content[0].text", None), # Will handle separately
|
| 417 |
+
("result", result if isinstance(result, list) else [])
|
| 418 |
+
]
|
| 419 |
+
|
| 420 |
+
for source_name, data in data_sources:
|
| 421 |
+
if data and isinstance(data, list) and len(data) > 0:
|
| 422 |
+
challenge_data_list = data
|
| 423 |
+
print(f"β
Found {len(challenge_data_list)} challenges in {source_name}")
|
| 424 |
+
break
|
| 425 |
+
|
| 426 |
+
# Special handling for content field
|
| 427 |
+
if not challenge_data_list and "content" in result:
|
| 428 |
+
content = result["content"]
|
| 429 |
+
if isinstance(content, list) and len(content) > 0:
|
| 430 |
+
content_item = content[0]
|
| 431 |
+
if isinstance(content_item, dict) and content_item.get("type") == "text":
|
| 432 |
+
try:
|
| 433 |
+
text_content = content_item.get("text", "")
|
| 434 |
+
print(f"π Content text preview: {text_content[:200]}...")
|
| 435 |
+
parsed_data = json.loads(text_content)
|
| 436 |
+
if "data" in parsed_data:
|
| 437 |
+
challenge_data_list = parsed_data["data"]
|
| 438 |
+
print(f"β
Found {len(challenge_data_list)} challenges in parsed content")
|
| 439 |
+
except json.JSONDecodeError as e:
|
| 440 |
+
print(f"β Failed to parse content JSON: {e}")
|
| 441 |
+
|
| 442 |
+
if challenge_data_list:
|
| 443 |
+
print(f"π― Sample challenge data keys: {list(challenge_data_list[0].keys()) if challenge_data_list else 'None'}")
|
| 444 |
+
|
| 445 |
+
# Convert challenges
|
| 446 |
+
challenges = []
|
| 447 |
+
for i, item in enumerate(challenge_data_list):
|
| 448 |
+
if isinstance(item, dict):
|
| 449 |
+
try:
|
| 450 |
+
challenge = self.convert_topcoder_challenge(item)
|
| 451 |
+
challenges.append(challenge)
|
| 452 |
+
if i == 0: # Show first challenge details
|
| 453 |
+
print(f"π First challenge: {challenge.title} | {challenge.prize} | {challenge.technologies}")
|
| 454 |
+
except Exception as e:
|
| 455 |
+
print(f"β Error converting challenge {i}: {e}")
|
| 456 |
+
continue
|
| 457 |
+
|
| 458 |
+
if challenges:
|
| 459 |
+
print(f"π SUCCESS with {strategy_name}! Converted {len(challenges)} REAL challenges")
|
| 460 |
+
return challenges
|
| 461 |
+
else:
|
| 462 |
+
print(f"β {strategy_name} - no challenges converted")
|
| 463 |
+
else:
|
| 464 |
+
print(f"β {strategy_name} - no challenge data found")
|
| 465 |
|
| 466 |
+
print("β All strategies failed - no real MCP data retrieved")
|
| 467 |
+
return []
|
| 468 |
|
| 469 |
def calculate_advanced_compatibility_score(self, challenge: Challenge, user_profile: UserProfile, query: str) -> tuple:
|
| 470 |
score = 0.0
|
|
|
|
| 1318 |
|
| 1319 |
return "\n".join(results)
|
| 1320 |
|
| 1321 |
+
def debug_mcp_queries():
|
| 1322 |
+
"""Debug specific MCP queries to see what works"""
|
| 1323 |
+
results = []
|
| 1324 |
+
results.append("π DEBUG MCP QUERY TESTING")
|
| 1325 |
+
results.append("=" * 40)
|
| 1326 |
+
|
| 1327 |
+
async def test_different_queries():
|
| 1328 |
+
# Test queries that should work vs ones that don't
|
| 1329 |
+
test_queries = [
|
| 1330 |
+
("AI", {"search": "AI", "perPage": 5}),
|
| 1331 |
+
("Python", {"search": "Python", "perPage": 5}),
|
| 1332 |
+
("React", {"search": "React", "perPage": 5}),
|
| 1333 |
+
("JavaScript", {"search": "JavaScript", "perPage": 5}),
|
| 1334 |
+
("AI with tags", {"tags": ["AI"], "perPage": 5}),
|
| 1335 |
+
("Python with tags", {"tags": ["Python"], "perPage": 5}),
|
| 1336 |
+
("Simple empty", {"perPage": 5}),
|
| 1337 |
+
("Status only", {"status": "Active", "perPage": 5}),
|
| 1338 |
+
("AI minimal", {"search": "ai", "perPage": 3})
|
| 1339 |
+
]
|
| 1340 |
+
|
| 1341 |
+
for query_name, query_params in test_queries:
|
| 1342 |
+
results.append(f"\nπ§ͺ Testing: {query_name}")
|
| 1343 |
+
results.append(f"π Parameters: {query_params}")
|
| 1344 |
+
|
| 1345 |
+
try:
|
| 1346 |
+
result = await intelligence_engine.call_tool("query-tc-challenges", query_params)
|
| 1347 |
+
|
| 1348 |
+
if result:
|
| 1349 |
+
results.append(f"β
Got response!")
|
| 1350 |
+
if isinstance(result, dict):
|
| 1351 |
+
results.append(f"π Response keys: {list(result.keys())}")
|
| 1352 |
+
|
| 1353 |
+
# Check for data
|
| 1354 |
+
challenge_count = 0
|
| 1355 |
+
if "structuredContent" in result and "data" in result["structuredContent"]:
|
| 1356 |
+
challenge_count = len(result["structuredContent"]["data"])
|
| 1357 |
+
elif "data" in result:
|
| 1358 |
+
challenge_count = len(result["data"])
|
| 1359 |
+
|
| 1360 |
+
results.append(f"π― Challenge count: {challenge_count}")
|
| 1361 |
+
|
| 1362 |
+
if challenge_count > 0:
|
| 1363 |
+
results.append(f"π₯ SUCCESS! {query_name} returned {challenge_count} challenges")
|
| 1364 |
+
else:
|
| 1365 |
+
results.append(f"β οΈ {query_name} returned empty data")
|
| 1366 |
+
else:
|
| 1367 |
+
results.append(f"π Response type: {type(result)}")
|
| 1368 |
+
else:
|
| 1369 |
+
results.append(f"β No response for {query_name}")
|
| 1370 |
+
|
| 1371 |
+
except Exception as e:
|
| 1372 |
+
results.append(f"β Error testing {query_name}: {str(e)}")
|
| 1373 |
+
|
| 1374 |
+
# Run the async test
|
| 1375 |
+
try:
|
| 1376 |
+
asyncio.run(test_different_queries())
|
| 1377 |
+
except Exception as e:
|
| 1378 |
+
results.append(f"β Test failed: {str(e)}")
|
| 1379 |
+
|
| 1380 |
+
results.append("\nπ― ANALYSIS:")
|
| 1381 |
+
results.append("This will show which query patterns work with the real MCP server.")
|
| 1382 |
+
results.append("If only 'AI' queries work, it might be a server-side data issue.")
|
| 1383 |
+
results.append("If multiple queries work, it might be our parsing logic.")
|
| 1384 |
+
|
| 1385 |
+
return "\n".join(results)
|
| 1386 |
+
|
| 1387 |
def create_ultimate_interface():
|
| 1388 |
"""Create the ULTIMATE Gradio interface combining all features"""
|
| 1389 |
print("π¨ Creating ULTIMATE Gradio interface...")
|
|
|
|
| 1596 |
outputs=[enhanced_chatbot, enhanced_chat_input]
|
| 1597 |
)
|
| 1598 |
|
| 1599 |
+
# Tab 3: FIXED ULTIMATE Performance - ALL OPTIONS RESTORED + DEBUG
|
| 1600 |
with gr.TabItem("β‘ ULTIMATE Performance"):
|
| 1601 |
gr.Markdown("""
|
| 1602 |
### π§ͺ ULTIMATE System Performance & Real MCP Integration
|
|
|
|
| 1609 |
ultimate_test_btn = gr.Button("π§ͺ Run ULTIMATE Performance Test", variant="secondary", size="lg", elem_classes="ultimate-btn")
|
| 1610 |
quick_benchmark_btn = gr.Button("β‘ Quick Benchmark", variant="secondary")
|
| 1611 |
mcp_status_btn = gr.Button("π₯ Check Real MCP Status", variant="secondary")
|
| 1612 |
+
debug_queries_btn = gr.Button("π Debug MCP Queries", variant="secondary")
|
| 1613 |
|
| 1614 |
with gr.Column():
|
| 1615 |
ultimate_test_output = gr.Textbox(
|
|
|
|
| 1618 |
show_label=True
|
| 1619 |
)
|
| 1620 |
|
| 1621 |
+
# FIXED: Connect all test functions including debug
|
| 1622 |
ultimate_test_btn.click(run_ultimate_performance_test, outputs=ultimate_test_output)
|
| 1623 |
quick_benchmark_btn.click(quick_benchmark, outputs=ultimate_test_output)
|
| 1624 |
mcp_status_btn.click(check_mcp_status, outputs=ultimate_test_output)
|
| 1625 |
+
debug_queries_btn.click(debug_mcp_queries, outputs=ultimate_test_output)
|
| 1626 |
|
| 1627 |
# Tab 4: ULTIMATE About & Documentation
|
| 1628 |
with gr.TabItem("βΉοΈ ULTIMATE About"):
|