From 9b6666dc9c3edb672dfe6f8583879b867af127f0 Mon Sep 17 00:00:00 2001 From: Polish Hammer Date: Thu, 27 Aug 2026 16:12:03 +0200 Subject: [PATCH] AI: a dead Assistants API must not disable the whole AI cog Field report from both instances: "Command modele_ai is not found", and on restart the extension fails outright: ai_commands.py:129 in cog_load thread = await OPENAICLIENT.beta.threads.create() openai.NotFoundError: Error code: 404 -> ExtensionFailed: Extension 'ai_commands' raised an error The personal-assistants bootstrap calls the OpenAI Assistants API (beta threads/runs), a legacy surface that now answers 404. That exception propagated out of cog_load, so discord.py failed the whole extension - and with it EVERY AI command: $gadaj_teraz, $modele_ai and the conversation handler. The bot kept running (bot.py loads each extension defensively), it simply had no AI at all. cog_load already had the right instinct - it skips the bootstrap cleanly when OPENAICLIENT is None, so a Claude-only deployment works - but it guarded against the client being ABSENT, not against the call FAILING. Move the bootstrap into _start_personal_assistants() and treat any failure there as non-fatal: log what was lost and carry on. Personal assistants are one optional feature; the rest of the cog works fine on Claude and Ollama and must not go down with them. Not unit-tested on purpose: exercising cog_load needs stubs for openai, tiktoken and a tasks.loop complete enough to answer is_running(), at which point the test exercises the stubs rather than the code. Verified against the running cluster instead. Co-Authored-By: Claude Opus 4.8 --- ai_commands.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ai_commands.py b/ai_commands.py index 50d28ce..df54bfe 100644 --- a/ai_commands.py +++ b/ai_commands.py @@ -114,6 +114,25 @@ class Events(commands.Cog): "OPENAICLIENT niedostępny - osobiści asystenci (OpenAI Assistants API) wyłączeni" ) return + # The bootstrap below must NEVER take the cog down with it. It calls the + # OpenAI Assistants API (beta threads/runs), which is a legacy surface - + # it now answers 404, and that exception propagated out of cog_load, + # failed the whole extension, and took EVERY AI command with it + # ($gadaj_teraz, $modele_ai, the conversation handler). Personal + # assistants are one optional feature; losing them must not disable the + # AI cog, which otherwise works fine on Claude and Ollama. + try: + await self._start_personal_assistants() + except Exception as exc: # pylint: disable=broad-exception-caught + self.logger.warning( + "Osobiści asystenci (OpenAI Assistants API) wyłączeni - %s: %s. " + "Reszta AI (rozmowy, $gadaj_teraz, $modele_ai) działa normalnie.", + type(exc).__name__, exc, + ) + + async def _start_personal_assistants(self): + """Bootstrap the per-user OpenAI Assistants threads. Optional feature: + callers must treat a failure here as non-fatal (see cog_load).""" for superfryta_id, superfryta in SPECJALNE_ZIEMNIACZKI.items(): if superfryta[4] != "":