Just a temp commit

This commit is contained in:
2026-03-23 08:14:23 +01:00
parent 2a2405ceae
commit c392916af4
19 changed files with 643 additions and 168 deletions

View File

@@ -6,6 +6,8 @@
<properties>
<qtjambi.version>6.10.0</qtjambi.version>
<jackson.version>3.0.3</jackson.version>
<maven.compiler.source>24</maven.compiler.source>
<maven.compiler.release>24</maven.compiler.release>
</properties>
<dependencies>
<dependency>

View File

@@ -1,71 +0,0 @@
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 java.util.function.Consumer;
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<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonNode root = mapper.readTree(response.body());
return root.path("choices").path(0).path("message").path("content").asString();
} catch (IOException | InterruptedException e) {
// NOOP
}
return "";
}
public static void runAsync(OpenAiDto dto, Consumer<String> onResult) {
ObjectMapper mapper = new ObjectMapper();
String jsonBody = mapper.writeValueAsString(dto);
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();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body)
.thenAccept(body -> {
try {
JsonNode root = mapper.readTree(body);
String content = root.path("choices").path(0).path("message").path("content").asString();
onResult.accept(content);
} catch (Exception e) {
onResult.accept("");
}
}).exceptionally(ex -> {
onResult.accept("");
return null;
});
}
}

View File

@@ -1,4 +1,4 @@
package de.derpandaa.aitestsuit;
package de.derpandaa.plinfa;
import io.qt.widgets.QApplication;
import io.qt.widgets.QBoxLayout;
@@ -9,12 +9,9 @@ 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();
public class AiWindow extends QMainWindow {
public AiWindow() {
super();
QWidget widget = new QWidget();
QBoxLayout layout = new QVBoxLayout();
@@ -39,16 +36,23 @@ public class AiWindow {
QPushButton buttonRun = new QPushButton("Run");
buttonRun.clicked.connect(() -> {
String result = ChatGPTApiWrapper.run(editSystemPrompt.getPlainText(), editUserPrompt.getPlainText());
editAiAnser.setText(result);
// String result = AiProviderManager.getAiProviderManager().run(editSystemPrompt.getPlainText(),
// editUserPrompt.getPlainText());
// editAiAnser.setText(result);
});
layout.addWidget(buttonRun);
widget.setLayout(layout);
window.setCentralWidget(widget);
window.show();
setCentralWidget(widget);
show();
}
public static void main(String[] args) {
QApplication.initialize(args);
AiWindow window = new AiWindow();
QApplication.exec();
QApplication.shutdown();
}

View File

@@ -0,0 +1,40 @@
package de.derpandaa.plinfa;
import java.io.File;
import java.util.function.Consumer;
import de.derpandaa.plinfa.dto.ChatDto;
import de.derpandaa.plinfa.projects.GenericProject;
import io.qt.core.Qt;
import io.qt.widgets.QTreeWidget;
import io.qt.widgets.QTreeWidgetItem;
public class ChatListWidget extends QTreeWidget {
public ChatListWidget(Consumer<ChatDto> clickedFunction) {
super();
setHeaderHidden(true);
GenericProject root = new GenericProject(new File(ChatDto.PROJECT_DIR));
loadProject(root, null);
itemClicked.connect((item, column) -> {
ChatDto chat = (ChatDto) item.data(0, Qt.ItemDataRole.UserRole);
if (chat != null) {
clickedFunction.accept(chat);
}
});
}
private void loadProject(GenericProject project, QTreeWidgetItem parent) {
for (GenericProject subProject : project.getSubProjects()) {
QTreeWidgetItem folderItem = parent == null ? new QTreeWidgetItem(this) : new QTreeWidgetItem(parent);
folderItem.setText(0, subProject.getName());
loadProject(subProject, folderItem);
}
for (ChatDto chat : project.getChats()) {
QTreeWidgetItem chatItem = parent == null ? new QTreeWidgetItem(this) : new QTreeWidgetItem(parent);
chatItem.setText(0, chat.getName());
chatItem.setData(0, Qt.ItemDataRole.UserRole, chat);
}
}
}

View File

@@ -1,27 +1,24 @@
package de.derpandaa.aitestsuit;
package de.derpandaa.plinfa;
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.QMetaObject;
import de.derpandaa.plinfa.aiprovider.AiProviderManager;
import de.derpandaa.plinfa.aiprovider.Model;
import de.derpandaa.plinfa.dto.ChatDto;
import de.derpandaa.plinfa.dto.MessageDto;
import de.derpandaa.plinfa.dto.MessageDto.Role;
import de.derpandaa.plinfa.dto.OpenAiDto;
import io.qt.core.QMimeData;
import io.qt.core.Qt.AlignmentFlag;
import io.qt.core.Qt.ConnectionType;
import io.qt.core.Qt.TextFormat;
import io.qt.gui.QColor;
import io.qt.gui.QKeySequence;
import io.qt.gui.QPalette;
import io.qt.gui.QPalette.ColorRole;
import io.qt.gui.QShortcut;
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.QMainWindow;
import io.qt.widgets.QPushButton;
import io.qt.widgets.QScrollArea;
import io.qt.widgets.QSizePolicy;
@@ -30,36 +27,43 @@ import io.qt.widgets.QTextEdit;
import io.qt.widgets.QVBoxLayout;
import io.qt.widgets.QWidget;
public class ChatWindow extends QMainWindow {
public class ChatWindow extends QWidget {
private QBoxLayout layout;
private QVBoxLayout chatLayout;
private QWidget chatWidget;
private QTextEdit textInput;
private OpenAiDto openAiDto;
private ChatDto chatDto;
private QComboBox modelComboBox;
private QScrollArea scrollArea;
public ChatWindow() {
this(new ChatDto());
}
public ChatWindow(ChatDto chatDto) {
super();
openAiDto = new OpenAiDto(Model.gpt5_2, new MessageDto(Role.system, "Antworte kurz und präzise"));
QPalette palette = getPalette();
palette.setColor(ColorRole.Window, PlinfaWindow.colorBackgroundAlt);
setPalette(palette);
this.chatDto = chatDto;
QWidget widget = new QWidget();
layout = new QVBoxLayout();
layout.setContentsMargins(10, 10, 10, 10);
layout = new QVBoxLayout(this);
layout.setContentsMargins(10, 0, 10, 10);
QPushButton button = new QPushButton("Import Chat");
layout.addWidget(button);
QLabel chatNameLabel = new QLabel(chatDto.getName());
layout.addWidget(chatNameLabel);
modelComboBox = new QComboBox();
for (OpenAiDto.Model m : OpenAiDto.Model.values()) {
for (Model m : AiProviderManager.getAiProviderManager().getActiveModels()) {
modelComboBox.addItem(m.toString(), m);
}
layout.addWidget(modelComboBox);
QScrollArea scrollArea = new QScrollArea();
scrollArea = new QScrollArea();
scrollArea.setWidgetResizable(true);
chatWidget = new QWidget();
chatWidget = new QWidget(this);
chatLayout = new QVBoxLayout(chatWidget);
chatLayout.setAlignment(AlignmentFlag.AlignTop);
chatLayout.setSpacing(5);
@@ -85,18 +89,21 @@ public class ChatWindow extends QMainWindow {
inputLayout.addWidget(sendButton);
layout.addLayout(inputLayout);
QShortcut shortcut = new QShortcut(new QKeySequence("Ctrl+Return"), widget);
QShortcut shortcut = new QShortcut(new QKeySequence("Ctrl+Return"), this);
shortcut.activated.connect(() -> sendMessage());
widget.setLayout(layout);
setCentralWidget(widget);
resize(600, 500);
show();
importChat(chatDto);
}
private void importChat(OpenAiDto openAiDto) {
for (MessageDto messageDto : openAiDto.getMessages()) {
// chatLayout.addWidget(createMessage(messageDto.getContent(), true));
private void importChat(ChatDto chatDto) {
if (chatDto.getOpenAiDto().getMessages() == null) {
return;
}
for (MessageDto messageDto : chatDto.getOpenAiDto().getMessages()) {
if (messageDto.getRole() != Role.system) {
chatLayout.addWidget(createMessage(messageDto.getContent(), messageDto.getRole()));
}
}
}
@@ -105,13 +112,14 @@ public class ChatWindow extends QMainWindow {
frame.setFrameShape(QFrame.Shape.Box);
frame.setFrameShadow(QFrame.Shadow.Raised);
// frame.setMaximumWidth(Integer.MAX_VALUE);
frame.setSizePolicy(QSizePolicy.Policy.Maximum, QSizePolicy.Policy.Preferred);
frame.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Maximum);
frame.setMaximumWidth((int) (chatWidget.getMaximumWidth() + 0.7));
QVBoxLayout frameLayout = new QVBoxLayout(frame);
frameLayout.setContentsMargins(10, 10, 10, 10);
QLabel textLabel = new QLabel(message);
textLabel.setTextFormat(TextFormat.MarkdownText);
textLabel.setWordWrap(true);
frameLayout.addWidget(textLabel);
@@ -152,12 +160,17 @@ public class ChatWindow extends QMainWindow {
if (message.isEmpty()) {
return;
}
openAiDto.setModel((Model) modelComboBox.currentData());
OpenAiDto openAiDto = chatDto.getOpenAiDto();
openAiDto.setModel((de.derpandaa.plinfa.aiprovider.Model) modelComboBox.currentData());
MessageDto messageDto = new MessageDto(Role.user, message);
openAiDto.addMessage(messageDto);
chatLayout.addWidget(createMessage(message, Role.user));
QWidget userWidget = createMessage(message, Role.user);
chatLayout.addWidget(userWidget);
scrollArea.ensureWidgetVisible(userWidget);
textInput.clear();
chatWidget.adjustSize();
@@ -166,41 +179,24 @@ public class ChatWindow extends QMainWindow {
chatLayout.addWidget(loadingWidget);
chatWidget.adjustSize();
ChatGPTApiWrapper.runAsync(openAiDto, answer -> {
QMetaObject.invokeMethod(this, () -> {
chatLayout.removeWidget(loadingWidget);
loadingWidget.disposeLater();
openAiDto.addMessage(new MessageDto(Role.assistant, answer));
chatLayout.addWidget(createMessage(answer, Role.assistant));
chatWidget.adjustSize();
}, ConnectionType.QueuedConnection);
// update();
});
}
public static void main(String[] args) {
QApplication.initialize(args);
QApplication.setStyle("Fusion");
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");
// .runAsync(openAiDto, answer -> {
// QMetaObject.invokeMethod(this, () -> {
// chatLayout.removeWidget(loadingWidget);
// loadingWidget.disposeLater();
//
// openAiDto.addMessage(new MessageDto(Role.assistant, answer));
// QWidget assistantWidget = createMessage(answer, Role.assistant);
// chatLayout.addWidget(assistantWidget);
// scrollArea.ensureWidgetVisible(assistantWidget);
// chatWidget.adjustSize();
// chatDto.writeToFile();
//
// }, ConnectionType.QueuedConnection);
// });
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,23 @@
package de.derpandaa.plinfa;
import java.util.function.Consumer;
import io.qt.gui.QIcon;
import io.qt.widgets.QToolBar;
import io.qt.widgets.QToolButton;
public class PlinfaMenu extends QToolBar {
public PlinfaMenu() {
setMaximumHeight(50);
}
public void addButton(QIcon icon, Consumer<Boolean> function, String toolTip) {
QToolButton button = new QToolButton();
button.setIcon(icon);
button.clicked.connect(bool -> function.accept(bool));
button.setToolTip(toolTip);
addWidget(button);
button.setDown(true);
}
}

View File

@@ -0,0 +1,104 @@
package de.derpandaa.plinfa;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import de.derpandaa.plinfa.aiprovider.OpenAiProvider;
import de.derpandaa.plinfa.dto.ChatDto;
import io.qt.gui.QColor;
import io.qt.gui.QIcon;
import io.qt.gui.QPalette;
import io.qt.gui.QPalette.ColorRole;
import io.qt.widgets.QApplication;
import io.qt.widgets.QHBoxLayout;
import io.qt.widgets.QMainWindow;
import io.qt.widgets.QVBoxLayout;
import io.qt.widgets.QWidget;
public class PlinfaWindow extends QMainWindow {
public final static QColor colorBackground = new QColor(40, 42, 46);
public final static QColor colorBackgroundAlt = new QColor(55, 59, 65);
public final static QColor colorForeground = new QColor(208, 208, 208);
private ChatWindow chatWindow;
private QVBoxLayout vLayout;
private QHBoxLayout hLayout;
private PlinfaMenu menuBar;
private Map<ChatDto, ChatWindow> chatMap;
public PlinfaWindow() {
super();
QPalette palette = getPalette();
palette.setColor(ColorRole.Window, colorBackground);
palette.setColor(ColorRole.Base, colorBackgroundAlt);
palette.setColor(ColorRole.Button, colorBackgroundAlt);
palette.setColor(ColorRole.Text, colorForeground);
palette.setColor(ColorRole.ButtonText, colorForeground);
palette.setColor(ColorRole.PlaceholderText, colorForeground);
setPalette(palette);
QWidget mainWidget = new QWidget();
QWidget widget = new QWidget();
vLayout = new QVBoxLayout(mainWidget);
menuBar = new PlinfaMenu();
menuBar.addButton(new QIcon("/usr/share/pandaaPop/img/brightness.svg"), null, "Test");
vLayout.addWidget(menuBar);
hLayout = new QHBoxLayout(widget);
vLayout.addWidget(widget);
ChatListWidget chatListWidget = new ChatListWidget(chat -> loadChat(chat));
hLayout.addWidget(chatListWidget, 1);
chatWindow = new ChatWindow();
hLayout.addWidget(chatWindow, 3);
chatMap = new HashMap<ChatDto, ChatWindow>();
setCentralWidget(mainWidget);
show();
}
public void loadChat(ChatDto chatDto) {
hLayout.removeWidget(chatWindow);
chatWindow.hide();
ChatWindow cachedChatWindow = chatMap.get(chatDto);
if (cachedChatWindow == null) {
cachedChatWindow = new ChatWindow(chatDto);
chatMap.put(chatDto, cachedChatWindow);
}
chatWindow = cachedChatWindow;
hLayout.addWidget(chatWindow, 3);
chatWindow.show();
}
public static void main(String[] args) {
QApplication.initialize(args);
QApplication.setStyle("Fusion");
initProperties();
PlinfaWindow window = new PlinfaWindow();
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);
}
OpenAiProvider.API_KEY = properties.getProperty("OPENAI_KEY");
ChatDto.PROJECT_DIR = properties.getProperty("PROJECT_DIR");
}
}

View File

@@ -0,0 +1,69 @@
package de.derpandaa.plinfa.aiprovider;
import java.io.IOException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.function.Consumer;
import de.derpandaa.plinfa.dto.AiRequest;
import de.derpandaa.plinfa.dto.AiResponseDto;
import de.derpandaa.plinfa.dto.OpenAiDto;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.ObjectMapper;
public abstract class AbstractAiProvider {
public enum Provider {
OPEN_AI
}
protected static final ObjectMapper mapper = new ObjectMapper();
public static String OpenAiKey;
// GPT5_NANO("gpt-5-nano", Provider.OPENAI), GPT5_MINI("gpt-5-mini", Provider.OPENAI),
// GPT5_2("gpt-5.2", Provider.OPENAI), CLAUDE_OPUS("claude-opus-4-6", Provider.ANTHROPIC),
// CLAUDE_SONNET("claude-sonnet-4-6", Provider.ANTHROPIC), CLAUDE_HAIKU("claude-haiku-4-5", Provider.ANTHROPIC);
public abstract List<Model> getModels();
public abstract HttpRequest buildRequest(String jsonBody);
public abstract AiResponseDto parseResponse(String body);
public AiResponseDto run(AiRequest request) {
String jsonBody = mapper.writeValueAsString(request);
System.out.println(jsonBody);
HttpRequest httpRequest = buildRequest(jsonBody);
HttpClient client = HttpClient.newHttpClient();
try {
HttpResponse<String> response = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());
return parseResponse(response.body());
} catch (IOException | InterruptedException e) {
// NOOP
}
return null;
}
public void runAsync(OpenAiDto dto, Consumer<String> onResult) {
String jsonBody = mapper.writeValueAsString(dto);
HttpRequest request = buildRequest(jsonBody);
HttpClient client = HttpClient.newHttpClient();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body)
.thenAccept(body -> {
JsonNode root = mapper.readTree(body);
String content = root.path("choices").path(0).path("message").path("content").asString();
onResult.accept(content);
}).exceptionally(ex -> {
onResult.accept("");
return null;
});
}
}

View File

@@ -0,0 +1,34 @@
package de.derpandaa.plinfa.aiprovider;
import java.util.ArrayList;
import java.util.List;
public class AiProviderManager {
private final List<AbstractAiProvider> providers;
private static AiProviderManager aiProviderManager;
private List<Model> models = new ArrayList<Model>();
public AiProviderManager() {
providers = new ArrayList<AbstractAiProvider>();
if (OpenAiProvider.API_KEY != null) {
providers.add(new OpenAiProvider());
}
}
public static AiProviderManager getAiProviderManager() {
if (aiProviderManager == null) {
aiProviderManager = new AiProviderManager();
}
return aiProviderManager;
}
public List<Model> getActiveModels() {
if (models.isEmpty()) {
for (AbstractAiProvider aiProvider : providers) {
models.addAll(aiProvider.getModels());
}
}
return models;
}
}

View File

@@ -0,0 +1,11 @@
package de.derpandaa.plinfa.aiprovider;
import de.derpandaa.plinfa.aiprovider.AbstractAiProvider.Provider;
public record Model(String modelName, Provider provider) {
@Override
public String toString() {
return modelName;
}
}

View File

@@ -0,0 +1,36 @@
package de.derpandaa.plinfa.aiprovider;
import java.net.URI;
import java.net.http.HttpRequest;
import java.util.List;
import de.derpandaa.plinfa.dto.AiResponseDto;
import de.derpandaa.plinfa.dto.OpenAiResponseDto;
public class OpenAiProvider extends AbstractAiProvider {
public static String API_KEY;
private static int maxTokens;
private static OpenAiProvider openAiProvider;
public OpenAiProvider() {
}
@Override
public HttpRequest buildRequest(String jsonBody) {
return 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();
}
@Override
public List<Model> getModels() {
return List.of(new Model("gpt-5-nano", Provider.OPEN_AI));
}
@Override
public AiResponseDto parseResponse(String body) {
return new OpenAiResponseDto(body);
}
}

View File

@@ -0,0 +1,51 @@
package de.derpandaa.plinfa.dto;
import java.util.ArrayList;
import java.util.List;
import de.derpandaa.plinfa.aiprovider.Model;
public class AiRequest {
private Model model;
private int maxTokens;
private String systemPrompt;
private List<MessageDto> messages;
public AiRequest(Model model) {
this.model = model;
this.maxTokens = 4096;
this.messages = new ArrayList<>();
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
public int getMaxTokens() {
return maxTokens;
}
public void setMaxTokens(int maxTokens) {
this.maxTokens = maxTokens;
}
public String getSystemPrompt() {
return systemPrompt;
}
public void setSystemPrompt(String systemPrompt) {
this.systemPrompt = systemPrompt;
}
public List<MessageDto> getMessages() {
return messages;
}
public void addMessages(MessageDto message) {
messages.add(message);
}
}

View File

@@ -0,0 +1,23 @@
package de.derpandaa.plinfa.dto;
import tools.jackson.databind.ObjectMapper;
public abstract class AiResponseDto {
protected String response;
protected int tokensUsed;
protected ObjectMapper mapper = new ObjectMapper();
public AiResponseDto(String jsonBody) {
parseBody(jsonBody);
}
protected abstract void parseBody(String jsonBody);
public String getResponse() {
return response;
}
public int getTokensUsed() {
return tokensUsed;
}
}

View File

@@ -0,0 +1,17 @@
package de.derpandaa.plinfa.dto;
import tools.jackson.databind.JsonNode;
public class AnthropicResponseDto extends AiResponseDto {
public AnthropicResponseDto(String jsonBody) {
super(jsonBody);
}
@Override
protected void parseBody(String jsonBody) {
JsonNode root = mapper.readTree(jsonBody);
response = root.path("content").path(0).path("text").asString();
tokensUsed = root.path("usage").path("input_tokens").asInt() + root.path("usage").path("output_tokens").asInt();
}
}

View File

@@ -0,0 +1,60 @@
package de.derpandaa.plinfa.dto;
import java.io.File;
import tools.jackson.core.JacksonException;
import tools.jackson.databind.ObjectMapper;
public class ChatDto {
public static String PROJECT_DIR;
private String name;
private OpenAiDto openAiDto;
public ChatDto() {
this.openAiDto = new OpenAiDto();
}
public ChatDto(File f) {
loadFromFile(f);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public OpenAiDto getOpenAiDto() {
return openAiDto;
}
public void setOpenAiDto(OpenAiDto openAiDto) {
this.openAiDto = openAiDto;
}
private void loadFromFile(File f) {
ObjectMapper mapper = new ObjectMapper();
setName(f.getName().substring(0, f.getName().indexOf(".json")));
try {
openAiDto = mapper.readValue(f, OpenAiDto.class);
} catch (JacksonException e) {
e.printStackTrace();
System.out.println("Deserialisierung fehlgeschlagen");
}
}
public void writeToFile() {
if (name == null) {
return;
}
ObjectMapper mapper = new ObjectMapper();
File f = new File(String.format("%s/%s.json", PROJECT_DIR, name));
mapper.writeValue(f.getAbsoluteFile(), openAiDto);
}
}

View File

@@ -1,7 +1,9 @@
package de.derpandaa.aitestsuit;
package de.derpandaa.plinfa.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonPropertyOrder({ "role", "content" })
public class MessageDto {
public enum Role {
@@ -13,6 +15,9 @@ public class MessageDto {
@JsonProperty("content")
private String content;
public MessageDto() {
}
public MessageDto(Role role, String content) {
this.role = role;
this.content = content;
@@ -22,4 +27,8 @@ public class MessageDto {
return content;
}
public Role getRole() {
return role;
}
}

View File

@@ -1,29 +1,17 @@
package de.derpandaa.aitestsuit;
package de.derpandaa.plinfa.dto;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import de.derpandaa.plinfa.aiprovider.Model;
@JsonPropertyOrder({ "model", "messages" })
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;
@@ -31,6 +19,22 @@ public class OpenAiDto {
@JsonProperty("messages")
private List<MessageDto> messages;
@JsonProperty("max_tokens")
private int maxTokens;
public OpenAiDto() {
this(8192);
}
public OpenAiDto(int maxTokens) {
this.maxTokens = maxTokens;
}
public OpenAiDto(Model model) {
this.model = model;
this.messages = new ArrayList<MessageDto>();
}
public OpenAiDto(Model model, MessageDto... messages) {
this.model = model;
this.messages = new ArrayList<MessageDto>();

View File

@@ -0,0 +1,17 @@
package de.derpandaa.plinfa.dto;
import tools.jackson.databind.JsonNode;
public class OpenAiResponseDto extends AiResponseDto {
public OpenAiResponseDto(String jsonBody) {
super(jsonBody);
}
@Override
protected void parseBody(String jsonBody) {
JsonNode root = mapper.readTree(jsonBody);
response = root.path("choices").path(0).path("message").path("content").asString();
tokensUsed = root.path("usage").path("total_tokens").asInt();
}
}

View File

@@ -0,0 +1,46 @@
package de.derpandaa.plinfa.projects;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import de.derpandaa.plinfa.dto.ChatDto;
public class GenericProject {
private String name;
private List<GenericProject> subProjects;
private List<ChatDto> chats;
public GenericProject(File dir) {
this.name = dir.getName();
this.subProjects = new ArrayList<>();
this.chats = new ArrayList<>();
load(dir);
}
private void load(File dir) {
File[] files = dir.listFiles();
if (files == null)
return;
for (File f : files) {
if (f.isDirectory()) {
subProjects.add(new GenericProject(f));
} else if (f.getName().endsWith(".json")) {
chats.add(new ChatDto(f));
}
}
}
public String getName() {
return name;
}
public List<GenericProject> getSubProjects() {
return subProjects;
}
public List<ChatDto> getChats() {
return chats;
}
}