Skip to content

Instantly share code, notes, and snippets.

@automenta
Created September 17, 2024 20:00
Show Gist options
  • Save automenta/69a2fdee288bf0627ea3e5ae6c125496 to your computer and use it in GitHub Desktop.
Save automenta/69a2fdee288bf0627ea3e5ae6c125496 to your computer and use it in GitHub Desktop.
import com.fasterxml.jackson.databind.ObjectMapper;
import jdk.jshell.JShell;
import jdk.jshell.SnippetEvent;
import jdk.jshell.VarSnippet;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.*;
import java.util.stream.Collectors;
public class JShellLM {
private final JShell jshell;
private final HttpClient httpClient;
private final String ollamaEndpoint;
private final ObjectMapper objectMapper;
private final Deque<String> commandHistory;
private static final int MAX_HISTORY = 5;
public JShellLM(String ollamaEndpoint) {
this.jshell = JShell.create();
this.httpClient = HttpClient.newHttpClient();
this.ollamaEndpoint = ollamaEndpoint;
this.objectMapper = new ObjectMapper();
this.commandHistory = new LinkedList<>();
}
public void run() {
var scanner = new Scanner(System.in);
while (true) {
try {
System.out.print("jshell> ");
var input = scanner.nextLine();
if (input.equals("/exit")) break;
var events = jshell.eval(input);
var output = processEvents(events);
System.out.println(output);
updateCommandHistory(input);
var feedback = getLMFeedback(input, output);
System.out.println(/*"LM Feedback: " + */feedback);
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
jshell.close();
}
private String processEvents(List<SnippetEvent> events) {
return events.stream()
.map(this::eventToString)
.collect(Collectors.joining("\n"));
}
private String eventToString(SnippetEvent event) {
if (event.exception() != null) {
return "Exception: " + event.exception().getMessage();
}
var value = event.value();
return value != null ? value.toString() : "(empty)";
}
private void updateCommandHistory(String command) {
commandHistory.addFirst(command);
if (commandHistory.size() > MAX_HISTORY)
commandHistory.removeLast();
}
private String getLMFeedback(String input, String output) {
var prompt = buildPrompt(input, output);
return sendToLM(prompt);
}
private String buildPrompt(String input, String output) {
var variables = getDetailedVariableInfo();
var history = String.join("\n", commandHistory);
return """
Analyze this Java JShell context & code evaluation:
Input History:
%s
Input: %s
Output: %s
Variables:
%s
Answer any of these questions if it would be informative to the user:
1. Explanation of the latest command and its output
2. Potential improvements or best practices
3. Suggestions for next steps or related concepts to explore
4. The cause of errors explained, and how to fix
Respond concise, focusing on important points. Don't state the obvious, or uninformative (ex: 'there is no error').
""".formatted(history, input, output, variables);
}
private String getDetailedVariableInfo() {
return jshell.variables()
.map(this::formatVariableInfo)
.collect(Collectors.joining("\n"));
}
private String formatVariableInfo(VarSnippet var) {
var value = jshell.eval(var.name())
.stream().findFirst()
.map(SnippetEvent::value)
.map(Object::toString)
.orElse("N/A");
return "%s %s = %s".formatted(var.typeName(), var.name(), value);
}
private String sendToLM(String prompt) {
var requestBody = Map.of(
"model", "llamablit2",
"prompt", prompt,
"stream", false
);
try {
var request = HttpRequest.newBuilder()
.uri(URI.create(ollamaEndpoint))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(requestBody)))
.build();
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200)
throw new RuntimeException("API request failed with status code: " + response.statusCode());
var responseBody = objectMapper.readTree(response.body());
return responseBody.at("/response").asText();
} catch (Exception e) {
throw new RuntimeException("Error getting LM feedback: " + e.getMessage(), e);
}
}
public static void main(String[] args) {
new JShellLM("http://localhost:11434/api/generate").run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment