Files
NeuroDock/Display/src/main/java/me/zacharias/chat/display/Display.java
T
Zacharias 8e44c11385 feat(api): major refactor from TCP socket to HTTP REST via Spring Boot
This commit introduces a large-scale refactor that replaces the existing TCP-based API with a Spring Boot-powered HTTP REST architecture. Due to the size and scope of this change, only essential structural notes are included below.

High-level changes:
- Replaced TCP-based communication with RESTful endpoints
- Introduced Spring Boot for API handling and configuration
- Refactored internal core logic to support REST architecture

New/Updated API components:
- `APIApplication.java`: Main Spring Boot entry point
- `MessageController.java`: Handles LLM-related queries
- `ToolController.java`: Handles adding/removing tools
- `NewToolRequest.java` / `NewToolResponse.java`: Data models for tool addition
- `NewQueryResponseHook.java`: Webhook handler for LLM query results
- `WebhookError.java`: Model for reporting webhook errors
- `EnableIfNotDisplay.java`: Conditional configuration for TTY context
- Other supporting classes (e.g., `ToolArgument`, `ToolRequest`)

Core changes:
- `Core.java`: Removed deprecated `addFunctionTool`, added `removeTool`
- `LaunchOptions.java`: Added `notDisplay` flag for headless operation
- `OllamaObject.java`: Implements tool removal logic

Launcher/display changes:
- `Launcher.java`: Starts `APIApplication` if not in TTY mode
- `Display.java`: Integrates REST API contextually with TTY display

NOTE: Several classes are included but not yet fully utilized; these are placeholders for upcoming features (e.g., `MessageResponse`, `ToolRequest`).

BREAKING CHANGE: This refactors removes all TCP-based API code and replaces it with HTTP REST using Spring Boot. Any clients or modules depending on the old TCP interface will need to be updated.
2025-05-24 18:11:58 +02:00

144 lines
5.8 KiB
Java

package me.zacharias.chat.display;
import me.zacharias.chat.api.APIApplication;
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.mal.api.MALAPITool;
import me.zacharias.chat.ollama.*;
import org.json.JSONObject;
import java.io.*;
import java.util.*;
import static me.zacharias.chat.core.Core.writeLog;
/**
* The main class of the Display.<br>
* This is the main class for running as a Terminal application.<br>
* Somewhat meant to be used as a Debug tool for testing your API.
*/
public class Display {
/**
* The Core instance.
*/
Core core = new Core(new PrintMessageHandler() {
@Override
public void printMessage(String message) {
System.out.println(">> "+message);
}
@Override
public boolean color() {
return true;
}
});
/**
* Creates a new instance of Display.<br>
* This Creates the OllamaObject and adds the tools to it. as well as handles the display of the messages. and the input from the user.
*/
public Display()
{
core.setOllamaObject/*NoMemory*/(OllamaObject.builder()
//.setModel("llama3.2")
//.setModel("gemma3:12b")
.setModel("qwen3:8b")
.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.addTools(new MALAPITool().getOllamaTools());
APIApplication.start();
//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");
writeLog("Tools installed in this instance");
for(Pair<OllamaFunctionTool, String> funtion : core.getFuntionTools())
{
StringBuilder args = new StringBuilder();
OllamaPerameter perameter = funtion.getKey().parameters();
if(perameter != null) {
JSONObject obj = perameter.getProperties();
for (String name : obj.keySet()) {
args.append(args.toString().isBlank() ? "" : ", ").append(obj.getJSONObject(name).getString("type")).append(Arrays.stream(perameter.getRequired()).anyMatch(str -> str.equalsIgnoreCase(name)) ? "" : "?").append(" ").append(name);
}
}
System.out.println("> Function: "+funtion.getKey().name()+"("+args+") ["+funtion.getValue()+"]");
writeLog("Function: "+funtion.getKey().name()+"("+args+") ["+funtion.getValue()+"]");
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Message Transcription:");
try {
while (true) {
System.out.print("> ");
StringBuilder message = new StringBuilder(br.readLine());
while (br.ready()) {
message.append("\n").append(br.readLine());
}
if (message.toString().startsWith("/")) {
switch (message.substring(1)) {
case "help":
System.out.print("""
Available commands:
/help Prints this help message.
/bye Exits the program.
/write Flushes the current log stream to file.
""");
break;
case "bye":
writeLog("Exiting program...");
System.out.println("Bye!");
System.exit(0);
return;
case "write":
Core.flushLog();
break;
case "peek":
CoreMemory coreMemory = CoreMemory.getInstance();
StringBuilder buffer = new StringBuilder("[");
ArrayList<String> 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);
}
} else {
writeLog("User: " + message);
core.getOllamaObject().addMessage(new OllamaMessage(OllamaMessageRole.USER, message.toString()));
//System.out.println(ollamaObject.toString());
core.handleResponce(core.qurryOllama());
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Exiting due to exception");
System.exit(-1);
}
}
}