This commit is contained in:
Minecon724 2024-08-31 17:34:57 +02:00
parent f75d1ca715
commit 63201d9888
Signed by: Minecon724
GPG key ID: 3CCC4D267742C8E8
3 changed files with 57 additions and 22 deletions

View file

@ -1,3 +1 @@
This is a Java library you can write scripts for to support an api with conversational language models A scriptable Java library for chatbots
I can't really say much because I'm still working out stuff so see `thinkings` directory

View file

@ -26,9 +26,11 @@ public class Main {
ChatSource source = new OaiSource(System.getenv("API_KEY")); ChatSource source = new OaiSource(System.getenv("API_KEY"));
//source.options().setValue("model", "chatgpt-4o-latest"); //source.options().setValue("model", "chatgpt-4o-latest");
Chat chat = new Chat("Speak in uwu wanguage."); Chat chat = new Chat("Speak in super wuper uwu wanguage.");
System.out.println("Welcome to CHUT chat. Say something after the \033[1m>\033[0m, or type \033[1m:help\033[0m to see available commands"); System.out.println("Welcome to CHUT chat. Say something after the \033[1m>\033[0m, or type \033[1m:help\033[0m to see available commands");
System.out.println("Source: " + source.getClass().getName());
Scanner scanner = new Scanner(System.in); Scanner scanner = new Scanner(System.in);
while (true) { while (true) {
@ -55,15 +57,21 @@ public class Main {
System.out.println(); System.out.println();
} else { } else {
String[] parts = prompt.substring(1).split(" "); String[] parts = prompt.substring(1).split(" ");
if (parts[0].startsWith(":")) {
System.out.println("If you want to start a message with a \033[1m:\033[0m, you can't");
}
switch (parts[0]) { switch (parts[0]) {
case "help": case "help":
case "h": case "h":
case "": case "":
System.out.println("Source: " + source.getClass().getName());
System.out.println("Available commands:"); System.out.println("Available commands:");
System.out.println(":help - this"); System.out.println(":help - this");
System.out.println(":dump - recap of the chat"); System.out.println(":dump - recap of the chat");
System.out.println(":opt - change source options"); System.out.println(":opt - change source options");
System.out.println(":system - system prompt");
System.out.println("Most commands have a few abbreviations like \033[1m:s\033[0m or \033[1m:sys\033[0m for :system");
break; break;
case "dump": case "dump":
case "d": case "d":
@ -81,20 +89,56 @@ public class Main {
case "options": case "options":
case "opt": case "opt":
case "o": case "o":
if (parts.length < 3 || Arrays.stream(source.options().keys()).noneMatch(parts[1]::equals)) { boolean shouldShowOptions = parts.length < 3;
System.out.println("Available options:"); boolean optionExists = parts.length > 1 && Arrays.asList(source.options().keys()).contains(parts[1]);
for (Map.Entry<String, Option<?>> entry : source.options().getOptions().entrySet()) { boolean complainNoOption = parts.length > 1 && !optionExists;
System.out.printf("%s (%s) = %s\n", entry.getValue().label, entry.getKey(), entry.getValue().getValue().toString()); String chosenOption = parts.length > 1 ? parts[1] : null;
}
} else { if (!shouldShowOptions) {
Option<?> option = source.options().getOptions().get(parts[1]); Option<?> option = source.options().getOptions().get(parts[1]);
Object value = option.fromString(parts[2]); if (option != null) {
option.setValue(value); Object value = option.fromString(parts[2]);
System.out.printf("Set %s to %s\n", option.label, option.getValue()); option.setValue(value);
System.out.printf("Set %s to %s\n", option.label, option.getValue());
} else {
shouldShowOptions = true;
System.out.printf("Unknown option \"%s\". ", parts[1]);
}
}
if (shouldShowOptions) {
if (complainNoOption)
System.out.printf("Unknown option \"%s\". ", chosenOption);
System.out.println("Available options:");
for (Map.Entry<String, Option<?>> entry : source.options().getOptions().entrySet()) {
String value = entry.getValue().getValue().toString() + " (" + entry.getValue().getType().getName() + ")";
if (entry.getKey().equals(chosenOption)) {
System.out.printf("\033[1m%s (%s) = %s\033[0m\n", entry.getValue().label, entry.getKey(), value);
} else {
if (entry.getValue().label.toLowerCase().contains("key")) {
value = "(looks confidential, specify to see)";
}
System.out.printf("%s (%s) = %s\n", entry.getValue().label, entry.getKey(), value);
}
}
}
break;
case "system":
case "sys":
case "s":
if (parts.length == 1) {
System.out.printf("System prompt:\n\033[1m%s\033[0m\n", chat.systemPrompt);
} else {
System.out.printf("Previous system prompt:\n%s\n\n", chat.systemPrompt);
chat.systemPrompt = prompt.substring(parts[0].length() + 2).replace("\\n", "\n");
System.out.printf("New system prompt:\n\033[1m%s\033[0m\n", chat.systemPrompt);
} }
break; break;
default: default:
System.out.println("Invalid command: " + parts[0]); System.out.println("Invalid command: \033[1m" + parts[0] + "\033[0m");
break; break;
} }
} }

View file

@ -1,15 +1,11 @@
package eu.m724.example package eu.m724.example
import eu.m724.chat.Chat import eu.m724.chat.Chat
import eu.m724.chat.ChatEvent
import eu.m724.chat.ChatMessage
import eu.m724.source.ChatResponse import eu.m724.source.ChatResponse
import eu.m724.source.ChatSource import eu.m724.source.ChatSource
import eu.m724.source.ChatSourceInfo import eu.m724.source.ChatSourceInfo
import eu.m724.source.NonStreamingChatResponse import eu.m724.source.NonStreamingChatResponse
import eu.m724.source.SimpleChatResponse
import eu.m724.source.option.DoubleOption import eu.m724.source.option.DoubleOption
import eu.m724.source.option.NumberOption
import eu.m724.source.option.Options import eu.m724.source.option.Options
import eu.m724.source.option.StringOption import eu.m724.source.option.StringOption
import org.json.JSONArray import org.json.JSONArray
@ -18,8 +14,6 @@ import org.json.JSONObject
import java.net.http.HttpClient import java.net.http.HttpClient
import java.net.http.HttpRequest import java.net.http.HttpRequest
import java.net.http.HttpResponse import java.net.http.HttpResponse
import java.util.concurrent.CompletableFuture
import java.util.concurrent.LinkedBlockingQueue
// for now let's not focus on readability // for now let's not focus on readability
// this is more about find out what is common and should be included in the common api // this is more about find out what is common and should be included in the common api
@ -36,7 +30,7 @@ class OaiSource implements ChatSource {
private def options = new Options( private def options = new Options(
new StringOption("apiKey", "API key", apiKey), new StringOption("apiKey", "API key", apiKey),
new StringOption("model", "Model", "gpt-4o-mini"), new StringOption("model", "Model", "gpt-4o-mini"),
new DoubleOption("temperature", "Temperature", 1.2) new DoubleOption("temperature", "Temperature", 1.1)
) )
@Override @Override
@ -56,7 +50,6 @@ class OaiSource implements ChatSource {
.put("model", options.getStringValue("model")) .put("model", options.getStringValue("model"))
.put("temperature", options.getOptionValue("temperature", Double::class)) .put("temperature", options.getOptionValue("temperature", Double::class))
.put("presence_penalty", 0.1) .put("presence_penalty", 0.1)
.put("frequency_penalty", 0.1)
.put("messages", formatChat(chat)).toString() .put("messages", formatChat(chat)).toString()
def request = HttpRequest.newBuilder() def request = HttpRequest.newBuilder()