#include <cpr/cpr.h>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main(int argc, char *argv[]) {
if (argc < 3 || std::string(argv[1]) != “-p”) {
std::cerr << “Expected first argument to be ‘-p’” << std::endl;
return 1;
}
std::string prompt = argv[2];
if (prompt.empty()) {
std::cerr << “Prompt must not be empty” << std::endl;
return 1;
}
const char *api_key_env = std::getenv(“OPENROUTER_API_KEY”);
const char *base_url_env = std::getenv(“OPENROUTER_BASE_URL”);
std::string api_key = api_key_env ? api_key_env : “”;
std::string base_url =
base_url_env ? base_url_env : " OpenRouter ";
if (api_key.empty()) {
std::cerr << “OPENROUTER_API_KEY is not set” << std::endl;
return 1;
}
json request_body = {
{"model", "anthropic/claude-haiku-4.5"},
{"messages", json::array({{{"role", "user"}, {"content", prompt}}})},
{"tools",
json::array(
{{{"type", "function"},
{"function",
{{"name", "Read"},
{"description", "Read and return the contents of a file"},
{"parameters",
{{"type", "object"},
{"properties",
{{"file_path",
{{"type", "string"},
{"description", "The path to the file to read"}}}}},
{"required", json::array({"file_path"})}}}}}}})}};
cpr::Response response =
cpr::Post(cpr::Url{base_url + “/chat/completions”},
cpr::Header{{“Authorization”, "Bearer " + api_key},
{"Content-Type", "application/json"}},
cpr::Body{request_body.dump()});
if (response.status_code != 200) {
std::cerr << "HTTP error: " << response.status_code << std::endl;
return 1;
}
json result = json::parse(response.text);
if (!result.contains(“choices”) || result[“choices”].empty()) {
std::cerr << “No choices in response” << std::endl;
return 1;
}
json message = result[“choices”][0][“message”];
// Check if there are tool calls
if (message.contains(“tool_calls”) && !message[“tool_calls”].empty()) {
json tool_call = message\["tool_calls"\]\[0\];
std::string function_name = tool_call[“function”][“name”];
std::string arguments_str = tool_call[“function”][“arguments”];
json arguments = json::parse(arguments_str);
if (function_name == “Read” && arguments.contains(“file_path”)) {
std::string file_path = arguments[“file_path”];
std::ifstream file(file_path);
if (file.is_open()) {
std::string content((std::istreambuf_iterator(file)),
std::istreambuf_iterator());
std::cout << content;
} else {
std::cerr << "Failed to open file: " << file_path << std::endl;
return 1;
}
}
} else {
// No tool calls, just print the message content
if (message.contains(“content”) && !message[“content”].is_null()) {
std::cout << message[“content”].getstd::string();
}
}
return 0;
}