summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaptainJack2491 <jayrupnakawala@gmail.com>2026-03-25 18:24:11 +0000
committerCaptainJack2491 <jayrupnakawala@gmail.com>2026-03-25 18:24:11 +0000
commita532e7b1696ef7539a4616b9c26fbf950f3721a3 (patch)
tree5b547cdc7efc003ae3c84ecb5429c519eec109a3
parent36f6dc6dea2046ac7d4b942a44c26a85b9c466ee (diff)
fix: catch and recover from JSONDecodeError on malformed tool args
-rw-r--r--src/agent.py28
-rw-r--r--tests/test_agent.py8
2 files changed, 20 insertions, 16 deletions
diff --git a/src/agent.py b/src/agent.py
index 4047b08..a8edb20 100644
--- a/src/agent.py
+++ b/src/agent.py
@@ -248,20 +248,24 @@ class Agent:
logger.info(f"LLM requested {len(response_message.tool_calls)} tool execution(s)")
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
- function_args = json.loads(tool_call.function.arguments)
-
- function_to_call = self.available_functions.get(function_name)
- if not function_to_call:
- error_msg = f"Unknown tool: {function_name}"
+ try:
+ function_args = json.loads(tool_call.function.arguments)
+ logger.info(f"Executing: {function_name}({function_args})")
+
+ function_to_call = self.available_functions.get(function_name)
+ if not function_to_call:
+ error_msg = f"Unknown tool: {function_name}"
+ logger.warning(error_msg)
+ function_output = error_msg
+ else:
+ try:
+ function_output = function_to_call(**function_args)
+ except Exception as e:
+ function_output = f"Error executing {function_name}: {str(e)}"
+ except json.JSONDecodeError as e:
+ error_msg = f"Error parsing tool arguments for {function_name}: {str(e)}. Arguments must be valid JSON."
logger.warning(error_msg)
function_output = error_msg
- else:
- try:
- function_output = function_to_call(**function_args)
- except Exception as e:
- function_output = f"Error executing {function_name}: {str(e)}"
-
- logger.info(f"Executing: {function_name}({function_args})")
tool_message = {
"tool_call_id": tool_call.id,
diff --git a/tests/test_agent.py b/tests/test_agent.py
index c8164e6..e73b41e 100644
--- a/tests/test_agent.py
+++ b/tests/test_agent.py
@@ -173,10 +173,10 @@ class TestAgentRun:
)
agent.client.chat.completions.create.side_effect = [tool_response, final_response]
- # json.loads will raise — this should be caught or propagate clearly
- # Current code does NOT catch this, so it should raise JSONDecodeError
- with pytest.raises(json.JSONDecodeError):
- agent.run("Do something")
+ # json.loads will fail, the agent will catch it, return an error to model,
+ # and on the next turn the model will return "Recovered".
+ result = agent.run("Do something")
+ assert result == "Recovered"
def test_api_error_propagates(self, agent):
"""API errors should propagate, not be silently swallowed."""