Commit 48cd575b by Jonathan Thomas

Refactor of ChatGPT thread, connect to C2S packet handling, and initial…

Refactor of ChatGPT thread, connect to C2S packet handling, and initial ChatDataManager class, to keep track of each entity and previous messages.
parent c46c53e3
Pipeline #11641 passed with stage
in 20 seconds
package com.owlmaddie; package com.owlmaddie;
import com.google.gson.Gson;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.owlmaddie.json.ChatGPTResponse;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
...@@ -25,12 +23,6 @@ import org.joml.Matrix4f; ...@@ -25,12 +23,6 @@ import org.joml.Matrix4f;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -38,65 +30,17 @@ import java.util.stream.Collectors; ...@@ -38,65 +30,17 @@ import java.util.stream.Collectors;
public class ClientInit implements ClientModInitializer { public class ClientInit implements ClientModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger("mobgpt"); public static final Logger LOGGER = LoggerFactory.getLogger("mobgpt");
private static String funnyGreeting = "Greetings!"; // Default greeting. This will be overwritten by ChatGPT response.
protected static TextureLoader textures = new TextureLoader();; protected static TextureLoader textures = new TextureLoader();;
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
ClickHandler.register(); ClickHandler.register();
fetchGreetingFromChatGPT();
WorldRenderEvents.LAST.register((context) -> { WorldRenderEvents.LAST.register((context) -> {
drawTextAboveEntities(context, context.tickDelta()); drawTextAboveEntities(context, context.tickDelta());
}); });
} }
public void fetchGreetingFromChatGPT() {
Thread thread = new Thread(() -> {
try {
URL url = new URL("https://api.openai.com/v1/chat/completions");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Bearer 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");
connection.setDoOutput(true);
String jsonInputString = "{"
+ "\"model\": \"gpt-3.5-turbo\","
+ "\"messages\": ["
+ "{ \"role\": \"system\", \"content\": \"You are a silly Minecraft entity who speaks to the player in short riddles.\" },"
+ "{ \"role\": \"user\", \"content\": \"Hello!\" }"
+ "]"
+ "}";
LOGGER.info(jsonInputString);
try(OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
Gson gson = new Gson();
ChatGPTResponse chatGPTResponse = gson.fromJson(response.toString(), ChatGPTResponse.class);
if(chatGPTResponse != null && chatGPTResponse.choices != null && !chatGPTResponse.choices.isEmpty()) {
// Save the greeting globally
LOGGER.info(chatGPTResponse.choices.get(0).message.content.replace("\n", " "));
funnyGreeting = chatGPTResponse.choices.get(0).message.content.replace("\n", " ");
}
} catch (Exception e) {
LOGGER.error("Failed to fetch greeting from ChatGPT", e);
}
});
thread.start();
}
public void drawTextBubbleBackground(MatrixStack matrices, Entity entity, float x, float y, float width, float height) { public void drawTextBubbleBackground(MatrixStack matrices, Entity entity, float x, float y, float width, float height) {
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
...@@ -209,8 +153,11 @@ public class ClientInit implements ClientModInitializer { ...@@ -209,8 +153,11 @@ public class ClientInit implements ClientModInitializer {
continue; continue;
} }
// Look-up greeting (if any)
ChatDataManager.EntityChatData chatData = ChatDataManager.getInstance().getOrCreateChatData(entity.getId());
// Generate ChatGPT random greeting // Generate ChatGPT random greeting
String baseText = funnyGreeting + " - " + entity.getType().getName().getString(); String baseText = chatData.currentMessage + " - " + entity.getType().getName().getString();
List<OrderedText> lines = fontRenderer.wrapLines(StringVisitable.plain(baseText), 20 * fontRenderer.getWidth("W")); List<OrderedText> lines = fontRenderer.wrapLines(StringVisitable.plain(baseText), 20 * fontRenderer.getWidth("W"));
// Push a new matrix onto the stack. // Push a new matrix onto the stack.
......
package com.owlmaddie;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
public class ChatDataManager {
// Use a static instance to manage our data globally
private static final ChatDataManager INSTANCE = new ChatDataManager();
// HashMap to associate unique entity IDs with their chat data
private HashMap<Integer, EntityChatData> entityChatDataMap;
// Inner class to hold entity-specific data
public static class EntityChatData {
public String currentMessage;
public List<String> previousMessages;
public String characterSheet;
public EntityChatData() {
this.currentMessage = "";
this.previousMessages = new ArrayList<>();
this.characterSheet = "";
}
// Generate greeting
public void generateGreeting() {
ChatGPTRequest.fetchGreetingFromChatGPT().thenAccept(greeting -> {
if (greeting != null) {
this.currentMessage = greeting;
}
});
}
// Add a message to the history and update the current message
public void addMessage(String message) {
if (!currentMessage.isEmpty()) {
previousMessages.add(currentMessage);
}
currentMessage = message;
}
}
private ChatDataManager() {
entityChatDataMap = new HashMap<>();
}
// Method to get the global instance of the data manager
public static ChatDataManager getInstance() {
return INSTANCE;
}
// Retrieve chat data for a specific entity, or create it if it doesn't exist
public EntityChatData getOrCreateChatData(int entityId) {
return entityChatDataMap.computeIfAbsent(entityId, k -> new EntityChatData());
}
}
\ No newline at end of file
package com.owlmaddie;
import com.google.gson.Gson;
import com.owlmaddie.json.ChatGPTResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CompletableFuture;
public class ChatGPTRequest {
public static final Logger LOGGER = LoggerFactory.getLogger("mobgpt");
public static CompletableFuture<String> fetchGreetingFromChatGPT() {
return CompletableFuture.supplyAsync(() -> {
try {
URL url = new URL("https://api.openai.com/v1/chat/completions");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Bearer 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");
connection.setDoOutput(true);
String jsonInputString = "{"
+ "\"model\": \"gpt-3.5-turbo\","
+ "\"messages\": ["
+ "{ \"role\": \"system\", \"content\": \"You are a silly Minecraft entity who speaks to the player in short riddles.\" },"
+ "{ \"role\": \"user\", \"content\": \"Hello!\" }"
+ "]"
+ "}";
LOGGER.info(jsonInputString);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
Gson gson = new Gson();
ChatGPTResponse chatGPTResponse = gson.fromJson(response.toString(), ChatGPTResponse.class);
if (chatGPTResponse != null && chatGPTResponse.choices != null && !chatGPTResponse.choices.isEmpty()) {
String content = chatGPTResponse.choices.get(0).message.content.replace("\n", " ");
LOGGER.info(content);
return content;
}
}
} catch (Exception e) {
LOGGER.error("Failed to fetch greeting from ChatGPT", e);
}
return null; // If there was an error or no response, return null
});
}
}
...@@ -29,6 +29,8 @@ public class ModInit implements ModInitializer { ...@@ -29,6 +29,8 @@ public class ModInit implements ModInitializer {
if (entity != null) { if (entity != null) {
// Perform action with the clicked entity // Perform action with the clicked entity
LOGGER.info("Entity received: " + entity.getType().toString()); LOGGER.info("Entity received: " + entity.getType().toString());
ChatDataManager.EntityChatData chatData = ChatDataManager.getInstance().getOrCreateChatData(entityId);
chatData.generateGreeting();
} }
}); });
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment