Skip to content

Commit 3604bff

Browse files
committed
Refactor: Update calculate function to use Wolfram Alpha LLM API and enhance error handling; improve README tool descriptions
1 parent cf8778f commit 3604bff

2 files changed

Lines changed: 98 additions & 37 deletions

File tree

LocalBot.py

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import os, random, asyncio, aiohttp, json, lyricsgenius, discord, wolframalpha
1+
import os, time, random, asyncio, aiohttp, json, lyricsgenius, discord
22
from discord.ext import commands, tasks
33
import yt_dlp as youtube_dl
44
from typing import Optional
@@ -59,9 +59,20 @@
5959
Available Tools:
6060
1. Information & Utility
6161
• weather [city] - Current weather conditions
62-
• calculate [query] - Math, time, date, general knowledge
62+
• calculate [query] - Wolfram Alpha queries for:
63+
- Mathematical calculations (2+2, solve x^2=16, derivatives, integrals)
64+
- Unit conversions (100 km to miles, 50 celsius to fahrenheit)
65+
- Scientific data (density of gold, speed of light, periodic table info)
66+
- Geographic information (population of Tokyo, area of France)
67+
- Historical facts (when was Einstein born, World War 2 dates)
68+
- Astronomical data (distance to moon, sunrise time in Paris)
69+
- Financial data (current exchange rates, stock prices)
70+
- General knowledge (tallest mountain, largest ocean, capital cities)
71+
- Statistics and comparisons (compare GDP of countries)
72+
- Date/time calculations (days between dates, time zones)
6373
• lyrics [song] - Get song lyrics
6474
• whats_new - Display recent bot updates and new features
75+
6576
2. Entertainment & Games
6677
• gtn - Number guessing game
6778
• dice [sides] - Roll dice (default: 6)
@@ -87,6 +98,15 @@
8798
• Format responses for readability
8899
• When using tools, focus on incorporating tool results naturally in your final response
89100
• For music playback, check if the user is in a voice channel first
101+
• Use the calculate tool for ANY factual information, data, or knowledge queries - not just math!
102+
• Examples of calculate tool usage:
103+
- "What's the population of Japan?" → calculate
104+
- "Convert 5 feet to meters" → calculate
105+
- "When was the iPhone first released?" → calculate
106+
- "What's the chemical formula for water?" → calculate
107+
- "Distance between Earth and Mars" → calculate
108+
• When you receive image URLs from tools (especially calculate), include them directly in your response - Discord will automatically display the images
109+
• Image URLs should be included on separate lines for best display
90110
91111
Note: Process user messages in format "username: message" but respond to message content only.
92112
"""
@@ -130,32 +150,82 @@ def bright_value():
130150

131151

132152
async def calculate(ctx, query, from_tool_call=False):
133-
client = wolframalpha.Client(WOLF)
134-
loop = asyncio.get_running_loop()
153+
"""Calculate using Wolfram Alpha LLM API."""
135154
try:
136-
res = await loop.run_in_executor(None, client.query, query)
137-
result_texts = []
138-
image_links = []
139-
for pod in res.pods:
140-
if "subpod" in pod:
141-
subpods = (
142-
pod["subpod"]
143-
if isinstance(pod["subpod"], list)
144-
else [pod["subpod"]]
145-
)
146-
for subpod in subpods:
147-
if "plaintext" in subpod and subpod["plaintext"]:
148-
result_texts.append(subpod["plaintext"])
149-
if "img" in subpod and "@src" in subpod["img"]:
150-
image_links.append(subpod["img"]["@src"])
151-
if result_texts and not from_tool_call:
152-
await send_response(ctx, result_texts[1])
153-
return result_texts[1] if result_texts else "No results found"
155+
base_url = "https://www.wolframalpha.com/api/v1/llm-api"
156+
params = {"input": query, "appid": WOLF, "maxchars": 2000}
157+
158+
async with aiohttp.ClientSession() as session:
159+
async with session.get(base_url, params=params) as response:
160+
if response.status == 200:
161+
result = await response.text()
162+
163+
# Extract image URLs from the result
164+
image_urls = []
165+
lines = result.split("\n")
166+
for line in lines:
167+
if (
168+
line.strip().startswith("image: https://")
169+
or line.strip().startswith("Image:")
170+
and "https://" in line
171+
):
172+
# Extract URL from the line
173+
url_start = line.find("https://")
174+
if url_start != -1:
175+
url_end = line.find(" ", url_start)
176+
if url_end == -1:
177+
url_end = len(line)
178+
image_url = line[url_start:url_end].strip()
179+
if (
180+
image_url.endswith(".png")
181+
or image_url.endswith(".jpg")
182+
or image_url.endswith(".jpeg")
183+
):
184+
image_urls.append(image_url)
185+
186+
if not from_tool_call:
187+
await send_response(ctx, result)
188+
# Send images if found
189+
if image_urls:
190+
for img_url in image_urls[:3]: # Limit to 3 images max
191+
try:
192+
embed = discord.Embed()
193+
embed.set_image(url=img_url)
194+
if hasattr(ctx, "respond"):
195+
await ctx.followup.send(embed=embed)
196+
else:
197+
await ctx.send(embed=embed)
198+
except Exception as e:
199+
pass
200+
201+
# Include image URLs in the return for tool calls
202+
if image_urls:
203+
result += f"\n\nImages available: {', '.join(image_urls[:3])}"
204+
205+
return result
206+
elif response.status == 501:
207+
error_msg = await response.text()
208+
if not from_tool_call:
209+
await send_response(ctx, f"Could not interpret query: {query}")
210+
return (
211+
f"Could not interpret query: {query}. Suggestions: {error_msg}"
212+
)
213+
elif response.status == 403:
214+
error_msg = "Invalid or missing Wolfram Alpha API key"
215+
if not from_tool_call:
216+
await send_response(ctx, error_msg)
217+
return error_msg
218+
else:
219+
error_msg = f"Wolfram Alpha API error (status {response.status})"
220+
if not from_tool_call:
221+
await send_response(ctx, error_msg)
222+
return error_msg
223+
154224
except Exception as e:
155-
print(f"An error occurred: {e}")
225+
error_msg = f"Error calculating: {str(e)}"
156226
if not from_tool_call:
157-
await send_response(ctx, "An error occurred while fetching the result.")
158-
return f"Error: {str(e)}"
227+
await send_response(ctx, "An error occurred while calculating.")
228+
return error_msg
159229

160230

161231
async def generate_chat_completion(
@@ -173,7 +243,7 @@ async def generate_chat_completion(
173243

174244
if context_key not in conversation_memory:
175245
conversation_memory[context_key] = ConversationBufferWindowMemory(
176-
k=42, memory_key="chat_history", return_messages=True
246+
k=42, return_messages=True
177247
)
178248

179249
memory = conversation_memory[context_key]
@@ -234,7 +304,6 @@ async def generate_chat_completion(
234304
return response_text
235305

236306
except Exception as e:
237-
print(f"Chat completion error: {str(e)}")
238307
await send_response(ctx, "I encountered an error processing your request.")
239308
return None
240309

@@ -309,13 +378,11 @@ async def handle_tool_call(
309378

310379
except (ValueError, KeyError) as e:
311380
error_msg = f"Tool call error: {str(e)}"
312-
print(error_msg)
313381
if not send_directly:
314382
await send_response(ctx, "I encountered an error with the requested tool.")
315383
return f"Error: {str(e)}"
316384

317385
except Exception as e:
318-
print(f"Unexpected tool error: {str(e)}")
319386
if not send_directly:
320387
await send_response(ctx, "An unexpected error occurred.")
321388
return f"Error: {str(e)}"
@@ -496,7 +563,7 @@ async def chat(ctx, *, message):
496563
global conversation_memory
497564
if context_key not in conversation_memory:
498565
conversation_memory[context_key] = ConversationBufferWindowMemory(
499-
k=42, memory_key="chat_history", return_messages=True
566+
k=42, return_messages=True
500567
)
501568

502569
memory = conversation_memory[context_key]
@@ -536,8 +603,6 @@ async def chat(ctx, *, message):
536603
send_directly=True,
537604
)
538605

539-
print(f"Tool result: {tool_result}")
540-
541606
remaining_text = response[tool_end:].strip()
542607

543608
if "<tool_calls>" in remaining_text:
@@ -568,7 +633,6 @@ async def chat(ctx, *, message):
568633
await send_complete_response(ctx, response)
569634

570635
except Exception as e:
571-
print(f"Error in chat command: {e}")
572636
await send_response(ctx, f"An error occurred: {e}")
573637

574638

requirements.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,4 @@ google-genai
1919
# Memory & Conversation Management
2020
langchain
2121
langchain-community
22-
langchain-core
23-
24-
# API Services
25-
wolframalpha
22+
langchain-core

0 commit comments

Comments
 (0)