diff --git a/.gitignore b/.gitignore index 728cbdc..4fd0163 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,5 @@ bin/ /pythonFiles/ /messages/ /logs/ -/cache/ +/data/ +/cache/ \ No newline at end of file diff --git a/API/src/main/java/me/zacharias/chat/api/APICodes.java b/API/src/main/java/me/zacharias/chat/api/APICodes.java new file mode 100644 index 0000000..08a452f --- /dev/null +++ b/API/src/main/java/me/zacharias/chat/api/APICodes.java @@ -0,0 +1,8 @@ +package me.zacharias.chat.api; + +public enum APICodes { + CREDENTIALS, + ERROR, + API, + SUCCESS, +} diff --git a/API/src/main/java/me/zacharias/chat/api/APIEndpoints.java b/API/src/main/java/me/zacharias/chat/api/APIEndpoints.java index 80a4aaf..45405c2 100644 --- a/API/src/main/java/me/zacharias/chat/api/APIEndpoints.java +++ b/API/src/main/java/me/zacharias/chat/api/APIEndpoints.java @@ -25,4 +25,9 @@ public enum APIEndpoints { */ USE_TOOL, + // API endpoints that doesn't require credentials even if the server has them required + /** + * Returns info about the server + */ + INFO } diff --git a/API/src/main/java/me/zacharias/chat/api/APIErrorCodes.java b/API/src/main/java/me/zacharias/chat/api/APIErrorCodes.java new file mode 100644 index 0000000..04250db --- /dev/null +++ b/API/src/main/java/me/zacharias/chat/api/APIErrorCodes.java @@ -0,0 +1,19 @@ +package me.zacharias.chat.api; + +public enum APIErrorCodes { + /** + * If the format is not a JSON or not having the expected JSON keys present + */ + FORMAT_ERROR, + + /** + * An error with credentials
+ * Can be that the credentials is not matching or other credentials related issue + */ + CREDENTIALS_ERROR, + + /** + * An error describing that the APIEndpoint is unavailable, invalid, or related issue + */ + API_ERROR, +} diff --git a/API/src/main/java/me/zacharias/chat/api/APIServer.java b/API/src/main/java/me/zacharias/chat/api/APIServer.java deleted file mode 100644 index 478aadb..0000000 --- a/API/src/main/java/me/zacharias/chat/api/APIServer.java +++ /dev/null @@ -1,164 +0,0 @@ -package me.zacharias.chat.api; - -import me.zacharias.chat.core.Core; -import me.zacharias.chat.core.LaunchOptions; -import me.zacharias.chat.core.PrintMessageHandler; -import me.zacharias.chat.ollama.OllamaObject; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.ServerSocket; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Date; -import java.util.Scanner; - -/** - * The API server.
- * This class is responsible for handling the server socket and the clients for the API.
- * It also handles the output redirection and the message printing.
- * And the Registration of Tools on the {@link Core} object. - */ -public class APIServer { - /** - * The list of clients connected to the server. - */ - ArrayList clientsList = new ArrayList<>(); - /** - * The server socket. - */ - ServerSocket serverSocket; - /** - * The output stream for the server. - */ - PrintStream dataOut; - - /** - * The message handler for the server. - */ - PrintMessageHandler printMessageHandler = new PrintMessageHandler() { - @Override - public void printMessage(String message) { - - synchronized (clientsList) { - for (Client client : clientsList) { - boolean success = client.sendMessage(message); - if (!success) { - clientsList.remove(client); - continue; - } - } - } - } - - @Override - public boolean color() { - return false; - } - }; - - /** - * The core object for the server. - */ - Core core = new Core(printMessageHandler); - - /** - * Options for this is expected to be passed through the {@link LaunchOptions#instance} object.
- * Used objects:
- * - {@link LaunchOptions#autoAccept}
- * - {@link LaunchOptions#redirectOutput}
- * - {@link LaunchOptions#port}
- */ - public APIServer() { - LaunchOptions options = LaunchOptions.getInstance(); - String redirectedOutput = options.getRedirectOutput(); - int port = options.getPort(); - - core.setOllamaObject(OllamaObject.builder() - .setModel("llama3-AI") - .keep_alive(10) - //.stream(false) - .build()); - - if (redirectedOutput != null && !Paths.get(redirectedOutput).toFile().getParentFile().exists()) { - System.out.println("Failed to be able to open the redirected output file due to missing directory"); - } - else { - redirectedOutput = "./out.txt"; - } - - File f = new File(redirectedOutput); - - try { - if (f.exists()) { - System.out.println("Output already exists"); - System.out.print("Overwrite the existing output file? [y/N]: "); - Scanner sc = new Scanner(System.in); - char c; - - if (options.isAutoAccept()) { - c = 'y'; - } else { - String s = sc.nextLine(); - c = s.isBlank() ? 'n' : s.charAt(0); - } - - if (Character.toLowerCase(c) == 'y') { - f.delete(); - f.createNewFile(); - dataOut = new PrintStream(new FileOutputStream(f), true); - } else { - System.out.print("Rename existing output file? [y/N]: "); - String s = sc.nextLine(); - c = s.isBlank() ? 'n' : s.charAt(0); - if (c == 'y') { - System.out.println("New file name for [" + f.getName() + "]: "); - File newFile = new File(f.getParentFile(), sc.nextLine().trim()); - if (f.renameTo(newFile)) { - System.out.println("Old file placed in [" + newFile.getPath() + "]"); - f = new File(redirectedOutput); - } else { - System.out.println("Failed to rename file. Proceeding with appending data."); - } - if (f.exists()) { - f.delete(); - } - f.createNewFile(); - dataOut = new PrintStream(new FileOutputStream(f), true); - } else { - System.out.print("Appending new data to [" + f.getPath() + "]"); - dataOut = new PrintStream(new FileOutputStream(f, true), true); - Date date = new Date(); - dataOut.println("\n\nNew instance started at: " + date.toString() + "\n"); - } - } - sc.close(); - } else { - f.createNewFile(); - dataOut = new PrintStream(new FileOutputStream(f, true), true); - } - } - catch (Exception e) { - e.printStackTrace(); - System.exit(1); - return; - } - - System.out.println("Redirecting output to [" + redirectedOutput + "]"); - System.out.println("Starting server on port [" + port + "]"); - - try{ - serverSocket = new ServerSocket(port); - - } - catch(Exception e){ - System.out.println("Failed to start server on port [" + port + "]"); - System.exit(1); - return; - } - - //serverSocket = new ServerSocket(port); - } -} diff --git a/API/src/main/java/me/zacharias/chat/api/client/APIClient.java b/API/src/main/java/me/zacharias/chat/api/client/APIClient.java new file mode 100644 index 0000000..69d3e83 --- /dev/null +++ b/API/src/main/java/me/zacharias/chat/api/client/APIClient.java @@ -0,0 +1,4 @@ +package me.zacharias.chat.api.client; + +public class APIClient { +} diff --git a/API/src/main/java/me/zacharias/chat/api/server/APIServer.java b/API/src/main/java/me/zacharias/chat/api/server/APIServer.java new file mode 100644 index 0000000..ad1ac99 --- /dev/null +++ b/API/src/main/java/me/zacharias/chat/api/server/APIServer.java @@ -0,0 +1,329 @@ +package me.zacharias.chat.api.server; + +import me.zacharias.chat.api.APICodes; +import me.zacharias.chat.api.APIEndpoints; +import me.zacharias.chat.api.APIErrorCodes; +import me.zacharias.chat.core.Core; +import me.zacharias.chat.core.LaunchOptions; +import me.zacharias.chat.core.PrintMessageHandler; +import me.zacharias.chat.ollama.OllamaObject; +import org.json.JSONObject; + +import java.io.*; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Date; +import java.util.Objects; +import java.util.Scanner; + +import static me.zacharias.chat.api.APIErrorCodes.*; + +/** + * The API server.
+ * This class is responsible for handling the server socket and the clients for the API.
+ * It also handles the output redirection and the message printing.
+ * And the Registration of Tools on the {@link Core} object. + */ +public class APIServer { + /** + * The list of clients connected to the server. + */ + ArrayList clientsList = new ArrayList<>(); + /** + * The server socket. + */ + ServerSocket serverSocket; + + Thread clientAcceptThread = new Thread(() -> { + while (true) { + try{ + Socket s = serverSocket.accept(); + BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); + PrintWriter out = new PrintWriter(s.getOutputStream(), true); + + JSONObject outObj = new JSONObject(); + + if(in.ready()) { + String line = in.readLine(); + JSONObject obj; + try{ + obj = new JSONObject(line); + }catch(Exception e){ + errorOutClient(out,"Invalid JSON object", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + if(!obj.has("code")) + { + errorOutClient(out, "Missing APICode", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + if(obj.getEnum(APICodes.class, "code") != APICodes.API) + { + errorOutClient(out, "Invalid APICode", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + if(!obj.has("api")) + { + errorOutClient(out, "Missing API", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + JSONObject apiObj = obj.getJSONObject("api"); + + if(!apiObj.has("code")) + { + errorOutClient(out, "Missing APIEndpoint", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + APIEndpoints apiEndpoint; + + if((apiEndpoint = apiObj.getEnum(APIEndpoints.class, "code")) != APIEndpoints.INFO) + { + errorOutClient(out, "APIEndpoint \""+apiEndpoint+"\" requires setup", API_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + outObj.put("code", APICodes.API); + JSONObject endpointObj = new JSONObject(); + + JSONObject infoObj = new JSONObject(); + infoObj.put("requires_credentials", LaunchOptions.getInstance().isServerCredentialsEnabled()); + + endpointObj.put("message", infoObj); + + outObj.put("api", endpointObj); + + out.println(outObj); + s.shutdownOutput(); + s.close(); + continue; + } + + if(LaunchOptions.getInstance().isServerCredentialsEnabled()) + { + outObj.put("code", APICodes.CREDENTIALS); + out.println(outObj); + + String line = in.readLine(); + JSONObject lineObj; + try{ + lineObj = new JSONObject(line); + }catch(Exception e) + { + errorOutClient(out, "Missing credentials or Incorrect format", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + if(!lineObj.has("code")) + { + errorOutClient(out, "Missing APICode", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + if(!(lineObj.getEnum(APICodes.class, "code") == APICodes.CREDENTIALS)) + { + errorOutClient(out, "Missing Credentials", CREDENTIALS_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + if(!lineObj.has("credentials")) + { + errorOutClient(out, "Missing Credentials", FORMAT_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + if(!Objects.equals(lineObj.getString("credentials"), LaunchOptions.getInstance().getServerCredentials())) + { + errorOutClient(out, "Invalid Credentials", CREDENTIALS_ERROR); + s.shutdownOutput(); + s.close(); + continue; + } + + outObj = new JSONObject(); + outObj.put("code", APICodes.SUCCESS); + out.println(outObj); + clientsList.add(new Client(s)); + continue; + } + else + { + outObj.put("code", APICodes.SUCCESS); + out.println(outObj); + clientsList.add(new Client(s)); + continue; + } + }catch(Exception e) { + + } + } + }); + + /** + * The output stream for the server. + */ + PrintStream dataOut; + + /** + * The message handler for the server. + */ + PrintMessageHandler printMessageHandler = new PrintMessageHandler() { + @Override + public void printMessage(String message) { + + synchronized (clientsList) { + for (Client client : clientsList) { + boolean success = client.sendMessage(message); + if (!success) { + clientsList.remove(client); + continue; + } + } + } + } + + @Override + public boolean color() { + return false; + } + }; + + /** + * The core object for the server. + */ + Core core = new Core(printMessageHandler); + + /** + * Options for this is expected to be passed through the {@link LaunchOptions#instance} object.
+ * Used objects:
+ * - {@link LaunchOptions#autoAccept}
+ * - {@link LaunchOptions#redirectOutput}
+ * - {@link LaunchOptions#port}
+ */ + public APIServer() { + LaunchOptions options = LaunchOptions.getInstance(); + String redirectedOutput = options.getRedirectOutput(); + int port = options.getPort(); + + core.setOllamaObject(OllamaObject.builder() + .setModel("llama3-AI") + .keep_alive(10) + //.stream(false) + .build()); + + if (redirectedOutput != null && !Paths.get(redirectedOutput).toFile().getParentFile().exists()) { + System.out.println("Failed to be able to open the redirected output file due to missing directory"); + } + else { + redirectedOutput = "./out.txt"; + } + + File f = new File(redirectedOutput); + + try { + if (f.exists()) { + System.out.println("Output already exists"); + System.out.print("Overwrite the existing output file? [y/N]: "); + Scanner sc = new Scanner(System.in); + char c; + + if (options.isAutoAccept()) { + c = 'y'; + } else { + String s = sc.nextLine(); + c = s.isBlank() ? 'n' : s.charAt(0); + } + + if (Character.toLowerCase(c) == 'y') { + f.delete(); + f.createNewFile(); + dataOut = new PrintStream(new FileOutputStream(f), true); + } else { + System.out.print("Rename existing output file? [y/N]: "); + String s = sc.nextLine(); + c = s.isBlank() ? 'n' : s.charAt(0); + if (c == 'y') { + System.out.println("New file name for [" + f.getName() + "]: "); + File newFile = new File(f.getParentFile(), sc.nextLine().trim()); + if (f.renameTo(newFile)) { + System.out.println("Old file placed in [" + newFile.getPath() + "]"); + f = new File(redirectedOutput); + } else { + System.out.println("Failed to rename file. Proceeding with appending data."); + } + if (f.exists()) { + f.delete(); + } + f.createNewFile(); + dataOut = new PrintStream(new FileOutputStream(f), true); + } else { + System.out.print("Appending new data to [" + f.getPath() + "]"); + dataOut = new PrintStream(new FileOutputStream(f, true), true); + Date date = new Date(); + dataOut.println("\n\nNew instance started at: " + date.toString() + "\n"); + } + } + sc.close(); + } else { + f.createNewFile(); + dataOut = new PrintStream(new FileOutputStream(f, true), true); + } + } + catch (Exception e) { + e.printStackTrace(); + System.exit(1); + return; + } + + System.out.println("Redirecting output to [" + redirectedOutput + "]"); + System.out.println("Starting server on port [" + port + "]"); + + try{ + serverSocket = new ServerSocket(port); + + } + catch(Exception e){ + System.out.println("Failed to start server on port [" + port + "]"); + System.exit(1); + return; + } + + //serverSocket = new ServerSocket(port); + } + + private void errorOutClient(PrintWriter writer, String errorMessage, APIErrorCodes apiErrorCodes) { + JSONObject outObj = new JSONObject(); + outObj.put("code", APICodes.ERROR); + JSONObject errObj = new JSONObject(); + errObj.put("code", apiErrorCodes); + errObj.put("message", errorMessage); + outObj.put("error", errObj); + writer.println(outObj); + } +} diff --git a/API/src/main/java/me/zacharias/chat/api/Client.java b/API/src/main/java/me/zacharias/chat/api/server/Client.java similarity index 95% rename from API/src/main/java/me/zacharias/chat/api/Client.java rename to API/src/main/java/me/zacharias/chat/api/server/Client.java index c22bc23..3e62a79 100644 --- a/API/src/main/java/me/zacharias/chat/api/Client.java +++ b/API/src/main/java/me/zacharias/chat/api/server/Client.java @@ -1,4 +1,4 @@ -package me.zacharias.chat.api; +package me.zacharias.chat.api.server; import java.io.BufferedWriter; import java.io.OutputStreamWriter; diff --git a/Core/src/main/java/me/zacharias/chat/core/Core.java b/Core/src/main/java/me/zacharias/chat/core/Core.java index a5aa706..a08a205 100644 --- a/Core/src/main/java/me/zacharias/chat/core/Core.java +++ b/Core/src/main/java/me/zacharias/chat/core/Core.java @@ -67,6 +67,39 @@ public class Core { */ private boolean supportColor; + public static final String DATA; + public static final File DATA_DIR; + + static { + String data; + + if(System.getenv("AI-CHAT-DEBUG") != null) { + data = "./data"; + } + else if(System.getProperty("os.name").toLowerCase().contains("windows")) { + String localappdata = System.getenv("LOCALAPPDATA"); + if(localappdata == null) { + localappdata = System.getenv("APPDATA"); + } + data = localappdata + "/AI-CHAT"; + } + else if (System.getProperty("os.name").toLowerCase().contains("linux")) { + data = System.getenv("HOME") + "/.local/share/AI-CHAT"; + } + else if (System.getProperty("os.name").toLowerCase().contains("mac")) { + data = System.getProperty("user.home") + "/Library/Application Support/AI-CHAT"; + } + else { + data = "./data"; + } + + DATA = data; + DATA_DIR = new File(DATA); + if(!DATA_DIR.exists()) { + DATA_DIR.mkdirs(); + } + } + { File dir = new File("./logs/"); if (!dir.exists()) { diff --git a/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java b/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java index 9ca20f1..b54d612 100644 --- a/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java +++ b/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java @@ -18,8 +18,10 @@ public class LaunchOptions { private boolean loadOld = true; private boolean autoAccept; private boolean serverMode; + private boolean serverCredentialsEnabled; private int port = 39075; private String redirectOutput; + private String serverCredentials; /** * Sets the singleton instance of the LaunchOptions class. @@ -109,4 +111,36 @@ public class LaunchOptions { public void setServerMode(boolean serverMode) { this.serverMode = serverMode; } + + /** + * Gets weather or not the API Server requires credentials + * @return if credentials is required + */ + public boolean isServerCredentialsEnabled() { + return serverCredentialsEnabled; + } + + /** + * Sets weather credentials are needed for the API Server + * @param serverCredentialsEnabled a boolean indicating if the APIServer needs credentials from clients + */ + public void setServerCredentialsEnabled(boolean serverCredentialsEnabled) { + this.serverCredentialsEnabled = serverCredentialsEnabled; + } + + /** + * get the credentials for the API Server + * @return the credentials + */ + public String getServerCredentials() { + return serverCredentials; + } + + /** + * Sets the credentials used by the API Server + * @param serverCredentials a String of the API Server + */ + public void setServerCredentials(String serverCredentials) { + this.serverCredentials = serverCredentials; + } } diff --git a/Core/src/main/java/me/zacharias/chat/core/files/FileHandler.java b/Core/src/main/java/me/zacharias/chat/core/files/FileHandler.java new file mode 100644 index 0000000..814566f --- /dev/null +++ b/Core/src/main/java/me/zacharias/chat/core/files/FileHandler.java @@ -0,0 +1,77 @@ +package me.zacharias.chat.core.files; + +import me.zacharias.chat.core.Core; +import org.intellij.lang.annotations.MagicConstant; + +import java.io.*; +import java.util.Arrays; + +/** + * Base class responsible for the {@link me.zacharias.chat.core.files} related systems + */ +public class FileHandler { + /** + * The current instance of {@link FileHandler} + */ + private static FileHandler instance; + + /** + * The directory used as base for this instance of {@link FileHandler}. This is where all files that can be read or writen will be located + */ + private final File directory; + + /** + * Creates a new instance as well as setting the {@link #instance} to this new one + * @param baseDirectory the directory to be used as base directory + */ + public FileHandler(@MagicConstant(valuesFromClass = FileHandlerLocation.class) String baseDirectory) { + + directory = new File(baseDirectory); + if(!directory.exists()) + directory.mkdirs(); + + instance = this; + } + + /** + * + * @param filename + * @return + * @throws FileHandlerException + */ + public String readFile(String filename) throws FileHandlerException { + if(filename.contains("..")) + { + throw new FileHandlerException("File \"" + filename + "\" tries to retrace path"); + } + File file = new File(directory, filename); + if(file.exists()) + { + try{ + BufferedReader reader = new BufferedReader(new FileReader(file)); + StringBuilder data = new StringBuilder(); + String line; + while((line = reader.readLine()) != null) + { + data.append(line); + } + return data.toString(); + } catch(FileNotFoundException e){ + Core.writeLog(e.getMessage()); + for(StackTraceElement st : e.getStackTrace()) + { + Core.writeLog(st.toString()); + } + throw new FileHandlerException("Cant find file \""+filename+"\""); + } catch (IOException e) { + Core.writeLog(e.getMessage()); + for(StackTraceElement st : e.getStackTrace()) + { + Core.writeLog(st.toString()); + } + throw new FileHandlerException(e.getMessage()); + } + } + throw new FileHandlerException("Cant find file \""+filename+"\""); + } +} diff --git a/Core/src/main/java/me/zacharias/chat/core/files/FileHandlerException.java b/Core/src/main/java/me/zacharias/chat/core/files/FileHandlerException.java new file mode 100644 index 0000000..b86830d --- /dev/null +++ b/Core/src/main/java/me/zacharias/chat/core/files/FileHandlerException.java @@ -0,0 +1,7 @@ +package me.zacharias.chat.core.files; + +public class FileHandlerException extends RuntimeException { + public FileHandlerException(String message) { + super(message); + } +} diff --git a/Core/src/main/java/me/zacharias/chat/core/files/FileHandlerLocation.java b/Core/src/main/java/me/zacharias/chat/core/files/FileHandlerLocation.java new file mode 100644 index 0000000..b93be34 --- /dev/null +++ b/Core/src/main/java/me/zacharias/chat/core/files/FileHandlerLocation.java @@ -0,0 +1,7 @@ +package me.zacharias.chat.core.files; + +import me.zacharias.chat.core.Core; + +public class FileHandlerLocation { + public static final String DATA_FILES = Core.DATA+"/files"; +} diff --git a/Core/src/main/java/me/zacharias/chat/core/files/ListFiles.java b/Core/src/main/java/me/zacharias/chat/core/files/ListFiles.java new file mode 100644 index 0000000..ab50a29 --- /dev/null +++ b/Core/src/main/java/me/zacharias/chat/core/files/ListFiles.java @@ -0,0 +1,4 @@ +package me.zacharias.chat.core.files; + +public class ListFiles { +} diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java index 05573c9..6a4f89a 100644 --- a/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java +++ b/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java @@ -23,13 +23,13 @@ public class AddMemoryFunction extends OllamaFunctionTool { @Override public String description() { - return "Add to the memory"; + return "Remember somthing"; } @Override public OllamaPerameter parameters() { return OllamaPerameter.builder() - .addProperty("memory", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The memory to store", true) + .addProperty("memory", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The memory to remember", true) .build(); } diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java index 6b8c68f..096e635 100644 --- a/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java +++ b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java @@ -24,7 +24,7 @@ public class GetMemoryFunction extends OllamaFunctionTool { @Override public String description() { - return "Retrives all the memory"; + return "Retrieves all the memory's"; } @Override diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java index 42dac7a..78be5ad 100644 --- a/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java +++ b/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java @@ -23,13 +23,13 @@ public class RemoveMemoryFunction extends OllamaFunctionTool { @Override public String description() { - return "Remove from the memory"; + return "Forget a memory"; } @Override public OllamaPerameter parameters() { return OllamaPerameter.builder() - .addProperty("memory", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The memory to remove", true) + .addProperty("memory", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The memory to forget", true) .build(); } diff --git a/Core/src/main/java/me/zacharias/chat/ollama/OllamaObject.java b/Core/src/main/java/me/zacharias/chat/ollama/OllamaObject.java index 8d54531..cbd6bbb 100644 --- a/Core/src/main/java/me/zacharias/chat/ollama/OllamaObject.java +++ b/Core/src/main/java/me/zacharias/chat/ollama/OllamaObject.java @@ -2,6 +2,10 @@ package me.zacharias.chat.ollama; import me.zacharias.chat.core.Core; import me.zacharias.chat.core.LaunchOptions; +import me.zacharias.chat.core.files.FileHandlerLocation; +import me.zacharias.chat.core.files.FileHandler; + +import org.intellij.lang.annotations.MagicConstant; import org.json.JSONArray; import org.json.JSONObject; @@ -365,6 +369,14 @@ public class OllamaObject { this.model = model; return this; } + + public OllamaObjectBuilder addFileTools(@MagicConstant(valuesFromClass = FileHandlerLocation.class) String baseDirectory) + { + FileHandler fileHandler = new FileHandler(baseDirectory); + + if(false); + return this; + } /** * Builds the {@link OllamaObject} diff --git a/Display/src/main/java/me/zacharias/chat/display/Display.java b/Display/src/main/java/me/zacharias/chat/display/Display.java index 74970d2..c41c7b4 100644 --- a/Display/src/main/java/me/zacharias/chat/display/Display.java +++ b/Display/src/main/java/me/zacharias/chat/display/Display.java @@ -3,6 +3,8 @@ package me.zacharias.chat.display; import me.zacharias.chat.core.Core; import me.zacharias.chat.core.Pair; import me.zacharias.chat.core.PrintMessageHandler; +import me.zacharias.chat.core.files.FileHandlerLocation; +import me.zacharias.chat.core.memory.CoreMemory; import me.zacharias.chat.ollama.*; import org.json.JSONObject; @@ -45,10 +47,11 @@ public class Display { //.setModel("deepseek-r1") .keep_alive(10) //.stream(false) + .addFileTools(FileHandlerLocation.DATA_FILES) .build()); - core.addTool(new TimeTool(), Core.Source.INTERNAL); - core.addTool(new PythonRunner(core), Core.Source.INTERNAL); + //core.addTool(new TimeTool(), Core.Source.INTERNAL); + //core.addTool(new PythonRunner(core), Core.Source.INTERNAL); //core.getOllamaObject().addMessage(new OllamaMessage(OllamaMessageRole.SYSTEM, "Have a nice tone and use formal wording")); @@ -100,6 +103,21 @@ public class Display { case "write": core.flushLog(); break; + case "peek": + CoreMemory coreMemory = CoreMemory.getInstance(); + StringBuilder buffer = new StringBuilder("["); + ArrayList memory = new ArrayList<>(coreMemory.getMemory()); + for(int i = 0; i < memory.size(); i++) { + String mem = memory.get(i); + buffer.append("\"").append(mem).append("\""); + if(i+1 < memory.size()) { + buffer.append(", "); + } + } + buffer.append("]"); + writeLog("Memory peek: "+buffer.toString()); + System.out.println(buffer.toString()); + break; default: System.out.println("Unknown command: " + message); } diff --git a/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java b/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java index 4cac132..7b7dce1 100644 --- a/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java +++ b/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java @@ -1,6 +1,6 @@ package me.zacharias.chat.launcher; -import me.zacharias.chat.api.APIServer; +import me.zacharias.chat.api.server.APIServer; import me.zacharias.chat.core.LaunchOptions; import me.zacharias.chat.display.Display;