From 01de196d82bf8f7554bae2cfd18394f174aa2254 Mon Sep 17 00:00:00 2001 From: Zacharias Date: Fri, 14 Mar 2025 20:01:38 +0100 Subject: [PATCH] Slight chages Display > Set both tools to INTERNAL GetMemoryFunction > Made so it gives a JSON PythonRunner > Fixed some value checkes --- .../chat/core/memory/GetMemoryFunction.java | 4 +- .../me/zacharias/chat/display/Display.java | 7 +- .../zacharias/chat/display/PythonRunner.java | 108 +++++++++++++++--- 3 files changed, 99 insertions(+), 20 deletions(-) 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 7c32a03..6b8c68f 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 @@ -4,6 +4,8 @@ import me.zacharias.chat.ollama.OllamaFunctionArgument; import me.zacharias.chat.ollama.OllamaFunctionTool; import me.zacharias.chat.ollama.OllamaPerameter; import me.zacharias.chat.ollama.OllamaToolRespnce; +import org.json.JSONArray; +import org.json.JSONObject; /** * Provides the get_memory function.
@@ -32,6 +34,6 @@ public class GetMemoryFunction extends OllamaFunctionTool { @Override public OllamaToolRespnce function(OllamaFunctionArgument... args) { - return new OllamaToolRespnce(name(), memory.getMemory().toString()); + return new OllamaToolRespnce(name(), new JSONObject().put("memory_items", new JSONArray(memory.getMemory())).toString()); } } 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 f57ccb0..74970d2 100644 --- a/Display/src/main/java/me/zacharias/chat/display/Display.java +++ b/Display/src/main/java/me/zacharias/chat/display/Display.java @@ -41,14 +41,17 @@ public class Display { { core.setOllamaObject(OllamaObject.builder() - .setModel("llama3-AI") + .setModel("llama3.2") + //.setModel("deepseek-r1") .keep_alive(10) //.stream(false) .build()); - core.addTool(new TimeTool(), Core.Source.EXTERNAL); + 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")); + writeLog("Creating base OllamaObject with model: "+core.getOllamaObject().getModel()); System.out.println("Installed tools"); diff --git a/Display/src/main/java/me/zacharias/chat/display/PythonRunner.java b/Display/src/main/java/me/zacharias/chat/display/PythonRunner.java index ce074e2..f99146f 100644 --- a/Display/src/main/java/me/zacharias/chat/display/PythonRunner.java +++ b/Display/src/main/java/me/zacharias/chat/display/PythonRunner.java @@ -2,8 +2,11 @@ package me.zacharias.chat.display; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.async.ResultCallback; -import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.async.ResultCallbackTemplate; +import com.github.dockerjava.api.command.*; +import com.github.dockerjava.api.model.BuildResponseItem; import com.github.dockerjava.api.model.Frame; +import com.github.dockerjava.api.model.Statistics; import com.github.dockerjava.core.DefaultDockerClientConfig; import com.github.dockerjava.core.DockerClientBuilder; import me.zacharias.chat.core.Core; @@ -39,12 +42,12 @@ public class PythonRunner extends OllamaFunctionTool { * The Core instance. */ private Core core; - + /** * The ServerSocket instance. */ private ServerSocket serverSocket; - + /** * Creates a new instance of PythonRunner. * @param core The Core instance @@ -70,7 +73,7 @@ public class PythonRunner extends OllamaFunctionTool { List> list = core.getFuntionTools().stream().filter(funtionTool -> funtionTool.getKey().name().equalsIgnoreCase(data.optString("function", ""))).toList(); if (list.isEmpty()) { - out.write(new JSONObject().put("error", "Function dose't exist").toString()); + out.write(new JSONObject().put("error", "Function don't exist").toString()); out.newLine(); out.flush(); out.close(); @@ -83,8 +86,10 @@ public class PythonRunner extends OllamaFunctionTool { for (Object o : data.optJSONArray("arguments", new JSONArray())) { if (o instanceof JSONObject obj) { - OllamaFunctionArgument arg = new OllamaFunctionArgument(obj.getString("name"), obj.getString("value")); - args.add(arg); + if(obj.has("value") && !obj.isNull("value")) { + OllamaFunctionArgument arg = new OllamaFunctionArgument(obj.getString("name"), obj.getString("value")); + args.add(arg); + } } } @@ -97,7 +102,7 @@ public class PythonRunner extends OllamaFunctionTool { } catch (Exception e) { } } catch (Exception e) { - + } } }); @@ -131,6 +136,7 @@ public class PythonRunner extends OllamaFunctionTool { return OllamaPerameter.builder() .addProperty("code", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The code to be executed", true) .addProperty("name", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The name of the python code") + .addProperty("libs", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "A space separated list of pip packages needed") .build(); } @@ -143,19 +149,24 @@ public class PythonRunner extends OllamaFunctionTool { String name = null; String code = null; + String libs = null; for(OllamaFunctionArgument arg : args) { - if(arg.argument().equals("name")) + if(arg.argument().equals("name") && !arg.value().equals("")) { name = (String) arg.value(); if(!name.endsWith(".py")) { name += ".py"; } - } else if (arg.argument().equals("code")) { + } else if (arg.argument().equals("code") && !arg.value().equals("")) { code = (String) arg.value(); } + else if(arg.argument().equals("libs") && !arg.value().equals("")) + { + libs = (String) arg.value(); + } } if(name == null) @@ -194,13 +205,55 @@ public class PythonRunner extends OllamaFunctionTool { try { String external_tools = generateExternalTools(); BufferedWriter bw = new BufferedWriter(new FileWriter(f)); - bw.write(external_tools); + bw.write(external_tools.replace("\\n", "\n")); bw.flush(); bw.close(); }catch(IOException e) {} try { - String containerId = dockerClient.createContainerCmd("python").withCmd("python", name).exec().getId(); + ArrayList pythonArgs = new ArrayList<>(); + + pythonArgs.add("/bin/bash"); + + StringBuilder cmd = new StringBuilder(); + cmd.append("set -e\n\npacman --noconfirm -Sy > /dev/null\npacman --noconfirm -S python python-pip > /dev/null\nmkdir pythonRun > /dev/null\npython -m venv ./pythonRun > /dev/null\ncp external_tools.py ./pythonRun > /dev/null\ncp ").append(name).append(" ./pythonRun > /dev/null\ncd pythonRun > /dev/null\nsource ./bin/activate > /dev/null\n"); + + if(libs != null && !libs.isEmpty()) + { + cmd.append("pip install "); + for(String lib : libs.split(" ")) + { + cmd.append(lib).append(" "); + } + cmd.append(" > /dev/null\n"); + } + + cmd.append("python ").append(name);//.append(" exit"); + + pythonArgs.add("-c"); + pythonArgs.add(cmd.toString()); + + StringBuilder fullCmd = new StringBuilder(); + + for(String arg : pythonArgs) + { + fullCmd.append(arg).append(" "); + } + + File program = new File("./cache", "cmd.sh"); + if(program.exists()){ + program.delete(); + } + program.createNewFile(); + + BufferedWriter bw = new BufferedWriter(new FileWriter(program)); + bw.write(cmd.toString()); + bw.flush(); + bw.close(); + + + String containerId = dockerClient.createContainerCmd("archlinux").withCmd("/bin/bash","./cmd.sh").exec().getId(); + dockerClient.copyArchiveToContainerCmd(containerId) .withHostResource(pythonFile.getPath()) .exec(); @@ -209,8 +262,18 @@ public class PythonRunner extends OllamaFunctionTool { .withHostResource(f.getPath()) .exec(); + dockerClient.copyArchiveToContainerCmd(containerId) + .withHostResource(program.getPath()) + .exec(); + + //InputStream stdin = new ByteArrayInputStream(fullCmd.toString().getBytes(StandardCharsets.UTF_8)); + dockerClient.startContainerCmd(containerId).exec(); + //dockerClient.attachContainerCmd(containerId).withStdIn(stdin).exec(null); + + //dockerClient.execCreateCmd(containerId).withCmd(fullCmd.toString()).exec(); + GetContainerLog log = new GetContainerLog(dockerClient, containerId); List logs = new ArrayList<>(); @@ -223,7 +286,7 @@ public class PythonRunner extends OllamaFunctionTool { } logs.addAll(log.getDockerLogs()); } - while (logs.isEmpty()); + while (isRunning(containerId)); StringBuilder output = new StringBuilder(); @@ -239,7 +302,7 @@ public class PythonRunner extends OllamaFunctionTool { throw new OllamaToolErrorException(name(), "Docker unavalible"); } } - + /** * Generates the external_tools.py file.
* This is meant to provide the python code with all ExternalTools defined in the OllamaObject. @@ -311,12 +374,23 @@ public class PythonRunner extends OllamaFunctionTool { code.append("]"); } code.append("}\n"); - code.append(" return connect(json.dumps(data))\n\n"); + code.append(" return json.loads(connect(json.dumps(data)))\n\n"); } return code.toString(); } - + + /** + * Checks if a Docker Container is running + * @param containerId The ID of the Container + * @return a boolean weather it's running or not + */ + public boolean isRunning(String containerId) + { + InspectContainerResponse cmd = dockerClient.inspectContainerCmd(containerId).exec(); + return Boolean.TRUE.equals(cmd.getState().getRunning()); + } + /** * A Helper class to get the logs from a docker container. */ @@ -327,7 +401,7 @@ public class PythonRunner extends OllamaFunctionTool { private static String nameOfLogger = "dockertest.PrintContainerLog"; private static Logger myLogger = Logger.getLogger(nameOfLogger); - + /** * Creates a new instance of {@link GetContainerLog} * @param dockerClient The DockerClient instance @@ -338,7 +412,7 @@ public class PythonRunner extends OllamaFunctionTool { this.containerId = containerId; this.lastLogTime = (int) (System.currentTimeMillis() / 1000); } - + /** * Gets the logs of the container. * @return The logs of the container