diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aab4095
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.settings
+.classpath
+.project
+target
+*.properties
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..3ba3d16
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,32 @@
+
+ 4.0.0
+ de.derpandaa
+ ai-testsuit
+ 0.0.1-SNAPSHOT
+
+ 6.10.0
+ 3.0.3
+
+
+
+ io.qtjambi
+ qtjambi
+ ${qtjambi.version}
+
+
+ io.qtjambi
+ qtjambi-native-linux-x64
+ ${qtjambi.version}
+
+
+ tools.jackson.core
+ jackson-core
+ ${jackson.version}
+
+
+ tools.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/derpandaa/aitestsuit/AiWindow.java b/src/main/java/de/derpandaa/aitestsuit/AiWindow.java
new file mode 100644
index 0000000..20fc50c
--- /dev/null
+++ b/src/main/java/de/derpandaa/aitestsuit/AiWindow.java
@@ -0,0 +1,56 @@
+package de.derpandaa.aitestsuit;
+
+import io.qt.widgets.QApplication;
+import io.qt.widgets.QBoxLayout;
+import io.qt.widgets.QLabel;
+import io.qt.widgets.QMainWindow;
+import io.qt.widgets.QPushButton;
+import io.qt.widgets.QTextEdit;
+import io.qt.widgets.QVBoxLayout;
+import io.qt.widgets.QWidget;
+
+public class AiWindow {
+
+
+ public static void main(String[] args) {
+ QApplication.initialize(args);
+ QMainWindow window = new QMainWindow();
+ QWidget widget = new QWidget();
+ QBoxLayout layout = new QVBoxLayout();
+
+ QLabel labelSystemPrompt = new QLabel("System Prompt");
+ layout.addWidget(labelSystemPrompt);
+
+ QTextEdit editSystemPrompt = new QTextEdit();
+ layout.addWidget(editSystemPrompt);
+
+ QLabel labelUserPrompt = new QLabel("User Prompt");
+ layout.addWidget(labelUserPrompt);
+
+ QTextEdit editUserPrompt = new QTextEdit();
+ layout.addWidget(editUserPrompt);
+
+ QLabel labelAiAnswer = new QLabel("Ai Answer");
+ layout.addWidget(labelAiAnswer);
+
+ QTextEdit editAiAnser = new QTextEdit();
+ editAiAnser.setEnabled(false);
+ layout.addWidget(editAiAnser);
+
+ QPushButton buttonRun = new QPushButton("Run");
+ buttonRun.clicked.connect(() -> {
+ String result = ChatGPTApiWrapper.run(editSystemPrompt.getPlainText(), editUserPrompt.getPlainText());
+ editAiAnser.setText(result);
+ });
+
+ layout.addWidget(buttonRun);
+
+ widget.setLayout(layout);
+
+ window.setCentralWidget(widget);
+ window.show();
+ QApplication.exec();
+ QApplication.shutdown();
+ }
+
+}
diff --git a/src/main/java/de/derpandaa/aitestsuit/ChatGPTApiWrapper.java b/src/main/java/de/derpandaa/aitestsuit/ChatGPTApiWrapper.java
new file mode 100644
index 0000000..b3e3c10
--- /dev/null
+++ b/src/main/java/de/derpandaa/aitestsuit/ChatGPTApiWrapper.java
@@ -0,0 +1,49 @@
+package de.derpandaa.aitestsuit;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+
+import de.derpandaa.aitestsuit.MessageDto.Role;
+import de.derpandaa.aitestsuit.OpenAiDto.Model;
+import tools.jackson.databind.JsonNode;
+import tools.jackson.databind.ObjectMapper;
+
+/*
+ * I dont know how to name it
+ */
+public class ChatGPTApiWrapper {
+
+ public static String API_KEY;
+
+ public static String run(String systemPrompt, String userPrompt) {
+ OpenAiDto dto = new OpenAiDto(Model.gpt5nano, new MessageDto(Role.system, systemPrompt),
+ new MessageDto(Role.user, userPrompt));
+ return run(dto);
+ }
+
+ public static String run(OpenAiDto dto) {
+ ObjectMapper mapper = new ObjectMapper();
+ String jsonBody = mapper.writeValueAsString(dto);
+
+ System.out.println(jsonBody);
+ HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.openai.com/v1/chat/completions"))
+ .header("Content-Type", "application/json").header("Authorization", "Bearer " + API_KEY)
+ .POST(HttpRequest.BodyPublishers.ofString(jsonBody)).build();
+
+ HttpClient client = HttpClient.newHttpClient();
+ try {
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ System.out.println(response.statusCode());
+ System.out.println(response.body());
+ JsonNode root = mapper.readTree(response.body());
+ return root.path("choices").path(0).path("message").path("content").asString();
+ } catch (IOException | InterruptedException e) {
+ // NOOP
+ }
+ return "";
+ }
+}
+
diff --git a/src/main/java/de/derpandaa/aitestsuit/ChatWindow.java b/src/main/java/de/derpandaa/aitestsuit/ChatWindow.java
new file mode 100644
index 0000000..697dc3f
--- /dev/null
+++ b/src/main/java/de/derpandaa/aitestsuit/ChatWindow.java
@@ -0,0 +1,175 @@
+package de.derpandaa.aitestsuit;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Properties;
+
+import de.derpandaa.aitestsuit.MessageDto.Role;
+import de.derpandaa.aitestsuit.OpenAiDto.Model;
+import io.qt.core.Qt.AlignmentFlag;
+import io.qt.gui.QColor;
+import io.qt.gui.QPalette;
+import io.qt.widgets.QApplication;
+import io.qt.widgets.QBoxLayout;
+import io.qt.widgets.QComboBox;
+import io.qt.widgets.QFrame;
+import io.qt.widgets.QHBoxLayout;
+import io.qt.widgets.QLabel;
+import io.qt.widgets.QLineEdit;
+import io.qt.widgets.QMainWindow;
+import io.qt.widgets.QPushButton;
+import io.qt.widgets.QScrollArea;
+import io.qt.widgets.QVBoxLayout;
+import io.qt.widgets.QWidget;
+
+public class ChatWindow extends QMainWindow {
+
+ private QBoxLayout layout;
+ private QVBoxLayout chatLayout;
+ private QWidget chatWidget;
+ private QLineEdit textInput;
+ private OpenAiDto openAiDto;
+ private QComboBox modelComboBox;
+
+ public ChatWindow() {
+ super();
+ openAiDto = new OpenAiDto(Model.gpt5_2, new MessageDto(Role.system, "Antworte kurz und präzise"));
+
+ QWidget widget = new QWidget();
+ layout = new QVBoxLayout();
+ layout.setContentsMargins(10, 10, 10, 10);
+
+ QPushButton button = new QPushButton("Import Chat");
+ layout.addWidget(button);
+
+ modelComboBox = new QComboBox();
+ for (OpenAiDto.Model m : OpenAiDto.Model.values()) {
+ modelComboBox.addItem(m.toString(), m);
+ }
+ layout.addWidget(modelComboBox);
+
+ QScrollArea scrollArea = new QScrollArea();
+ scrollArea.setWidgetResizable(true);
+
+ chatWidget = new QWidget();
+ chatLayout = new QVBoxLayout(chatWidget);
+ chatLayout.setAlignment(AlignmentFlag.AlignTop);
+ chatLayout.setSpacing(5);
+
+ scrollArea.setWidget(chatWidget);
+ layout.addWidget(scrollArea);
+
+ QHBoxLayout inputLayout = new QHBoxLayout();
+ textInput = new QLineEdit();
+ textInput.setPlaceholderText("Nachricht eingeben...");
+ QPushButton sendButton = new QPushButton("Senden");
+ sendButton.clicked.connect(() -> sendMessage());
+
+ inputLayout.addWidget(textInput);
+ inputLayout.addWidget(sendButton);
+ layout.addLayout(inputLayout);
+
+ widget.setLayout(layout);
+ setCentralWidget(widget);
+ resize(600, 500);
+ show();
+ }
+
+ private void importChat(OpenAiDto openAiDto) {
+ for (MessageDto messageDto : openAiDto.getMessages()) {
+// chatLayout.addWidget(createMessage(messageDto.getContent(), true));
+ }
+ }
+
+ private QWidget createMessage(String message, Role role) {
+ QFrame frame = new QFrame();
+ frame.setFrameShape(QFrame.Shape.Box);
+ frame.setFrameShadow(QFrame.Shadow.Raised);
+
+// frame.setMaximumWidth(Integer.MAX_VALUE);
+// frame.setSizePolicy(QSizePolicy.Policy.Maximum, QSizePolicy.Policy.Preferred);
+
+ QVBoxLayout frameLayout = new QVBoxLayout(frame);
+
+ frameLayout.setContentsMargins(10, 10, 10, 10);
+ QLabel textLabel = new QLabel(message);
+ textLabel.setWordWrap(true);
+ frameLayout.addWidget(textLabel);
+
+ QWidget container = new QWidget();
+ QHBoxLayout boxLayout = new QHBoxLayout(container);
+ boxLayout.setContentsMargins(0, 0, 0, 0);
+
+ QPalette palette = frame.palette();
+ QColor messageColor;
+
+ switch (role) {
+ case user:
+ messageColor = new QColor(209, 114, 246);
+ boxLayout.addStretch(30);
+ boxLayout.addWidget(frame, 70);
+ break;
+ case assistant:
+ messageColor = new QColor(106, 91, 117);
+ boxLayout.addWidget(frame, 70);
+ boxLayout.addStretch(30);
+ break;
+ default:
+ messageColor = new QColor(100, 100, 100);
+ boxLayout.addStretch(15);
+ boxLayout.addWidget(frame, 70);
+ boxLayout.addStretch(15);
+ break;
+ }
+ palette.setColor(QPalette.ColorRole.Window, messageColor);
+ frame.setAutoFillBackground(true);
+ frame.setPalette(palette);
+ return container;
+ }
+
+ private void sendMessage() {
+ String message = textInput.text().trim();
+
+ if (message.isEmpty()) {
+ return;
+ }
+ openAiDto.setModel((Model) modelComboBox.currentData());
+
+ MessageDto messageDto = new MessageDto(Role.user, message);
+ openAiDto.addMessage(messageDto);
+
+ chatLayout.addWidget(createMessage(message, Role.user));
+
+ textInput.clear();
+ chatWidget.adjustSize();
+
+ String answer = ChatGPTApiWrapper.run(openAiDto);
+
+ openAiDto.addMessage(new MessageDto(Role.assistant, answer));
+ chatLayout.addWidget(createMessage(answer, Role.assistant));
+ }
+
+ public static void main(String[] args) {
+ QApplication.initialize(args);
+ initProperties();
+ ChatWindow window = new ChatWindow();
+
+ QApplication.exec();
+ QApplication.shutdown();
+ }
+
+ private static void initProperties() {
+ Properties properties = new Properties();
+ try {
+ properties.load(new FileInputStream("ai.properties"));
+ } catch (FileNotFoundException e) {
+ System.out.println("[ERROR] No Properties File");
+ System.exit(1);
+ } catch (IOException e) {
+ System.out.println("[ERROR] Cannot Access File");
+ System.exit(1);
+ }
+ ChatGPTApiWrapper.API_KEY = properties.getProperty("OPENAI_KEY");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/derpandaa/aitestsuit/MessageDto.java b/src/main/java/de/derpandaa/aitestsuit/MessageDto.java
new file mode 100644
index 0000000..7ba996a
--- /dev/null
+++ b/src/main/java/de/derpandaa/aitestsuit/MessageDto.java
@@ -0,0 +1,25 @@
+package de.derpandaa.aitestsuit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class MessageDto {
+
+ public enum Role {
+ system, user, assistant
+ };
+
+ @JsonProperty("role")
+ private Role role;
+ @JsonProperty("content")
+ private String content;
+
+ public MessageDto(Role role, String content) {
+ this.role = role;
+ this.content = content;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+}
diff --git a/src/main/java/de/derpandaa/aitestsuit/OpenAiDto.java b/src/main/java/de/derpandaa/aitestsuit/OpenAiDto.java
new file mode 100644
index 0000000..2f4f14a
--- /dev/null
+++ b/src/main/java/de/derpandaa/aitestsuit/OpenAiDto.java
@@ -0,0 +1,52 @@
+package de.derpandaa.aitestsuit;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class OpenAiDto {
+
+ public enum Model {
+ gpt5nano("gpt-5-nano"),
+ gpt5mini("gpt-5-mini"),
+ gpt5_2("gpt-5.2");
+
+ final String value;
+
+ Model(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+ }
+
+ @JsonProperty("model")
+ private Model model;
+
+ @JsonProperty("messages")
+ private List messages;
+
+ public OpenAiDto(Model model, MessageDto... messages) {
+ this.model = model;
+ this.messages = new ArrayList();
+ this.messages.addAll(Arrays.asList(messages));
+ }
+
+ public void addMessage(MessageDto messageDto) {
+ messages.add(messageDto);
+ }
+
+ public List getMessages() {
+ return messages;
+ }
+
+ public void setModel(Model model) {
+ this.model = model;
+ }
+
+}