From be606c1020cae8066dec01f31a403ba84745dec8 Mon Sep 17 00:00:00 2001 From: hkr04 Date: Mon, 17 Mar 2025 16:35:11 +0800 Subject: [PATCH] zh -> en --- CMakeLists.txt | 25 ++-------- agent/planning.cpp | 2 +- config.cpp | 6 +-- config.h | 27 +++++------ llm.h | 60 +++++++++++------------ logger.cpp | 6 +-- logger.h | 13 ++--- mcp | 2 +- server/mcp_server_main.cpp | 24 ++++----- server/python_execute.cpp | 86 ++++++++++++++++----------------- tool/base.h | 44 ++++++++--------- tool/create_chat_completion.cpp | 10 ++-- tool/create_chat_completion.h | 2 +- tool/filesystem.h | 3 +- tool/puppeteer.h | 3 +- tool/shell.h | 8 +-- tool/tool_collection.h | 26 +++++----- 17 files changed, 160 insertions(+), 187 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 793bd0a..580b05c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,6 @@ project(humanus.cpp VERSION 0.1.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# 查找OpenSSL库 find_package(OpenSSL 3.0.0 REQUIRED) if(OPENSSL_FOUND) message(STATUS "OpenSSL found: ${OPENSSL_VERSION}") @@ -16,7 +15,6 @@ else() message(FATAL_ERROR "OpenSSL not found. Please install OpenSSL development libraries.") endif() -# 查找Python库 find_package(Python3 COMPONENTS Development) if(Python3_FOUND) message(STATUS "Python3 found: ${Python3_VERSION}") @@ -28,21 +26,19 @@ else() message(WARNING "Python3 development libraries not found. Python interpreter will not be available.") endif() -# 添加MCP库 +# mcp add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/mcp) -# 添加服务器组件 +# server add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/server) -# 添加包含目录 +# include include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/mcp/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/mcp/common) -# 查找必要的包 find_package(Threads REQUIRED) -# 添加源文件 file(GLOB AGENT_SOURCES "agent/*.cpp" "agent/*.cc" @@ -58,7 +54,6 @@ file(GLOB FLOW_SOURCES "flow/*.cc" ) -# 添加可执行文件 add_executable(humanus_cpp main.cpp config.cpp @@ -71,19 +66,9 @@ add_executable(humanus_cpp ${FLOW_SOURCES} ) -# 链接库 -target_link_libraries(humanus_cpp PRIVATE Threads::Threads mcp server ${OPENSSL_LIBRARIES}) +target_link_libraries(humanus_cpp PRIVATE Threads::Threads mcp ${OPENSSL_LIBRARIES}) if(Python3_FOUND) target_link_libraries(humanus_cpp PRIVATE ${Python3_LIBRARIES}) endif() -# 添加简单版本的可执行文件 -# add_executable(humanus_simple main_simple.cpp logger.cpp schema.cpp) -# target_link_libraries(humanus_simple PRIVATE Threads::Threads ${OPENSSL_LIBRARIES}) -# if(Python3_FOUND) -# target_link_libraries(humanus_simple PRIVATE ${Python3_LIBRARIES}) -# endif() - -# 安装目标 -install(TARGETS humanus_cpp DESTINATION bin) -# install(TARGETS humanus_simple DESTINATION bin) \ No newline at end of file +install(TARGETS humanus_cpp DESTINATION bin) \ No newline at end of file diff --git a/agent/planning.cpp b/agent/planning.cpp index 1e8a6c2..d6e390d 100644 --- a/agent/planning.cpp +++ b/agent/planning.cpp @@ -1,5 +1,5 @@ #include "planning.h" -#include // 添加iomanip头文件,用于std::setprecision +#include namespace humanus { diff --git a/config.cpp b/config.cpp index 8dbcae2..9942d5e 100644 --- a/config.cpp +++ b/config.cpp @@ -6,7 +6,7 @@ namespace humanus { -// 初始化静态成员 +// Initialize static members Config* Config::_instance = nullptr; std::mutex Config::_mutex; @@ -17,7 +17,7 @@ void Config::_load_initial_config() { const auto& data = toml::parse_file(config_path.string()); - // 检查工具配置是否存在 + // Check if tool configuration exists if (!data.contains("llm") || !data["llm"].is_table()) { throw std::runtime_error("找不到llm配置: "); } @@ -59,7 +59,7 @@ void Config::_load_initial_config() { _config.llm["default"] = llm_settings; } catch (const std::exception& e) { std::cerr << "加载配置文件失败: " << e.what() << std::endl; - // 设置默认配置 + // Set default configuration LLMSettings default_settings; default_settings.model = "gpt-3.5-turbo"; default_settings.api_key = "sk-"; diff --git a/config.h b/config.h index eee69bd..48c6461 100644 --- a/config.h +++ b/config.h @@ -13,17 +13,14 @@ namespace humanus { +// Get project root directory static std::filesystem::path get_project_root() { - // 获取项目根目录 return std::filesystem::path(__FILE__).parent_path(); } inline const std::filesystem::path PROJECT_ROOT = get_project_root(); inline const std::filesystem::path WORKSPACE_ROOT = PROJECT_ROOT / "workspace"; -/** - * @brief LLM设置结构体 - */ struct LLMSettings { std::string model; std::string api_key; @@ -65,19 +62,17 @@ private: bool _initialized = false; AppConfig _config; - // 私有构造函数 Config() { _load_initial_config(); _initialized = true; } - // 禁止拷贝和赋值 Config(const Config&) = delete; Config& operator=(const Config&) = delete; /** - * @brief 获取配置文件路径 - * @return 配置文件路径 + * @brief Get the config path + * @return The config path */ static std::filesystem::path _get_config_path() { auto root = PROJECT_ROOT; @@ -89,18 +84,18 @@ private: if (std::filesystem::exists(example_path)) { return example_path; } - throw std::runtime_error("无法找到配置文件"); + throw std::runtime_error("Config file not found"); } /** - * @brief 加载配置文件 + * @brief Load the initial config */ void _load_initial_config(); public: /** - * @brief 获取单例实例 - * @return 配置实例 + * @brief Get the singleton instance + * @return The config instance */ static Config& get_instance() { if (_instance == nullptr) { @@ -113,16 +108,16 @@ public: } /** - * @brief 获取LLM设置 - * @return LLM设置映射 + * @brief Get the LLM settings + * @return The LLM settings map */ const std::map& llm() const { return _config.llm; } /** - * @brief 获取应用配置 - * @return 应用配置 + * @brief Get the app config + * @return The app config */ const AppConfig& get_config() const { return _config; diff --git a/llm.h b/llm.h index a387b74..e22a550 100644 --- a/llm.h +++ b/llm.h @@ -24,7 +24,7 @@ private: std::shared_ptr llm_config_; public: - // 构造函数 + // Constructor LLM(const std::string& config_name, const std::shared_ptr& llm_config = nullptr) : llm_config_(llm_config) { if (!llm_config_) { if (Config::get_instance().llm().find(config_name) == Config::get_instance().llm().end()) { @@ -38,7 +38,7 @@ public: }); } - // 单例模式获取实例 + // Get the singleton instance static std::shared_ptr get_instance(const std::string& config_name = "default", const std::shared_ptr& llm_config = nullptr) { if (_instances.find(config_name) == _instances.end()) { _instances[config_name] = std::make_shared(config_name, llm_config); @@ -47,11 +47,11 @@ public: } /** - * @brief 格式化消息列表为LLM可接受的格式 - * @param messages Message对象消息列表 - * @return 格式化后的消息列表 - * @throws std::invalid_argument 如果消息格式无效或缺少必要字段 - * @throws std::runtime_error 如果消息类型不支持 + * @brief Format the message list to the format that LLM can accept + * @param messages Message object message list + * @return The formatted message list + * @throws std::invalid_argument If the message format is invalid or missing necessary fields + * @throws std::runtime_error If the message type is not supported */ static std::vector format_messages(const std::vector& messages) { std::vector formatted_messages; @@ -73,18 +73,18 @@ public: } /** - * @brief 格式化消息列表为LLM可接受的格式 - * @param messages json对象消息列表 - * @return 格式化后的消息列表 - * @throws std::invalid_argument 如果消息格式无效或缺少必要字段 - * @throws std::runtime_error 如果消息类型不支持 + * @brief Format the message list to the format that LLM can accept + * @param messages json object message list + * @return The formatted message list + * @throws std::invalid_argument If the message format is invalid or missing necessary fields + * @throws std::runtime_error If the message type is not supported */ static std::vector format_messages(const std::vector& messages) { std::vector formatted_messages; for (const auto& message : messages) { if (!message.contains("role")) { - throw std::invalid_argument("消息缺少必要字段: role"); + throw std::invalid_argument("Message missing necessary field: role"); } formatted_messages.push_back(message); } @@ -102,13 +102,13 @@ public: } /** - * @brief 向LLM发送请求并获取回复 - * @param messages 对话消息列表 - * @param system_msgs 可选的系统消息 - * @param max_retries 最大重试次数 - * @return 生成的assitant content - * @throws std::invalid_argument 如果消息无效或回复为空 - * @throws std::runtime_error 如果API调用失败 + * @brief Send a request to the LLM and get the reply + * @param messages The conversation message list + * @param system_msgs Optional system messages + * @param max_retries The maximum number of retries + * @return The generated assistant content + * @throws std::invalid_argument If the message is invalid or the reply is empty + * @throws std::runtime_error If the API call fails */ std::string ask( const std::vector& messages, @@ -169,16 +169,16 @@ public: } /** - * @brief 使用工具功能向LLM发送请求 - * @param messages 对话消息列表 - * @param system_msgs 可选的系统消息 - * @param timeout 请求超时时间(秒) - * @param tools 工具列表 - * @param tool_choice 工具选择策略 - * @param max_retries 最大重试次数 - * @return 生成的assistant message (content, tool_calls) - * @throws std::invalid_argument 如果工具、工具选择或消息无效 - * @throws std::runtime_error 如果API调用失败 + * @brief Send a request to the LLM with tool functions + * @param messages The conversation message list + * @param system_msgs Optional system messages + * @param timeout The request timeout (seconds) + * @param tools The tool list + * @param tool_choice The tool choice strategy + * @param max_retries The maximum number of retries + * @return The generated assistant message (content, tool_calls) + * @throws std::invalid_argument If the tool, tool choice or message is invalid + * @throws std::runtime_error If the API call fails */ json ask_tool( const std::vector& messages, diff --git a/logger.cpp b/logger.cpp index 1e533a0..0a7fb05 100644 --- a/logger.cpp +++ b/logger.cpp @@ -20,18 +20,16 @@ std::shared_ptr define_log_level(spdlog::level::level_enum print std::string log_name = name.empty() ? formatted_date : name + "_" + formatted_date; std::string log_file_path = (PROJECT_ROOT / "logs" / (log_name + ".log")).string(); - // 确保日志目录存在 + // Ensure the log directory exists std::filesystem::create_directories(PROJECT_ROOT / "logs"); - // 重置日志输出 + // Reset the log output std::shared_ptr _logger = std::make_shared(log_name); - // 添加标准错误输出sink,相当于Python中的sys.stderr auto stderr_sink = std::make_shared(); stderr_sink->set_level(print_level); _logger->sinks().push_back(stderr_sink); - // 添加文件sink,相当于Python中的PROJECT_ROOT / f"logs/{log_name}.log" auto file_sink = std::make_shared(log_file_path, false); file_sink->set_level(logfile_level); _logger->sinks().push_back(file_sink); diff --git a/logger.h b/logger.h index 1b2a810..6b835eb 100644 --- a/logger.h +++ b/logger.h @@ -14,17 +14,14 @@ namespace humanus { -// 使用config.h中定义的PROJECT_ROOT -// static const std::filesystem::path PROJECT_ROOT = std::filesystem::current_path(); - static spdlog::level::level_enum _print_level = spdlog::level::info; /** - * @brief 调整日志级别 - * @param print_level 控制台输出日志级别 - * @param logfile_level 文件记录日志级别 - * @param name 日志文件名前缀 - * @return 日志记录器实例 + * @brief Adjust the log level + * @param print_level The console output log level + * @param logfile_level The file record log level + * @param name The log file name prefix + * @return The log record instance */ extern std::shared_ptr define_log_level(spdlog::level::level_enum print_level = spdlog::level::info, spdlog::level::level_enum logfile_level = spdlog::level::debug, diff --git a/mcp b/mcp index 5e9ff48..7f9862f 160000 --- a/mcp +++ b/mcp @@ -1 +1 @@ -Subproject commit 5e9ff48b070a11ba20529feb22c68d0e9ef46f3d +Subproject commit 7f9862f91ca82118f31834570ee409381574eba0 diff --git a/server/mcp_server_main.cpp b/server/mcp_server_main.cpp index c127246..b79254d 100644 --- a/server/mcp_server_main.cpp +++ b/server/mcp_server_main.cpp @@ -1,9 +1,9 @@ /** * @file mcp_server_main.cpp - * @brief OpenManus MCP服务器实现 + * @brief OpenManus MCP Server Implementation * - * 这个文件实现了OpenManus的MCP服务器,提供工具调用功能。 - * 当前实现了PythonExecute工具。 + * This file implements the OpenManus MCP server that provides tool invocation functionality. + * Currently implements the PythonExecute tool. */ #include "../mcp/include/mcp_server.h" @@ -15,27 +15,27 @@ #include #include -// 导入Python执行工具 +// Import Python execution tool extern void register_python_execute_tool(mcp::server& server); int main() { - // 创建并配置服务器 + // Create and configure server mcp::server server("localhost", 8818); server.set_server_info("OpenManusMCPServer", "0.0.1"); - // 设置服务器能力 + // Set server capabilities mcp::json capabilities = { {"tools", mcp::json::object()} }; server.set_capabilities(capabilities); - // 注册Python执行工具 + // Register Python execution tool register_python_execute_tool(server); - // 启动服务器 - std::cout << "启动OpenManus MCP服务器,地址: localhost:8818..." << std::endl; - std::cout << "按Ctrl+C停止服务器" << std::endl; - server.start(true); // 阻塞模式 + // Start server + std::cout << "Starting OpenManus MCP server at localhost:8818..." << std::endl; + std::cout << "Press Ctrl+C to stop server" << std::endl; + server.start(true); // Blocking mode return 0; -} \ No newline at end of file +} \ No newline at end of file diff --git a/server/python_execute.cpp b/server/python_execute.cpp index 216b982..d5dbeb1 100644 --- a/server/python_execute.cpp +++ b/server/python_execute.cpp @@ -1,8 +1,8 @@ /** * @file python_execute.cpp - * @brief OpenManus Python执行工具实现 + * @brief OpenManus Python execution tool implementation * - * 这个文件实现了OpenManus的Python执行工具,使用Python.h直接调用Python解释器。 + * This file implements the OpenManus Python execution tool, using Python.h to directly call the Python interpreter. */ #include "mcp/include/mcp_server.h" @@ -15,24 +15,24 @@ #include #include -// 检查是否找到Python +// Check if Python is found #ifdef PYTHON_FOUND #include #endif /** * @class python_interpreter - * @brief Python解释器类,用于执行Python代码 + * @brief Python interpreter class for executing Python code */ class python_interpreter { private: - // 互斥锁,确保Python解释器的线程安全 + // Mutex to ensure thread safety of Python interpreter mutable std::mutex py_mutex; bool is_initialized; public: /** - * @brief 构造函数,初始化Python解释器 + * @brief Constructor, initializes Python interpreter */ python_interpreter() : is_initialized(false) { #ifdef PYTHON_FOUND @@ -40,21 +40,21 @@ public: Py_Initialize(); if (Py_IsInitialized()) { is_initialized = true; - // 初始化线程支持 + // Initialize thread support PyEval_InitThreads(); - // 释放GIL,允许其他线程获取 + // Release GIL to allow other threads to acquire PyThreadState *_save = PyEval_SaveThread(); } else { - std::cerr << "Python解释器初始化失败" << std::endl; + std::cerr << "Failed to initialize Python interpreter" << std::endl; } } catch (const std::exception& e) { - std::cerr << "Python解释器初始化异常: " << e.what() << std::endl; + std::cerr << "Python interpreter initialization exception: " << e.what() << std::endl; } #endif } /** - * @brief 析构函数,释放Python解释器 + * @brief Destructor, releases Python interpreter */ ~python_interpreter() { #ifdef PYTHON_FOUND @@ -67,17 +67,17 @@ public: } /** - * @brief 执行Python代码 - * @param input 包含Python代码的JSON对象 - * @return 执行结果的JSON对象 + * @brief Execute Python code + * @param input JSON object containing Python code + * @return JSON object with execution results */ mcp::json forward(const mcp::json& input) const { #ifdef PYTHON_FOUND if (!is_initialized) { - return mcp::json{{"error", "Python解释器未正确初始化"}}; + return mcp::json{{"error", "Python interpreter not properly initialized"}}; } - // 获取GIL锁 + // Acquire GIL lock std::lock_guard lock(py_mutex); PyGILState_STATE gstate = PyGILState_Ensure(); @@ -87,25 +87,25 @@ public: if (input.contains("code") && input["code"].is_string()) { std::string code = input["code"].get(); - // 获取主模块和字典 + // Get main module and dictionary PyObject *main_module = PyImport_AddModule("__main__"); if (!main_module) { PyGILState_Release(gstate); - return mcp::json{{"error", "无法获取Python主模块"}}; + return mcp::json{{"error", "Failed to get Python main module"}}; } PyObject *main_dict = PyModule_GetDict(main_module); if (!main_dict) { PyGILState_Release(gstate); - return mcp::json{{"error", "无法获取Python主模块字典"}}; + return mcp::json{{"error", "Failed to get Python main module dictionary"}}; } - // 导入sys和io模块 + // Import sys and io modules PyObject *sys_module = PyImport_ImportModule("sys"); if (!sys_module) { PyErr_Print(); PyGILState_Release(gstate); - return mcp::json{{"error", "无法导入sys模块"}}; + return mcp::json{{"error", "Failed to import sys module"}}; } PyObject *io_module = PyImport_ImportModule("io"); @@ -113,20 +113,20 @@ public: Py_DECREF(sys_module); PyErr_Print(); PyGILState_Release(gstate); - return mcp::json{{"error", "无法导入io模块"}}; + return mcp::json{{"error", "Failed to import io module"}}; } - // 获取StringIO类 + // Get StringIO class PyObject *string_io = PyObject_GetAttrString(io_module, "StringIO"); if (!string_io) { Py_DECREF(io_module); Py_DECREF(sys_module); PyErr_Print(); PyGILState_Release(gstate); - return mcp::json{{"error", "无法获取StringIO类"}}; + return mcp::json{{"error", "Failed to get StringIO class"}}; } - // 创建StringIO对象 + // Create StringIO objects PyObject *sys_stdout = PyObject_CallObject(string_io, nullptr); if (!sys_stdout) { Py_DECREF(string_io); @@ -134,7 +134,7 @@ public: Py_DECREF(sys_module); PyErr_Print(); PyGILState_Release(gstate); - return mcp::json{{"error", "无法创建stdout StringIO对象"}}; + return mcp::json{{"error", "Failed to create stdout StringIO object"}}; } PyObject *sys_stderr = PyObject_CallObject(string_io, nullptr); @@ -145,17 +145,17 @@ public: Py_DECREF(sys_module); PyErr_Print(); PyGILState_Release(gstate); - return mcp::json{{"error", "无法创建stderr StringIO对象"}}; + return mcp::json{{"error", "Failed to create stderr StringIO object"}}; } - // 保存原始的stdout和stderr + // Save original stdout and stderr PyObject *old_stdout = PySys_GetObject("stdout"); PyObject *old_stderr = PySys_GetObject("stderr"); if (old_stdout) Py_INCREF(old_stdout); if (old_stderr) Py_INCREF(old_stderr); - // 替换sys.stdout和sys.stderr + // Replace sys.stdout and sys.stderr if (PySys_SetObject("stdout", sys_stdout) != 0 || PySys_SetObject("stderr", sys_stderr) != 0) { Py_DECREF(sys_stderr); @@ -165,23 +165,23 @@ public: Py_DECREF(sys_module); PyErr_Print(); PyGILState_Release(gstate); - return mcp::json{{"error", "无法设置stdout/stderr重定向"}}; + return mcp::json{{"error", "Failed to set stdout/stderr redirection"}}; } - // 执行Python代码 + // Execute Python code PyObject *result = PyRun_String(code.c_str(), Py_file_input, main_dict, main_dict); if (!result) { PyErr_Print(); } Py_XDECREF(result); - // 获取输出和错误 + // Get output and errors PyObject *out_value = PyObject_CallMethod(sys_stdout, "getvalue", nullptr); PyObject *err_value = PyObject_CallMethod(sys_stderr, "getvalue", nullptr); std::string output, error; - // 安全地转换Python字符串到C++字符串 + // Safely convert Python strings to C++ strings if (out_value && PyUnicode_Check(out_value)) { output = PyUnicode_AsUTF8(out_value); } @@ -190,7 +190,7 @@ public: error = PyUnicode_AsUTF8(err_value); } - // 恢复原始的stdout和stderr + // Restore original stdout and stderr if (old_stdout) { PySys_SetObject("stdout", old_stdout); Py_DECREF(old_stdout); @@ -201,7 +201,7 @@ public: Py_DECREF(old_stderr); } - // 清理 + // Cleanup Py_XDECREF(out_value); Py_XDECREF(err_value); Py_DECREF(sys_stdout); @@ -210,7 +210,7 @@ public: Py_DECREF(io_module); Py_DECREF(sys_module); - // 准备JSON输出 + // Prepare JSON output if (!output.empty()) { result_json["output"] = output; } @@ -237,10 +237,10 @@ public: result_json["error"] = "Invalid parameters or code not provided"; } } catch (const std::exception& e) { - result_json["error"] = std::string("Python执行异常: ") + e.what(); + result_json["error"] = std::string("Python execution exception: ") + e.what(); } - // 释放GIL + // Release GIL PyGILState_Release(gstate); return result_json; #else @@ -249,17 +249,17 @@ public: } }; -// 全局Python解释器实例 +// Global Python interpreter instance static python_interpreter interpreter; -// Python执行工具处理函数 +// Python execution tool handler function mcp::json python_execute_handler(const mcp::json& args) { if (!args.contains("code")) { - throw mcp::mcp_exception(mcp::error_code::invalid_params, "缺少'code'参数"); + throw mcp::mcp_exception(mcp::error_code::invalid_params, "Missing 'code' parameter"); } try { - // 使用Python解释器执行代码 + // Use Python interpreter to execute code mcp::json result = interpreter.forward(args); return {{ @@ -268,7 +268,7 @@ mcp::json python_execute_handler(const mcp::json& args) { }}; } catch (const std::exception& e) { throw mcp::mcp_exception(mcp::error_code::internal_error, - "执行Python代码失败: " + std::string(e.what())); + "Failed to execute Python code: " + std::string(e.what())); } } diff --git a/tool/base.h b/tool/base.h index 71dca05..5c8917d 100644 --- a/tool/base.h +++ b/tool/base.h @@ -11,11 +11,11 @@ namespace humanus { -// 从config_mcp.toml中读取工具配置 +// Read tool configuration from config_mcp.toml struct MCPToolConfig { std::string type; std::string host; - int port; + int port; std::string url; std::string command; std::vector args; @@ -25,36 +25,36 @@ struct MCPToolConfig { MCPToolConfig config; try { - // 获取配置文件路径 + // Get config file path auto config_path = PROJECT_ROOT / "config" / "config_mcp.toml"; if (!std::filesystem::exists(config_path)) { - throw std::runtime_error("找不到MCP配置文件: " + config_path.string()); + throw std::runtime_error("MCP config file not found: " + config_path.string()); } - // 解析TOML文件 + // Parse TOML file const auto& data = toml::parse_file(config_path.string()); - // 检查工具配置是否存在 + // Check if tool config exists if (!data.contains(tool_name) || !data[tool_name].is_table()) { - throw std::runtime_error("MCP配置文件中找不到工具配置: " + tool_name); + throw std::runtime_error("Tool configuration not found in MCP config file: " + tool_name); } const auto& tool_table = *data[tool_name].as_table(); - // 读取类型 + // Read type if (!tool_table.contains("type") || !tool_table["type"].is_string()) { - throw std::runtime_error("工具配置缺少type字段: " + tool_name); + throw std::runtime_error("Tool configuration missing type field: " + tool_name); } config.type = tool_table["type"].as_string()->get(); if (config.type == "stdio") { - // 读取命令 + // Read command if (!tool_table.contains("command") || !tool_table["command"].is_string()) { - throw std::runtime_error("stdio类型工具配置缺少command字段: " + tool_name); + throw std::runtime_error("stdio type tool configuration missing command field: " + tool_name); } config.command = tool_table["command"].as_string()->get(); - // 读取参数(如果有) + // Read arguments (if any) if (tool_table.contains("args") && tool_table["args"].is_array()) { const auto& args_array = *tool_table["args"].as_array(); for (const auto& arg : args_array) { @@ -64,7 +64,7 @@ struct MCPToolConfig { } } - // 读取环境变量 + // Read environment variables std::string env_section = tool_name + ".env"; if (data.contains(env_section) && data[env_section].is_table()) { const auto& env_table = *data[env_section].as_table(); @@ -81,25 +81,25 @@ struct MCPToolConfig { } } } else if (config.type == "sse") { - // 读取host和port或url + // Read host and port or url if (tool_table.contains("url") && tool_table["url"].is_string()) { config.url = tool_table["url"].as_string()->get(); } else { if (!tool_table.contains("host") || !tool_table["host"].is_string()) { - throw std::runtime_error("sse类型工具配置缺少host字段: " + tool_name); + throw std::runtime_error("sse type tool configuration missing host field: " + tool_name); } config.host = tool_table["host"].as_string()->get(); if (!tool_table.contains("port") || !tool_table["port"].is_integer()) { - throw std::runtime_error("sse类型工具配置缺少port字段: " + tool_name); + throw std::runtime_error("sse type tool configuration missing port field: " + tool_name); } config.port = tool_table["port"].as_integer()->get(); } } else { - throw std::runtime_error("不支持的工具类型: " + config.type); + throw std::runtime_error("Unsupported tool type: " + config.type); } } catch (const std::exception& e) { - std::cerr << "加载MCP工具配置失败: " << e.what() << std::endl; + std::cerr << "Failed to load MCP tool configuration: " << e.what() << std::endl; throw; } @@ -182,7 +182,7 @@ struct BaseTool { if (special_tool_name.find(name) != special_tool_name.end()) { return; } - // 从配置文件加载工具配置 + // Load tool configuration from config file auto _config = MCPToolConfig::load_from_toml(name); if (_config.type == "stdio") { @@ -199,7 +199,7 @@ struct BaseTool { } else if (!_config.url.empty()) { _client = std::make_unique(_config.url, "/sse"); } else { - throw std::runtime_error("MCP SSE 配置缺少 host 或 port 或 url"); + throw std::runtime_error("MCP SSE configuration missing host or port or url"); } } @@ -215,11 +215,11 @@ struct BaseTool { virtual ToolResult execute(const json& arguments) { try { if (!_client) { - throw std::runtime_error("MCP 客户端未初始化"); + throw std::runtime_error("MCP client not initialized"); } json result = _client->call_tool(name, arguments); bool is_error = result.value("isError", false); - // 根据是否有错误返回不同的ToolResult + // Return different ToolResult based on whether there is an error if (is_error) { return ToolError(result.value("content", json::array())); } else { diff --git a/tool/create_chat_completion.cpp b/tool/create_chat_completion.cpp index 0bd4518..a1a36ab 100644 --- a/tool/create_chat_completion.cpp +++ b/tool/create_chat_completion.cpp @@ -22,7 +22,7 @@ json CreateChatCompletion::_build_parameters() const { } json CreateChatCompletion::_create_type_schema(const std::string& type_hint) const { - // 处理基本类型 + // Handle basic types if (type_mapping.find(type_hint) != type_mapping.end()) { return { {"type", "object"}, @@ -36,9 +36,9 @@ json CreateChatCompletion::_create_type_schema(const std::string& type_hint) con }; } - // 处理数组类型 + // Handle array types if (type_hint.find("array") == 0) { - std::string item_type = "string"; // 默认项类型 + std::string item_type = "string"; // Default item type return { {"type", "object"}, {"properties", { @@ -51,7 +51,7 @@ json CreateChatCompletion::_create_type_schema(const std::string& type_hint) con }; } - // 处理字典类型 + // Handle dictionary type if (type_hint.find("object") == 0) { return { {"type", "object"}, @@ -65,7 +65,7 @@ json CreateChatCompletion::_create_type_schema(const std::string& type_hint) con }; } - // 默认返回字符串类型 + // Default return string type return { {"type", "object"}, {"properties", { diff --git a/tool/create_chat_completion.h b/tool/create_chat_completion.h index 28c3722..4808091 100644 --- a/tool/create_chat_completion.h +++ b/tool/create_chat_completion.h @@ -14,7 +14,7 @@ struct CreateChatCompletion : BaseTool { inline static const std::string name_ = "create_chat_completion"; inline static const std::string description_ = "Creates a structured completion with specified output formatting."; - // 类型映射表,用于JSON schema + // Type mapping table, used for JSON schema inline static std::unordered_map type_mapping = { {"string", "string"}, {"int", "integer"}, diff --git a/tool/filesystem.h b/tool/filesystem.h index 51fa49b..f61beb1 100644 --- a/tool/filesystem.h +++ b/tool/filesystem.h @@ -83,7 +83,6 @@ struct FileSystem : BaseTool { return ToolError("Failed to initialize shell client"); } - // 处理命令参数 std::string tool; if (args.contains("tool")) { if (args["tool"].is_string()) { @@ -107,7 +106,7 @@ struct FileSystem : BaseTool { bool is_error = result.value("isError", false); - // 根据是否有错误返回不同的ToolResult + // Return different ToolResult based on whether there is an error if (is_error) { return ToolError(result.value("content", json::array())); } else { diff --git a/tool/puppeteer.h b/tool/puppeteer.h index 9cdd26c..b959012 100644 --- a/tool/puppeteer.h +++ b/tool/puppeteer.h @@ -76,7 +76,6 @@ struct Puppeteer : BaseTool { return ToolError("Failed to initialize puppeteer client"); } - // 处理命令参数 std::string tool; if (args.contains("tool")) { if (args["tool"].is_string()) { @@ -100,7 +99,7 @@ struct Puppeteer : BaseTool { bool is_error = result.value("isError", false); - // 根据是否有错误返回不同的ToolResult + // Return different ToolResult based on whether there is an error if (is_error) { return ToolError(result.value("content", json::array())); } else { diff --git a/tool/shell.h b/tool/shell.h index 1107910..066e6b4 100644 --- a/tool/shell.h +++ b/tool/shell.h @@ -58,12 +58,12 @@ struct Shell : BaseTool { ToolResult execute(const json& args) override { try { - // 确保客户端已初始化 + // Ensure client is initialized if (!_client) { return ToolError("Failed to initialize shell client"); } - // 处理命令参数 + // Handle command parameters std::string command; if (args.contains("command")) { if (args["command"].is_string()) { @@ -78,12 +78,12 @@ struct Shell : BaseTool { json tool_args = args; tool_args.erase("command"); - // 调用shell工具 + // Call shell tool json result = _client->call_tool("shell_" + command, tool_args); bool is_error = result.value("isError", false); - // 根据是否有错误返回不同的ToolResult + // Return different ToolResult based on whether there is an error if (is_error) { return ToolError(result.value("content", json::array())); } else { diff --git a/tool/tool_collection.h b/tool/tool_collection.h index fc7b5e7..3f671a3 100644 --- a/tool/tool_collection.h +++ b/tool/tool_collection.h @@ -35,19 +35,19 @@ struct ToolCollection { } } - // // Execute all tools in the collection sequentially. - // std::vector execute_all(const json& args) const { // No reference now - // std::vector results; - // for (auto tool : tools) { - // try { - // auto result = tool->execute(args); - // results.push_back(result); - // } catch (const std::exception& e) { - // results.push_back(ToolError(e.what())); - // } - // } - // return results; - // } + // Execute all tools in the collection sequentially. + std::vector execute_all(const json& args) const { // No reference now + std::vector results; + for (auto tool : tools) { + try { + auto result = tool->execute(args); + results.push_back(result); + } catch (const std::exception& e) { + results.push_back(ToolError(e.what())); + } + } + return results; + } void add_tool(const std::shared_ptr& tool) { tools.push_back(tool);