Misc improvements:
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 27 May 2024 15:43:23 +0000 (18:43 +0300)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Mon, 27 May 2024 15:43:23 +0000 (18:43 +0300)
- Document selftest command.
- Allow choosing model and prompt for per task.

doc/index.org
src/main/java/eu/svjatoslav/alyverkko_cli/commands/JoinFilesCommand.java
src/main/java/eu/svjatoslav/alyverkko_cli/commands/MailCorrespondentCommand.java

index f9b2613..3cd03db 100644 (file)
@@ -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.
 
index ba05ffa..7d4c1e6 100644 (file)
@@ -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 {
index b2ef933..7ad54f0 100644 (file)
@@ -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<String, String> settings = parseSettings(firstLine);
+        String systemPromptAlias = settings.getOrDefault("prompt", "default");
+        String modelAlias = settings.getOrDefault("model", "default");
+
+        mailQuery.systemPrompt = configuration.getPromptByAlias(systemPromptAlias);
+        Optional<Model> 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<String, String> 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<String, String> 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();