7878 • news_top [category, country, limit] - Get top news stories (real-time data)
7979 - Categories: general, business, tech, science, health, entertainment, sports, politics
8080 - Country: in, us, ca, gb, au, etc. (default: in)
81- - Limit: number of articles (1-10, default: 5)
82- • news_headlines [category, country] - Get categorized headlines (real-time data)
83- - Shows latest headlines organized by category
84- - More comprehensive overview of current news
81+ - Limit: number of articles (1-3, default: 3)
8582 • news_search [query, category, limit] - Search for specific news (historical & real-time)
8683 - Search for specific topics, people, events, companies
8784 - Can filter by category and limit results
122119• For news requests, choose the appropriate news tool:
123120 - "What's in the news today?" → news_top
124121 - "Latest tech news" → news_top with category="tech"
125- - "Headlines " → news_headlines
122+ - "Top stories " → news_top (general news)
126123 - "News about Tesla" → news_search with query="Tesla"
127124 - "What happened with the stock market?" → news_search with query="stock market"
128125• When you receive image URLs from tools (especially calculate), include them directly in your response - Discord will automatically display the images
@@ -277,7 +274,6 @@ async def generate_chat_completion(
277274 return None
278275
279276 conversation_history = []
280- system_content = system_prompt
281277 chat_history = memory .chat_memory .messages
282278
283279 for message in chat_history :
@@ -289,9 +285,7 @@ async def generate_chat_completion(
289285
290286 conversation_history .append (prompt )
291287
292- full_prompt = f"{ system_content } \n \n Conversation:\n " + "\n " .join (
293- conversation_history
294- )
288+ full_prompt = "Conversation:\n " + "\n " .join (conversation_history )
295289
296290 contents = [
297291 types .Content (
@@ -309,6 +303,9 @@ async def generate_chat_completion(
309303 thinking_budget = 0 ,
310304 ),
311305 response_mime_type = "text/plain" ,
306+ system_instruction = [
307+ types .Part .from_text (text = system_prompt ),
308+ ],
312309 )
313310
314311 response = gemini_client .models .generate_content (
@@ -352,11 +349,12 @@ async def handle_tool_call(
352349 if not tool_name :
353350 raise ValueError ("Tool name not specified" )
354351
352+ print (f"Executing tool: { tool_name } with arguments: { tool_arguments } " )
353+
355354 tool_actions = {
356355 "cat" : lambda : cat (ctx , from_tool_call = send_directly ),
357356 "dog" : lambda : dog (ctx , from_tool_call = send_directly ),
358357 "gtn" : lambda : gtn (ctx , from_tool_call = send_directly ),
359- "hello" : lambda : hello (ctx , from_tool_call = send_directly ),
360358 "dice" : lambda : dice (
361359 ctx ,
362360 sides = int (tool_arguments .get ("sides" , 6 )),
@@ -383,20 +381,14 @@ async def handle_tool_call(
383381 ctx ,
384382 category = tool_arguments .get ("category" ),
385383 country = tool_arguments .get ("country" , "in" ),
386- limit = int (tool_arguments .get ("limit" , 5 )),
387- from_tool_call = send_directly ,
388- ),
389- "news_headlines" : lambda : news_headlines (
390- ctx ,
391- category = tool_arguments .get ("category" ),
392- country = tool_arguments .get ("country" , "in" ),
384+ limit = int (tool_arguments .get ("limit" , 3 )),
393385 from_tool_call = send_directly ,
394386 ),
395387 "news_search" : lambda : news_search (
396388 ctx ,
397389 query = tool_arguments .get ("query" ),
398390 category = tool_arguments .get ("category" ),
399- limit = int (tool_arguments .get ("limit" , 5 )),
391+ limit = int (tool_arguments .get ("limit" , 3 )),
400392 from_tool_call = send_directly ,
401393 ),
402394 "gt" : lambda : gt (ctx , from_tool_call = send_directly ),
@@ -405,6 +397,9 @@ async def handle_tool_call(
405397 ),
406398 "leave" : lambda : music_leave (ctx , from_tool_call = send_directly ),
407399 "whats_new" : lambda : whats_new (ctx , from_tool_call = send_directly ),
400+ "lyrics" : lambda : lyrics (
401+ ctx , song_name = tool_arguments .get ("song" ), from_tool_call = send_directly
402+ ),
408403 }
409404
410405 if tool_name not in tool_actions :
@@ -631,7 +626,7 @@ async def chat(ctx, *, message):
631626
632627 pre_tool_text = response [:tool_start ].strip ()
633628 if pre_tool_text :
634-
629+ # Check if this is the first tool call in the conversation
635630 first_tool_call = not any (
636631 "<tool_calls>" in msg .content
637632 for msg in memory .chat_memory .messages
@@ -866,34 +861,43 @@ async def stop(ctx):
866861
867862
868863@bot .slash_command (description = "Get lyrics for the current song or a specified song." )
869- async def lyrics (ctx , * , song_name : Optional [str ] = None ):
864+ async def lyrics (ctx , * , song_name : Optional [str ] = None , from_tool_call : bool = False ):
870865 state = await get_server_state (ctx .guild .id )
871- await ctx .response .defer ()
866+ if not from_tool_call :
867+ await ctx .response .defer ()
872868 search_title = (
873869 song_name
874870 if song_name
875871 else state ["current_song" ]["title" ] if state ["current_song" ] else None
876872 )
877873
878874 if not search_title :
879- await ctx . followup . send (
880- "No song is currently playing and no song name was provided."
881- )
882- return
875+ message = "No song is currently playing and no song name was provided."
876+ if not from_tool_call :
877+ await ctx . followup . send ( message )
878+ return message
883879
884880 try :
885881 song = genius .search_song (search_title )
886882 if song :
887- lyrics = song .lyrics
888- if len (lyrics ) > 2000 :
889- for i in range (0 , len (lyrics ), 2000 ):
890- await ctx .followup .send (lyrics [i : i + 2000 ])
891- else :
892- await ctx .followup .send (lyrics )
883+ lyrics_text = song .lyrics
884+ if not from_tool_call :
885+ if len (lyrics_text ) > 2000 :
886+ for i in range (0 , len (lyrics_text ), 2000 ):
887+ await ctx .followup .send (lyrics_text [i : i + 2000 ])
888+ else :
889+ await ctx .followup .send (lyrics_text )
890+ return lyrics_text [:500 ] + "..." if len (lyrics_text ) > 500 else lyrics_text
893891 else :
894- await ctx .followup .send (f"Lyrics for '{ search_title } ' not found." )
892+ message = f"Lyrics for '{ search_title } ' not found."
893+ if not from_tool_call :
894+ await ctx .followup .send (message )
895+ return message
895896 except Exception as e :
896- await ctx .followup .send (f"Error: { str (e )} " )
897+ error_msg = f"Error: { str (e )} "
898+ if not from_tool_call :
899+ await ctx .followup .send (error_msg )
900+ return error_msg
897901
898902
899903@bot .command (description = "Clear the conversation history." )
@@ -996,7 +1000,7 @@ async def news_top_stories(
9961000 ctx ,
9971001 category : Optional [str ] = None ,
9981002 country : str = "in" ,
999- limit : int = 5 ,
1003+ limit : int = 3 ,
10001004 from_tool_call : bool = False ,
10011005) -> str :
10021006 """Get top news stories using The News API."""
@@ -1012,7 +1016,7 @@ async def news_top_stories(
10121016 params = {
10131017 "api_token" : NEWS_API_KEY ,
10141018 "locale" : country ,
1015- "limit" : min (limit , 10 ), # Limit to max 10 articles
1019+ "limit" : min (limit , 3 ), # Limit to max 3 articles
10161020 "language" : "en" ,
10171021 }
10181022
@@ -1022,7 +1026,9 @@ async def news_top_stories(
10221026 async with aiohttp .ClientSession () as session :
10231027 async with session .get (base_url , params = params ) as response :
10241028 if response .status != 200 :
1025- error_msg = f"News API error: { response .status } "
1029+ error_text = await response .text ()
1030+ error_msg = f"News API error { response .status } : { error_text [:200 ]} "
1031+ print (f"News API Error: { response .status } - { error_text } " )
10261032 if not from_tool_call :
10271033 await send_response (ctx , "Sorry, I couldn't fetch the news." )
10281034 return error_msg
@@ -1066,99 +1072,17 @@ async def news_top_stories(
10661072
10671073 except Exception as e :
10681074 error_msg = f"Error fetching news: { str (e )} "
1069- print (error_msg )
1075+ print (f"News API Exception: { error_msg } " )
10701076 if not from_tool_call :
10711077 await send_response (ctx , "Sorry, I couldn't fetch the news." )
10721078 return error_msg
10731079
10741080
1075- async def news_headlines (
1076- ctx ,
1077- category : Optional [str ] = None ,
1078- country : str = "in" ,
1079- from_tool_call : bool = False ,
1080- ) -> str :
1081- """Get news headlines using The News API."""
1082- try :
1083- if not NEWS_API_KEY :
1084- error_msg = "News API key not configured."
1085- if not from_tool_call :
1086- await send_response (ctx , error_msg )
1087- return error_msg
1088-
1089- # Build API URL
1090- base_url = "https://api.thenewsapi.com/v1/news/headlines"
1091- params = {
1092- "api_token" : NEWS_API_KEY ,
1093- "locale" : country ,
1094- "language" : "en" ,
1095- "headlines_per_category" : 6 ,
1096- }
1097-
1098- async with aiohttp .ClientSession () as session :
1099- async with session .get (base_url , params = params ) as response :
1100- if response .status != 200 :
1101- error_msg = f"News API error: { response .status } "
1102- if not from_tool_call :
1103- await send_response (
1104- ctx , "Sorry, I couldn't fetch the headlines."
1105- )
1106- return error_msg
1107-
1108- data = await response .json ()
1109- headlines_data = data .get ("data" , {})
1110-
1111- if not headlines_data :
1112- message = "No headlines found."
1113- if not from_tool_call :
1114- await send_response (ctx , message )
1115- return message
1116-
1117- # Format response
1118- news_emoji = "📰"
1119- response = f"{ news_emoji } **Latest Headlines:**\n \n "
1120-
1121- # If specific category requested, show only that category
1122- if category and category in headlines_data :
1123- categories_to_show = {category : headlines_data [category ]}
1124- else :
1125- # Show all categories, limited to avoid long messages
1126- categories_to_show = {
1127- k : v for k , v in list (headlines_data .items ())[:3 ]
1128- }
1129-
1130- for cat_name , articles in categories_to_show .items ():
1131- if articles :
1132- response += f"**{ cat_name .upper ()} :**\n "
1133- for article in articles [:3 ]: # Limit to 3 per category
1134- title = article .get ("title" , "No title" )
1135- source = article .get ("source" , "Unknown" )
1136- url = article .get ("url" , "" )
1137-
1138- response += f"• { title } \n "
1139- response += f" 📰 { source } "
1140- if url :
1141- response += f" | { url } "
1142- response += "\n "
1143- response += "\n "
1144-
1145- if not from_tool_call :
1146- await send_response (ctx , response )
1147- return response
1148-
1149- except Exception as e :
1150- error_msg = f"Error fetching headlines: { str (e )} "
1151- print (error_msg )
1152- if not from_tool_call :
1153- await send_response (ctx , "Sorry, I couldn't fetch the headlines." )
1154- return error_msg
1155-
1156-
11571081async def news_search (
11581082 ctx ,
11591083 query : str ,
11601084 category : Optional [str ] = None ,
1161- limit : int = 5 ,
1085+ limit : int = 3 ,
11621086 from_tool_call : bool = False ,
11631087) -> str :
11641088 """Search for specific news articles using The News API."""
@@ -1181,7 +1105,7 @@ async def news_search(
11811105 "api_token" : NEWS_API_KEY ,
11821106 "search" : query ,
11831107 "language" : "en" ,
1184- "limit" : min (limit , 10 ), # Limit to max 10 articles
1108+ "limit" : min (limit , 3 ), # Limit to max 3 articles
11851109 "sort" : "relevance_score" ,
11861110 }
11871111
@@ -1245,11 +1169,6 @@ async def getnews(ctx, category: Optional[str] = None, *, country: str = "in"):
12451169 await news_top_stories (ctx , category = category , country = country )
12461170
12471171
1248- @bot .slash_command (description = "Get latest news headlines." )
1249- async def headlines (ctx , * , category : Optional [str ] = None ):
1250- await news_headlines (ctx , category = category )
1251-
1252-
12531172@bot .slash_command (description = "Search for news articles." )
12541173async def searchnews (ctx , * , query : str ):
12551174 await news_search (ctx , query = query )
0 commit comments