Priyanshi Saxena commited on
Commit
1799dd5
·
1 Parent(s): e142284
Files changed (1) hide show
  1. app.py +87 -303
app.py CHANGED
@@ -46,20 +46,13 @@ class Web3CoPilotService:
46
  def __init__(self):
47
  try:
48
  logger.info("Initializing Web3 Research Service...")
49
- logger.info(f"Environment check - GEMINI_API_KEY present: {bool(config.GEMINI_API_KEY)}")
50
 
51
  if config.GEMINI_API_KEY:
52
  logger.info("AI research capabilities enabled")
53
- try:
54
- self.agent = Web3ResearchAgent()
55
- self.enabled = self.agent.enabled
56
- logger.info(f"Web3ResearchAgent initialized - enabled: {self.enabled}")
57
- except Exception as e:
58
- logger.error(f"Failed to initialize Web3ResearchAgent: {e}")
59
- self.agent = None
60
- self.enabled = False
61
  else:
62
- logger.warning("AI research capabilities disabled - GEMINI_API_KEY not configured")
63
  self.agent = None
64
  self.enabled = False
65
 
@@ -401,9 +394,6 @@ async def get_homepage(request: Request):
401
  <title>Web3 Research Co-Pilot</title>
402
  <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22><path fill=%22%2300d4aa%22 d=%22M12 2L2 7v10c0 5.5 3.8 7.7 9 9 5.2-1.3 9-3.5 9-9V7l-10-5z%22/></svg>">
403
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
404
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/components/prism-core.min.js"></script>
405
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/plugins/autoloader/prism-autoloader.min.js"></script>
406
- <link href="https://cdn.jsdelivr.net/npm/[email protected]/themes/prism-tomorrow.min.css" rel="stylesheet">
407
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
408
 
409
  <style>
@@ -622,197 +612,90 @@ async def get_homepage(request: Request):
622
  border-bottom-left-radius: 8px;
623
  border: 1px solid var(--border);
624
  }
625
- /* Enhanced text formatting for better UX */
626
- .message-content h1, .message-content h2, .message-content h3, .message-content h4, .message-content h5, .message-content h6 {
627
  color: var(--accent);
628
- margin: 1.5rem 0 0.75rem 0;
629
  font-weight: 600;
630
  line-height: 1.3;
631
- letter-spacing: -0.025em;
632
- }
633
- .message-content h1 {
634
- font-size: 1.35rem;
635
- border-bottom: 2px solid var(--accent);
636
- padding-bottom: 0.5rem;
637
  }
638
- .message-content h2 {
639
- font-size: 1.2rem;
640
- border-bottom: 1px solid var(--border);
641
- padding-bottom: 0.25rem;
642
- }
643
- .message-content h3 { font-size: 1.1rem; }
644
- .message-content h4 { font-size: 1rem; }
645
- .message-content h5 { font-size: 0.95rem; }
646
- .message-content h6 { font-size: 0.9rem; opacity: 0.9; }
647
-
648
  .message-content p {
649
- margin: 0.875rem 0;
650
  line-height: 1.65;
651
- text-align: justify;
652
- text-justify: inter-word;
653
  }
654
-
655
  .message-content ul, .message-content ol {
656
- margin: 1rem 0;
657
- padding-left: 1.75rem;
 
658
  }
659
-
660
- .message-content ul {
661
- list-style-type: none;
662
  }
663
-
664
- .message-content ul li::before {
665
- content: '•';
666
- color: var(--accent);
667
- font-weight: bold;
668
- position: absolute;
669
- margin-left: -1.25rem;
670
  }
671
-
672
- .message-content ol li {
673
- list-style-type: decimal;
674
- color: var(--text);
675
  }
676
-
677
- .message-content li {
678
- margin: 0.5rem 0;
679
- line-height: 1.6;
680
- position: relative;
681
  }
682
-
683
- .message-content strong, .message-content b {
684
  color: var(--accent);
685
- font-weight: 650;
686
- text-shadow: 0 0 2px rgba(0, 212, 170, 0.3);
687
  }
688
-
689
- .message-content em, .message-content i {
690
  color: var(--text-secondary);
691
  font-style: italic;
692
- font-weight: 450;
693
  }
694
-
695
  .message-content code {
696
- background: linear-gradient(135deg, rgba(0, 102, 255, 0.12), rgba(0, 212, 170, 0.08));
697
  border: 1px solid rgba(0, 102, 255, 0.25);
698
- padding: 0.2rem 0.5rem;
699
- border-radius: 6px;
700
- font-family: 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', Consolas, monospace;
701
- font-size: 0.875rem;
702
  color: var(--accent);
703
  font-weight: 500;
704
- letter-spacing: 0.025em;
705
- box-shadow: 0 1px 3px rgba(0, 102, 255, 0.1);
706
  }
707
-
708
  .message-content pre {
709
- background: linear-gradient(135deg, var(--background), var(--surface));
710
  border: 1px solid var(--border);
711
- border-radius: 10px;
712
- padding: 1.25rem;
713
- margin: 1.5rem 0;
714
  overflow-x: auto;
715
- font-family: 'SF Mono', 'Monaco', 'Cascadia Code', 'Roboto Mono', Consolas, monospace;
716
- font-size: 0.875rem;
717
  line-height: 1.5;
718
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
719
- position: relative;
720
  }
721
-
722
  .message-content pre code {
723
  background: none;
724
  border: none;
725
  padding: 0;
726
- border-radius: 0;
727
- box-shadow: none;
728
- color: var(--text);
729
  }
730
-
731
  .message-content blockquote {
732
- border-left: 4px solid var(--accent);
733
- background: rgba(0, 212, 170, 0.05);
734
- padding: 1rem 1.5rem;
735
- margin: 1.5rem 0;
736
- color: var(--text-secondary);
737
- font-style: italic;
738
- border-radius: 0 8px 8px 0;
739
- position: relative;
740
- }
741
-
742
- .message-content blockquote::before {
743
- content: '"';
744
- font-size: 3rem;
745
- color: var(--accent);
746
- position: absolute;
747
- top: -0.5rem;
748
- left: 0.5rem;
749
- opacity: 0.3;
750
- font-family: Georgia, serif;
751
- }
752
-
753
- .message-content a {
754
- color: var(--primary);
755
- text-decoration: none;
756
- font-weight: 500;
757
- border-bottom: 1px solid transparent;
758
- transition: all 0.2s ease;
759
- }
760
-
761
- .message-content a:hover {
762
- color: var(--accent);
763
- border-bottom-color: var(--accent);
764
- }
765
-
766
- .message-content table {
767
- width: 100%;
768
- border-collapse: collapse;
769
- margin: 1.5rem 0;
770
- background: var(--surface-elevated);
771
- border-radius: 8px;
772
- overflow: hidden;
773
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
774
- }
775
-
776
- .message-content th, .message-content td {
777
- padding: 0.875rem;
778
- text-align: left;
779
- border-bottom: 1px solid var(--border);
780
- }
781
-
782
- .message-content th {
783
- background: var(--surface);
784
- font-weight: 600;
785
- color: var(--accent);
786
- }
787
-
788
- .message-content tr:last-child td {
789
- border-bottom: none;
790
- }
791
-
792
- .message-content hr {
793
- border: none;
794
- height: 2px;
795
- background: linear-gradient(90deg, transparent, var(--border), transparent);
796
- margin: 2rem 0;
797
- }
798
-
799
- /* Number formatting for crypto values */
800
- .message-content .crypto-value {
801
- font-family: 'SF Mono', monospace;
802
- font-weight: 600;
803
- color: var(--accent);
804
- background: rgba(0, 212, 170, 0.1);
805
- padding: 0.1rem 0.3rem;
806
- border-radius: 4px;
807
- }
808
-
809
- /* Highlight important information */
810
- .message-content .highlight {
811
- background: linear-gradient(135deg, rgba(0, 102, 255, 0.15), rgba(0, 212, 170, 0.1));
812
- padding: 0.75rem 1rem;
813
- border-radius: 8px;
814
  border-left: 3px solid var(--accent);
 
815
  margin: 1rem 0;
 
 
 
 
 
816
  }
817
 
818
  .message-meta {
@@ -1185,78 +1068,37 @@ async def get_homepage(request: Request):
1185
  </div>
1186
 
1187
  <script>
1188
- // Configure marked.js for better markdown rendering
1189
- if (typeof marked !== 'undefined') {
1190
- marked.setOptions({
1191
- breaks: true,
1192
- gfm: true,
1193
- highlight: function(code, lang) {
1194
- if (typeof Prism !== 'undefined' && lang && Prism.languages[lang]) {
1195
- return Prism.highlight(code, Prism.languages[lang], lang);
1196
- }
1197
- return code;
1198
- },
1199
- sanitize: false,
1200
- smartLists: true,
1201
- smartypants: true
1202
- });
1203
- }
1204
-
1205
  let chatHistory = [];
1206
  let messageCount = 0;
1207
 
1208
  async function checkStatus() {
1209
- console.log('Checking system status...');
1210
  try {
1211
  const response = await fetch('/status');
1212
- console.log('Status response:', response.status, response.statusText);
1213
-
1214
- if (!response.ok) {
1215
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
1216
- }
1217
-
1218
  const status = await response.json();
1219
- console.log('Status data:', status);
1220
 
1221
  const statusDiv = document.getElementById('status');
1222
 
1223
- // Check if system is operational (either fully enabled or in limited mode)
1224
- if (status.enabled) {
1225
- if (status.gemini_configured) {
1226
- console.log('✅ System is fully operational');
1227
- statusDiv.className = 'status online';
1228
- statusDiv.innerHTML = `
1229
- <span>Research systems online</span>
1230
- <div style="margin-top: 0.5rem; font-size: 0.85rem; opacity: 0.8;">
1231
- Tools: ${status.tools_available.join(' • ')}
1232
- </div>
1233
- `;
1234
- } else {
1235
- console.log('⚠️ System is in limited mode');
1236
- statusDiv.className = 'status offline';
1237
- statusDiv.innerHTML = `
1238
- <span>Limited mode - Configure GEMINI_API_KEY for full functionality</span>
1239
- <div style="margin-top: 0.5rem; font-size: 0.85rem; opacity: 0.8;">
1240
- Available: ${status.tools_available.join(' • ')}
1241
- </div>
1242
- `;
1243
- }
1244
  } else {
1245
- console.log('❌ System is disabled');
1246
  statusDiv.className = 'status offline';
1247
- statusDiv.innerHTML = '<span>System disabled</span>';
 
 
 
 
 
1248
  }
1249
  } catch (error) {
1250
- console.error('❌ Status check failed:', error);
1251
  const statusDiv = document.getElementById('status');
1252
  statusDiv.className = 'status offline';
1253
- statusDiv.innerHTML = `<span>Connection error: ${error.message}</span>`;
1254
-
1255
- // Retry after 5 seconds
1256
- setTimeout(() => {
1257
- console.log('🔄 Retrying status check...');
1258
- checkStatus();
1259
- }, 5000);
1260
  }
1261
  }
1262
 
@@ -1359,35 +1201,24 @@ async def get_homepage(request: Request):
1359
  }).join('');
1360
  }
1361
 
1362
- // Format content based on sender with enhanced markdown processing
1363
  let formattedContent = content;
1364
  if (sender === 'assistant') {
1365
- // Enhanced markdown to HTML conversion for assistant responses
1366
  try {
1367
- // Use marked.js if available
1368
- if (typeof marked !== 'undefined') {
1369
- formattedContent = marked.parse(content);
1370
- } else {
1371
- throw new Error('marked.js not available');
1372
- }
1373
  } catch (error) {
1374
- // Simple fallback formatting if marked.js fails
1375
- console.warn('Markdown parsing failed, using simple fallback:', error);
1376
  formattedContent = content
1377
- .replace(/\n\n/g, '<br><br>')
1378
- .replace(/\n/g, '<br>')
1379
- .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
1380
- .replace(/\*(.*?)\*/g, '<em>$1</em>')
1381
  .replace(/`(.*?)`/g, '<code>$1</code>');
1382
  }
1383
- }
1384
  } else {
1385
- // Simple user message formatting
1386
- formattedContent = content
1387
- .replace(/\n/g, '<br>')
1388
- .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
1389
- .replace(/\*(.*?)\*/g, '<em>$1</em>')
1390
- .replace(/`(.*?)`/g, '<code>$1</code>');
1391
  }
1392
 
1393
  messageDiv.innerHTML = `
@@ -1402,11 +1233,6 @@ async def get_homepage(request: Request):
1402
  messagesDiv.appendChild(messageDiv);
1403
  messagesDiv.scrollTop = messagesDiv.scrollHeight;
1404
 
1405
- // Apply syntax highlighting to code blocks
1406
- if (typeof Prism !== 'undefined') {
1407
- Prism.highlightAllUnder(messageDiv);
1408
- }
1409
-
1410
  // Execute any scripts in the visualizations after DOM insertion
1411
  if (visualizations && visualizations.length > 0) {
1412
  console.log('Executing visualization scripts...');
@@ -1499,28 +1325,10 @@ async def get_homepage(request: Request):
1499
 
1500
  // Initialize
1501
  document.addEventListener('DOMContentLoaded', () => {
1502
- console.log('🚀 Web3 Research Co-Pilot - Application initializing...');
1503
- console.log('📍 Current URL:', window.location.href);
1504
- console.log('🌐 User Agent:', navigator.userAgent.substring(0, 100));
1505
-
1506
- // Test basic functionality
1507
- const statusDiv = document.getElementById('status');
1508
- console.log('📋 Status div found:', !!statusDiv);
1509
-
1510
  initializeTheme();
1511
-
1512
- // Immediate status check for debugging
1513
- console.log('🔍 Starting immediate status check...');
1514
  checkStatus();
1515
-
1516
- // Also do a delayed check
1517
- setTimeout(() => {
1518
- console.log('🔍 Starting delayed status check...');
1519
- checkStatus();
1520
- }, 2000);
1521
-
1522
  document.getElementById('queryInput').focus();
1523
- console.log('✅ Application initialization complete');
1524
  });
1525
  </script>
1526
  </body>
@@ -1530,40 +1338,16 @@ async def get_homepage(request: Request):
1530
 
1531
  @app.get("/status")
1532
  async def get_status():
1533
- """System status endpoint with detailed debugging information"""
1534
- try:
1535
- gemini_configured = bool(config.GEMINI_API_KEY)
1536
- service_enabled = service.enabled
1537
- agent_available = service.agent is not None
1538
-
1539
- status = {
1540
- "enabled": service_enabled,
1541
- "gemini_configured": gemini_configured,
1542
- "agent_available": agent_available,
1543
- "tools_available": ["Market Data", "DeFi Analytics", "Network Metrics"],
1544
- "airaa_enabled": service.airaa.enabled if service.airaa else False,
1545
- "timestamp": datetime.now().isoformat(),
1546
- "version": "2.0.0",
1547
- "debug_info": {
1548
- "gemini_key_length": len(config.GEMINI_API_KEY) if config.GEMINI_API_KEY else 0,
1549
- "service_enabled": service_enabled,
1550
- "agent_initialized": agent_available
1551
- }
1552
- }
1553
- logger.info(f"Status check - Enabled: {service_enabled}, Gemini: {gemini_configured}")
1554
- return status
1555
- except Exception as e:
1556
- logger.error(f"Status endpoint error: {e}")
1557
- return {
1558
- "enabled": False,
1559
- "gemini_configured": False,
1560
- "agent_available": False,
1561
- "tools_available": [],
1562
- "airaa_enabled": False,
1563
- "timestamp": datetime.now().isoformat(),
1564
- "version": "2.0.0",
1565
- "error": str(e)
1566
- }
1567
 
1568
  @app.post("/query", response_model=QueryResponse)
1569
  async def process_query(request: QueryRequest):
 
46
  def __init__(self):
47
  try:
48
  logger.info("Initializing Web3 Research Service...")
 
49
 
50
  if config.GEMINI_API_KEY:
51
  logger.info("AI research capabilities enabled")
52
+ self.agent = Web3ResearchAgent()
53
+ self.enabled = self.agent.enabled
 
 
 
 
 
 
54
  else:
55
+ logger.info("AI research capabilities disabled - API key required")
56
  self.agent = None
57
  self.enabled = False
58
 
 
394
  <title>Web3 Research Co-Pilot</title>
395
  <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22><path fill=%22%2300d4aa%22 d=%22M12 2L2 7v10c0 5.5 3.8 7.7 9 9 5.2-1.3 9-3.5 9-9V7l-10-5z%22/></svg>">
396
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
 
 
 
397
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
398
 
399
  <style>
 
612
  border-bottom-left-radius: 8px;
613
  border: 1px solid var(--border);
614
  }
615
+ .message-content h1, .message-content h2, .message-content h3, .message-content h4 {
 
616
  color: var(--accent);
617
+ margin: 1.25rem 0 0.5rem 0;
618
  font-weight: 600;
619
  line-height: 1.3;
 
 
 
 
 
 
620
  }
621
+ .message-content h1 { font-size: 1.25rem; }
622
+ .message-content h2 { font-size: 1.1rem; }
623
+ .message-content h3 { font-size: 1rem; }
624
+ .message-content h4 { font-size: 0.95rem; }
 
 
 
 
 
 
625
  .message-content p {
626
+ margin: 0.75rem 0;
627
  line-height: 1.65;
628
+ color: var(--text);
 
629
  }
 
630
  .message-content ul, .message-content ol {
631
+ margin: 0.75rem 0;
632
+ padding-left: 1.5rem;
633
+ line-height: 1.6;
634
  }
635
+ .message-content li {
636
+ margin: 0.3rem 0;
637
+ line-height: 1.6;
638
  }
639
+ .message-content table {
640
+ width: 100%;
641
+ border-collapse: collapse;
642
+ margin: 1rem 0;
643
+ font-size: 0.9rem;
 
 
644
  }
645
+ .message-content th, .message-content td {
646
+ border: 1px solid var(--border);
647
+ padding: 0.5rem 0.75rem;
648
+ text-align: left;
649
  }
650
+ .message-content th {
651
+ background: var(--surface);
652
+ font-weight: 600;
653
+ color: var(--accent);
 
654
  }
655
+ .message-content strong {
 
656
  color: var(--accent);
657
+ font-weight: 600;
 
658
  }
659
+ .message-content em {
 
660
  color: var(--text-secondary);
661
  font-style: italic;
 
662
  }
 
663
  .message-content code {
664
+ background: rgba(0, 102, 255, 0.12);
665
  border: 1px solid rgba(0, 102, 255, 0.25);
666
+ padding: 0.2rem 0.45rem;
667
+ border-radius: 4px;
668
+ font-family: 'SF Mono', Consolas, 'Courier New', monospace;
669
+ font-size: 0.85rem;
670
  color: var(--accent);
671
  font-weight: 500;
 
 
672
  }
 
673
  .message-content pre {
674
+ background: var(--background);
675
  border: 1px solid var(--border);
676
+ border-radius: 8px;
677
+ padding: 1rem;
678
+ margin: 1rem 0;
679
  overflow-x: auto;
680
+ font-family: 'SF Mono', Consolas, 'Courier New', monospace;
681
+ font-size: 0.85rem;
682
  line-height: 1.5;
 
 
683
  }
 
684
  .message-content pre code {
685
  background: none;
686
  border: none;
687
  padding: 0;
688
+ font-size: inherit;
 
 
689
  }
 
690
  .message-content blockquote {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
691
  border-left: 3px solid var(--accent);
692
+ padding-left: 1rem;
693
  margin: 1rem 0;
694
+ color: var(--text-secondary);
695
+ font-style: italic;
696
+ background: rgba(0, 212, 170, 0.05);
697
+ padding: 0.75rem 0 0.75rem 1rem;
698
+ border-radius: 0 4px 4px 0;
699
  }
700
 
701
  .message-meta {
 
1068
  </div>
1069
 
1070
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1071
  let chatHistory = [];
1072
  let messageCount = 0;
1073
 
1074
  async function checkStatus() {
 
1075
  try {
1076
  const response = await fetch('/status');
 
 
 
 
 
 
1077
  const status = await response.json();
 
1078
 
1079
  const statusDiv = document.getElementById('status');
1080
 
1081
+ if (status.enabled && status.gemini_configured) {
1082
+ statusDiv.className = 'status online';
1083
+ statusDiv.innerHTML = `
1084
+ <span>Research systems online</span>
1085
+ <div style="margin-top: 0.5rem; font-size: 0.85rem; opacity: 0.8;">
1086
+ Tools: ${status.tools_available.join(' ')}
1087
+ </div>
1088
+ `;
 
 
 
 
 
 
 
 
 
 
 
 
 
1089
  } else {
 
1090
  statusDiv.className = 'status offline';
1091
+ statusDiv.innerHTML = `
1092
+ <span>Limited mode - Configure GEMINI_API_KEY for full functionality</span>
1093
+ <div style="margin-top: 0.5rem; font-size: 0.85rem; opacity: 0.8;">
1094
+ Available: ${status.tools_available.join(' • ')}
1095
+ </div>
1096
+ `;
1097
  }
1098
  } catch (error) {
 
1099
  const statusDiv = document.getElementById('status');
1100
  statusDiv.className = 'status offline';
1101
+ statusDiv.innerHTML = '<span>Connection error</span>';
 
 
 
 
 
 
1102
  }
1103
  }
1104
 
 
1201
  }).join('');
1202
  }
1203
 
1204
+ // Format content based on sender
1205
  let formattedContent = content;
1206
  if (sender === 'assistant') {
1207
+ // Convert markdown to HTML for assistant responses
1208
  try {
1209
+ formattedContent = marked.parse(content);
 
 
 
 
 
1210
  } catch (error) {
1211
+ // Fallback to basic formatting if marked.js fails
1212
+ console.warn('Markdown parsing failed, using fallback:', error);
1213
  formattedContent = content
1214
+ .replace(/\\n/g, '<br>')
1215
+ .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')
1216
+ .replace(/\\*(.*?)\\*/g, '<em>$1</em>')
 
1217
  .replace(/`(.*?)`/g, '<code>$1</code>');
1218
  }
 
1219
  } else {
1220
+ // Simple line breaks for user messages
1221
+ formattedContent = content.replace(/\\n/g, '<br>');
 
 
 
 
1222
  }
1223
 
1224
  messageDiv.innerHTML = `
 
1233
  messagesDiv.appendChild(messageDiv);
1234
  messagesDiv.scrollTop = messagesDiv.scrollHeight;
1235
 
 
 
 
 
 
1236
  // Execute any scripts in the visualizations after DOM insertion
1237
  if (visualizations && visualizations.length > 0) {
1238
  console.log('Executing visualization scripts...');
 
1325
 
1326
  // Initialize
1327
  document.addEventListener('DOMContentLoaded', () => {
1328
+ console.log('Application initialized');
 
 
 
 
 
 
 
1329
  initializeTheme();
 
 
 
1330
  checkStatus();
 
 
 
 
 
 
 
1331
  document.getElementById('queryInput').focus();
 
1332
  });
1333
  </script>
1334
  </body>
 
1338
 
1339
  @app.get("/status")
1340
  async def get_status():
1341
+ """System status endpoint"""
1342
+ status = {
1343
+ "enabled": service.enabled,
1344
+ "gemini_configured": bool(config.GEMINI_API_KEY),
1345
+ "tools_available": ["Market Data", "DeFi Analytics", "Network Metrics"],
1346
+ "airaa_enabled": service.airaa.enabled if service.airaa else False,
1347
+ "timestamp": datetime.now().isoformat(),
1348
+ "version": "2.0.0"
1349
+ }
1350
+ return status
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1351
 
1352
  @app.post("/query", response_model=QueryResponse)
1353
  async def process_query(request: QueryRequest):