Upload app.py
Browse files
app.py
CHANGED
|
@@ -855,6 +855,7 @@ class EnhancedLLMChatbot:
|
|
| 855 |
history_text = "\n".join([f"User: {h[0]}\nAssistant: {h[1]}" for h in recent_history])
|
| 856 |
|
| 857 |
# Create comprehensive prompt for LLM
|
|
|
|
| 858 |
system_prompt = f"""You are an expert Topcoder Challenge Intelligence Assistant with ENHANCED REAL-TIME access to live challenge data through advanced MCP integration.
|
| 859 |
|
| 860 |
ENHANCED REAL CHALLENGE DATA CONTEXT:
|
|
@@ -880,10 +881,15 @@ ENHANCED Guidelines:
|
|
| 880 |
- For skill questions, suggest real challenges that match their level with smart recommendations
|
| 881 |
- Keep responses concise but informative (max 300 words)
|
| 882 |
|
| 883 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 884 |
|
| 885 |
-
|
| 886 |
|
|
|
|
| 887 |
# ENHANCED: Try OpenAI API if available
|
| 888 |
if self.llm_available:
|
| 889 |
try:
|
|
@@ -925,7 +931,7 @@ Provide a helpful, intelligent response using the enhanced real challenge data c
|
|
| 925 |
return await self.get_enhanced_fallback_response_with_context(user_message, challenge_context)
|
| 926 |
|
| 927 |
async def get_enhanced_fallback_response_with_context(self, user_message: str, challenge_context: str) -> str:
|
| 928 |
-
"""Enhanced fallback using real enhanced challenge data"""
|
| 929 |
message_lower = user_message.lower()
|
| 930 |
|
| 931 |
# Parse enhanced challenge context for intelligent responses
|
|
@@ -940,7 +946,7 @@ Provide a helpful, intelligent response using the enhanced real challenge data c
|
|
| 940 |
enhanced_features = "Advanced MCP integration"
|
| 941 |
|
| 942 |
# Technology-specific responses using enhanced real data
|
| 943 |
-
tech_keywords = ['python', 'react', 'javascript', 'blockchain', 'ai', 'ml', 'java', 'nodejs', 'angular', 'vue']
|
| 944 |
matching_tech = [tech for tech in tech_keywords if tech in message_lower]
|
| 945 |
|
| 946 |
if matching_tech:
|
|
@@ -951,13 +957,23 @@ Provide a helpful, intelligent response using the enhanced real challenge data c
|
|
| 951 |
relevant_challenges.append(challenge)
|
| 952 |
|
| 953 |
if relevant_challenges:
|
| 954 |
-
response = f"
|
|
|
|
| 955 |
for i, challenge in enumerate(relevant_challenges[:3], 1):
|
| 956 |
-
|
| 957 |
-
|
| 958 |
-
|
| 959 |
-
|
| 960 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 961 |
|
| 962 |
response += f"*These are ENHANCED REAL challenges from my live MCP connection to Topcoder's database of {total_challenges} challenges with {enhanced_features}!*"
|
| 963 |
return response
|
|
@@ -967,8 +983,16 @@ Provide a helpful, intelligent response using the enhanced real challenge data c
|
|
| 967 |
if challenges:
|
| 968 |
response = f"π° Based on enhanced real MCP data, current Topcoder challenges offer:\n\n"
|
| 969 |
for i, challenge in enumerate(challenges[:3], 1):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 970 |
response += f"{i}. **{challenge['title']}** - {challenge['prize']}\n"
|
| 971 |
-
response += f" π Difficulty: {challenge['difficulty']} | π₯ Competition: {challenge['registrants']} registered\n
|
|
|
|
| 972 |
response += f"*This is enhanced live prize data from {total_challenges} real challenges with {enhanced_features}!*"
|
| 973 |
return response
|
| 974 |
|
|
@@ -976,6 +1000,13 @@ Provide a helpful, intelligent response using the enhanced real challenge data c
|
|
| 976 |
if any(word in message_lower for word in ['career', 'skill', 'learn', 'beginner', 'advanced', 'help']):
|
| 977 |
if challenges:
|
| 978 |
sample_challenge = challenges[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 979 |
return f"""I'm your enhanced intelligent Topcoder assistant with ADVANCED MCP integration! π
|
| 980 |
|
| 981 |
I currently have enhanced live access to {total_challenges} real challenges with {enhanced_features}. For example, right now there's:
|
|
@@ -984,6 +1015,7 @@ I currently have enhanced live access to {total_challenges} real challenges with
|
|
| 984 |
π° Prize: **{sample_challenge['prize']}**
|
| 985 |
π οΈ Technologies: {', '.join(sample_challenge['technologies'][:3])}
|
| 986 |
π Difficulty: {sample_challenge['difficulty']}
|
|
|
|
| 987 |
|
| 988 |
My ENHANCED capabilities include:
|
| 989 |
π― Smart challenge matching with advanced filtering
|
|
@@ -1013,7 +1045,7 @@ ENHANCED Features:
|
|
| 1013 |
π Intelligent career recommendations
|
| 1014 |
|
| 1015 |
Ask me about:
|
| 1016 |
-
π― Specific technologies (Python, React, blockchain, etc.)
|
| 1017 |
π° Prize ranges and earning potential
|
| 1018 |
π Difficulty levels and skill requirements
|
| 1019 |
π Enhanced career advice and skill development
|
|
@@ -1021,6 +1053,8 @@ Ask me about:
|
|
| 1021 |
*All responses powered by enhanced real-time Topcoder MCP data with advanced intelligence!*"""
|
| 1022 |
|
| 1023 |
return "I'm your enhanced intelligent Topcoder assistant with advanced MCP data access! Ask me about challenges, skills, or career advice and I'll help you using enhanced live data from 1,485+ real challenges! π"
|
|
|
|
|
|
|
| 1024 |
|
| 1025 |
# ENHANCED: Properly placed standalone functions with correct signatures
|
| 1026 |
async def chat_with_enhanced_llm_agent(message: str, history: List[Tuple[str, str]], mcp_engine) -> Tuple[List[Tuple[str, str]], str]:
|
|
@@ -1058,7 +1092,7 @@ enhanced_intelligence_engine = EnhancedTopcoderMCPEngine()
|
|
| 1058 |
|
| 1059 |
# Keep all your existing formatting functions (they're perfect as-is)
|
| 1060 |
def format_challenge_card(challenge: Dict) -> str:
|
| 1061 |
-
"""Format challenge as professional HTML card with
|
| 1062 |
|
| 1063 |
# Create technology badges
|
| 1064 |
tech_badges = " ".join([
|
|
@@ -1093,6 +1127,26 @@ def format_challenge_card(challenge: Dict) -> str:
|
|
| 1093 |
prize_color = "#6c757d"
|
| 1094 |
prize_display = "Merit-based"
|
| 1095 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1096 |
return f"""
|
| 1097 |
<div style='border:2px solid {card_border};border-radius:16px;padding:25px;margin:20px 0;background:white;box-shadow:0 8px 25px rgba(0,0,0,0.1);transition:all 0.3s ease;position:relative;overflow:hidden;'>
|
| 1098 |
|
|
@@ -1137,6 +1191,8 @@ def format_challenge_card(challenge: Dict) -> str:
|
|
| 1137 |
<div style='font-size:0.85em;color:#6c757d;margin-top:4px;font-weight:500;'>Registered</div>
|
| 1138 |
</div>
|
| 1139 |
</div>
|
|
|
|
|
|
|
| 1140 |
</div>
|
| 1141 |
"""
|
| 1142 |
|
|
|
|
| 855 |
history_text = "\n".join([f"User: {h[0]}\nAssistant: {h[1]}" for h in recent_history])
|
| 856 |
|
| 857 |
# Create comprehensive prompt for LLM
|
| 858 |
+
# Create comprehensive prompt for LLM with FIXED link instructions
|
| 859 |
system_prompt = f"""You are an expert Topcoder Challenge Intelligence Assistant with ENHANCED REAL-TIME access to live challenge data through advanced MCP integration.
|
| 860 |
|
| 861 |
ENHANCED REAL CHALLENGE DATA CONTEXT:
|
|
|
|
| 881 |
- For skill questions, suggest real challenges that match their level with smart recommendations
|
| 882 |
- Keep responses concise but informative (max 300 words)
|
| 883 |
|
| 884 |
+
IMPORTANT LINK FORMATTING RULES:
|
| 885 |
+
- DO NOT include "View Details" or "View Challenge Details" text without proper URLs
|
| 886 |
+
- If you mention a challenge, either provide the full Topcoder URL or omit link references
|
| 887 |
+
- Instead of broken links, say "Available on Topcoder platform" or "Check Topcoder for details"
|
| 888 |
+
- Focus on the challenge content rather than linking instructions
|
| 889 |
|
| 890 |
+
User's current question: {user_message}
|
| 891 |
|
| 892 |
+
Provide a helpful, intelligent response using the enhanced real challenge data context. Do not include non-functional link text."""
|
| 893 |
# ENHANCED: Try OpenAI API if available
|
| 894 |
if self.llm_available:
|
| 895 |
try:
|
|
|
|
| 931 |
return await self.get_enhanced_fallback_response_with_context(user_message, challenge_context)
|
| 932 |
|
| 933 |
async def get_enhanced_fallback_response_with_context(self, user_message: str, challenge_context: str) -> str:
|
| 934 |
+
"""Enhanced fallback using real enhanced challenge data with FIXED links"""
|
| 935 |
message_lower = user_message.lower()
|
| 936 |
|
| 937 |
# Parse enhanced challenge context for intelligent responses
|
|
|
|
| 946 |
enhanced_features = "Advanced MCP integration"
|
| 947 |
|
| 948 |
# Technology-specific responses using enhanced real data
|
| 949 |
+
tech_keywords = ['python', 'react', 'javascript', 'blockchain', 'ai', 'ml', 'java', 'nodejs', 'angular', 'vue', 'aws', 'ec2', 'cpu', 'gpu']
|
| 950 |
matching_tech = [tech for tech in tech_keywords if tech in message_lower]
|
| 951 |
|
| 952 |
if matching_tech:
|
|
|
|
| 957 |
relevant_challenges.append(challenge)
|
| 958 |
|
| 959 |
if relevant_challenges:
|
| 960 |
+
response = f"Based on your skills in {', '.join(matching_tech)}, I found several exciting challenges! π\n\n"
|
| 961 |
+
|
| 962 |
for i, challenge in enumerate(relevant_challenges[:3], 1):
|
| 963 |
+
# FIXED: Create proper challenge display without broken links
|
| 964 |
+
challenge_id = challenge.get('id', '')
|
| 965 |
+
if challenge_id and challenge_id != 'unknown':
|
| 966 |
+
challenge_url = f"https://www.topcoder.com/challenges/{challenge_id}"
|
| 967 |
+
view_link = f"[View Challenge Details]({challenge_url})"
|
| 968 |
+
else:
|
| 969 |
+
view_link = "π‘ Available on Topcoder platform"
|
| 970 |
+
|
| 971 |
+
response += f"**{i}. {challenge['title']}**\n"
|
| 972 |
+
response += f" π° **Prize**: {challenge['prize']}\n"
|
| 973 |
+
response += f" π οΈ **Technologies**: {', '.join(challenge['technologies'][:5])}\n"
|
| 974 |
+
response += f" π **Difficulty**: {challenge['difficulty']}\n"
|
| 975 |
+
response += f" π₯ **Registrants**: {challenge['registrants']}\n"
|
| 976 |
+
response += f" π {view_link}\n\n"
|
| 977 |
|
| 978 |
response += f"*These are ENHANCED REAL challenges from my live MCP connection to Topcoder's database of {total_challenges} challenges with {enhanced_features}!*"
|
| 979 |
return response
|
|
|
|
| 983 |
if challenges:
|
| 984 |
response = f"π° Based on enhanced real MCP data, current Topcoder challenges offer:\n\n"
|
| 985 |
for i, challenge in enumerate(challenges[:3], 1):
|
| 986 |
+
challenge_id = challenge.get('id', '')
|
| 987 |
+
if challenge_id and challenge_id != 'unknown':
|
| 988 |
+
challenge_url = f"https://www.topcoder.com/challenges/{challenge_id}"
|
| 989 |
+
view_link = f"[View Details]({challenge_url})"
|
| 990 |
+
else:
|
| 991 |
+
view_link = "Available on Topcoder"
|
| 992 |
+
|
| 993 |
response += f"{i}. **{challenge['title']}** - {challenge['prize']}\n"
|
| 994 |
+
response += f" π Difficulty: {challenge['difficulty']} | π₯ Competition: {challenge['registrants']} registered\n"
|
| 995 |
+
response += f" π {view_link}\n\n"
|
| 996 |
response += f"*This is enhanced live prize data from {total_challenges} real challenges with {enhanced_features}!*"
|
| 997 |
return response
|
| 998 |
|
|
|
|
| 1000 |
if any(word in message_lower for word in ['career', 'skill', 'learn', 'beginner', 'advanced', 'help']):
|
| 1001 |
if challenges:
|
| 1002 |
sample_challenge = challenges[0]
|
| 1003 |
+
challenge_id = sample_challenge.get('id', '')
|
| 1004 |
+
if challenge_id and challenge_id != 'unknown':
|
| 1005 |
+
challenge_url = f"https://www.topcoder.com/challenges/{challenge_id}"
|
| 1006 |
+
view_link = f"[View This Challenge]({challenge_url})"
|
| 1007 |
+
else:
|
| 1008 |
+
view_link = "Available on Topcoder platform"
|
| 1009 |
+
|
| 1010 |
return f"""I'm your enhanced intelligent Topcoder assistant with ADVANCED MCP integration! π
|
| 1011 |
|
| 1012 |
I currently have enhanced live access to {total_challenges} real challenges with {enhanced_features}. For example, right now there's:
|
|
|
|
| 1015 |
π° Prize: **{sample_challenge['prize']}**
|
| 1016 |
π οΈ Technologies: {', '.join(sample_challenge['technologies'][:3])}
|
| 1017 |
π Difficulty: {sample_challenge['difficulty']}
|
| 1018 |
+
π {view_link}
|
| 1019 |
|
| 1020 |
My ENHANCED capabilities include:
|
| 1021 |
π― Smart challenge matching with advanced filtering
|
|
|
|
| 1045 |
π Intelligent career recommendations
|
| 1046 |
|
| 1047 |
Ask me about:
|
| 1048 |
+
π― Specific technologies (Python, React, blockchain, AWS, etc.)
|
| 1049 |
π° Prize ranges and earning potential
|
| 1050 |
π Difficulty levels and skill requirements
|
| 1051 |
π Enhanced career advice and skill development
|
|
|
|
| 1053 |
*All responses powered by enhanced real-time Topcoder MCP data with advanced intelligence!*"""
|
| 1054 |
|
| 1055 |
return "I'm your enhanced intelligent Topcoder assistant with advanced MCP data access! Ask me about challenges, skills, or career advice and I'll help you using enhanced live data from 1,485+ real challenges! π"
|
| 1056 |
+
|
| 1057 |
+
return "I'm your enhanced intelligent Topcoder assistant with advanced MCP data access! Ask me about challenges, skills, or career advice and I'll help you using enhanced live data from 1,485+ real challenges! π"
|
| 1058 |
|
| 1059 |
# ENHANCED: Properly placed standalone functions with correct signatures
|
| 1060 |
async def chat_with_enhanced_llm_agent(message: str, history: List[Tuple[str, str]], mcp_engine) -> Tuple[List[Tuple[str, str]], str]:
|
|
|
|
| 1092 |
|
| 1093 |
# Keep all your existing formatting functions (they're perfect as-is)
|
| 1094 |
def format_challenge_card(challenge: Dict) -> str:
|
| 1095 |
+
"""Format challenge as professional HTML card with FIXED links"""
|
| 1096 |
|
| 1097 |
# Create technology badges
|
| 1098 |
tech_badges = " ".join([
|
|
|
|
| 1127 |
prize_color = "#6c757d"
|
| 1128 |
prize_display = "Merit-based"
|
| 1129 |
|
| 1130 |
+
# FIXED: Create proper Topcoder URL or remove if not available
|
| 1131 |
+
challenge_id = challenge.get('id', '')
|
| 1132 |
+
if challenge_id and challenge_id != 'unknown':
|
| 1133 |
+
# Create working Topcoder challenge URL
|
| 1134 |
+
topcoder_url = f"https://www.topcoder.com/challenges/{challenge_id}"
|
| 1135 |
+
action_button = f"""
|
| 1136 |
+
<div style='text-align:center;margin-top:20px;'>
|
| 1137 |
+
<a href="{topcoder_url}" target="_blank" style='background:linear-gradient(135deg,{card_border},transparent);color:white;padding:12px 24px;border-radius:25px;text-decoration:none;font-weight:600;display:inline-block;box-shadow:0 4px 12px rgba(0,0,0,0.15);transition:all 0.3s ease;'>
|
| 1138 |
+
π View Challenge Details
|
| 1139 |
+
</a>
|
| 1140 |
+
</div>
|
| 1141 |
+
"""
|
| 1142 |
+
else:
|
| 1143 |
+
# If no valid ID, show info message instead of broken links
|
| 1144 |
+
action_button = f"""
|
| 1145 |
+
<div style='background:#f8f9fa;border-radius:12px;padding:15px;margin-top:20px;text-align:center;'>
|
| 1146 |
+
<div style='color:#6c757d;font-size:0.9em;'>π‘ This is a live challenge from Topcoder's database</div>
|
| 1147 |
+
</div>
|
| 1148 |
+
"""
|
| 1149 |
+
|
| 1150 |
return f"""
|
| 1151 |
<div style='border:2px solid {card_border};border-radius:16px;padding:25px;margin:20px 0;background:white;box-shadow:0 8px 25px rgba(0,0,0,0.1);transition:all 0.3s ease;position:relative;overflow:hidden;'>
|
| 1152 |
|
|
|
|
| 1191 |
<div style='font-size:0.85em;color:#6c757d;margin-top:4px;font-weight:500;'>Registered</div>
|
| 1192 |
</div>
|
| 1193 |
</div>
|
| 1194 |
+
|
| 1195 |
+
{action_button}
|
| 1196 |
</div>
|
| 1197 |
"""
|
| 1198 |
|