#include "agent/humanus.h" #include "logger.h" #include "prompt.h" #include "flow/flow_factory.h" #include "memory/mem0/base.h" #if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) #include #include #elif defined (_WIN32) #define WIN32_LEAN_AND_MEAN #ifndef NOMINMAX #define NOMINMAX #endif #include #include #endif using namespace humanus; #if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) || defined (_WIN32) static void sigint_handler(int signo) { if (signo == SIGINT) { logger->info("Interrupted by user\n"); exit(0); } } #endif static bool readline_utf8(std::string & line, bool multiline_input) { #if defined(_WIN32) std::wstring wline; if (!std::getline(std::wcin, wline)) { // Input stream is bad or EOF received line.clear(); GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); return false; } int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wline[0], (int)wline.size(), NULL, 0, NULL, NULL); line.resize(size_needed); WideCharToMultiByte(CP_UTF8, 0, &wline[0], (int)wline.size(), &line[0], size_needed, NULL, NULL); #else if (!std::getline(std::cin, line)) { // Input stream is bad or EOF received line.clear(); return false; } #endif if (!line.empty()) { char last = line.back(); if (last == '/') { // Always return control on '/' symbol line.pop_back(); return false; } if (last == '\\') { // '\\' changes the default action line.pop_back(); multiline_input = !multiline_input; } } line += '\n'; // By default, continue input if multiline_input is set return multiline_input; } int main() { // ctrl+C handling { #if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) struct sigaction sigint_action; sigint_action.sa_handler = sigint_handler; sigemptyset (&sigint_action.sa_mask); sigint_action.sa_flags = 0; sigaction(SIGINT, &sigint_action, NULL); #elif defined (_WIN32) auto console_ctrl_handler = +[](DWORD ctrl_type) -> BOOL { return (ctrl_type == CTRL_C_EVENT) ? (sigint_handler(SIGINT), true) : false; }; SetConsoleCtrlHandler(reinterpret_cast(console_ctrl_handler), true); SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8); _setmode(_fileno(stdin), _O_WTEXT); // wide character input mode #endif } std::shared_ptr agent_ptr = std::make_shared( ToolCollection( // Add general-purpose tools to the tool collection { std::make_shared(), std::make_shared(), // for web browsing std::make_shared(), std::make_shared() } ), "auto", std::set{"terminate"}, "humanus_mem0", "A versatile agent that can solve various tasks using multiple tools", prompt::humanus::SYSTEM_PROMPT, prompt::humanus::NEXT_STEP_PROMPT, nullptr, std::make_shared(mem0::MemoryConfig()) ); std::map> agents; agents["default"] = agent_ptr; auto flow = FlowFactory::create_flow( FlowType::PLANNING, nullptr, // llm nullptr, // planning_tool std::vector{}, // executor_keys "", // active_plan_id agents, // agents std::vector>{}, // tools "default" // primary_agent_key ); while (true) { if (agent_ptr->current_step == agent_ptr->max_steps) { std::cout << "Automatically paused after " << agent_ptr->current_step << " steps." << std::endl; std::cout << "Enter your prompt (enter an empty line to resume or 'exit' to quit): "; agent_ptr->reset(false); } else { std::cout << "Enter your prompt (or 'exit' to quit): "; } if (agent_ptr->state != AgentState::IDLE) { break; } std::string prompt; readline_utf8(prompt, false); if (prompt == "exit" || prompt == "exit\n") { logger->info("Goodbye!"); break; } std::cout << "Processing your request..." << std::endl; auto result = flow->execute(prompt); std::cout << result << std::endl; } }