From 63a79d13d2f4a1482410317e9186c31cc11ceba8 Mon Sep 17 00:00:00 2001 From: Xiaotian Date: Thu, 28 Nov 2024 10:04:37 +0300 Subject: [PATCH 1/3] add brave search api --- camel/toolkits/search_toolkit.py | 140 +++++++++++++++++++++++++++- examples/toolkits/search_toolkit.py | 25 ++++- 2 files changed, 162 insertions(+), 3 deletions(-) diff --git a/camel/toolkits/search_toolkit.py b/camel/toolkits/search_toolkit.py index f61e1c47bf..0fb3bfef38 100644 --- a/camel/toolkits/search_toolkit.py +++ b/camel/toolkits/search_toolkit.py @@ -13,7 +13,7 @@ # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. ========= import os import xml.etree.ElementTree as ET -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Optional, TypeAlias, Union import requests @@ -26,7 +26,7 @@ class SearchToolkit(BaseToolkit): r"""A class representing a toolkit for web search. This class provides methods for searching information on the web using - search engines like Google, DuckDuckGo, Wikipedia and Wolfram Alpha. + search engines like Google, DuckDuckGo, Wikipedia and Wolfram Alpha, Brave. """ @dependencies_required("wikipedia") @@ -151,6 +151,142 @@ def search_duckduckgo( # If no answer found, return an empty list return responses + @api_keys_required("BRAVE_API_KEY") + def search_brave( + self, + q: str, + country: str = "US", + search_lang: str = "en", + ui_lang: str = "en-US", + count: int = 20, + offset: int = 0, + safesearch: str = "moderate", + freshness: Optional[str] = None, + text_decorations: bool = True, + spellcheck: bool = True, + result_filter: Optional[str] = None, + goggles_id: Optional[str] = None, + units: Optional[str] = None, + extra_snippets: Optional[bool] = None, + summary: Optional[bool] = None, + ) -> Dict[str, Any]: + r"""This function queries the Brave search engine API and returns a + dictionary, representing a search result. + See https://api.search.brave.com/app/documentation/web-search/query + for more details. + + Args: + q (str): The user's search query term. Query cannot be empty. + Maximum of 400 characters and 50 words in the query. + country (str): The search query country where results come from. + The country string is limited to 2 character country codes of + supported countries. For a list of supported values, see + Country Codes. + search_lang (str): The search language preference. The 2 or more + character language code for which search results are provided. + For a list of possible values, see Language Codes. + ui_lang (str): User interface language preferred in response. + Usually of the format '-'. For + more, see RFC 9110. For a list of supported values, see UI + Language Codes. + count (int): The number of search results returned in response. + The maximum is 20. The actual number delivered may be less than + requested. Combine this parameter with offset to paginate + search results. + offset (int): The zero based offset that indicates number of search + results per page (count) to skip before returning the result. + The maximum is 9. The actual number delivered may be less than + requested based on the query. In order to paginate results use + this parameter together with count. For example, if your user + interface displays 20 search results per page, set count to 20 + and offset to 0 to show the first page of results. To get + subsequent pages, increment offset by 1 (e.g. 0, 1, 2). The + results may overlap across multiple pages. + safesearch (str): Filters search results for adult content. + The following values are supported: + - 'off': No filtering is done. + - 'moderate': Filters explicit content, like images and videos, + but allows adult domains in the search results. + - 'strict': Drops all adult content from search results. + freshness (str): Filters search results by when they were + discovered: + - 'pd': Discovered within the last 24 hours. + - 'pw': Discovered within the last 7 Days. + - 'pm': Discovered within the last 31 Days. + - 'py': Discovered within the last 365 Days. + - 'YYYY-MM-DDtoYYYY-MM-DD': Timeframe is also supported by + specifying the date range e.g. '2022-04-01to2022-07-30'. + text_decorations (bool): Whether display strings (e.g. result + snippets) should include decoration markers (e.g. highlighting + characters). + spellcheck (bool): Whether to spellcheck provided query. If the + spellchecker is enabled, the modified query is always used for + search. The modified query can be found in altered key from the + query response model. + result_filter (str): A comma delimited string of result types to + include in the search response. Not specifying this parameter + will return back all result types in search response where data + is available and a plan with the corresponding option is + subscribed. The response always includes query and type to + identify any query modifications and response type + respectively. + Available result filter values are: 'discussions', 'faq', + 'infobox', 'news', 'query', 'summarizer', 'videos', 'web', + 'locations'. + goggles_id (str): Goggles act as a custom re-ranking on top of + Brave's search index. For more details, refer to the Goggles + repository. + units (str): The measurement units. If not provided, units are + derived from search country. Possible values are: + - 'metric': The standardized measurement system + - 'imperial': The British Imperial system of units. + extra_snippets (bool): A snippet is an excerpt from a page you get + as a result of the query, and extra_snippets allow you to get + up to 5 additional, alternative excerpts. Only available under + Free AI, Base AI, Pro AI, Base Data, Pro Data and Custom plans. + summary (bool): This parameter enables summary key generation in + web search results. This is required for summarizer to be + enabled. + """ + + import requests + + BRAVE_API_KEY = os.getenv("BRAVE_API_KEY") + + url = "https://api.search.brave.com/res/v1/web/search" + headers = { + "Content-Type": "application/json", + "X-BCP-APIV": "1.0", + "X-Subscription-Token": BRAVE_API_KEY, + } + + ParamsType: TypeAlias = Dict[ + str, + Union[str, int, float, List[Union[str, int, float]], None], + ] + + params: ParamsType = { + "q": q, + "country": country, + "search_lang": search_lang, + "ui_lang": ui_lang, + "count": count, + "offset": offset, + "safesearch": safesearch, + "freshness": freshness, + "text_decorations": text_decorations, + "spellcheck": spellcheck, + "result_filter": result_filter, + "goggles_id": goggles_id, + "units": units, + "extra_snippets": extra_snippets, + "summary": summary, + } + + response = requests.get(url, headers=headers, params=params) + data = response.json()["web"] + return data + @api_keys_required("GOOGLE_API_KEY", "SEARCH_ENGINE_ID") def search_google( self, query: str, num_result_pages: int = 5 diff --git a/examples/toolkits/search_toolkit.py b/examples/toolkits/search_toolkit.py index 3534a9a76f..5d088cfb5a 100644 --- a/examples/toolkits/search_toolkit.py +++ b/examples/toolkits/search_toolkit.py @@ -12,7 +12,8 @@ # limitations under the License. # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. ========= -from camel.toolkits import SearchToolkit +from camel.agents import ChatAgent +from camel.toolkits import FunctionTool, SearchToolkit res_simple = SearchToolkit().query_wolfram_alpha( query="solve 3x-7=11", is_detailed=False @@ -55,3 +56,25 @@ x 6 = 6\nAnswer: | \n | x = 6'}} =============================================================================== ''' + +res_brave = SearchToolkit().search_brave( + q="What is the weather in Tokyo?", + search_lang="en", +) + +print(res_brave) + +# Example with ChatAgent using the Brave search engine + +agent = ChatAgent( + system_message="""You are a helpful assistant that can use brave search + engine to answer questions.""", + tools=[FunctionTool(SearchToolkit().search_brave)], +) + +usr_msg = "What is the temperature in Tokyo?" + +response = agent.step(input_message=usr_msg, response_format=None) + +print(response.msgs[0].content) +print(response.info["tool_calls"]) From 8720b5c01e20d543d38decdce211b9f14d2352be Mon Sep 17 00:00:00 2001 From: Xiaotian Date: Thu, 28 Nov 2024 10:09:05 +0300 Subject: [PATCH 2/3] add brave api in search toolkit --- camel/toolkits/search_toolkit.py | 1 + 1 file changed, 1 insertion(+) diff --git a/camel/toolkits/search_toolkit.py b/camel/toolkits/search_toolkit.py index 0fb3bfef38..4b920edbcc 100644 --- a/camel/toolkits/search_toolkit.py +++ b/camel/toolkits/search_toolkit.py @@ -607,4 +607,5 @@ def get_tools(self) -> List[FunctionTool]: FunctionTool(self.search_duckduckgo), FunctionTool(self.query_wolfram_alpha), FunctionTool(self.tavily_search), + FunctionTool(self.search_brave), ] From 6753772233659fcad745a372c5e272b074942311 Mon Sep 17 00:00:00 2001 From: Xiaotian Date: Thu, 5 Dec 2024 16:10:10 +0300 Subject: [PATCH 3/3] add print examples, fix docs --- camel/toolkits/search_toolkit.py | 58 +++++++++++++++++------------ examples/toolkits/search_toolkit.py | 13 ++++++- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/camel/toolkits/search_toolkit.py b/camel/toolkits/search_toolkit.py index 4b920edbcc..0c501cc86f 100644 --- a/camel/toolkits/search_toolkit.py +++ b/camel/toolkits/search_toolkit.py @@ -181,7 +181,7 @@ def search_brave( country (str): The search query country where results come from. The country string is limited to 2 character country codes of supported countries. For a list of supported values, see - Country Codes. + Country Codes. (default::obj:`US `) search_lang (str): The search language preference. The 2 or more character language code for which search results are provided. For a list of possible values, see Language Codes. @@ -208,7 +208,7 @@ def search_brave( - 'moderate': Filters explicit content, like images and videos, but allows adult domains in the search results. - 'strict': Drops all adult content from search results. - freshness (str): Filters search results by when they were + freshness (Optional[str]): Filters search results by when they were discovered: - 'pd': Discovered within the last 24 hours. - 'pw': Discovered within the last 7 Days. @@ -223,30 +223,40 @@ def search_brave( spellchecker is enabled, the modified query is always used for search. The modified query can be found in altered key from the query response model. - result_filter (str): A comma delimited string of result types to - include in the search response. Not specifying this parameter - will return back all result types in search response where data - is available and a plan with the corresponding option is - subscribed. The response always includes query and type to - identify any query modifications and response type - respectively. - Available result filter values are: 'discussions', 'faq', - 'infobox', 'news', 'query', 'summarizer', 'videos', 'web', - 'locations'. - goggles_id (str): Goggles act as a custom re-ranking on top of - Brave's search index. For more details, refer to the Goggles - repository. - units (str): The measurement units. If not provided, units are - derived from search country. Possible values are: + result_filter (Optional[str]): A comma delimited string of result + types to include in the search response. Not specifying this + parameter will return back all result types in search response + where data is available and a plan with the corresponding + option is subscribed. The response always includes query and + type to identify any query modifications and response type + respectively. Available result filter values are: + - 'discussions' + - 'faq' + - 'infobox' + - 'news' + - 'query' + - 'summarizer' + - 'videos' + - 'web' + - 'locations' + goggles_id (Optional[str]): Goggles act as a custom re-ranking on + top of Brave's search index. For more details, refer to the + Goggles repository. + units (Optional[str]): The measurement units. If not provided, + units are derived from search country. Possible values are: - 'metric': The standardized measurement system - 'imperial': The British Imperial system of units. - extra_snippets (bool): A snippet is an excerpt from a page you get - as a result of the query, and extra_snippets allow you to get - up to 5 additional, alternative excerpts. Only available under - Free AI, Base AI, Pro AI, Base Data, Pro Data and Custom plans. - summary (bool): This parameter enables summary key generation in - web search results. This is required for summarizer to be - enabled. + extra_snippets (Optional[bool]): A snippet is an excerpt from a + page you get as a result of the query, and extra_snippets + allow you to get up to 5 additional, alternative excerpts. Only + available under Free AI, Base AI, Pro AI, Base Data, Pro Data + and Custom plans. + summary (Optional[bool]): This parameter enables summary key + generation in web search results. This is required for + summarizer to be enabled. + + Returns: + Dict[str, Any]: A dictionary representing a search result. """ import requests diff --git a/examples/toolkits/search_toolkit.py b/examples/toolkits/search_toolkit.py index 5d088cfb5a..b79ef4b52f 100644 --- a/examples/toolkits/search_toolkit.py +++ b/examples/toolkits/search_toolkit.py @@ -61,7 +61,6 @@ q="What is the weather in Tokyo?", search_lang="en", ) - print(res_brave) # Example with ChatAgent using the Brave search engine @@ -77,4 +76,14 @@ response = agent.step(input_message=usr_msg, response_format=None) print(response.msgs[0].content) -print(response.info["tool_calls"]) +''' +The current temperature in Tokyo can be found on various weather websites. +Here are a couple of reliable sources where you can check the latest weather +conditions: + +1. [AccuWeather - Tokyo Current Weather](https://www.accuweather.com/en/jp/tokyo/226396/current-weather/226396) +2. [Time and Date - Tokyo Weather](https://www.timeanddate.com/weather/japan/tokyo) + +You can visit these links to get the most up-to-date temperature and weather +conditions in Tokyo. +'''