You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.4 KiB
152 lines
4.4 KiB
#pragma once
|
|
#include "ofMain.h"
|
|
#include "ofThread.h"
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
#include <atomic>
|
|
#include <string>
|
|
#include "ofxNetwork.h"
|
|
|
|
|
|
class LLMRequestThread : public ofThread {
|
|
public:
|
|
LLMRequestThread() {}
|
|
~LLMRequestThread() {
|
|
stop();
|
|
waitForThread(false);
|
|
}
|
|
|
|
void setup(std::string url_) {
|
|
url = url_;
|
|
resultReady = false;
|
|
startThread();
|
|
}
|
|
|
|
void requestPromptTest(std::string newPrompt) {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
prompt = newPrompt;
|
|
resultReady = false;
|
|
hasNewPrompt = true;
|
|
condition.notify_all(); // wake thread to start processing
|
|
}
|
|
|
|
void requestPrompt(const std::string& speaker_, const std::string& text_, const std::string& emotion_, const float temp_) {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
speaker = speaker_;
|
|
text = text_;
|
|
emotion = emotion_;
|
|
llmTemperature = temp_;
|
|
resultReady = false;
|
|
hasNewPrompt = true;
|
|
condition.notify_all(); // wake thread to start processing
|
|
}
|
|
|
|
std::string getResult() {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
return result;
|
|
}
|
|
|
|
bool isResultReady() {
|
|
return resultReady.load();
|
|
}
|
|
|
|
void stop() {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
stopThread();
|
|
condition.notify_all();
|
|
}
|
|
|
|
protected:
|
|
void threadedFunction() override {
|
|
while (isThreadRunning()) {
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
condition.wait(lock, [this] { return hasNewPrompt || !isThreadRunning(); });
|
|
|
|
if (!isThreadRunning()) break;
|
|
|
|
std::string localSpeaker = speaker;
|
|
std::string localBody = text;
|
|
std::string localEmotion = emotion;
|
|
float localTemp = llmTemperature;
|
|
|
|
hasNewPrompt = false;
|
|
lock.unlock(); // unlock during HTTP request
|
|
|
|
// Do HTTP POST request to FastAPI
|
|
std::string responseText = makeRequest(localSpeaker, localBody, localEmotion, localTemp);
|
|
|
|
lock.lock();
|
|
result = responseText;
|
|
resultReady = true;
|
|
}
|
|
}
|
|
|
|
std::string makeRequest(const std::string& speaker_, const std::string& text_, const std::string& emotion_, const float temp_) {
|
|
ofxTCPClient client;
|
|
std::string host = "127.0.0.1"; // or extract from your url
|
|
int port = 8000; // or extract from your url
|
|
|
|
// Connect to server
|
|
if (!client.setup(host, port, false)) {
|
|
return "Error: Could not connect";
|
|
}
|
|
|
|
// Prepare HTTP POST request
|
|
// Build JSON body with all fields
|
|
std::string body = "{\"speaker\":\"" + speaker_ + "\","
|
|
"\"sentence\":\"" + text_ + "\","
|
|
"\"emotion\":\"" + emotion_ + "\","
|
|
"\"temp\":" + ofToString(temp_) + "}";
|
|
|
|
ofLog() << body;
|
|
|
|
std::string request =
|
|
"POST /generate HTTP/1.1\r\n"
|
|
"Host: " + host + "\r\n"
|
|
"Content-Type: application/json\r\n"
|
|
"Content-Length: " + std::to_string(body.size()) + "\r\n"
|
|
"Connection: close\r\n"
|
|
"\r\n" +
|
|
body;
|
|
|
|
client.sendRaw(request);
|
|
|
|
// Wait for response (simple, not robust)
|
|
std::string response;
|
|
uint64_t startTime = ofGetElapsedTimeMillis();
|
|
while (ofGetElapsedTimeMillis() - startTime < 3000) { // 3s timeout
|
|
std::string received = client.receiveRaw();
|
|
if (!received.empty()) {
|
|
response += received;
|
|
}
|
|
if (response.find("\r\n\r\n") != std::string::npos) break; // End of headers
|
|
ofSleepMillis(10);
|
|
}
|
|
client.close();
|
|
|
|
// Extract body (after \r\n\r\n)
|
|
size_t pos = response.find("\r\n\r\n");
|
|
if (pos != std::string::npos) {
|
|
std::string body = response.substr(pos + 4);
|
|
// Optionally parse JSON here
|
|
return body;
|
|
} else {
|
|
return "Error: No response body";
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::string url;
|
|
std::string prompt;
|
|
|
|
std::string speaker;
|
|
std::string text;
|
|
std::string emotion;
|
|
float llmTemperature;
|
|
|
|
std::string result;
|
|
std::condition_variable condition;
|
|
std::mutex mutex;
|
|
std::atomic<bool> resultReady;
|
|
bool hasNewPrompt = false;
|
|
};
|
|
|