Spaces:
Sleeping
Sleeping
# coding: utf-8 | |
import json | |
import os | |
import requests | |
from typing import Tuple, Any, List, Dict | |
from examples.tools.tool_action import SearchAction | |
from aworld.core.tool.action_factory import ActionFactory | |
from aworld.core.common import ActionModel, ActionResult | |
from aworld.logs.util import logger | |
from aworld.utils import import_package | |
from aworld.core.tool.action import ExecutableAction | |
class SearchWiki(ExecutableAction): | |
def __init__(self): | |
import_package("wikipedia") | |
def act(self, action: ActionModel, **kwargs) -> Tuple[ActionResult, Any]: | |
import wikipedia | |
query = action.params.get("query") | |
logger.info(f"Calling search_wiki api with query: {query}") | |
result: str = '' | |
try: | |
page = wikipedia.page(query) | |
result_dict = { | |
'url': page.url, | |
'title': page.title, | |
'content': page.content, | |
} | |
result = str(result_dict) | |
except wikipedia.exceptions.DisambiguationError as e: | |
result = wikipedia.summary( | |
e.options[0], sentences=5, auto_suggest=False | |
) | |
except wikipedia.exceptions.PageError: | |
result = ( | |
"There is no page in Wikipedia corresponding to entity " | |
f"{query}, please specify another word to describe the" | |
" entity to be searched." | |
) | |
except Exception as e: | |
logger.error(f"An exception occurred during the search: {e}") | |
result = f"An exception occurred during the search: {e}" | |
logger.debug(f"wiki result: {result}") | |
return ActionResult(content=result, keep=True, is_done=True), None | |
class Duckduckgo(ExecutableAction): | |
def __init__(self): | |
import_package("duckduckgo_search") | |
def act(self, action: ActionModel, **kwargs) -> Tuple[ActionResult, Any]: | |
r"""Use DuckDuckGo search engine to search information for | |
the given query. | |
This function queries the DuckDuckGo API for related topics to | |
the given search term. The results are formatted into a list of | |
dictionaries, each representing a search result. | |
Args: | |
query (str): The query to be searched. | |
source (str): The type of information to query (e.g., "text", | |
"images", "videos"). Defaults to "text". | |
max_results (int): Max number of results, defaults to `5`. | |
Returns: | |
List[Dict[str, Any]]: A list of dictionaries where each dictionary | |
represents a search result. | |
""" | |
from duckduckgo_search import DDGS | |
params = action.params | |
query = params.get("query") | |
max_results = params.get("max_results", 5) | |
source = params.get("source", "text") | |
logger.debug(f"Calling search_duckduckgo function with query: {query}") | |
ddgs = DDGS() | |
responses: List[Dict[str, Any]] = [] | |
if source == "text": | |
try: | |
results = ddgs.text(keywords=query, max_results=max_results) | |
except Exception as e: | |
# Handle specific exceptions or general request exceptions | |
responses.append({"error": f"duckduckgo search failed.{e}"}) | |
return ActionResult(content="duckduckgo search failed", keep=True), responses | |
for i, result in enumerate(results, start=1): | |
# Creating a response object with a similar structure | |
response = { | |
"result_id": i, | |
"title": result["title"], | |
"description": result["body"], | |
"url": result["href"], | |
} | |
responses.append(response) | |
elif source == "images": | |
try: | |
results = ddgs.images(keywords=query, max_results=max_results) | |
except Exception as e: | |
# Handle specific exceptions or general request exceptions | |
responses.append({"error": f"duckduckgo search failed.{e}"}) | |
return ActionResult(content="duckduckgo search failed", keep=True), responses | |
# Iterate over results found | |
for i, result in enumerate(results, start=1): | |
# Creating a response object with a similar structure | |
response = { | |
"result_id": i, | |
"title": result["title"], | |
"image": result["image"], | |
"url": result["url"], | |
"source": result["source"], | |
} | |
responses.append(response) | |
elif source == "videos": | |
try: | |
results = ddgs.videos(keywords=query, max_results=max_results) | |
except Exception as e: | |
# Handle specific exceptions or general request exceptions | |
responses.append({"error": f"duckduckgo search failed.{e}"}) | |
return ActionResult(content="duckduckgo search failed", keep=True), responses | |
# Iterate over results found | |
for i, result in enumerate(results, start=1): | |
# Creating a response object with a similar structure | |
response = { | |
"result_id": i, | |
"title": result["title"], | |
"description": result["description"], | |
"embed_url": result["embed_url"], | |
"publisher": result["publisher"], | |
"duration": result["duration"], | |
"published": result["published"], | |
} | |
responses.append(response) | |
logger.debug(f"Search results: {responses}") | |
return ActionResult(content=json.dumps(responses), keep=True, is_done=True), None | |
class SearchGoogle(ExecutableAction): | |
def act(self, action: ActionModel, **kwargs) -> Tuple[ActionResult, Any]: | |
query = action.params.get("query") | |
num_result_pages = action.params.get("num_result_pages", 6) | |
# https://developers.google.com/custom-search/v1/overview | |
api_key = action.params.get("api_key", os.environ.get("GOOGLE_API_KEY")) | |
# https://cse.google.com/cse/all | |
engine_id = action.params.get("engine_id", os.environ.get("GOOGLE_ENGINE_ID")) | |
logger.debug(f"Calling search_google function with query: {query}") | |
# Using the first page | |
start_page_idx = 1 | |
# Different language may get different result | |
search_language = "en" | |
# How many pages to return | |
num_result_pages = num_result_pages | |
# Constructing the URL | |
# Doc: https://developers.google.com/custom-search/v1/using_rest | |
url = f"https://www.googleapis.com/customsearch/v1?key={api_key}&cx={engine_id}&q={query}&start={start_page_idx}&lr={search_language}&num={num_result_pages}" | |
responses = [] | |
try: | |
result = requests.get(url) | |
result.raise_for_status() | |
data = result.json() | |
# Get the result items | |
if "items" in data: | |
search_items = data.get("items") | |
for i, search_item in enumerate(search_items, start=1): | |
# Check metatags are present | |
if "pagemap" not in search_item: | |
continue | |
if "metatags" not in search_item["pagemap"]: | |
continue | |
if "og:description" in search_item["pagemap"]["metatags"][0]: | |
long_description = search_item["pagemap"]["metatags"][0]["og:description"] | |
else: | |
long_description = "N/A" | |
# Get the page title | |
title = search_item.get("title") | |
# Page snippet | |
snippet = search_item.get("snippet") | |
# Extract the page url | |
link = search_item.get("link") | |
response = { | |
"result_id": i, | |
"title": title, | |
"description": snippet, | |
"long_description": long_description, | |
"url": link, | |
} | |
if "huggingface.co" in link: | |
logger.warning(f"Filter out the link: {link}") | |
continue | |
responses.append(response) | |
else: | |
responses.append({"error": f"google search failed with response: {data}"}) | |
except Exception as e: | |
logger.error(f"Google search failed with error: {e}") | |
responses.append({"error": f"google search failed with error: {e}"}) | |
if len(responses) == 0: | |
responses.append( | |
"No relevant webpages found. Please simplify your query and expand the search space as much as you can, then try again.") | |
logger.debug(f"search result: {responses}") | |
responses.append( | |
"If the search result does not contain the information you want, please make reflection on your query: what went well, what didn't, then refine your search plan.") | |
return ActionResult(content=json.dumps(responses), keep=True, is_done=True), None | |
class SearchBaidu(ExecutableAction): | |
def __init__(self): | |
import_package("baidusearch") | |
def act(self, action: ActionModel, **kwargs) -> Tuple[ActionResult, Any]: | |
from baidusearch.baidusearch import search | |
query = action.params.get("query") | |
num_results = action.params.get("num_results", 6) | |
num_results = int(num_results) | |
logger.debug(f"Calling search_baidu with query: {query}") | |
responses = [] | |
try: | |
responses = search(query, num_results=num_results) | |
except Exception as e: | |
logger.error(f"Baidu search failed with error: {e}") | |
responses.append({"error": f"baidu search failed with error: {e}"}) | |
if len(responses) == 0: | |
responses.append( | |
"No relevant webpages found. Please simplify your query and expand the search space as much as you can, then try again.") | |
logger.debug(f"search result: {responses}") | |
responses.append( | |
"If the search result does not contain the information you want, please make reflection on your query: what went well, what didn't, then refine your search plan.") | |
return ActionResult(content=json.dumps(responses), keep=True, is_done=True), None | |