From 4db1dfdece53d913a4cbf532eeda805d3d132056 Mon Sep 17 00:00:00 2001 From: Anders Holck Date: Thu, 30 Apr 2026 19:17:48 +0200 Subject: [PATCH] Improve translation prompt and add /trans off toggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Focus on grammar/sentence structure for language detection - Ignore code, URLs, tech jargon in language classification - /trans cycles: local → public → off - Strip trailing whitespace from LLM responses - Suppress empty translation results --- main.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 499132a..d7610e1 100644 --- a/main.c +++ b/main.c @@ -78,6 +78,7 @@ static struct { /* Query target (for /q) */ static char query_target[64] = ""; static int translate_public = 0; /* /trans toggle: echo translations to channel */ +static int translate_enabled = 1; /* master toggle for translation */ /* Track nicks who sent us private messages */ #define MAX_PM_NICKS 32 @@ -186,7 +187,7 @@ static void ai_config_load(void) static int needs_translation(const char *text) { - if (!ai_cfg.enabled) return 0; + if (!ai_cfg.enabled || !translate_enabled) return 0; /* Skip very short messages (nicks, URLs, single words like "ok") */ int words = 0; for (const char *p = text; *p; p++) @@ -241,7 +242,7 @@ static void translate_async(const char *text, int level, const char *target) char body[2048]; snprintf(body, sizeof(body), "{\"model\":\"%s\",\"messages\":[" - "{\"role\":\"system\",\"content\":\"You are a translator for an IRC chat. The user understands %s. If the message is in any of those languages or a mix of them, respond with exactly SKIP. Only translate messages in other languages to %s. Respond with only the translation or SKIP.\"}," + "{\"role\":\"system\",\"content\":\"You are a language filter for IRC. Respond with ONLY the word SKIP or a translation. Rules: If the sentence structure and grammar is %s, respond SKIP. Code snippets, function names, URLs, and technical jargon inside a sentence do NOT change the language. Only translate if the grammar itself is in another language. Translate to %s.\"}," "{\"role\":\"user\",\"content\":\"%s\"}" "],\"stream\":false,\"tool_choice\":\"none\"}", ai_cfg.model, ai_cfg.skip_langs, ai_cfg.target_lang, escaped); @@ -1188,9 +1189,18 @@ static void handle_input(char *line) wprintf(WL_MSG, "* %s %s\n", nick, slap); } } else if (strcasecmp(cmd, "trans") == 0) { - translate_public = !translate_public; - wprintf(current_level, "* Translation echo %s\n", - translate_public ? "ON" : "OFF"); + if (!translate_enabled) { + translate_enabled = 1; + translate_public = 0; + wprintf(current_level, "* Translation ON (local only)\n"); + } else if (!translate_public) { + translate_public = 1; + wprintf(current_level, "* Translation ON (public echo)\n"); + } else { + translate_enabled = 0; + translate_public = 0; + wprintf(current_level, "* Translation OFF\n"); + } } else if (strcasecmp(cmd, "ctcp") == 0 && args) { char *target = args; char *ctcp_cmd = strchr(args, ' '); @@ -1473,8 +1483,12 @@ int main(int argc, char *argv[]) waitpid(translate_pending[ti].pid, NULL, 0); if (n > 0) { tbuf[n] = '\0'; + /* Strip trailing whitespace */ + while (n > 0 && (tbuf[n-1] == '\n' || tbuf[n-1] == '\r' || tbuf[n-1] == ' ')) + tbuf[--n] = '\0'; /* Skip if LLM says it's already in a skip language */ - if (strcasecmp(tbuf, "SKIP") == 0 || + if (n == 0 || + strcasecmp(tbuf, "SKIP") == 0 || strncasecmp(tbuf, "SKIP", 4) == 0) { /* do nothing */ } else {