Priyanshi Saxena commited on
Commit
a4b05e9
Β·
1 Parent(s): faf01ab

fix: Clean LLM responses and fix variable scope errors

Browse files

- Fixed Gemini response cleaning to extract content properly from LangChain objects
- Fixed Ollama response cleaning to handle string conversion
- Fixed variable scope error in timeout handler (btc_data -> summary_data)
- Fixed DeFi TVL sorting error by filtering out None values
- Enhanced error handling in fallback response mechanism
- Improved response content extraction for both LLMs

src/agent/research_agent.py CHANGED
@@ -202,6 +202,7 @@ class Web3ResearchAgent:
202
  "metadata": {"llm": "ollama", "mode": "simple", "timestamp": datetime.now().isoformat()}
203
  }
204
  except Exception as fallback_error:
 
205
  return {
206
  "success": False,
207
  "query": query,
@@ -333,8 +334,11 @@ Just list the tool names:"""
333
  )
334
  logger.info(f"🎯 Ollama final response preview: {str(final_response)[:300]}...")
335
 
 
 
 
336
  # AI Safety Check: Validate response
337
- clean_response, response_safe, response_reason = ai_safety.validate_ollama_response(final_response)
338
  if not response_safe:
339
  ai_safety.log_safety_event("blocked_ollama_response", {
340
  "reason": response_reason,
@@ -355,16 +359,20 @@ Based on the available data:
355
  except asyncio.TimeoutError:
356
  logger.warning("⏱️ Ollama final response timed out, using tool data directly")
357
  # Create a summary from the tool results directly
358
- if "cryptocompare_data" in suggested_tools and "Bitcoin" in query:
359
- btc_data = "Bitcoin: $122,044+ USD"
 
 
 
 
360
  elif "defillama_data" in suggested_tools:
361
- defi_data = "DeFi protocols data available"
362
- else:
363
- btc_data = "Tool data available"
364
 
365
  final_response = f"""## {query.split()[0]} Analysis
366
 
367
- **Quick Summary**: {btc_data}
368
 
369
  The system successfully gathered data from {len(suggested_tools)} tools:
370
  {', '.join(suggested_tools)}
@@ -502,8 +510,14 @@ Respond with only the tool names, comma-separated (no explanations)."""
502
  )
503
  logger.info(f"🎯 Gemini final response preview: {str(final_response)[:300]}...")
504
 
 
 
 
 
 
 
505
  # AI Safety Check: Validate response
506
- clean_response, response_safe, response_reason = ai_safety.validate_gemini_response(str(final_response))
507
  if not response_safe:
508
  ai_safety.log_safety_event("blocked_gemini_response", {
509
  "reason": response_reason,
 
202
  "metadata": {"llm": "ollama", "mode": "simple", "timestamp": datetime.now().isoformat()}
203
  }
204
  except Exception as fallback_error:
205
+ logger.error(f"Fallback response failed: {fallback_error}")
206
  return {
207
  "success": False,
208
  "query": query,
 
334
  )
335
  logger.info(f"🎯 Ollama final response preview: {str(final_response)[:300]}...")
336
 
337
+ # Extract content from Ollama response
338
+ response_content = str(final_response)
339
+
340
  # AI Safety Check: Validate response
341
+ clean_response, response_safe, response_reason = ai_safety.validate_ollama_response(response_content)
342
  if not response_safe:
343
  ai_safety.log_safety_event("blocked_ollama_response", {
344
  "reason": response_reason,
 
359
  except asyncio.TimeoutError:
360
  logger.warning("⏱️ Ollama final response timed out, using tool data directly")
361
  # Create a summary from the tool results directly
362
+ summary_data = "Tool data available"
363
+ if "cryptocompare_data" in suggested_tools:
364
+ if "bitcoin" in query.lower() or "btc" in query.lower():
365
+ summary_data = "Bitcoin price data retrieved"
366
+ else:
367
+ summary_data = "Cryptocurrency price data retrieved"
368
  elif "defillama_data" in suggested_tools:
369
+ summary_data = "DeFi protocols data available"
370
+ elif "etherscan_data" in suggested_tools:
371
+ summary_data = "Ethereum blockchain data available"
372
 
373
  final_response = f"""## {query.split()[0]} Analysis
374
 
375
+ **Quick Summary**: {summary_data}
376
 
377
  The system successfully gathered data from {len(suggested_tools)} tools:
378
  {', '.join(suggested_tools)}
 
510
  )
511
  logger.info(f"🎯 Gemini final response preview: {str(final_response)[:300]}...")
512
 
513
+ # Extract content from Gemini response object
514
+ if hasattr(final_response, 'content'):
515
+ response_content = final_response.content
516
+ else:
517
+ response_content = str(final_response)
518
+
519
  # AI Safety Check: Validate response
520
+ clean_response, response_safe, response_reason = ai_safety.validate_gemini_response(response_content)
521
  if not response_safe:
522
  ai_safety.log_safety_event("blocked_gemini_response", {
523
  "reason": response_reason,
src/tools/chart_data_tool.py CHANGED
@@ -271,9 +271,9 @@ class ChartDataTool(BaseTool):
271
  break
272
  protocols_data = filtered_protocols[:8] # Limit to 8
273
  else:
274
- # Get top protocols by TVL
275
- protocols_data = sorted([p for p in data if p.get("tvl", 0) > 0],
276
- key=lambda x: x.get("tvl", 0), reverse=True)[:8]
277
 
278
  if not protocols_data:
279
  return await self._get_mock_defi_data(protocols)
 
271
  break
272
  protocols_data = filtered_protocols[:8] # Limit to 8
273
  else:
274
+ # Get top protocols by TVL (filter out None values)
275
+ valid_protocols = [p for p in data if p.get("tvl") is not None and p.get("tvl", 0) > 0]
276
+ protocols_data = sorted(valid_protocols, key=lambda x: x.get("tvl", 0), reverse=True)[:8]
277
 
278
  if not protocols_data:
279
  return await self._get_mock_defi_data(protocols)
test_tool_selection.py DELETED
@@ -1,69 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test the updated tool selection to ensure we use CryptoCompare/Etherscan instead of CoinGecko
4
- """
5
-
6
- import asyncio
7
- import sys
8
- import os
9
-
10
- # Add src to path
11
- sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
12
-
13
- from src.agent.research_agent import Web3ResearchAgent
14
-
15
- async def test_tool_selection():
16
- """Test that the system prioritizes CryptoCompare and Etherscan over CoinGecko"""
17
- print("πŸ§ͺ Testing tool selection...")
18
-
19
- agent = Web3ResearchAgent()
20
-
21
- if not agent.enabled:
22
- print("❌ Agent not enabled")
23
- return False
24
-
25
- # Check which tools are initialized
26
- tool_names = [tool.name for tool in agent.tools]
27
- print(f"πŸ› οΈ Available tools: {tool_names}")
28
-
29
- # Verify CoinGecko is not in tools (since no API key)
30
- if 'coingecko_data' in tool_names:
31
- print("⚠️ CoinGecko tool is still initialized - this may cause API failures")
32
- else:
33
- print("βœ… CoinGecko tool properly skipped (no API key)")
34
-
35
- # Verify we have the working tools
36
- expected_tools = ['cryptocompare_data', 'etherscan_data', 'defillama_data', 'chart_data_provider']
37
- working_tools = [tool for tool in expected_tools if tool in tool_names]
38
- print(f"βœ… Working tools available: {working_tools}")
39
-
40
- # Test a simple query
41
- try:
42
- print("\nπŸ“Š Testing Bitcoin price query...")
43
- result = await agent.research_query("Analyze Bitcoin price trends", use_gemini=True)
44
-
45
- if result['success']:
46
- print("βœ… Query successful!")
47
- print(f"πŸ“ˆ Result preview: {result['result'][:200]}...")
48
- print(f"πŸ”§ Tools used: {result.get('metadata', {}).get('tools_used', 'N/A')}")
49
- return True
50
- else:
51
- print(f"❌ Query failed: {result.get('error', 'Unknown error')}")
52
- return False
53
-
54
- except Exception as e:
55
- print(f"❌ Test failed with exception: {e}")
56
- return False
57
-
58
- async def main():
59
- success = await test_tool_selection()
60
- if success:
61
- print("\nπŸŽ‰ Tool selection test passed!")
62
- return 0
63
- else:
64
- print("\n❌ Tool selection test failed!")
65
- return 1
66
-
67
- if __name__ == "__main__":
68
- exit_code = asyncio.run(main())
69
- sys.exit(exit_code)