Commit ec8b7994 by Jonathan Thomas

Integrated character builder and initial greeting handling.

parent 5d7dceae
Pipeline #11658 passed with stage
in 20 seconds
...@@ -8,6 +8,8 @@ import java.util.ArrayList; ...@@ -8,6 +8,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ChatDataManager { public class ChatDataManager {
...@@ -52,8 +54,21 @@ public class ChatDataManager { ...@@ -52,8 +54,21 @@ public class ChatDataManager {
this.sender = ChatSender.NONE; this.sender = ChatSender.NONE;
} }
public static String extractGreeting(String inputText) {
// Regex pattern to match the "Short Greeting" line and capture the greeting text
Pattern pattern = Pattern.compile("- Short Greeting: \"?([^\"]+)\"?");
Matcher matcher = pattern.matcher(inputText);
if (matcher.find()) {
// Return the captured group (greeting text), removing any quotes
return matcher.group(1).replace("\"", "");
}
return "Umm... hello... ugh..."; // Return a default string if no match is found
}
// Generate greeting // Generate greeting
public void generateMessage(ServerPlayerEntity player, String user_message) { public void generateMessage(ServerPlayerEntity player, String systemPrompt, String user_message) {
this.status = ChatStatus.PENDING; this.status = ChatStatus.PENDING;
// Add USER Message // Add USER Message
//this.addMessage(user_message, ChatSender.USER); //this.addMessage(user_message, ChatSender.USER);
...@@ -89,12 +104,19 @@ public class ChatDataManager { ...@@ -89,12 +104,19 @@ public class ChatDataManager {
contextData.put("entity_name", entity.getCustomName().toString()); contextData.put("entity_name", entity.getCustomName().toString());
} }
contextData.put("entity_type", entity.getType().getName().getString().toString()); contextData.put("entity_type", entity.getType().getName().getString().toString());
contextData.put("entity_character_sheet", characterSheet);
// fetch HTTP response from ChatGPT // fetch HTTP response from ChatGPT
ChatGPTRequest.fetchMessageFromChatGPT("chat", contextData).thenAccept(output_message -> { ChatGPTRequest.fetchMessageFromChatGPT(systemPrompt, contextData).thenAccept(output_message -> {
if (output_message != null) { if (output_message != null && systemPrompt == "system-character") {
// Add NEW CHARACTER sheet & greeting
this.characterSheet = output_message;
String shortGreeting = extractGreeting(output_message);
this.addMessage(shortGreeting.replace("\n", " "), ChatSender.ASSISTANT);
} else if (output_message != null && systemPrompt == "system-chat") {
// Add ASSISTANT message // Add ASSISTANT message
this.addMessage(output_message, ChatSender.ASSISTANT); this.addMessage(output_message.replace("\n", " "), ChatSender.ASSISTANT);
} }
}); });
......
...@@ -70,21 +70,22 @@ public class ChatGPTRequest { ...@@ -70,21 +70,22 @@ public class ChatGPTRequest {
return result.replace("\"", "") ; return result.replace("\"", "") ;
} }
public static CompletableFuture<String> fetchMessageFromChatGPT(String promptFileName, Map<String, String> context) { public static CompletableFuture<String> fetchMessageFromChatGPT(String systemPrompt, Map<String, String> context) {
return CompletableFuture.supplyAsync(() -> { return CompletableFuture.supplyAsync(() -> {
try { try {
// Load and prepare the prompt template // Get user message
String template = ""; String userMessage = context.get("message");
if (!promptFileName.isEmpty()) {
// Load and prepare the system prompt template
String systemMessage = "";
if (!systemPrompt.isEmpty()) {
// Load prompt from resources // Load prompt from resources
template = loadPromptFromResource(ModInit.serverInstance.getResourceManager(), "prompts/" + promptFileName); systemMessage = loadPromptFromResource(ModInit.serverInstance.getResourceManager(), "prompts/" + systemPrompt);
} else if (context.containsKey("user_message")) {
// Use 'user_message' as prompt if no template specified
template = context.get("user_message");
} }
// Replace placeholders (if any) // Replace placeholders (if any)
String prompt = replacePlaceholders(template, context); systemMessage = replacePlaceholders(systemMessage, context);
userMessage = replacePlaceholders(userMessage, context);
URL url = new URL("https://api.openai.com/v1/chat/completions"); URL url = new URL("https://api.openai.com/v1/chat/completions");
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
...@@ -95,8 +96,8 @@ public class ChatGPTRequest { ...@@ -95,8 +96,8 @@ public class ChatGPTRequest {
// Build JSON payload for ChatGPT // Build JSON payload for ChatGPT
List<ChatGPTRequestMessage> messages = new ArrayList<>(); List<ChatGPTRequestMessage> messages = new ArrayList<>();
messages.add(new ChatGPTRequestMessage("system", "You are a silly Minecraft entity who speaks to the player in short riddles.")); messages.add(new ChatGPTRequestMessage("system", systemMessage));
messages.add(new ChatGPTRequestMessage("user", prompt)); messages.add(new ChatGPTRequestMessage("user", userMessage));
// Convert JSON to String // Convert JSON to String
ChatGPTRequestPayload payload = new ChatGPTRequestPayload("gpt-3.5-turbo", messages); ChatGPTRequestPayload payload = new ChatGPTRequestPayload("gpt-3.5-turbo", messages);
...@@ -118,7 +119,7 @@ public class ChatGPTRequest { ...@@ -118,7 +119,7 @@ public class ChatGPTRequest {
Gson gsonOutput = new Gson(); Gson gsonOutput = new Gson();
ChatGPTResponse chatGPTResponse = gsonOutput.fromJson(response.toString(), ChatGPTResponse.class); ChatGPTResponse chatGPTResponse = gsonOutput.fromJson(response.toString(), ChatGPTResponse.class);
if (chatGPTResponse != null && chatGPTResponse.choices != null && !chatGPTResponse.choices.isEmpty()) { if (chatGPTResponse != null && chatGPTResponse.choices != null && !chatGPTResponse.choices.isEmpty()) {
String content = chatGPTResponse.choices.get(0).message.content.replace("\n", " "); String content = chatGPTResponse.choices.get(0).message.content;
LOGGER.info(content); LOGGER.info(content);
return content; return content;
} }
......
...@@ -48,7 +48,7 @@ public class ModInit implements ModInitializer { ...@@ -48,7 +48,7 @@ public class ModInit implements ModInitializer {
chatData.status == ChatDataManager.ChatStatus.END) { chatData.status == ChatDataManager.ChatStatus.END) {
// Only generate a new greeting if not already doing so // Only generate a new greeting if not already doing so
LOGGER.info("Generate greeting for: " + entity.getType().toString()); LOGGER.info("Generate greeting for: " + entity.getType().toString());
chatData.generateMessage(player, "Hello!"); chatData.generateMessage(player, "system-character", "Please generate a new background character who lives near the {{player_biome}}");
} }
} }
}); });
...@@ -106,7 +106,7 @@ public class ModInit implements ModInitializer { ...@@ -106,7 +106,7 @@ public class ModInit implements ModInitializer {
if (chatData.status == ChatDataManager.ChatStatus.END) { if (chatData.status == ChatDataManager.ChatStatus.END) {
// Add new message // Add new message
LOGGER.info("Add new message (" + message + ") to Entity: " + entity.getType().toString()); LOGGER.info("Add new message (" + message + ") to Entity: " + entity.getType().toString());
chatData.generateMessage(player, message); chatData.generateMessage(player, "system-chat", message);
} }
} }
}); });
......
You are a RPG dungeon master, crafting a new character sheet in the following format. Be very creative with each new
character. These characters will be inhabiting and participating in an epic fantasy adventure which takes place in
Minecraft. Please limit traits to a few choices and keep them short and concise. Please avoid any specific races or
classes. Please follow the character sheet format below:
- Name:
- Personality:
- Speaking Style / Tone:
- Likes:
- Dislikes:
- Age:
- Alignment:
- Short Greeting:
\ No newline at end of file
Please respond directly to the following player's message, as if it was written by this Minecraft entity. Please respond directly to the player, as if it was written by the
Please do NOT break the 4th wall and refer to the player or game. following Minecraft character. Please do NOT break the 4th wall.
Entity Details: Entity Details:
- Name: {{entity_name}} - Type: {{entity_type}}
- Type: {{entity_type}} {{entity_character_sheet}}
Player Details: Player Character Sheet:
- Name: {{player_name}} - Name: {{player_name}}
- Health: {{player_health}} - Health: {{player_health}}
- Hunger: {{player_hunger}} - Hunger: {{player_hunger}}
- Biome: {{player_biome}} - Held Item: {{player_held_item}}
- Held Item: {{player_held_item}} - Armor: Head: {{player_armor_head}}, Chest: {{player_armor_chest}}, Legs: {{player_armor_legs}}, Feet: {{player_armor_feet}}
- Armor: Head: {{player_armor_head}}, Chest: {{player_armor_chest}}, Legs: {{player_armor_legs}}, Feet: {{player_armor_feet}}
- Current World Time: {{world_time}} (24 hour format)
Player Message: World Info:
{{message}} - Biome: {{player_biome}}
\ No newline at end of file - Current Time: {{world_time}} (24 hour format)
\ No newline at end of file
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