Commit 2e7dfe49 by Jonathan Thomas

Added message history for each entity conversation. Also tweaked the prompts a…

Added message history for each entity conversation. Also tweaked the prompts a bit. Feels pretty nice now
parent ec8b7994
Pipeline #11659 passed with stage
in 20 seconds
......@@ -259,7 +259,7 @@ public class ClientInit implements ClientModInitializer {
// Draw 'pending' button
drawIcon("button-dotdot", matrices, entity, -16, textHeaderHeight, 32, 17);
} else {
} else if (chatData.sender == ChatDataManager.ChatSender.ASSISTANT) {
// Draw text background (no smaller than 50F tall)
drawTextBubbleBackground(matrices, entity, -64, 0, 128, scaledTextHeight);
......
......@@ -26,7 +26,6 @@ public class ChatDataManager {
}
public enum ChatSender {
NONE, // A blank chat message
USER, // A user chat message
ASSISTANT // A GPT generated message
}
......@@ -34,13 +33,23 @@ public class ChatDataManager {
// HashMap to associate unique entity IDs with their chat data
private HashMap<Integer, EntityChatData> entityChatDataMap;
public static class ChatMessage {
public String message;
public ChatSender sender;
public ChatMessage(String message, ChatSender sender) {
this.message = message;
this.sender = sender;
}
}
// Inner class to hold entity-specific data
public static class EntityChatData {
public int entityId;
public String currentMessage;
public int currentLineNumber;
public ChatStatus status;
public List<String> previousMessages;
public List<ChatMessage> previousMessages;
public String characterSheet;
public ChatSender sender;
......@@ -51,7 +60,7 @@ public class ChatDataManager {
this.previousMessages = new ArrayList<>();
this.characterSheet = "";
this.status = ChatStatus.NONE;
this.sender = ChatSender.NONE;
this.sender = ChatSender.USER;
}
public static String extractGreeting(String inputText) {
......@@ -71,11 +80,10 @@ public class ChatDataManager {
public void generateMessage(ServerPlayerEntity player, String systemPrompt, String user_message) {
this.status = ChatStatus.PENDING;
// Add USER Message
//this.addMessage(user_message, ChatSender.USER);
this.addMessage(user_message, ChatSender.USER);
// Add PLAYER context information
Map<String, String> contextData = new HashMap<>();
contextData.put("message", user_message);
contextData.put("player_name", player.getDisplayName().getString());
contextData.put("player_health", String.valueOf(player.getHealth()));
contextData.put("player_hunger", String.valueOf(player.getHungerManager().getFoodLevel()));
......@@ -107,7 +115,7 @@ public class ChatDataManager {
contextData.put("entity_character_sheet", characterSheet);
// fetch HTTP response from ChatGPT
ChatGPTRequest.fetchMessageFromChatGPT(systemPrompt, contextData).thenAccept(output_message -> {
ChatGPTRequest.fetchMessageFromChatGPT(systemPrompt, contextData, previousMessages).thenAccept(output_message -> {
if (output_message != null && systemPrompt == "system-character") {
// Add NEW CHARACTER sheet & greeting
this.characterSheet = output_message;
......@@ -125,15 +133,21 @@ public class ChatDataManager {
}
// Add a message to the history and update the current message
public void addMessage(String message, ChatSender sender) {
if (!currentMessage.isEmpty()) {
previousMessages.add(sender.toString() + ": " + currentMessage);
}
currentMessage = message;
public void addMessage(String message, ChatSender messageSender) {
// Add message to history
previousMessages.add(new ChatMessage(message, messageSender));
// Set line number of displayed text
// Set new message and reset line number of displayed text
currentMessage = message;
currentLineNumber = 0;
if (messageSender == ChatSender.ASSISTANT) {
// Show new generated message
status = ChatStatus.DISPLAY;
} else if (messageSender == ChatSender.USER) {
// Show pending icon
status = ChatStatus.PENDING;
}
sender = messageSender;
// Broadcast to all players
ModInit.BroadcastPacketMessage(this);
......
......@@ -70,12 +70,9 @@ public class ChatGPTRequest {
return result.replace("\"", "") ;
}
public static CompletableFuture<String> fetchMessageFromChatGPT(String systemPrompt, Map<String, String> context) {
public static CompletableFuture<String> fetchMessageFromChatGPT(String systemPrompt, Map<String, String> context, List<ChatDataManager.ChatMessage> messageHistory) {
return CompletableFuture.supplyAsync(() -> {
try {
// Get user message
String userMessage = context.get("message");
// Load and prepare the system prompt template
String systemMessage = "";
if (!systemPrompt.isEmpty()) {
......@@ -85,7 +82,6 @@ public class ChatGPTRequest {
// Replace placeholders (if any)
systemMessage = replacePlaceholders(systemMessage, context);
userMessage = replacePlaceholders(userMessage, context);
URL url = new URL("https://api.openai.com/v1/chat/completions");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
......@@ -94,13 +90,17 @@ public class ChatGPTRequest {
connection.setRequestProperty("Authorization", "Bearer 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");
connection.setDoOutput(true);
// Build JSON payload for ChatGPT
// Build JSON payload for ChatGPT (with previous messages)
List<ChatGPTRequestMessage> messages = new ArrayList<>();
messages.add(new ChatGPTRequestMessage("system", systemMessage));
messages.add(new ChatGPTRequestMessage("user", userMessage));
for (ChatDataManager.ChatMessage chatMessage : messageHistory) {
String senderName = chatMessage.sender.toString().toLowerCase();
String messageText = replacePlaceholders(chatMessage.message, context);
messages.add(new ChatGPTRequestMessage(senderName, messageText));
}
// Convert JSON to String
ChatGPTRequestPayload payload = new ChatGPTRequestPayload("gpt-3.5-turbo", messages);
ChatGPTRequestPayload payload = new ChatGPTRequestPayload("gpt-3.5-turbo-1106", messages);
Gson gsonInput = new Gson();
String jsonInputString = gsonInput.toJson(payload);
......
Please respond directly to the player, as if it was written by the
following Minecraft character. Please do NOT break the 4th wall.
Please respond directly to the player, as if the response was written by the following Minecraft entity.
Please do NOT break the 4th wall and try and leverage the entity's character sheet below as much as
possible.
Entity Details:
- Type: {{entity_type}}
Entity Character Sheet:
- Type / Species: {{entity_type}}
{{entity_character_sheet}}
Player Character Sheet:
......
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