diff --git a/docs/extras/integrations/tools/search_tools.ipynb b/docs/extras/integrations/tools/search_tools.ipynb index 208d4436169..f9c538322a8 100644 --- a/docs/extras/integrations/tools/search_tools.ipynb +++ b/docs/extras/integrations/tools/search_tools.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "e6860c2d", "metadata": { "pycharm": { @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "dadbcfcd", "metadata": {}, "outputs": [], @@ -119,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 5, "id": "e1c39a0f", "metadata": {}, "outputs": [], @@ -129,7 +129,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 6, "id": "900dd6cb", "metadata": {}, "outputs": [], @@ -141,7 +141,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 7, "id": "342ee8ec", "metadata": {}, "outputs": [ @@ -155,9 +155,9 @@ "\u001b[32;1m\u001b[1;3m I need to find out what the current weather is in Pomfret.\n", "Action: Search\n", "Action Input: \"weather in Pomfret\"\u001b[0m\n", - "Observation: \u001b[36;1m\u001b[1;3mPartly cloudy skies during the morning hours will give way to cloudy skies with light rain and snow developing in the afternoon. High 42F. Winds WNW at 10 to 15 ...\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3m{'type': 'weather_result', 'temperature': '69', 'unit': 'Fahrenheit', 'precipitation': '2%', 'humidity': '90%', 'wind': '1 mph', 'location': 'Pomfret, CT', 'date': 'Sunday 9:00 PM', 'weather': 'Clear'}\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the current weather in Pomfret.\n", - "Final Answer: Partly cloudy skies during the morning hours will give way to cloudy skies with light rain and snow developing in the afternoon. High 42F. Winds WNW at 10 to 15 mph.\u001b[0m\n", + "Final Answer: The current weather in Pomfret is 69 degrees Fahrenheit, 2% precipitation, 90% humidity, and 1 mph wind. It is currently clear.\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] @@ -165,10 +165,10 @@ { "data": { "text/plain": [ - "'Partly cloudy skies during the morning hours will give way to cloudy skies with light rain and snow developing in the afternoon. High 42F. Winds WNW at 10 to 15 mph.'" + "'The current weather in Pomfret is 69 degrees Fahrenheit, 2% precipitation, 90% humidity, and 1 mph wind. It is currently clear.'" ] }, - "execution_count": 11, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -351,7 +351,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.11" + "version": "3.11.3" }, "vscode": { "interpreter": { diff --git a/libs/langchain/langchain/utilities/serpapi.py b/libs/langchain/langchain/utilities/serpapi.py index 4d5af099775..337e89a1195 100644 --- a/libs/langchain/langchain/utilities/serpapi.py +++ b/libs/langchain/langchain/utilities/serpapi.py @@ -129,42 +129,92 @@ class SerpAPIWrapper(BaseModel): """Process response from SerpAPI.""" if "error" in res.keys(): raise ValueError(f"Got error from SerpAPI: {res['error']}") - if "answer_box" in res.keys() and isinstance(res["answer_box"], list): - res["answer_box"] = res["answer_box"][0] - if "answer_box" in res.keys() and "answer" in res["answer_box"].keys(): - toret = res["answer_box"]["answer"] - elif "answer_box" in res.keys() and "snippet" in res["answer_box"].keys(): - toret = res["answer_box"]["snippet"] - elif ( - "answer_box" in res.keys() - and "snippet_highlighted_words" in res["answer_box"].keys() - ): - toret = res["answer_box"]["snippet_highlighted_words"][0] - elif ( - "sports_results" in res.keys() - and "game_spotlight" in res["sports_results"].keys() - ): - toret = res["sports_results"]["game_spotlight"] + if "answer_box_list" in res.keys(): + res["answer_box"] = res["answer_box_list"] + if "answer_box" in res.keys(): + answer_box = res["answer_box"] + if isinstance(answer_box, list): + answer_box = answer_box[0] + if "result" in answer_box.keys(): + return answer_box["result"] + elif "answer" in answer_box.keys(): + return answer_box["answer"] + elif "snippet" in answer_box.keys(): + return answer_box["snippet"] + elif "snippet_highlighted_words" in answer_box.keys(): + return answer_box["snippet_highlighted_words"] + else: + answer = {} + for key, value in answer_box.items(): + if not isinstance(value, (list, dict)) and not ( + type(value) == str and value.startswith("http") + ): + answer[key] = value + return str(answer) + elif "events_results" in res.keys(): + return res["events_results"][:10] + elif "sports_results" in res.keys(): + return res["sports_results"] + elif "top_stories" in res.keys(): + return res["top_stories"] + elif "news_results" in res.keys(): + return res["news_results"] + elif "jobs_results" in res.keys() and "jobs" in res["jobs_results"].keys(): + return res["jobs_results"]["jobs"] elif ( "shopping_results" in res.keys() and "title" in res["shopping_results"][0].keys() ): - toret = res["shopping_results"][:3] + return res["shopping_results"][:3] + elif "questions_and_answers" in res.keys(): + return res["questions_and_answers"] elif ( - "knowledge_graph" in res.keys() - and "description" in res["knowledge_graph"].keys() + "popular_destinations" in res.keys() + and "destinations" in res["popular_destinations"].keys() ): - toret = res["knowledge_graph"]["description"] - elif "snippet" in res["organic_results"][0].keys(): - toret = res["organic_results"][0]["snippet"] - elif "link" in res["organic_results"][0].keys(): - toret = res["organic_results"][0]["link"] + return res["popular_destinations"]["destinations"] + elif "top_sights" in res.keys() and "sights" in res["top_sights"].keys(): + return res["top_sights"]["sights"] elif ( "images_results" in res.keys() and "thumbnail" in res["images_results"][0].keys() ): - thumbnails = [item["thumbnail"] for item in res["images_results"][:10]] - toret = thumbnails + return str([item["thumbnail"] for item in res["images_results"][:10]]) + + snippets = [] + if "knowledge_graph" in res.keys(): + knowledge_graph = res["knowledge_graph"] + title = knowledge_graph["title"] if "title" in knowledge_graph else "" + if "description" in knowledge_graph.keys(): + snippets.append(knowledge_graph["description"]) + for key, value in knowledge_graph.items(): + if ( + type(key) == str + and type(value) == str + and key not in ["title", "description"] + and not key.endswith("_stick") + and not key.endswith("_link") + and not value.startswith("http") + ): + snippets.append(f"{title} {key}: {value}.") + if "organic_results" in res.keys(): + first_organic_result = res["organic_results"][0] + if "snippet" in first_organic_result.keys(): + snippets.append(first_organic_result["snippet"]) + elif "snippet_highlighted_words" in first_organic_result.keys(): + snippets.append(first_organic_result["snippet_highlighted_words"]) + elif "rich_snippet" in first_organic_result.keys(): + snippets.append(first_organic_result["rich_snippet"]) + elif "rich_snippet_table" in first_organic_result.keys(): + snippets.append(first_organic_result["rich_snippet_table"]) + elif "link" in first_organic_result.keys(): + snippets.append(first_organic_result["link"]) + if "buying_guide" in res.keys(): + snippets.append(res["buying_guide"]) + if "local_results" in res.keys() and "places" in res["local_results"].keys(): + snippets.append(res["local_results"]["places"]) + + if len(snippets) > 0: + return str(snippets) else: - toret = "No good search result found" - return toret + return "No good search result found"