diff --git a/plugins/_memory/extensions/python/message_loop_prompts_after/_50_recall_memories.py b/plugins/_memory/extensions/python/message_loop_prompts_after/_50_recall_memories.py index 42fb393b0a..be971505d3 100644 --- a/plugins/_memory/extensions/python/message_loop_prompts_after/_50_recall_memories.py +++ b/plugins/_memory/extensions/python/message_loop_prompts_after/_50_recall_memories.py @@ -1,4 +1,6 @@ import asyncio +import litellm +from litellm.exceptions import AuthenticationError from helpers.extension import Extension from agent import LoopData from helpers import dirty_json, errors, log, plugins @@ -101,7 +103,18 @@ async def search_memories(self, log_item: log.LogItem, loop_data: LoopData, **kw ) query = query.strip() log_item.update(query=query) # no need for streaming here + except AuthenticationError as e: + # Guard against NVIDIA API key being sent to OpenAI endpoint + if "nvapi-" in str(e): + log_item.update(heading="SKIPPED: Invalid API Key (NVIDIA key on OpenAI endpoint)") + log_item.update(content="Memory recall skipped due to configuration error. Please update API_KEY_OPENAI in .env or fix provider routing.") + # Gracefully exit without crashing or logging full traceback + query = "" + else: + # Re-raise if it is a different authentication error + raise except Exception as e: + # Catch any other unexpected errors err = errors.format_error(e) self.agent.context.log.log( type="warning", heading="Recall memories extension error:", content=err @@ -114,7 +127,7 @@ async def search_memories(self, log_item: log.LogItem, loop_data: LoopData, **kw heading="Failed to generate memory query", ) return - + # otherwise use the message and history as query else: query = user_instruction + "\n\n" + history diff --git a/plugins/_memory/extensions/python/monologue_end/_51_memorize_solutions.py b/plugins/_memory/extensions/python/monologue_end/_51_memorize_solutions.py index 7e9bb8cd5e..fc7296950b 100644 --- a/plugins/_memory/extensions/python/monologue_end/_51_memorize_solutions.py +++ b/plugins/_memory/extensions/python/monologue_end/_51_memorize_solutions.py @@ -1,4 +1,6 @@ import asyncio +import litellm +from litellm.exceptions import AuthenticationError from helpers import errors, plugins from helpers.extension import Extension from helpers.dirty_json import DirtyJson @@ -23,7 +25,7 @@ def execute(self, loop_data: LoopData = LoopData(), **kwargs): if not set["memory_memorize_enabled"]: return - + # show full util message log_item = self.agent.context.log.log( type="util", @@ -57,12 +59,28 @@ async def memorize(self, loop_data: LoopData, log_item: LogItem, **kwargs): # log_item.stream(content=content) # call util llm to find solutions in history - solutions_json = await self.agent.call_utility_model( - system=system, - message=msgs_text, - # callback=log_callback, - background=True, - ) + try: + solutions_json = await self.agent.call_utility_model( + system=system, + message=msgs_text, + # callback=log_callback, + background=True, + ) + except AuthenticationError as e: + # Guard against NVIDIA API key being sent to OpenAI endpoint + if "nvapi-" in str(e): + log_item.update(heading="SKIPPED: Invalid API Key (NVIDIA key on OpenAI endpoint)") + log_item.update(content="Memory memorization skipped due to configuration error. Please update API_KEY_OPENAI in .env or fix provider routing.") + # Gracefully exit without crashing the background thread + return + else: + # Re-raise if it is a different authentication error + raise + except Exception as e: + # Catch any other unexpected errors to prevent thread crashes + log_item.update(heading="SKIPPED: Memory memorization failed") + log_item.update(content=f"Error: {str(e)}") + return # log query < no need for streaming utility messages log_item.update(content=solutions_json)