From 96a6ed169e9b026977111495393b30ef8cc33e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zacharias=20Zell=C3=A9n?= Date: Mon, 4 May 2026 14:23:26 +0200 Subject: [PATCH] Extracted the external tool base for python runner Fixed URL building in APITool.java. Updated libraries for API, Launcher. Started applying NotNull annotation to methods and arguments in Core.java. Started handeling the big init block in Core.java. Added overloaded constructor for Core.java and made Core.ollamaIP a variabled that's definible Updated Tool.addTool return for 400 error. --- API/build.gradle | 8 ++--- .../java/me/zacharias/chat/api/APITool.java | 2 +- .../zacharias/chat/api/controllers/Tool.java | 2 +- .../java/me/zacharias/chat/core/Core.java | 32 ++++++++++++++++-- .../me/zacharias/chat/display/Display.java | 15 +++++---- .../zacharias/chat/display/PythonRunner.java | 33 +++++++++---------- .../src/main/resources/external_tool_base.py | 24 ++++++++++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- launcher/build.gradle | 13 -------- 9 files changed, 83 insertions(+), 48 deletions(-) create mode 100644 Display/src/main/resources/external_tool_base.py diff --git a/API/build.gradle b/API/build.gradle index ff45d90..2dd2d34 100644 --- a/API/build.gradle +++ b/API/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.2.2' + id 'org.springframework.boot' version '4.1.0-M4' id 'io.spring.dependency-management' version '1.1.4' } @@ -12,11 +12,11 @@ dependencies { implementation project(":Core") - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-webflux' + implementation 'org.springframework.boot:spring-boot-starter-web:4.1.0-M4' + implementation 'org.springframework.boot:spring-boot-starter-webflux:4.1.0-M4' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.0-M1' //implementation 'org.springframework.boot:spring-boot-starter-actuator' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.boot:spring-boot-starter-test:4.1.0-M4' //runtimeOnly('org.springframework.boot:spring-boot-starter-web') } diff --git a/API/src/main/java/me/zacharias/chat/api/APITool.java b/API/src/main/java/me/zacharias/chat/api/APITool.java index b7227c6..2417f4b 100644 --- a/API/src/main/java/me/zacharias/chat/api/APITool.java +++ b/API/src/main/java/me/zacharias/chat/api/APITool.java @@ -65,7 +65,7 @@ public class APITool extends OllamaFunctionTool { @Override public OllamaToolRespnce function(OllamaFunctionArgument... args) { - UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(requestUrl); + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(requestUrl); for (OllamaFunctionArgument arg : args) { builder.queryParam(arg.argument(), arg.value()); } diff --git a/API/src/main/java/me/zacharias/chat/api/controllers/Tool.java b/API/src/main/java/me/zacharias/chat/api/controllers/Tool.java index 6a2a1a9..d025833 100644 --- a/API/src/main/java/me/zacharias/chat/api/controllers/Tool.java +++ b/API/src/main/java/me/zacharias/chat/api/controllers/Tool.java @@ -34,7 +34,7 @@ public class Tool { } return ResponseEntity.ok(new NewToolResponse(request.getName(), request.getDescription(), arguments)); } else { - return new ResponseEntity<>("Tool already exists", null, 400); + return ResponseEntity.status(400).body("Tool already exists"); } } } 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 60f4d1d..7bce34c 100644 --- a/Core/src/main/java/me/zacharias/chat/core/Core.java +++ b/Core/src/main/java/me/zacharias/chat/core/Core.java @@ -7,6 +7,7 @@ import me.zacharias.chat.plugin.Plugin; import me.zacharias.chat.plugin.PluginLoader; import me.zacharias.chat.plugin.exceptions.PluginLoadingException; import org.intellij.lang.annotations.MagicConstant; +import org.jetbrains.annotations.NotNull; import org.json.JSONArray; import org.json.JSONObject; @@ -54,7 +55,7 @@ public class Core { /** * The IP of the Ollama API. */ - private String ollamaIP = "10.0.1.101";//"192.168.5.184"; + private String ollamaIP; /** * The port of the Ollama API. */ @@ -118,7 +119,12 @@ public class Core { } } - { + /** + * This function is pending a better name, as this was introduced from being a generic block. This was ugly, and ideally things here should be refactored more. + * + * TODO: Fix a better name and refactor this method. + */ + private void constructCore(){ File dir = new File("./logs/"); if (!dir.exists()) { dir.mkdir(); @@ -139,6 +145,7 @@ public class Core { } catch (URISyntaxException e) { throw new RuntimeException(e); } + try { if (logFile.exists()) { BufferedReader br = new BufferedReader(new FileReader(logFile)); @@ -221,9 +228,28 @@ public class Core { * Creates a new instance of Core with the provided PrintMessageHandler * @param printMessageHandler The PrintMessageHandler to use as the default Output */ - public Core(PrintMessageHandler printMessageHandler) { + public Core(@NotNull PrintMessageHandler printMessageHandler) { this.printMessageHandler = printMessageHandler; supportColor = printMessageHandler.color(); + ollamaIP = "localhost"; + + // TODO: This is a dirty way to not have a masisive init block, please check this methods comment. + constructCore(); + } + + /** + * Creates a new instance of Core with the provided PrintMessageHandler, with a specific IP used for Ollama + * @param printMessageHandler The PrintMessageHandler to use as the default Output + * @param ollamaIP The IP used for the Ollama backend + */ + public Core(@NotNull PrintMessageHandler printMessageHandler, @NotNull String ollamaIP) + { + this.printMessageHandler = printMessageHandler; + supportColor = printMessageHandler.color(); + this.ollamaIP = ollamaIP; + + // TODO: This is a dirty way to not have a masisive init block, please check this methods comment. + constructCore(); } /** 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 19eb9e3..a153c56 100644 --- a/Display/src/main/java/me/zacharias/chat/display/Display.java +++ b/Display/src/main/java/me/zacharias/chat/display/Display.java @@ -14,6 +14,8 @@ import me.zacharias.neuro.dock.wikipedia.WikipediaTool; import org.json.JSONObject; import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.*; import static me.zacharias.chat.core.Core.writeLog; @@ -48,9 +50,7 @@ public class Display { { core.setOllamaObject/*NoMemory*/(OllamaObject.builder() - //.setModel("llama3.2") - //.setModel("gemma3:12b") - .setModel("qwen3:8b") + .setModel("llama3.2") .keep_alive(10) //.stream(false) //.addFileTools(FileHandlerLocation.DATA_FILES) @@ -61,10 +61,11 @@ public class Display { core.addTool(new TimeTool(), Core.Source.INTERNAL); // TODO: Well Docker failes when luanched.... Fuck - //core.addTool(new PythonRunner(core), Core.Source.INTERNAL); - core.addTools(new MALAPITool().getOllamaTools()); - core.addTools(new GeniusTools().getGeniusTools()); - core.addTools(new WikipediaTool().getWikipediaToolsInstance()); + PythonRunner pythonRunner = new PythonRunner(core); + core.addTool(pythonRunner, Core.Source.INTERNAL); + //core.addTools(new MALAPITool().getOllamaTools()); + //core.addTools(new GeniusTools().getGeniusTools()); + //core.addTools(new WikipediaTool().getWikipediaToolsInstance()); APIApplication.start(); 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 a014539..9246cd4 100644 --- a/Display/src/main/java/me/zacharias/chat/display/PythonRunner.java +++ b/Display/src/main/java/me/zacharias/chat/display/PythonRunner.java @@ -59,6 +59,8 @@ public class PythonRunner extends OllamaFunctionTool { public PythonRunner(Core core) { this.core = core; + generateExternalTools(); + try { serverSocket = new ServerSocket(6050); Thread thread = new Thread(() -> { @@ -350,27 +352,22 @@ public class PythonRunner extends OllamaFunctionTool { * Generates the external_tools.py file.
* This is meant to provide the python code with all ExternalTools defined in the OllamaObject. * @return The generated external_tools.py file + * @throws IllegalStateException This is thrown when the external_tool_base.py can not be read, this should be handled by disabling the python runner. */ - private String generateExternalTools() { + private String generateExternalTools() throws IllegalStateException{ StringBuilder code = new StringBuilder(); - code.append(""" - import socket - import json - - HOST = "host.docker.internal" - PORT = 6050 - - def connect(data): - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect((HOST, PORT)) - data = data + "\\n" - s.sendall(data.encode("utf-8")) - responce = s.recv(4096) - return responce.decode("utf-8") - - - """); + try (InputStream in = getClass().getResourceAsStream("/external_tool_base.py"); + BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { + String tmp = null; + while((tmp = reader.readLine()) != null) + { + code.append(tmp).append('\n'); + } + }catch (Exception ex) + { + throw new IllegalStateException("Can not read the base external tools file, this is a fetal error for the python runner!"); + } for(Pair funtionTool : core.getFuntionTools()) { diff --git a/Display/src/main/resources/external_tool_base.py b/Display/src/main/resources/external_tool_base.py new file mode 100644 index 0000000..20d25d4 --- /dev/null +++ b/Display/src/main/resources/external_tool_base.py @@ -0,0 +1,24 @@ +import socket +import json +import builtins + +HOST = "host.docker.internal" +PORT = 6050 + +def connect(data): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((HOST, PORT)) + data = data + "\n" + s.sendall(data.encode("utf-8")) + responce = s.recv(4096) + return responce.decode("utf-8") + +def print_output(text): + data = {"function": "print_output", "arguments": [{"name": "text", "value": text}]} + connect(json.dumps(data)) + +def _neurodock_print(*args, **kwargs): + text = " ".join(str(a) for a in args) + print_output(text) + +builtins.print = _neurodock_print \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4854ea6..0e6b07e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Thu Feb 20 00:10:50 CET 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/launcher/build.gradle b/launcher/build.gradle index 6369ecf..4d73288 100644 --- a/launcher/build.gradle +++ b/launcher/build.gradle @@ -1,8 +1,5 @@ plugins { id 'java' - - id 'org.springframework.boot' version '3.2.2' - id 'io.spring.dependency-management' version '1.1.4' } group = 'me.zacharias' @@ -12,16 +9,6 @@ dependencies { implementation project(":Display") implementation project(":API") implementation project(":Core") - - afterEvaluate { - boolean hasAPIDependency = configurations.implementation.dependencies.any { it.name.contains('API') } - - if (hasAPIDependency) { - dependencies.add("implementation", 'org.springframework.boot:spring-boot-starter-web') - dependencies.add("implementation", 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0') - dependencies.add("testImplementation", 'org.springframework.boot:spring-boot-starter-test') - } - } } jar{