From 1b1393da2c724df3fe0f1d29834767d2cea34b72 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Thu, 29 Aug 2024 19:50:58 +0200 Subject: [PATCH] make it work for real this time --- src/main/java/eu/m724/Main.java | 65 ++++++++++++++++--- .../java/eu/m724/example/ExampleSource.groovy | 33 ++++++---- .../responsesource/ChatResponseSource.java | 18 ----- .../ChatResponseSourceInfo.java | 20 ------ .../eu/m724/responsesource/net/Requester.java | 4 -- .../ChatResponse.java | 2 +- src/main/java/eu/m724/source/ChatSource.java | 33 ++++++++++ .../java/eu/m724/source/ChatSourceInfo.java | 4 ++ .../java/eu/m724/source/net/Requester.java | 4 ++ .../eu/m724/source/option/NumberOption.java | 21 ++++++ .../java/eu/m724/source/option/Option.java | 53 +++++++++++++++ .../java/eu/m724/source/option/Options.java | 48 ++++++++++++++ .../eu/m724/source/option/StringOption.java | 26 ++++++++ src/main/resources/name.txt | 18 +++++ 14 files changed, 285 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/eu/m724/responsesource/ChatResponseSource.java delete mode 100644 src/main/java/eu/m724/responsesource/ChatResponseSourceInfo.java delete mode 100644 src/main/java/eu/m724/responsesource/net/Requester.java rename src/main/java/eu/m724/{responsesource => source}/ChatResponse.java (96%) create mode 100644 src/main/java/eu/m724/source/ChatSource.java create mode 100644 src/main/java/eu/m724/source/ChatSourceInfo.java create mode 100644 src/main/java/eu/m724/source/net/Requester.java create mode 100644 src/main/java/eu/m724/source/option/NumberOption.java create mode 100644 src/main/java/eu/m724/source/option/Option.java create mode 100644 src/main/java/eu/m724/source/option/Options.java create mode 100644 src/main/java/eu/m724/source/option/StringOption.java create mode 100644 src/main/resources/name.txt diff --git a/src/main/java/eu/m724/Main.java b/src/main/java/eu/m724/Main.java index 219b1b2..058a92d 100644 --- a/src/main/java/eu/m724/Main.java +++ b/src/main/java/eu/m724/Main.java @@ -4,16 +4,24 @@ import eu.m724.chat.Chat; import eu.m724.chat.ChatEvent; import eu.m724.chat.ChatMessage; import eu.m724.example.ExampleSource; -import eu.m724.responsesource.ChatResponse; -import eu.m724.responsesource.ChatResponseSource; -import groovy.lang.GroovyShell; +import eu.m724.source.ChatResponse; +import eu.m724.source.ChatSource; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.LongStream; public class Main { public static void main(String[] args) throws InterruptedException { - ChatResponseSource source = new ExampleSource(); + ChatSource source = new ExampleSource(); + source.options().setValue("name", readResourceFile("name.txt")); Chat chat = new Chat(); chat.messages.add(new ChatMessage(false, "hello")); @@ -24,6 +32,12 @@ public class Main { List tokens = new ArrayList<>(); List delays = new ArrayList<>(); + System.out.printf("%s has %d options: %s\n\n", + source.getClass().getName(), + source.options().count(), + source.options().getOptions().values().stream().map(o -> "%s (%s)".formatted(o.label, o.getType().getName())).collect(Collectors.joining(", ")) + ); + System.out.println("Streaming response now\n"); ChatEvent token; @@ -40,12 +54,43 @@ public class Main { System.out.printf("Tokens: %d\n", tokens.size()); long time = delays.getFirst(); - for (int i=0; i queue = new LinkedBlockingQueue<>() @@ -36,7 +47,7 @@ class ExampleSource implements ChatResponseSource { for (int i=0; i 0 ? " " : "") + parts[i] queue.put(ChatEvent.of(token)); - Thread.sleep(random.nextInt(200, 500)) + Thread.sleep(random.nextInt(50, 200)) } queue.put(ChatEvent.finished("stop")) diff --git a/src/main/java/eu/m724/responsesource/ChatResponseSource.java b/src/main/java/eu/m724/responsesource/ChatResponseSource.java deleted file mode 100644 index 585c993..0000000 --- a/src/main/java/eu/m724/responsesource/ChatResponseSource.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.m724.responsesource; - -import eu.m724.chat.Chat; - -public interface ChatResponseSource { - ChatResponseSourceInfo info(); - - ChatResponse onAsked(Chat chat); - - default ChatResponse ask(Chat chat) { - ChatResponse chatResponse = onAsked(chat); - - // TODO make sure it works in parallel - chatResponse.message().thenAccept(chat::addMessage); - - return chatResponse; - } -} diff --git a/src/main/java/eu/m724/responsesource/ChatResponseSourceInfo.java b/src/main/java/eu/m724/responsesource/ChatResponseSourceInfo.java deleted file mode 100644 index 948b460..0000000 --- a/src/main/java/eu/m724/responsesource/ChatResponseSourceInfo.java +++ /dev/null @@ -1,20 +0,0 @@ -package eu.m724.responsesource; - -public class ChatResponseSourceInfo { - public final String name; - public final String author; - public final String versionName; - public final int version; - - public ChatResponseSourceInfo( - String name, - String author, - String versionName, - int version - ) { - this.name = name; - this.author = author; - this.versionName = versionName; - this.version = version; - } -} diff --git a/src/main/java/eu/m724/responsesource/net/Requester.java b/src/main/java/eu/m724/responsesource/net/Requester.java deleted file mode 100644 index b48dd24..0000000 --- a/src/main/java/eu/m724/responsesource/net/Requester.java +++ /dev/null @@ -1,4 +0,0 @@ -package eu.m724.responsesource.net; - -public interface Requester { -} diff --git a/src/main/java/eu/m724/responsesource/ChatResponse.java b/src/main/java/eu/m724/source/ChatResponse.java similarity index 96% rename from src/main/java/eu/m724/responsesource/ChatResponse.java rename to src/main/java/eu/m724/source/ChatResponse.java index e7d2379..c2f9fe2 100644 --- a/src/main/java/eu/m724/responsesource/ChatResponse.java +++ b/src/main/java/eu/m724/source/ChatResponse.java @@ -1,4 +1,4 @@ -package eu.m724.responsesource; +package eu.m724.source; import eu.m724.chat.ChatEvent; import eu.m724.chat.ChatMessage; diff --git a/src/main/java/eu/m724/source/ChatSource.java b/src/main/java/eu/m724/source/ChatSource.java new file mode 100644 index 0000000..c18a6b7 --- /dev/null +++ b/src/main/java/eu/m724/source/ChatSource.java @@ -0,0 +1,33 @@ +package eu.m724.source; + +import eu.m724.chat.Chat; +import eu.m724.source.option.Option; +import eu.m724.source.option.Options; + +public interface ChatSource { + /** + * gets information about this ChatSource + * @return information ({@link ChatSourceInfo}) about this {@link ChatSource} + * @see ChatSourceInfo + */ + ChatSourceInfo info(); + + Options options(); + + ChatResponse onAsked(Chat chat); + + /** + * ask for chat completion + * @param chat the current chat, it's recommended that the last message is user's message + * @return a response + * @see ChatResponse + */ + default ChatResponse ask(Chat chat) { + ChatResponse chatResponse = onAsked(chat); + + // TODO make sure it works in parallel + chatResponse.message().thenAccept(chat::addMessage); + + return chatResponse; + } +} diff --git a/src/main/java/eu/m724/source/ChatSourceInfo.java b/src/main/java/eu/m724/source/ChatSourceInfo.java new file mode 100644 index 0000000..93d55b7 --- /dev/null +++ b/src/main/java/eu/m724/source/ChatSourceInfo.java @@ -0,0 +1,4 @@ +package eu.m724.source; + +public record ChatSourceInfo(String name, String author, String versionName, int version) { +} diff --git a/src/main/java/eu/m724/source/net/Requester.java b/src/main/java/eu/m724/source/net/Requester.java new file mode 100644 index 0000000..8de0ad0 --- /dev/null +++ b/src/main/java/eu/m724/source/net/Requester.java @@ -0,0 +1,4 @@ +package eu.m724.source.net; + +public interface Requester { +} diff --git a/src/main/java/eu/m724/source/option/NumberOption.java b/src/main/java/eu/m724/source/option/NumberOption.java new file mode 100644 index 0000000..7755c8a --- /dev/null +++ b/src/main/java/eu/m724/source/option/NumberOption.java @@ -0,0 +1,21 @@ +package eu.m724.source.option; + +public class NumberOption extends Option { + private int minValue = Integer.MIN_VALUE; + private int maxValue = Integer.MAX_VALUE; + + public NumberOption(String id, String label, Integer value) { + super(id, label, value); + } + + public NumberOption(String id, String label, Integer value, int minValue, int maxValue) { + super(id, label, value); + this.minValue = minValue; + this.maxValue = maxValue; + } + + @Override + boolean isValid(Integer value) { + return value >= minValue && value <= maxValue; + } +} diff --git a/src/main/java/eu/m724/source/option/Option.java b/src/main/java/eu/m724/source/option/Option.java new file mode 100644 index 0000000..4e464bd --- /dev/null +++ b/src/main/java/eu/m724/source/option/Option.java @@ -0,0 +1,53 @@ +package eu.m724.source.option; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + * represents an option that is a text label and value of any type + * @param what type is the option + */ +public abstract class Option { + public final String id; + public final String label; + private T value; + + public Option(String id, String label, T value) { + this.id = id; + this.label = label; + this.value = value; + } + + public T getValue() { + return value; + } + + /** + * set value of this option + * @param valueObject the value as an object, it will be converted + * @throws IllegalArgumentException if value doesn't fit constraints + * @throws ClassCastException if type is wrong + */ + public void setValue(Object valueObject) { + Class type = getType(); + + if (!type.isInstance(valueObject)) { + throw new ClassCastException("Invalid type %s, expected %s".formatted(valueObject.getClass().getName(), getType().getName())); + } + + T value = (T) valueObject; + + if (!isValid(value)) + throw new IllegalArgumentException("Value invalid"); + + this.value = value; + } + + public Class getType() { + return (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; + } + + // TODO I'm not a fan of that, probably should address the warnings + + abstract boolean isValid(T value); +} diff --git a/src/main/java/eu/m724/source/option/Options.java b/src/main/java/eu/m724/source/option/Options.java new file mode 100644 index 0000000..f5f8cd4 --- /dev/null +++ b/src/main/java/eu/m724/source/option/Options.java @@ -0,0 +1,48 @@ +package eu.m724.source.option; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class Options { + private final Map> options; + + public Options(Option... options) { + this.options = Arrays.stream(options).collect( + Collectors.toMap(o -> o.id, Function.identity()) + ); + } + + public int count() { + return options.size(); + } + + public String[] keys() { + return options.keySet().toArray(String[]::new); // TODO I should think whether it's a good idea to cast when I don't have to + } + + public Map> getOptions() { + return options; + } // TODO remove that + + public Option getOption(String id) { + return options.get(id); + } + + public Object getOptionValue(String id, T type) { + return (T) options.get(id).getValue(); + } + + /** + * set a value of an option + * @param id the option id + * @param value the value + * @throws IllegalArgumentException if value doesn't fit constraints + * @throws ClassCastException if type is wrong + * @throws NullPointerException if no such option + */ + public void setValue(String id, Object value) { + options.get(id).setValue(value); + } +} diff --git a/src/main/java/eu/m724/source/option/StringOption.java b/src/main/java/eu/m724/source/option/StringOption.java new file mode 100644 index 0000000..e3e8974 --- /dev/null +++ b/src/main/java/eu/m724/source/option/StringOption.java @@ -0,0 +1,26 @@ +package eu.m724.source.option; + +import java.util.regex.Pattern; + +public class StringOption extends Option { + private Pattern pattern = null; + + public StringOption(String id, String label, String value) { + super(id, label, value); + } + + public StringOption( + String id, + String label, + String value, + String pattern + ) { + super(id, label, value); + this.pattern = Pattern.compile(pattern); + } + + @Override + boolean isValid(String value) { + return pattern == null || pattern.matcher(value).matches(); + } +} diff --git a/src/main/resources/name.txt b/src/main/resources/name.txt new file mode 100644 index 0000000..3adb807 --- /dev/null +++ b/src/main/resources/name.txt @@ -0,0 +1,18 @@ +His Royal Majesty, The Quantum Übermensch, ☆☆☆ Ω∞Ж (pronounced "Steve") Ж∞Ω ☆☆☆, +Grand Poobah of the 18th Dimension, Archduke of Antimatter, Lord of the Dance (Interpretive), +Master of Ceremonies for the Heat Death of the Universe, +Chief Executive Sandwich Artist of the Multiverse, +Bearer of the Holy Hand Grenade of Antioch, +Time Lord (Retired), +Keeper of the Sacred Chao, +Last of the Star Whales, +Wielder of Occam's Electric Toothbrush, +01100010 01101001 01101110 01100001 01110010 01111001, +🦄🌈🍕, +Winner of the 2525 Ms. Universe Pageant (Heavy-Fermion Division), +Inventor of Invisible Transparent Ink, +Certified Schrödinger's Cat Herder, +Dungeon Master of Dungeon Masters who Dungeon Master while Dungeon Mastering, +Holder of the Guinness World Record for "Most Titles in a Single Name" (Pending), +Et Cetera, Ad Infinitum, Amen, +The Third-and-a-Half \ No newline at end of file