96 lines
3.4 KiB
C++
96 lines
3.4 KiB
C++
#ifndef HUMANUS_TOOL_GOOGLE_SEARCH_H
|
|
#define HUMANUS_TOOL_GOOGLE_SEARCH_H
|
|
|
|
#include "../mcp/common/httplib.h"
|
|
#include "base.h"
|
|
|
|
namespace humanus {
|
|
|
|
struct GoogleSearch : BaseTool {
|
|
inline static const std::string name_ = "google_search";
|
|
inline static const std::string description_ = R"(Perform a Google search and return a list of relevant links.
|
|
Use this tool when you need to find information on the web, get up-to-date data, or research specific topics.
|
|
The tool returns a list of URLs that match the search query.)";
|
|
inline static const json parameters_ = json::parse(R"json( {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {
|
|
"type": "string",
|
|
"description": "(required) The search query to submit to Google.",
|
|
},
|
|
"num_results": {
|
|
"type": "integer",
|
|
"description": "(optional) The number of search results to return. Default is 10.",
|
|
"default": 10,
|
|
},
|
|
},
|
|
"required": ["query"],
|
|
})json");
|
|
|
|
GoogleSearch() : BaseTool(name_, description_, parameters_) {}
|
|
|
|
ToolResult execute(const json& args) override {
|
|
try {
|
|
std::string query = args["query"];
|
|
int num_results = args.value("num_results", 10);
|
|
|
|
// 创建HTTP客户端连接到serper.dev API
|
|
httplib::Client cli("https://api.serper.dev");
|
|
|
|
// 准备请求体
|
|
json request_body = {
|
|
{"q", query},
|
|
{"num", num_results}
|
|
};
|
|
|
|
// 设置请求头
|
|
const char* api_key = std::getenv("X_API_KEY");
|
|
if (!api_key) {
|
|
return ToolError("X_API_KEY is not set");
|
|
}
|
|
|
|
httplib::Headers headers = {
|
|
{"Content-Type", "application/json"},
|
|
{"X-API-KEY", api_key}
|
|
};
|
|
|
|
// 发送POST请求
|
|
auto res = cli.Post("/search", headers, request_body.dump(), "application/json");
|
|
|
|
if (!res) {
|
|
return ToolError("Failed to connect to search API");
|
|
}
|
|
|
|
if (res->status != 200) {
|
|
return ToolError("Search API returned status code = " + std::to_string(res->status) + ", body = " + res->body);
|
|
}
|
|
|
|
// 解析响应
|
|
json response = json::parse(res->body);
|
|
|
|
// 格式化结果
|
|
std::string result = "Search results for: " + query + "\n\n";
|
|
|
|
if (response.contains("organic") && response["organic"].is_array()) {
|
|
for (size_t i = 0; i < response["organic"].size() && i < static_cast<size_t>(num_results); ++i) {
|
|
const auto& item = response["organic"][i];
|
|
result += std::to_string(i+1) + ". " + item.value("title", "No title") + "\n";
|
|
result += " URL: " + item.value("link", "No link") + "\n";
|
|
result += " Snippet: " + item.value("snippet", "No description") + "\n\n";
|
|
}
|
|
} else {
|
|
result += "No results found.";
|
|
}
|
|
|
|
return ToolResult(result);
|
|
} catch (const std::exception& e) {
|
|
return ToolResult("Error executing Google search: " + std::string(e.what()));
|
|
}
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#endif // OPEMANUS_TOOL_GOOGLE_SEARCH_H
|
|
|