Just a temp commit
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -6,6 +6,8 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<qtjambi.version>6.10.0</qtjambi.version>
|
<qtjambi.version>6.10.0</qtjambi.version>
|
||||||
<jackson.version>3.0.3</jackson.version>
|
<jackson.version>3.0.3</jackson.version>
|
||||||
|
<maven.compiler.source>24</maven.compiler.source>
|
||||||
|
<maven.compiler.release>24</maven.compiler.release>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package de.derpandaa.aitestsuit;
|
package de.derpandaa.plinfa;
|
||||||
|
|
||||||
import io.qt.widgets.QApplication;
|
import io.qt.widgets.QApplication;
|
||||||
import io.qt.widgets.QBoxLayout;
|
import io.qt.widgets.QBoxLayout;
|
||||||
@@ -9,12 +9,9 @@ import io.qt.widgets.QTextEdit;
|
|||||||
import io.qt.widgets.QVBoxLayout;
|
import io.qt.widgets.QVBoxLayout;
|
||||||
import io.qt.widgets.QWidget;
|
import io.qt.widgets.QWidget;
|
||||||
|
|
||||||
public class AiWindow {
|
public class AiWindow extends QMainWindow {
|
||||||
|
public AiWindow() {
|
||||||
|
super();
|
||||||
public static void main(String[] args) {
|
|
||||||
QApplication.initialize(args);
|
|
||||||
QMainWindow window = new QMainWindow();
|
|
||||||
QWidget widget = new QWidget();
|
QWidget widget = new QWidget();
|
||||||
QBoxLayout layout = new QVBoxLayout();
|
QBoxLayout layout = new QVBoxLayout();
|
||||||
|
|
||||||
@@ -39,16 +36,23 @@ public class AiWindow {
|
|||||||
|
|
||||||
QPushButton buttonRun = new QPushButton("Run");
|
QPushButton buttonRun = new QPushButton("Run");
|
||||||
buttonRun.clicked.connect(() -> {
|
buttonRun.clicked.connect(() -> {
|
||||||
String result = ChatGPTApiWrapper.run(editSystemPrompt.getPlainText(), editUserPrompt.getPlainText());
|
// String result = AiProviderManager.getAiProviderManager().run(editSystemPrompt.getPlainText(),
|
||||||
editAiAnser.setText(result);
|
// editUserPrompt.getPlainText());
|
||||||
|
// editAiAnser.setText(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
layout.addWidget(buttonRun);
|
layout.addWidget(buttonRun);
|
||||||
|
|
||||||
widget.setLayout(layout);
|
widget.setLayout(layout);
|
||||||
|
|
||||||
window.setCentralWidget(widget);
|
setCentralWidget(widget);
|
||||||
window.show();
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
QApplication.initialize(args);
|
||||||
|
AiWindow window = new AiWindow();
|
||||||
|
|
||||||
QApplication.exec();
|
QApplication.exec();
|
||||||
QApplication.shutdown();
|
QApplication.shutdown();
|
||||||
}
|
}
|
||||||
40
src/main/java/de/derpandaa/plinfa/ChatListWidget.java
Normal file
40
src/main/java/de/derpandaa/plinfa/ChatListWidget.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +1,24 @@
|
|||||||
package de.derpandaa.aitestsuit;
|
package de.derpandaa.plinfa;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import de.derpandaa.plinfa.aiprovider.AiProviderManager;
|
||||||
import java.io.FileNotFoundException;
|
import de.derpandaa.plinfa.aiprovider.Model;
|
||||||
import java.io.IOException;
|
import de.derpandaa.plinfa.dto.ChatDto;
|
||||||
import java.util.Properties;
|
import de.derpandaa.plinfa.dto.MessageDto;
|
||||||
|
import de.derpandaa.plinfa.dto.MessageDto.Role;
|
||||||
import de.derpandaa.aitestsuit.MessageDto.Role;
|
import de.derpandaa.plinfa.dto.OpenAiDto;
|
||||||
import de.derpandaa.aitestsuit.OpenAiDto.Model;
|
|
||||||
import io.qt.core.QMetaObject;
|
|
||||||
import io.qt.core.QMimeData;
|
import io.qt.core.QMimeData;
|
||||||
import io.qt.core.Qt.AlignmentFlag;
|
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.QColor;
|
||||||
import io.qt.gui.QKeySequence;
|
import io.qt.gui.QKeySequence;
|
||||||
import io.qt.gui.QPalette;
|
import io.qt.gui.QPalette;
|
||||||
|
import io.qt.gui.QPalette.ColorRole;
|
||||||
import io.qt.gui.QShortcut;
|
import io.qt.gui.QShortcut;
|
||||||
import io.qt.widgets.QApplication;
|
|
||||||
import io.qt.widgets.QBoxLayout;
|
import io.qt.widgets.QBoxLayout;
|
||||||
import io.qt.widgets.QComboBox;
|
import io.qt.widgets.QComboBox;
|
||||||
import io.qt.widgets.QFrame;
|
import io.qt.widgets.QFrame;
|
||||||
import io.qt.widgets.QHBoxLayout;
|
import io.qt.widgets.QHBoxLayout;
|
||||||
import io.qt.widgets.QLabel;
|
import io.qt.widgets.QLabel;
|
||||||
import io.qt.widgets.QMainWindow;
|
|
||||||
import io.qt.widgets.QPushButton;
|
import io.qt.widgets.QPushButton;
|
||||||
import io.qt.widgets.QScrollArea;
|
import io.qt.widgets.QScrollArea;
|
||||||
import io.qt.widgets.QSizePolicy;
|
import io.qt.widgets.QSizePolicy;
|
||||||
@@ -30,36 +27,43 @@ import io.qt.widgets.QTextEdit;
|
|||||||
import io.qt.widgets.QVBoxLayout;
|
import io.qt.widgets.QVBoxLayout;
|
||||||
import io.qt.widgets.QWidget;
|
import io.qt.widgets.QWidget;
|
||||||
|
|
||||||
public class ChatWindow extends QMainWindow {
|
public class ChatWindow extends QWidget {
|
||||||
|
|
||||||
private QBoxLayout layout;
|
private QBoxLayout layout;
|
||||||
private QVBoxLayout chatLayout;
|
private QVBoxLayout chatLayout;
|
||||||
private QWidget chatWidget;
|
private QWidget chatWidget;
|
||||||
private QTextEdit textInput;
|
private QTextEdit textInput;
|
||||||
private OpenAiDto openAiDto;
|
private ChatDto chatDto;
|
||||||
private QComboBox modelComboBox;
|
private QComboBox modelComboBox;
|
||||||
|
private QScrollArea scrollArea;
|
||||||
|
|
||||||
public ChatWindow() {
|
public ChatWindow() {
|
||||||
|
this(new ChatDto());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatWindow(ChatDto chatDto) {
|
||||||
super();
|
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(this);
|
||||||
layout = new QVBoxLayout();
|
layout.setContentsMargins(10, 0, 10, 10);
|
||||||
layout.setContentsMargins(10, 10, 10, 10);
|
|
||||||
|
|
||||||
QPushButton button = new QPushButton("Import Chat");
|
QLabel chatNameLabel = new QLabel(chatDto.getName());
|
||||||
layout.addWidget(button);
|
layout.addWidget(chatNameLabel);
|
||||||
|
|
||||||
modelComboBox = new QComboBox();
|
modelComboBox = new QComboBox();
|
||||||
for (OpenAiDto.Model m : OpenAiDto.Model.values()) {
|
for (Model m : AiProviderManager.getAiProviderManager().getActiveModels()) {
|
||||||
modelComboBox.addItem(m.toString(), m);
|
modelComboBox.addItem(m.toString(), m);
|
||||||
}
|
}
|
||||||
layout.addWidget(modelComboBox);
|
layout.addWidget(modelComboBox);
|
||||||
|
|
||||||
QScrollArea scrollArea = new QScrollArea();
|
scrollArea = new QScrollArea();
|
||||||
scrollArea.setWidgetResizable(true);
|
scrollArea.setWidgetResizable(true);
|
||||||
|
|
||||||
chatWidget = new QWidget();
|
chatWidget = new QWidget(this);
|
||||||
chatLayout = new QVBoxLayout(chatWidget);
|
chatLayout = new QVBoxLayout(chatWidget);
|
||||||
chatLayout.setAlignment(AlignmentFlag.AlignTop);
|
chatLayout.setAlignment(AlignmentFlag.AlignTop);
|
||||||
chatLayout.setSpacing(5);
|
chatLayout.setSpacing(5);
|
||||||
@@ -85,18 +89,21 @@ public class ChatWindow extends QMainWindow {
|
|||||||
inputLayout.addWidget(sendButton);
|
inputLayout.addWidget(sendButton);
|
||||||
layout.addLayout(inputLayout);
|
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());
|
shortcut.activated.connect(() -> sendMessage());
|
||||||
|
|
||||||
widget.setLayout(layout);
|
|
||||||
setCentralWidget(widget);
|
|
||||||
resize(600, 500);
|
resize(600, 500);
|
||||||
show();
|
importChat(chatDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importChat(OpenAiDto openAiDto) {
|
private void importChat(ChatDto chatDto) {
|
||||||
for (MessageDto messageDto : openAiDto.getMessages()) {
|
if (chatDto.getOpenAiDto().getMessages() == null) {
|
||||||
// chatLayout.addWidget(createMessage(messageDto.getContent(), true));
|
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.setFrameShape(QFrame.Shape.Box);
|
||||||
frame.setFrameShadow(QFrame.Shadow.Raised);
|
frame.setFrameShadow(QFrame.Shadow.Raised);
|
||||||
|
|
||||||
// frame.setMaximumWidth(Integer.MAX_VALUE);
|
frame.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Maximum);
|
||||||
frame.setSizePolicy(QSizePolicy.Policy.Maximum, QSizePolicy.Policy.Preferred);
|
frame.setMaximumWidth((int) (chatWidget.getMaximumWidth() + 0.7));
|
||||||
|
|
||||||
QVBoxLayout frameLayout = new QVBoxLayout(frame);
|
QVBoxLayout frameLayout = new QVBoxLayout(frame);
|
||||||
|
|
||||||
frameLayout.setContentsMargins(10, 10, 10, 10);
|
frameLayout.setContentsMargins(10, 10, 10, 10);
|
||||||
QLabel textLabel = new QLabel(message);
|
QLabel textLabel = new QLabel(message);
|
||||||
|
textLabel.setTextFormat(TextFormat.MarkdownText);
|
||||||
textLabel.setWordWrap(true);
|
textLabel.setWordWrap(true);
|
||||||
frameLayout.addWidget(textLabel);
|
frameLayout.addWidget(textLabel);
|
||||||
|
|
||||||
@@ -152,12 +160,17 @@ public class ChatWindow extends QMainWindow {
|
|||||||
if (message.isEmpty()) {
|
if (message.isEmpty()) {
|
||||||
return;
|
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);
|
MessageDto messageDto = new MessageDto(Role.user, message);
|
||||||
openAiDto.addMessage(messageDto);
|
openAiDto.addMessage(messageDto);
|
||||||
|
|
||||||
chatLayout.addWidget(createMessage(message, Role.user));
|
QWidget userWidget = createMessage(message, Role.user);
|
||||||
|
chatLayout.addWidget(userWidget);
|
||||||
|
scrollArea.ensureWidgetVisible(userWidget);
|
||||||
|
|
||||||
textInput.clear();
|
textInput.clear();
|
||||||
chatWidget.adjustSize();
|
chatWidget.adjustSize();
|
||||||
@@ -166,41 +179,24 @@ public class ChatWindow extends QMainWindow {
|
|||||||
chatLayout.addWidget(loadingWidget);
|
chatLayout.addWidget(loadingWidget);
|
||||||
chatWidget.adjustSize();
|
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 {
|
try {
|
||||||
properties.load(new FileInputStream("ai.properties"));
|
// .runAsync(openAiDto, answer -> {
|
||||||
} catch (FileNotFoundException e) {
|
// QMetaObject.invokeMethod(this, () -> {
|
||||||
System.out.println("[ERROR] No Properties File");
|
// chatLayout.removeWidget(loadingWidget);
|
||||||
System.exit(1);
|
// loadingWidget.disposeLater();
|
||||||
} catch (IOException e) {
|
//
|
||||||
System.out.println("[ERROR] Cannot Access File");
|
// openAiDto.addMessage(new MessageDto(Role.assistant, answer));
|
||||||
System.exit(1);
|
// 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();
|
||||||
}
|
}
|
||||||
ChatGPTApiWrapper.API_KEY = properties.getProperty("OPENAI_KEY");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
23
src/main/java/de/derpandaa/plinfa/PlinfaMenu.java
Normal file
23
src/main/java/de/derpandaa/plinfa/PlinfaMenu.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
src/main/java/de/derpandaa/plinfa/PlinfaWindow.java
Normal file
104
src/main/java/de/derpandaa/plinfa/PlinfaWindow.java
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
11
src/main/java/de/derpandaa/plinfa/aiprovider/Model.java
Normal file
11
src/main/java/de/derpandaa/plinfa/aiprovider/Model.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
51
src/main/java/de/derpandaa/plinfa/dto/AiRequest.java
Normal file
51
src/main/java/de/derpandaa/plinfa/dto/AiRequest.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/main/java/de/derpandaa/plinfa/dto/AiResponseDto.java
Normal file
23
src/main/java/de/derpandaa/plinfa/dto/AiResponseDto.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
60
src/main/java/de/derpandaa/plinfa/dto/ChatDto.java
Normal file
60
src/main/java/de/derpandaa/plinfa/dto/ChatDto.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package de.derpandaa.aitestsuit;
|
package de.derpandaa.plinfa.dto;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||||
|
|
||||||
|
@JsonPropertyOrder({ "role", "content" })
|
||||||
public class MessageDto {
|
public class MessageDto {
|
||||||
|
|
||||||
public enum Role {
|
public enum Role {
|
||||||
@@ -13,6 +15,9 @@ public class MessageDto {
|
|||||||
@JsonProperty("content")
|
@JsonProperty("content")
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
|
public MessageDto() {
|
||||||
|
}
|
||||||
|
|
||||||
public MessageDto(Role role, String content) {
|
public MessageDto(Role role, String content) {
|
||||||
this.role = role;
|
this.role = role;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
@@ -22,4 +27,8 @@ public class MessageDto {
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Role getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,17 @@
|
|||||||
package de.derpandaa.aitestsuit;
|
package de.derpandaa.plinfa.dto;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
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 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")
|
@JsonProperty("model")
|
||||||
private Model model;
|
private Model model;
|
||||||
@@ -31,6 +19,22 @@ public class OpenAiDto {
|
|||||||
@JsonProperty("messages")
|
@JsonProperty("messages")
|
||||||
private List<MessageDto> 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) {
|
public OpenAiDto(Model model, MessageDto... messages) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.messages = new ArrayList<MessageDto>();
|
this.messages = new ArrayList<MessageDto>();
|
||||||
17
src/main/java/de/derpandaa/plinfa/dto/OpenAiResponseDto.java
Normal file
17
src/main/java/de/derpandaa/plinfa/dto/OpenAiResponseDto.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user