Refactor to put all curl logic in one place

This commit is contained in:
2026-05-05 07:46:07 -05:00
parent 0f8cf6e92c
commit 1679818167
2 changed files with 44 additions and 55 deletions
+3
View File
@@ -28,4 +28,7 @@ public:
private:
OllamaConfig config_;
static size_t write_cb(char* ptr, size_t size, size_t nmemb, void* userdata);
std::string http_request(const std::string& full_url,
const std::string& method,
const std::string& body = "") const;
};
+41 -55
View File
@@ -17,76 +17,33 @@ size_t OllamaClient::write_cb(char* ptr, size_t size, size_t nmemb, void* userda
return size * nmemb;
}
nlohmann::json OllamaClient::chat(const nlohmann::json& messages,
const nlohmann::json& tools) const {
nlohmann::json body = {
{"model", config_.model},
{"stream", false},
{"messages", messages}
};
if (!tools.empty())
body["tools"] = tools;
std::string body_str = body.dump();
std::string OllamaClient::http_request(const std::string& full_url,
const std::string& method,
const std::string& body) const {
std::string response_buf;
//std::cerr << "Sending: " << body_str << std::endl;
CURL* curl = curl_easy_init();
if (!curl)
throw OllamaClientError("curl_easy_init failed");
std::string url = config_.base_url + "/v1/chat/completions";
std::string url = full_url;
curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
if (config_.auth_token != "")
headers = curl_slist_append(headers, ("Authorization: Bearer " + config_.auth_token).c_str());
if (!body.empty())
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body_str.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)body_str.size());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_buf);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)config_.timeout_s);
CURLcode res = curl_easy_perform(curl);
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
if (res != CURLE_OK)
throw OllamaClientError(std::string("curl error: ") + curl_easy_strerror(res));
if (http_code != 200)
throw OllamaClientError("HTTP " + std::to_string(http_code) + ": " + response_buf);
try {
std::cerr << "Repsonse: " << response_buf << std::endl;
return nlohmann::json::parse(response_buf);
} catch (const nlohmann::json::exception& e) {
throw OllamaClientError(std::string("JSON parse error: ") + e.what());
if (method == "POST" || !body.empty()) {
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)body.size());
}
}
std::vector<std::string> OllamaClient::list_models() const {
std::string response_buf;
CURL* curl = curl_easy_init();
if (!curl)
throw OllamaClientError("curl_easy_init failed");
std::string url = config_.base_url + "/api/tags";
curl_slist* headers = nullptr;
if (config_.auth_token != "")
headers = curl_slist_append(headers, ("Authorization: Bearer " + config_.auth_token).c_str());
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_buf);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)config_.timeout_s);
CURLcode res = curl_easy_perform(curl);
@@ -100,7 +57,36 @@ std::vector<std::string> OllamaClient::list_models() const {
if (http_code != 200)
throw OllamaClientError("HTTP " + std::to_string(http_code) + ": " + response_buf);
auto json = nlohmann::json::parse(response_buf);
return response_buf;
}
nlohmann::json OllamaClient::chat(const nlohmann::json& messages,
const nlohmann::json& tools) const {
nlohmann::json body = {
{"model", config_.model},
{"stream", false},
{"messages", messages}
};
if (!tools.empty())
body["tools"] = tools;
std::string body_str = body.dump();
std::string url = config_.base_url + "/v1/chat/completions";
std::string response_buf = http_request(url, "POST", body_str);
try {
std::cerr << "Repsonse: " << response_buf << std::endl;
return nlohmann::json::parse(response_buf);
} catch (const nlohmann::json::exception& e) {
throw OllamaClientError(std::string("JSON parse error: ") + e.what());
}
}
std::vector<std::string> OllamaClient::list_models() const {
std::string url = config_.base_url + "/api/tags";
std::string response_str = http_request(url, "GET", "");
auto json = nlohmann::json::parse(response_str);
std::vector<std::string> models;
if (json.contains("models") && json["models"].is_array()) {
for (const auto& m : json["models"]) {