FER Macbeth Project
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

#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;
};