#include "Ollama.h" #include "modules/ImguiModule/ImguiModule.h" #include Ollama::Ollama(Archimedes::App* a, void* h) : Archimedes::Module(a, h) { name = "Ollama"; ImguiModule* im = new ImguiModule(a, h); deps[*im] = im; } Ollama::~Ollama() { if(app) { if(curl) { curl_easy_cleanup(curl); curl = nullptr; } curl_global_cleanup(); ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } im->releaseContext(ImGui::GetCurrentContext()); } } static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::ostream* userp) { userp->write(static_cast(contents), size * nmemb); return size * nmemb; } void Ollama::onLoad() { ImguiModule* im; { im = (ImguiModule*) moduleInstances[ImguiModule()]; } if(!im) { std::cout << "No ImguiModule for Ollama!\n"; std::abort(); } ImGui::SetCurrentContext(im->aquireContext()); curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); } void Ollama::run() { ImGuiIO& io = ImGui::GetIO(); static std::string s, url = "https://ollama.blunkall.us", response = ""; static nlohmann::json sendObj; static std::ostringstream oss; static nlohmann::json jsonObj; static std::future result; static bool inFlight = false; ImGui::Begin("Ollama Module"); ImGui::InputText("url: ", &url); static const std::string replace = "\\n"; static const std::string replace_by = "\n"; static std::string print = jsonObj["response"].dump(); print = jsonObj["response"].dump(); static auto pos = print.find(replace); pos = print.find(replace); while (pos != std::string::npos) { // Replace the substring with the specified string print.replace(pos, replace.size(), replace_by); // Find the next occurrence of the substring pos = print.find(replace, pos + replace_by.size()); } print = "\n\n\n" + print + "\n\n\n"; ImGui::TextWrapped("%s", print.c_str()); ImGui::InputTextMultiline("prompt: ", &s); if(ImGui::Button("send")) { sendObj["model"] = "llama3.2"; sendObj["stream"] = false; sendObj["prompt"] = s; curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_URL, (url + "/api/generate").c_str()); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss); //curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); //curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, sendObj.dump().c_str()); result = std::async(std::launch::async, curl_easy_perform, curl); inFlight = true; } ImGui::Text("ms per frame: %f", 1000 / io.Framerate); ImGui::End(); if(curl) { } if(inFlight && result.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { CURLcode code = result.get(); response = oss.str(); oss.str(""); if(code != CURLE_OK) { std::cerr << "curl_easy_perform() failed!: " << curl_easy_strerror(code) << std::endl; app->emitEvent(new Archimedes::DoUnloadModuleEvent(name)); return; } else { jsonObj = nlohmann::json::parse(response); std::cout << "Full json object:\n" << jsonObj.dump() << std::endl; } inFlight = false; } }