humanus.cpp/tool/google_search.h

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