From: Svjatoslav Agejenko Date: Mon, 27 May 2024 15:43:23 +0000 (+0300) Subject: Misc improvements: X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=bea1a4c6e74b317e65b20d82cb94606ea7637b2f;p=alyverkko-cli.git Misc improvements: - Document selftest command. - Allow choosing model and prompt for per task. --- diff --git a/doc/index.org b/doc/index.org index f9b2613..3cd03db 100644 --- a/doc/index.org +++ b/doc/index.org @@ -10,7 +10,7 @@ * General - This program is free software: released under Creative Commons Zero - (CC0) license + (CC0) license. - Program author: - Svjatoslav Agejenko @@ -43,8 +43,8 @@ language models through CPU-based computation in batch processing mode. To illustrate its capabilities: Imagine harnessing the power of a vast -language model, boasting around 100 billion parameters, solely relying -on CPU computations and leveraging the open-source software +language model, boasting approximately 100 billion parameters, solely +relying on CPU computations and leveraging the open-source software llama.cpp. This setup requires a modern consumer-grade CPU and approximately 128 GB of RAM. To put this into perspective, 128 GB of RAM is financially comparable to purchasing a high-quality smartphone, @@ -307,7 +307,7 @@ Here are available parameters: - Default value: 6 - models :: List of available large language models. - - alias :: Short model alias. + - alias :: Short model alias. Model with alias "default" would be used by default. - filesystem_path :: File name of the model as located within *models_directory* - context_size_tokens :: Context size in tokens that model was @@ -318,18 +318,10 @@ Here are available parameters: conversation. Default value is: *null*. - prompts :: List of predefined system prompts for AI. - - alias :: Short prompt alias. + - alias :: Short prompt alias. Prompt with alias "default" will be used by default. - prompt :: Actual prompt that will be sent to AI alongside actual user question. - -*WARNING: MODEL SELECTION AND PROMPT SELECTION IS CURRENTLY NOT IMPLEMENTED* - -While it is possible to configure many prompts and models, at the -moment Älyverkko CLI will always choose model and prompt with -"default" alias. This is going to be fixed soon. - - *** Enlisting available models Once Älyverkko CLI is installed and properly configured, you can run following command at commandline to see what models are available to @@ -337,6 +329,17 @@ it: : alyverkko-cli listmodels +*** Self test +The *selftest* command performs a series of checks to ensure the +system is configured correctly: + +: alyverkko-cli selftest + +It verifies: +- Configuration file integrity. +- Model directory existence. +- The presence of the *llama.cpp* executable. + ** Starting daemon Älyverkko CLI keeps continuously listening for and processing tasks @@ -592,10 +595,6 @@ Ideas to be possibly implemented in the future: - Add support for speculative decoding to speed up inference. -- Implement selftest command. It shall validate that configuration is - correct and all is operational. If errors are found, it should tell - what exactly is wrong and suggest how to fix it. - - Explain how to monitor system performance and resource usage during AI processing tasks. diff --git a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/JoinFilesCommand.java b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/JoinFilesCommand.java index ba05ffa..7d4c1e6 100644 --- a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/JoinFilesCommand.java +++ b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/JoinFilesCommand.java @@ -72,13 +72,8 @@ public class JoinFilesCommand implements Command { } private void openFileWithEditor() throws IOException { - String editorCommand = sanitizeArgumentForShell(StringUtils.join(" ", "emc", outputFile.getAbsolutePath())); - Runtime.getRuntime().exec(editorCommand); - } - - private String sanitizeArgumentForShell(String argument) { - // Implement logic to escape or quote the argument for use in shell commands - return "\"" + argument.replace("\"", "\\\"") + "\""; + String [] cmd = {"emc", outputFile.getAbsolutePath()}; + Runtime.getRuntime().exec(cmd); } private void joinFiles() throws IOException { diff --git a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/MailCorrespondentCommand.java b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/MailCorrespondentCommand.java index b2ef933..7ad54f0 100644 --- a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/MailCorrespondentCommand.java +++ b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/MailCorrespondentCommand.java @@ -1,9 +1,9 @@ package eu.svjatoslav.alyverkko_cli.commands; import eu.svjatoslav.alyverkko_cli.*; +import eu.svjatoslav.alyverkko_cli.model.Model; import eu.svjatoslav.alyverkko_cli.model.ModelLibrary; import eu.svjatoslav.commons.cli_helper.parameter_parser.Parser; -import eu.svjatoslav.commons.cli_helper.parameter_parser.parameter.DirectoryOption; import eu.svjatoslav.commons.cli_helper.parameter_parser.parameter.FileOption; import java.io.BufferedReader; @@ -11,6 +11,9 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.file.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; import static eu.svjatoslav.alyverkko_cli.configuration.Configuration.loadConfiguration; import static eu.svjatoslav.alyverkko_cli.Main.configuration; @@ -97,11 +100,18 @@ public class MailCorrespondentCommand implements Command { mailQuery.userPrompt = inputFileContent.substring(firstNewLineIndex + 1); } + // Parse TOCOMPUTE line for inference settings String firstLine = inputFileContent.substring(0, firstNewLineIndex); - //System.out.println("First line is: \"" + firstLine + "\""); - - mailQuery.systemPrompt = configuration.getPromptByAlias("default"); - mailQuery.model = modelLibrary.findModelByAlias("default").get(); + Map settings = parseSettings(firstLine); + String systemPromptAlias = settings.getOrDefault("prompt", "default"); + String modelAlias = settings.getOrDefault("model", "default"); + + mailQuery.systemPrompt = configuration.getPromptByAlias(systemPromptAlias); + Optional modelOptional = modelLibrary.findModelByAlias(modelAlias); + if (!modelOptional.isPresent()) { + throw new IllegalArgumentException("Model with alias '" + modelAlias + "' not found."); + } + mailQuery.model = modelOptional.get(); return mailQuery; } @@ -157,6 +167,27 @@ public class MailCorrespondentCommand implements Command { watcher.close(); } + private Map parseSettings(String toComputeLine) { + + if (!toComputeLine.startsWith("TOCOMPUTE:")) { + throw new IllegalArgumentException("Invalid TOCOMPUTE line: " + toComputeLine); + } + + if (toComputeLine.length() <= "TOCOMPUTE: ".length()) { + return new HashMap<>(); + } + + // Assuming the format is "TOCOMPUTE: key1=value1 key2=value2 ..." + String[] parts = toComputeLine.substring("TOCOMPUTE: ".length()).split("\\s+"); + + Map settings = new HashMap<>(); + for (String part : parts) { + String[] keyValue = part.split("="); + if (keyValue.length == 2) settings.put(keyValue[0], keyValue[1]); + } + return settings; + } + private void processDetectedFilesystemEvents(WatchKey key) throws IOException, InterruptedException { for (WatchEvent event : key.pollEvents()) { WatchEvent.Kind kind = event.kind();