kylea commited on
Commit
96cc16a
·
1 Parent(s): 3a61d67

Completed New York Times Best Sellers List

Browse files
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .env
app.py CHANGED
@@ -1,39 +1,15 @@
1
- from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
2
  import datetime
3
  import requests
4
  import pytz
5
  import yaml
6
- from tools.final_answer import FinalAnswerTool
7
 
8
  from Gradio_UI import GradioUI
9
 
10
  # Below is an example of a tool that does nothing. Amaze us with your creativity !
11
- @tool
12
- def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
13
- #Keep this format for the description / args / args description but feel free to modify the tool
14
- """A tool that does nothing yet
15
- Args:
16
- arg1: the first argument
17
- arg2: the second argument
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.
24
- Args:
25
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
26
- """
27
- try:
28
- # Create timezone object
29
- tz = pytz.timezone(timezone)
30
- # Get current time in that timezone
31
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
32
- return f"The current local time in {timezone} is: {local_time}"
33
- except Exception as e:
34
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
35
-
36
 
 
37
  final_answer = FinalAnswerTool()
38
 
39
  # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
@@ -46,16 +22,12 @@ model_id='Qwen/Qwen2.5-Coder-32B-Instruct',# it is possible that this model may
46
  custom_role_conversions=None,
47
  )
48
 
49
-
50
- # Import tool from Hub
51
- image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
52
-
53
  with open("prompts.yaml", 'r') as stream:
54
  prompt_templates = yaml.safe_load(stream)
55
 
56
  agent = CodeAgent(
57
  model=model,
58
- tools=[final_answer], ## add your tools here (don't remove final answer)
59
  max_steps=6,
60
  verbosity_level=1,
61
  grammar=None,
 
1
+ from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool, FinalAnswerTool
2
  import datetime
3
  import requests
4
  import pytz
5
  import yaml
6
+ from tools.book_search import NYTBestSellerTool
7
 
8
  from Gradio_UI import GradioUI
9
 
10
  # Below is an example of a tool that does nothing. Amaze us with your creativity !
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ nyt_best_seller_tool = NYTBestSellerTool()
13
  final_answer = FinalAnswerTool()
14
 
15
  # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
 
22
  custom_role_conversions=None,
23
  )
24
 
 
 
 
 
25
  with open("prompts.yaml", 'r') as stream:
26
  prompt_templates = yaml.safe_load(stream)
27
 
28
  agent = CodeAgent(
29
  model=model,
30
+ tools=[nyt_best_seller_tool, final_answer], ## add your tools here (don't remove final answer)
31
  max_steps=6,
32
  verbosity_level=1,
33
  grammar=None,
nyt_tool.ipynb CHANGED
@@ -1,5 +1,292 @@
1
  {
2
- "cells": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  "metadata": {
4
  "kernelspec": {
5
  "display_name": "agents_env",
@@ -7,8 +294,16 @@
7
  "name": "python3"
8
  },
9
  "language_info": {
 
 
 
 
 
 
10
  "name": "python",
11
- "version": "3.10.12"
 
 
12
  }
13
  },
14
  "nbformat": 4,
 
1
  {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 11,
6
+ "metadata": {},
7
+ "outputs": [
8
+ {
9
+ "data": {
10
+ "text/plain": [
11
+ "True"
12
+ ]
13
+ },
14
+ "execution_count": 11,
15
+ "metadata": {},
16
+ "output_type": "execute_result"
17
+ }
18
+ ],
19
+ "source": [
20
+ "import requests\n",
21
+ "import dotenv\n",
22
+ "import os\n",
23
+ "from datetime import datetime\n",
24
+ "\n",
25
+ "dotenv.load_dotenv(\".env\")"
26
+ ]
27
+ },
28
+ {
29
+ "cell_type": "code",
30
+ "execution_count": 8,
31
+ "metadata": {},
32
+ "outputs": [],
33
+ "source": [
34
+ "params = {\n",
35
+ " \"api-key\":api_key\n",
36
+ "}\n",
37
+ "\n",
38
+ "result = requests.get(\n",
39
+ " \"https://api.nytimes.com/svc/books/v3/lists/names.json\",\n",
40
+ " params=params\n",
41
+ " )"
42
+ ]
43
+ },
44
+ {
45
+ "cell_type": "code",
46
+ "execution_count": 12,
47
+ "metadata": {},
48
+ "outputs": [],
49
+ "source": [
50
+ "results = result.json()['results']"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "code",
55
+ "execution_count": 13,
56
+ "metadata": {},
57
+ "outputs": [
58
+ {
59
+ "data": {
60
+ "text/plain": [
61
+ "{'list_name': 'Combined Print and E-Book Fiction',\n",
62
+ " 'display_name': 'Combined Print & E-Book Fiction',\n",
63
+ " 'list_name_encoded': 'combined-print-and-e-book-fiction',\n",
64
+ " 'oldest_published_date': '2011-02-13',\n",
65
+ " 'newest_published_date': '2025-03-16',\n",
66
+ " 'updated': 'WEEKLY'}"
67
+ ]
68
+ },
69
+ "execution_count": 13,
70
+ "metadata": {},
71
+ "output_type": "execute_result"
72
+ }
73
+ ],
74
+ "source": [
75
+ "results[0]"
76
+ ]
77
+ },
78
+ {
79
+ "cell_type": "code",
80
+ "execution_count": 20,
81
+ "metadata": {},
82
+ "outputs": [
83
+ {
84
+ "name": "stdout",
85
+ "output_type": "stream",
86
+ "text": [
87
+ "\"combined-print-and-e-book-fiction, \"\n",
88
+ "\"combined-print-and-e-book-nonfiction, \"\n",
89
+ "\"hardcover-fiction, \"\n",
90
+ "\"hardcover-nonfiction, \"\n",
91
+ "\"trade-fiction-paperback, \"\n",
92
+ "\"paperback-nonfiction, \"\n",
93
+ "\"advice-how-to-and-miscellaneous, \"\n",
94
+ "\"childrens-middle-grade-hardcover, \"\n",
95
+ "\"picture-books, \"\n",
96
+ "\"series-books, \"\n",
97
+ "\"young-adult-hardcover, \"\n",
98
+ "\"audio-fiction, \"\n",
99
+ "\"audio-nonfiction, \"\n",
100
+ "\"business-books, \"\n",
101
+ "\"graphic-books-and-manga, \"\n",
102
+ "\"mass-market-monthly, \"\n",
103
+ "\"middle-grade-paperback-monthly, \"\n",
104
+ "\"young-adult-paperback-monthly, \"\n"
105
+ ]
106
+ }
107
+ ],
108
+ "source": [
109
+ "for nyt_list in results:\n",
110
+ " if datetime.strptime(nyt_list['newest_published_date'], \"%Y-%m-%d\").year == 2025:\n",
111
+ " print('\"' + nyt_list['list_name_encoded'] + ', \"')"
112
+ ]
113
+ },
114
+ {
115
+ "cell_type": "code",
116
+ "execution_count": 38,
117
+ "metadata": {},
118
+ "outputs": [],
119
+ "source": [
120
+ "result = requests.get(\n",
121
+ " \"https://api.nytimes.com/svc/books/v3/lists/current/graphic-books-and-manga.json\",\n",
122
+ " params=params\n",
123
+ " )"
124
+ ]
125
+ },
126
+ {
127
+ "cell_type": "code",
128
+ "execution_count": 39,
129
+ "metadata": {},
130
+ "outputs": [],
131
+ "source": [
132
+ "list_results = result.json()"
133
+ ]
134
+ },
135
+ {
136
+ "cell_type": "code",
137
+ "execution_count": 40,
138
+ "metadata": {},
139
+ "outputs": [],
140
+ "source": [
141
+ "book_results = result.json()['results']['books']"
142
+ ]
143
+ },
144
+ {
145
+ "cell_type": "code",
146
+ "execution_count": 41,
147
+ "metadata": {},
148
+ "outputs": [],
149
+ "source": [
150
+ "book_result_str = \"\"\n",
151
+ "for ix, book_result in enumerate(book_results):\n",
152
+ "\n",
153
+ " rank = book_result.get(\"rank\")\n",
154
+ " if rank:\n",
155
+ " book_result_str += f\"rank: {rank}\\n\"\n",
156
+ "\n",
157
+ " title = book_result.get(\"title\")\n",
158
+ " if title:\n",
159
+ " book_result_str += f\"title: {title}\\n\"\n",
160
+ "\n",
161
+ " author = book_result.get(\"author\")\n",
162
+ " if author:\n",
163
+ " book_result_str += f\"author: {author}\\n\"\n",
164
+ "\n",
165
+ " description = book_result.get(\"description\")\n",
166
+ " if description:\n",
167
+ " book_result_str += f\"description: {description}\\n\"\n",
168
+ "\n",
169
+ " primary_isbn10 = book_result.get(\"primary_isbn10\")\n",
170
+ " if primary_isbn10:\n",
171
+ " book_result_str += f\"primary_isbn10: {primary_isbn10}\\n\"\n",
172
+ "\n",
173
+ " primary_isbn13 = book_result.get(\"primary_isbn13\")\n",
174
+ " if primary_isbn13:\n",
175
+ " book_result_str += f\"primary_isbn13: {primary_isbn13}\\n\"\n",
176
+ "\n",
177
+ " buy_links = book_result.get(\"buy_links\")\n",
178
+ " if buy_links:\n",
179
+ " book_result_str += f\"buy_links: \"\n",
180
+ " for buy_link in buy_links:\n",
181
+ " book_result_str += f\"{buy_link.get('name')} {buy_link.get('url')}\\n\"\n",
182
+ "\n",
183
+ " book_result_str += \"=============================\\n\\n\"\n",
184
+ "\n",
185
+ " if ix + 1 == 5:\n",
186
+ " break"
187
+ ]
188
+ },
189
+ {
190
+ "cell_type": "code",
191
+ "execution_count": 42,
192
+ "metadata": {},
193
+ "outputs": [
194
+ {
195
+ "name": "stdout",
196
+ "output_type": "stream",
197
+ "text": [
198
+ "rank: 1\n",
199
+ "title: BIG JIM BEGINS\n",
200
+ "author: Dav Pilkey\n",
201
+ "description: The 13th book in the Dog Man series. Big Jim has an adventure that brings up the past.\n",
202
+ "primary_isbn10: 1338896458\n",
203
+ "primary_isbn13: 9781338896459\n",
204
+ "buy_links: Amazon https://www.amazon.com/dp/1338896458?tag=thenewyorktim-20\n",
205
+ "Apple Books https://goto.applebooks.apple/9781338896459?at=10lIEQ\n",
206
+ "Barnes and Noble https://www.anrdoezrs.net/click-7990613-11819508?url=https%3A%2F%2Fwww.barnesandnoble.com%2Fw%2F%3Fean%3D9781338896459\n",
207
+ "Books-A-Million https://www.anrdoezrs.net/click-7990613-35140?url=https%3A%2F%2Fwww.booksamillion.com%2Fp%2FBIG%2BJIM%2BBEGINS%2FDav%2BPilkey%2F9781338896459\n",
208
+ "Bookshop.org https://bookshop.org/a/3546/9781338896459\n",
209
+ "=============================\n",
210
+ "\n",
211
+ "rank: 2\n",
212
+ "title: THE SCARLET SHEDDER\n",
213
+ "author: Dav Pilkey\n",
214
+ "description: The 12th book in the Dog Man series. Dog Man finds himself back on his hind legs after being sprayed by a skunk.\n",
215
+ "primary_isbn10: 1338896431\n",
216
+ "primary_isbn13: 9781338896435\n",
217
+ "buy_links: Amazon https://www.amazon.com/dp/1338896431?tag=thenewyorktim-20\n",
218
+ "Apple Books https://goto.applebooks.apple/9781338896435?at=10lIEQ\n",
219
+ "Barnes and Noble https://www.anrdoezrs.net/click-7990613-11819508?url=https%3A%2F%2Fwww.barnesandnoble.com%2Fw%2F%3Fean%3D9781338896435\n",
220
+ "Books-A-Million https://www.anrdoezrs.net/click-7990613-35140?url=https%3A%2F%2Fwww.booksamillion.com%2Fp%2FTHE%2BSCARLET%2BSHEDDER%2FDav%2BPilkey%2F9781338896435\n",
221
+ "Bookshop.org https://bookshop.org/a/3546/9781338896435\n",
222
+ "=============================\n",
223
+ "\n",
224
+ "rank: 3\n",
225
+ "title: DOG MAN\n",
226
+ "author: Dav Pilkey\n",
227
+ "description: A dog’s head is combined with a policeman’s body to create this hybrid supercop hound.\n",
228
+ "primary_isbn10: 1338741039\n",
229
+ "primary_isbn13: 9781338741032\n",
230
+ "buy_links: Amazon https://www.amazon.com/dp/1338741039?tag=thenewyorktim-20\n",
231
+ "Apple Books https://goto.applebooks.apple/9781338741032?at=10lIEQ\n",
232
+ "Barnes and Noble https://www.anrdoezrs.net/click-7990613-11819508?url=https%3A%2F%2Fwww.barnesandnoble.com%2Fw%2F%3Fean%3D9781338741032\n",
233
+ "Books-A-Million https://www.anrdoezrs.net/click-7990613-35140?url=https%3A%2F%2Fwww.booksamillion.com%2Fp%2FDOG%2BMAN%2FDav%2BPilkey%2F9781338741032\n",
234
+ "Bookshop.org https://bookshop.org/a/3546/9781338741032\n",
235
+ "=============================\n",
236
+ "\n",
237
+ "rank: 4\n",
238
+ "title: ESCAPING PERIL\n",
239
+ "author: Tui T. Sutherland.\n",
240
+ "description: The eighth book in the Wings of Fire graphic novel series. Peril's sense of loyalty becomes tested.\n",
241
+ "primary_isbn10: 1339001233\n",
242
+ "primary_isbn13: 9781339001234\n",
243
+ "buy_links: Amazon https://www.amazon.com/dp/1339001233?tag=thenewyorktim-20\n",
244
+ "Apple Books https://goto.applebooks.apple/9781339001234?at=10lIEQ\n",
245
+ "Barnes and Noble https://www.anrdoezrs.net/click-7990613-11819508?url=https%3A%2F%2Fwww.barnesandnoble.com%2Fw%2F%3Fean%3D9781339001234\n",
246
+ "Books-A-Million https://www.anrdoezrs.net/click-7990613-35140?url=https%3A%2F%2Fwww.booksamillion.com%2Fp%2FESCAPING%2BPERIL%2FTui%2BT.%2BSutherland.%2F9781339001234\n",
247
+ "Bookshop.org https://bookshop.org/a/3546/9781339001234\n",
248
+ "=============================\n",
249
+ "\n",
250
+ "rank: 5\n",
251
+ "title: TWENTY THOUSAND FLEAS UNDER THE SEA\n",
252
+ "author: Dav Pilkey\n",
253
+ "description: The 11th book in the Dog Man series. Piggy returns and the Supa Buddies are sabotaged.\n",
254
+ "primary_isbn10: 1338801910\n",
255
+ "primary_isbn13: 9781338801910\n",
256
+ "buy_links: Amazon https://www.amazon.com/dp/1338801910?tag=thenewyorktim-20\n",
257
+ "Apple Books https://goto.applebooks.apple/9781338801910?at=10lIEQ\n",
258
+ "Barnes and Noble https://www.anrdoezrs.net/click-7990613-11819508?url=https%3A%2F%2Fwww.barnesandnoble.com%2Fw%2F%3Fean%3D9781338801910\n",
259
+ "Books-A-Million https://www.anrdoezrs.net/click-7990613-35140?url=https%3A%2F%2Fwww.booksamillion.com%2Fp%2FTWENTY%2BTHOUSAND%2BFLEAS%2BUNDER%2BTHE%2BSEA%2FDav%2BPilkey%2F9781338801910\n",
260
+ "Bookshop.org https://bookshop.org/a/3546/9781338801910\n",
261
+ "=============================\n",
262
+ "\n",
263
+ "\n"
264
+ ]
265
+ },
266
+ {
267
+ "data": {
268
+ "text/plain": [
269
+ "3737"
270
+ ]
271
+ },
272
+ "execution_count": 42,
273
+ "metadata": {},
274
+ "output_type": "execute_result"
275
+ }
276
+ ],
277
+ "source": [
278
+ "print(book_result_str)\n",
279
+ "len(book_result_str)"
280
+ ]
281
+ },
282
+ {
283
+ "cell_type": "code",
284
+ "execution_count": null,
285
+ "metadata": {},
286
+ "outputs": [],
287
+ "source": []
288
+ }
289
+ ],
290
  "metadata": {
291
  "kernelspec": {
292
  "display_name": "agents_env",
 
294
  "name": "python3"
295
  },
296
  "language_info": {
297
+ "codemirror_mode": {
298
+ "name": "ipython",
299
+ "version": 3
300
+ },
301
+ "file_extension": ".py",
302
+ "mimetype": "text/x-python",
303
  "name": "python",
304
+ "nbconvert_exporter": "python",
305
+ "pygments_lexer": "ipython3",
306
+ "version": "3.10.11"
307
  }
308
  },
309
  "nbformat": 4,
tools/book_search.py CHANGED
@@ -1,25 +1,120 @@
1
  import os
 
2
  from typing import Any, Optional
3
  from smolagents.tools import Tool
4
- import duckduckgo_search
5
 
6
- class NYTSearchTool(Tool):
7
- name = "best_sellers_tool"
8
  description = (
9
  "Performs a search of the New York Times best seller list "
10
- "for a specific genre and returns the best selling books"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  )
12
 
13
- inputs = {'genre': {'type': 'string', 'description': 'The genre to search'}}
 
 
 
 
 
14
  output_type = "string"
15
 
16
  def __init__(self, max_results=10, **kwargs):
17
  super().__init__()
18
  self.api_prefix = "https://api.nytimes.com/svc/books/v3/lists/current"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
- def forward(self, query: str) -> str:
21
- results = self.ddgs.text(query, max_results=self.max_results)
22
- if len(results) == 0:
23
- raise Exception("No results found! Try a less restrictive/shorter query.")
24
- postprocessed_results = [f"[{result['title']}]({result['href']})\n{result['body']}" for result in results]
25
- return "## Search Results\n\n" + "\n\n".join(postprocessed_results)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+ import requests
3
  from typing import Any, Optional
4
  from smolagents.tools import Tool
 
5
 
6
+ class NYTBestSellerTool(Tool):
7
+ name = "nyt_best_sellers_tool"
8
  description = (
9
  "Performs a search of the New York Times best seller list "
10
+ "for a specific genre and returns the best selling books.\n"
11
+ "The possible options for genre are:\n"
12
+ "combined-print-and-e-book-fiction, "
13
+ "combined-print-and-e-book-nonfiction, "
14
+ "hardcover-fiction, "
15
+ "hardcover-nonfiction, "
16
+ "trade-fiction-paperback, "
17
+ "paperback-nonfiction, "
18
+ "advice-how-to-and-miscellaneous, "
19
+ "childrens-middle-grade-hardcover, "
20
+ "picture-books, "
21
+ "series-books, "
22
+ "young-adult-hardcover, "
23
+ "audio-fiction, "
24
+ "audio-nonfiction, "
25
+ "business-books, "
26
+ "graphic-books-and-manga, "
27
+ "mass-market-monthly, "
28
+ "middle-grade-paperback-monthly, "
29
+ "young-adult-paperback-monthly."
30
  )
31
 
32
+ inputs = {
33
+ 'genre':
34
+ {'type': 'string', 'description': 'The genre to search'},
35
+ 'limit':
36
+ {'type': 'int', 'description': 'The number of results to include'}
37
+ }
38
  output_type = "string"
39
 
40
  def __init__(self, max_results=10, **kwargs):
41
  super().__init__()
42
  self.api_prefix = "https://api.nytimes.com/svc/books/v3/lists/current"
43
+ self.api_key = os.getenv("NYT_API_KEY")
44
+ self.possible_genres = [
45
+ "combined-print-and-e-book-fiction"
46
+ "combined-print-and-e-book-nonfiction"
47
+ "hardcover-fiction"
48
+ "hardcover-nonfiction"
49
+ "trade-fiction-paperback"
50
+ "paperback-nonfiction"
51
+ "advice-how-to-and-miscellaneous"
52
+ "childrens-middle-grade-hardcover"
53
+ "picture-books"
54
+ "series-books"
55
+ "young-adult-hardcover"
56
+ "audio-fiction"
57
+ "audio-nonfiction"
58
+ "business-books"
59
+ "graphic-books-and-manga"
60
+ "mass-market-monthly"
61
+ "middle-grade-paperback-monthly"
62
+ "young-adult-paperback-monthly"
63
+ ]
64
 
65
+ def forward(self, genre: str, limit: int = 5) -> str:
66
+ if isinstance(limit,str):
67
+ limit = int(limit)
68
+
69
+ if genre not in self.possible_genres:
70
+ raise Exception(
71
+ f"{genre} is not a valid genre. Please search by a genre from the list: {self.possible_genres}"
72
+ )
73
+
74
+ result = requests.get(
75
+ f"https://api.nytimes.com/svc/books/v3/lists/{genre}.json",
76
+ params={"api-key":self.api_key}
77
+ )
78
+ if len(result.status_code) != 200:
79
+ raise Exception("Error getting the best seller list. Please try again later.")
80
+
81
+ book_results = result.json()['results']['books']
82
+
83
+ book_result_str = ""
84
+ for ix, book_result in enumerate(book_results):
85
+
86
+ rank = book_result.get("rank")
87
+ if rank:
88
+ book_result_str += f"rank: {rank}\n"
89
+
90
+ title = book_result.get("title")
91
+ if title:
92
+ book_result_str += f"title: {title}\n"
93
+
94
+ author = book_result.get("author")
95
+ if author:
96
+ book_result_str += f"author: {author}\n"
97
+
98
+ description = book_result.get("description")
99
+ if description:
100
+ book_result_str += f"description: {description}\n"
101
+
102
+ primary_isbn10 = book_result.get("primary_isbn10")
103
+ if primary_isbn10:
104
+ book_result_str += f"primary_isbn10: {primary_isbn10}\n"
105
+
106
+ primary_isbn13 = book_result.get("primary_isbn13")
107
+ if primary_isbn13:
108
+ book_result_str += f"primary_isbn13: {primary_isbn13}\n"
109
+
110
+ buy_links = book_result.get("buy_links")
111
+ if buy_links:
112
+ book_result_str += f"buy_links: "
113
+ for buy_link in buy_links:
114
+ book_result_str += f"{buy_link.get('name')} {buy_link.get('url')}\n"
115
+
116
+ book_result_str += "=============================\n\n"
117
+
118
+ if ix + 1 == limit:
119
+ break
120
+ return book_result_str
tools/final_answer.py DELETED
@@ -1,14 +0,0 @@
1
- from typing import Any, Optional
2
- from smolagents.tools import Tool
3
-
4
- class FinalAnswerTool(Tool):
5
- name = "final_answer"
6
- description = "Provides a final answer to the given problem."
7
- inputs = {'answer': {'type': 'any', 'description': 'The final answer to the problem'}}
8
- output_type = "any"
9
-
10
- def forward(self, answer: Any) -> Any:
11
- return answer
12
-
13
- def __init__(self, *args, **kwargs):
14
- self.is_initialized = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/visit_webpage.py DELETED
@@ -1,45 +0,0 @@
1
- from typing import Any, Optional
2
- from smolagents.tools import Tool
3
- import requests
4
- import markdownify
5
- import smolagents
6
-
7
- class VisitWebpageTool(Tool):
8
- name = "visit_webpage"
9
- description = "Visits a webpage at the given url and reads its content as a markdown string. Use this to browse webpages."
10
- inputs = {'url': {'type': 'string', 'description': 'The url of the webpage to visit.'}}
11
- output_type = "string"
12
-
13
- def forward(self, url: str) -> str:
14
- try:
15
- import requests
16
- from markdownify import markdownify
17
- from requests.exceptions import RequestException
18
-
19
- from smolagents.utils import truncate_content
20
- except ImportError as e:
21
- raise ImportError(
22
- "You must install packages `markdownify` and `requests` to run this tool: for instance run `pip install markdownify requests`."
23
- ) from e
24
- try:
25
- # Send a GET request to the URL with a 20-second timeout
26
- response = requests.get(url, timeout=20)
27
- response.raise_for_status() # Raise an exception for bad status codes
28
-
29
- # Convert the HTML content to Markdown
30
- markdown_content = markdownify(response.text).strip()
31
-
32
- # Remove multiple line breaks
33
- markdown_content = re.sub(r"\n{3,}", "\n\n", markdown_content)
34
-
35
- return truncate_content(markdown_content, 10000)
36
-
37
- except requests.exceptions.Timeout:
38
- return "The request timed out. Please try again later or check the URL."
39
- except RequestException as e:
40
- return f"Error fetching the webpage: {str(e)}"
41
- except Exception as e:
42
- return f"An unexpected error occurred: {str(e)}"
43
-
44
- def __init__(self, *args, **kwargs):
45
- self.is_initialized = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/web_search.py DELETED
@@ -1,27 +0,0 @@
1
- from typing import Any, Optional
2
- from smolagents.tools import Tool
3
- import duckduckgo_search
4
-
5
- class DuckDuckGoSearchTool(Tool):
6
- name = "web_search"
7
- description = "Performs a duckduckgo web search based on your query (think a Google search) then returns the top search results."
8
- inputs = {'query': {'type': 'string', 'description': 'The search query to perform.'}}
9
- output_type = "string"
10
-
11
- def __init__(self, max_results=10, **kwargs):
12
- super().__init__()
13
- self.max_results = max_results
14
- try:
15
- from duckduckgo_search import DDGS
16
- except ImportError as e:
17
- raise ImportError(
18
- "You must install package `duckduckgo_search` to run this tool: for instance run `pip install duckduckgo-search`."
19
- ) from e
20
- self.ddgs = DDGS(**kwargs)
21
-
22
- def forward(self, query: str) -> str:
23
- results = self.ddgs.text(query, max_results=self.max_results)
24
- if len(results) == 0:
25
- raise Exception("No results found! Try a less restrictive/shorter query.")
26
- postprocessed_results = [f"[{result['title']}]({result['href']})\n{result['body']}" for result in results]
27
- return "## Search Results\n\n" + "\n\n".join(postprocessed_results)