From 06b4bd58b8c80a12055a3c5c92da3d4913e06114 Mon Sep 17 00:00:00 2001 From: Jonathan Hill Date: Mon, 18 May 2026 03:54:08 -0500 Subject: [PATCH] fix: guard against empty/filtered LLM responses in openai adapter An empty choices list raises IndexError; a None message (returned by some providers on filtered content with HTTP 200) raises AttributeError. Add null checks in generate_response, agenerate_response, evaluate_responsegen, and chat_history.summarize_memory before accessing choices[0].message. --- agentverse/llms/openai.py | 8 ++++++++ agentverse/memory/chat_history.py | 7 +++++-- scripts/evaluate_responsegen.py | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/agentverse/llms/openai.py b/agentverse/llms/openai.py index 11b17f02..505a7757 100644 --- a/agentverse/llms/openai.py +++ b/agentverse/llms/openai.py @@ -239,6 +239,8 @@ def generate_response( functions=functions, **self.args.dict(), ) + if not response.choices or response.choices[0].message is None: + raise ValueError("LLM returned empty or filtered response") logger.log_prompt( [ @@ -281,6 +283,8 @@ def generate_response( messages=messages, **self.args.dict(), ) + if not response.choices or response.choices[0].message is None: + raise ValueError("LLM returned empty or filtered response") logger.log_prompt( [ { @@ -335,6 +339,8 @@ async def agenerate_response( functions=functions, **self.args.dict(), ) + if not response.choices or response.choices[0].message is None: + raise ValueError("LLM returned empty or filtered response") logger.log_prompt( [ { @@ -415,6 +421,8 @@ async def agenerate_response( messages=messages, **self.args.dict(), ) + if not response.choices or response.choices[0].message is None: + raise ValueError("LLM returned empty or filtered response") self.collect_metrics(response) logger.log_prompt( [ diff --git a/agentverse/memory/chat_history.py b/agentverse/memory/chat_history.py index 65d00751..6a34b8df 100644 --- a/agentverse/memory/chat_history.py +++ b/agentverse/memory/chat_history.py @@ -206,12 +206,15 @@ async def _update_summary_with_batch( summary=self.summary, new_events=new_events_batch ) - self.summary = await openai_client.chat.completions.acreate( + _resp = await openai_client.chat.completions.acreate( messages=[{"role": "user", "content": prompt}], model=model, max_tokens=max_summary_length, temperature=0.5, - ).choices[0].message.content + ) + if not _resp.choices or _resp.choices[0].message is None: + raise ValueError("LLM returned empty or filtered response") + self.summary = _resp.choices[0].message.content def summary_message(self) -> dict: return { diff --git a/scripts/evaluate_responsegen.py b/scripts/evaluate_responsegen.py index 0b7adabf..16912016 100644 --- a/scripts/evaluate_responsegen.py +++ b/scripts/evaluate_responsegen.py @@ -59,6 +59,8 @@ def write_eval_to_file(file, skip=0): time.sleep(min(i**2, 60)) continue break + if not eval_response.choices or eval_response.choices[0].message is None: + raise ValueError("LLM returned empty or filtered response") text = eval_response.choices[0].message.content eval.append(text) text = text.replace("\n", "\n\n")