From 26053c9d1ae01362db9ae1453f01ccd6e71dc34f Mon Sep 17 00:00:00 2001 From: Brandon Hancock Date: Wed, 8 Jan 2025 17:03:45 -0500 Subject: [PATCH] Fix issues with parsing none/null --- src/crewai/tools/tool_usage.py | 11 +++++++---- src/crewai/translations/en.json | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/crewai/tools/tool_usage.py b/src/crewai/tools/tool_usage.py index eddecaa38..b0ae69f78 100644 --- a/src/crewai/tools/tool_usage.py +++ b/src/crewai/tools/tool_usage.py @@ -396,26 +396,29 @@ class ToolUsage: return self._tool_calling(tool_string) def _validate_tool_input(self, tool_input: str) -> Dict[str, Any]: - print("tool_input:", tool_input) try: - # Try to parse with json.loads directly + # Replace 'None' strings with null in the JSON string for proper parsing + tool_input = tool_input.replace('"None"', "null") + arguments = json.loads(tool_input) - return arguments except json.JSONDecodeError: # Fix common issues in the tool_input string # Replace single quotes with double quotes tool_input = tool_input.replace("'", '"') + # Replace 'None' strings with null + tool_input = tool_input.replace('"None"', "null") # Use json_repair to fix common JSON issues repaired_input = repair_json(tool_input) try: arguments = json.loads(repaired_input) - return arguments except json.JSONDecodeError as e: # If all else fails, raise an error raise Exception(f"Invalid tool input JSON: {e}") + return arguments + def on_tool_error(self, tool: Any, tool_calling: ToolCalling, e: Exception) -> None: event_data = self._prepare_event_data(tool, tool_calling) events.emit( diff --git a/src/crewai/translations/en.json b/src/crewai/translations/en.json index 97510d39b..ceaa2f0ae 100644 --- a/src/crewai/translations/en.json +++ b/src/crewai/translations/en.json @@ -9,9 +9,9 @@ "task": "\nCurrent Task: {input}\n\nBegin! This is VERY important to you, use the tools available and give your best Final Answer, your job depends on it!\n\nThought:", "memory": "\n\n# Useful context: \n{memory}", "role_playing": "You are {role}. {backstory}\nYour personal goal is: {goal}", - "tools": "\nYou ONLY have access to the following tools, and should NEVER make up tools that are not listed here:\n\n{tools}\n\nUse the following format:\n\nThought: you should always think about what to do\nAction: the action to take, only one name of [{tool_names}], just the name, exactly as it's written.\nAction Input: the input to the action, just a simple python dictionary, enclosed in curly braces, using \" to wrap keys and values.\nObservation: the result of the action\n\nOnce all necessary information is gathered:\n\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n", - "no_tools": "\nTo give my best complete final answer to the task use the exact following format:\n\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described.\n\nI MUST use these formats, my job depends on it!", - "format": "I MUST either use a tool (use one at time) OR give my best final answer not both at the same time. To Use the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action, dictionary enclosed in curly braces\nObservation: the result of the action\n... (this Thought/Action/Action Input/Result can repeat N times)\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described\n\n", + "tools": "\nYou ONLY have access to the following tools, and should NEVER make up tools that are not listed here:\n\n{tools}\n\nIMPORTANT: Use the following format in your response:\n\n```\nThought: you should always think about what to do\nAction: the action to take, only one name of [{tool_names}], just the name, exactly as it's written.\nAction Input: the input to the action, just a simple python dictionary, enclosed in curly braces, using \" to wrap keys and values.\nObservation: the result of the action\n```\n\nOnce all necessary information is gathered:\n\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n", + "no_tools": "\nTo give my best complete final answer to the task respond using the exact following format:\n\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described.\n\nI MUST use these formats, my job depends on it!", + "format": "I MUST either use a tool (use one at time) OR give my best final answer not both at the same time. When responding, use the following format:\n\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action, dictionary enclosed in curly braces\nObservation: the result of the action\n... (this Thought/Action/Action Input/Result can repeat N times)\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described\n\n", "final_answer_format": "If you don't need to use any more tools, you must give your best complete final answer, make sure it satisfies the expected criteria, use the EXACT format below:\n\nThought: I now can give a great answer\nFinal Answer: my best complete final answer to the task.\n\n", "format_without_tools": "\nSorry, I didn't use the right format. I MUST either use a tool (among the available ones), OR give my best final answer.\nI just remembered the expected format I must follow:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [{tool_names}]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Result can repeat N times)\nThought: I now can give a great answer\nFinal Answer: Your final answer must be the great and the most complete as possible, it must be outcome described\n\n", "task_with_context": "{task}\n\nThis is the context you're working with:\n{context}",