cocolook commited on
Commit
0ca4cfd
·
verified ·
1 Parent(s): 8c5c24b

Update app.py

Browse files

add a joke tool

Files changed (1) hide show
  1. app.py +73 -0
app.py CHANGED
@@ -4,6 +4,7 @@ import requests
4
  import pytz
5
  import yaml
6
  from tools.final_answer import FinalAnswerTool
 
7
 
8
  from Gradio_UI import GradioUI
9
 
@@ -18,6 +19,78 @@ def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return
18
  """
19
  return "What magic will you build ?"
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  @tool
22
  def get_current_time_in_timezone(timezone: str) -> str:
23
  """A tool that fetches the current local time in a specified timezone.
 
4
  import pytz
5
  import yaml
6
  from tools.final_answer import FinalAnswerTool
7
+ from urllib.parse import quote
8
 
9
  from Gradio_UI import GradioUI
10
 
 
19
  """
20
  return "What magic will you build ?"
21
 
22
+ @tool
23
+ def get_relevant_joke(keyword: str = None) -> str:
24
+ """
25
+ Fetches a safe joke from the JokeAPI (v2.jokeapi.dev).
26
+ It can return either a single-part or a two-part joke.
27
+
28
+ The joke can be optionally filtered by a keyword to provide some relevance.
29
+ If no keyword is provided, a random joke from the "Any" category is returned.
30
+
31
+ Args:
32
+ keyword: An optional keyword to search for within the joke text.
33
+
34
+ Returns:
35
+ A string containing the joke, or an error message if the fetch fails.
36
+ """
37
+ base_url = "https://v2.jokeapi.dev/joke/Any"
38
+
39
+ # Removed 'type': 'single' to allow for both single and two-part jokes.
40
+ # We still enforce safe-mode for safety.
41
+ params = {
42
+ 'safe-mode': ''
43
+ }
44
+
45
+ if keyword:
46
+ # URL-encode the keyword to handle spaces and special characters
47
+ safe_keyword = quote(keyword)
48
+ # The API uses the 'contains' parameter for keyword filtering
49
+ params['contains'] = safe_keyword
50
+
51
+ # We implement a simple retry mechanism with exponential backoff for robustness
52
+ max_retries = 3
53
+ for attempt in range(max_retries):
54
+ try:
55
+ # Make the API request
56
+ response = requests.get(base_url, params=params, timeout=10)
57
+
58
+ # Raise an exception for bad status codes (4xx or 5xx)
59
+ response.raise_for_status()
60
+
61
+ data = response.json()
62
+
63
+ # The JokeAPI returns a 'success' field implicitly, but checks for 'error'
64
+ if data.get('error') is True:
65
+ # If the API returns an error, it often means no joke was found for the keyword
66
+ return (f"**[Joke Tool Error]** Sorry, I couldn't find a joke about '{keyword}'! "
67
+ f"Perhaps try a more general term. (API Message: {data.get('message', 'Unknown error')})")
68
+
69
+ # --- Logic to handle both single and two-part jokes ---
70
+ if data.get('type') == 'single':
71
+ # Case 1: Single-part joke
72
+ return data.get('joke')
73
+ elif data.get('type') == 'twopart':
74
+ # Case 2: Two-part joke (combine setup and delivery)
75
+ setup = data.get('setup', 'Setup missing...')
76
+ delivery = data.get('delivery', 'Punchline missing...')
77
+ return f"{setup}\n\n...{delivery}"
78
+ else:
79
+ return "The Joke API returned an unknown joke format."
80
+
81
+
82
+ except requests.exceptions.RequestException as e:
83
+ # Handle connection errors, timeouts, and bad status codes
84
+ print(f"Attempt {attempt + 1} failed: {e}")
85
+ if attempt < max_retries - 1:
86
+ # Wait before retrying (exponential backoff)
87
+ wait_time = 2 ** attempt
88
+ time.sleep(wait_time)
89
+ else:
90
+ return f"**[Joke Tool Error]** Failed to connect to the Joke API after {max_retries} attempts."
91
+ except Exception as e:
92
+ return f"**[Joke Tool Error]** An unexpected error occurred: {e}"
93
+
94
  @tool
95
  def get_current_time_in_timezone(timezone: str) -> str:
96
  """A tool that fetches the current local time in a specified timezone.