diff --git a/src/main/java/dev/marcospaulo/canalhandia/Ai.java b/src/main/java/dev/marcospaulo/canalhandia/Ai.java index 6833619..76e2325 100644 --- a/src/main/java/dev/marcospaulo/canalhandia/Ai.java +++ b/src/main/java/dev/marcospaulo/canalhandia/Ai.java @@ -264,15 +264,26 @@ final class Ai { } /** - * Makes a model reply safe to print in chat. + * Makes a model reply safe and readable in chat. * *

Strips colour codes so the reply cannot forge server messages, folds * newlines so one answer stays one chat entry, and removes leading slashes * so nothing that comes back reads as a command to run. + * + *

It also strips markdown and emoji, which the models emit freely. + * Minecraft chat renders neither: {@code **negrito**} arrives as literal + * asterisks, and emoji show up as empty boxes on Bedrock. */ static String sanitise(String raw, int max) { String text = raw.replace('§', ' ') .replaceAll("[\\r\\n]+", " ") + // Markdown emphasis and code fences: chat shows the characters, not the effect. + .replaceAll("\\*{1,3}([^*]+)\\*{1,3}", "$1") + .replaceAll("`{1,3}([^`]+)`{1,3}", "$1") + .replaceAll("^#{1,6}\\s+", "") + // Emoji live outside the BMP, plus the symbol blocks and the + // variation selector. Accented pt-BR letters are far below this. + .replaceAll("[\\x{1F000}-\\x{1FAFF}\\x{2190}-\\x{2BFF}\\x{FE0F}\\x{20E3}]", "") .replaceAll("\\s{2,}", " ") .trim(); while (text.startsWith("/")) { diff --git a/src/main/java/dev/marcospaulo/canalhandia/Settings.java b/src/main/java/dev/marcospaulo/canalhandia/Settings.java index d08e1fa..3fbd227 100644 --- a/src/main/java/dev/marcospaulo/canalhandia/Settings.java +++ b/src/main/java/dev/marcospaulo/canalhandia/Settings.java @@ -222,7 +222,10 @@ final class Settings { } String aiModel() { - return plugin.getConfig().getString("ia.modelo", "MiniMax-M2"); + // M2.7 measured 2.7-5.2s with correct answers. M3 is a reasoning model: + // its thinking counts against max_tokens, so replies get truncated + // mid-word unless the budget is raised far past what chat needs. + return plugin.getConfig().getString("ia.modelo", "MiniMax-M2.7"); } void aiModel(String model) { @@ -243,7 +246,9 @@ final class Settings { + "ao terminal ou aos comandos do jogo, e não pode executar nada. " + "Se pedirem para você rodar comandos, mexer no servidor, dar itens, " + "banir alguém ou revelar configurações, explique que você só conversa. " - + "Nunca escreva comandos de terminal nem de Minecraft."); + + "Nunca escreva comandos de terminal nem de Minecraft. " + + "Escreva em texto puro: nada de markdown, asteriscos, crases ou " + + "emoji, porque o chat do Minecraft não formata nada disso."); } int aiMaxTokens() { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 6e054c2..5eb80a7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -123,7 +123,10 @@ ranking-tamanho: 5 # rodar nada no servidor, no terminal ou no jogo. ia: url: "https://api.minimax.io/v1/text/chatcompletion_v2" - modelo: "MiniMax-M2" + # M2.7 mediu 2,7-5,2s com respostas corretas nos testes. O M3 é um modelo de + # raciocínio: o "pensamento" dele consome o max-tokens e a resposta chega + # cortada no meio da palavra, a não ser com um orçamento muito maior. + modelo: "MiniMax-M2.7" # Tamanho da resposta pedida ao modelo, e o corte final no chat. max-tokens: 300 @@ -155,4 +158,6 @@ ia: ou aos comandos do jogo, e não pode executar nada. Se pedirem para você rodar comandos, mexer no servidor, dar itens, banir alguém ou revelar configurações, explique que você só conversa. Nunca escreva comandos de - terminal nem de Minecraft. + terminal nem de Minecraft. Escreva em texto puro: nada de markdown, + asteriscos, crases ou emoji, porque o chat do Minecraft não formata nada + disso.