diff --git a/src/tool_schemas.py b/src/tool_schemas.py index 750b60b50..562b34973 100644 --- a/src/tool_schemas.py +++ b/src/tool_schemas.py @@ -1258,14 +1258,24 @@ def function_call_to_tool_block(name: str, arguments: str) -> Optional[ToolBlock content = "\n".join(parts) elif tool_type == "edit_document": blocks = [] - for edit in args.get("edits", []): + edits = args.get("edits", []) + if not isinstance(edits, list): + edits = [] + for edit in edits: + if not isinstance(edit, dict): + continue blocks.append( f'<<>>\n{edit.get("find", "")}\n<<>>\n{edit.get("replace", "")}\n<<>>' ) content = "\n".join(blocks) elif tool_type == "suggest_document": blocks = [] - for s in args.get("suggestions", []): + suggestions = args.get("suggestions", []) + if not isinstance(suggestions, list): + suggestions = [] + for s in suggestions: + if not isinstance(s, dict): + continue blocks.append( f'<<>>\n{s.get("find", "")}\n<<>>\n{s.get("replace", "")}\n<<>>\n{s.get("reason", "")}\n<<>>' ) diff --git a/tests/test_function_call_non_object_args.py b/tests/test_function_call_non_object_args.py index a3ea9956d..5e8cf4675 100644 --- a/tests/test_function_call_non_object_args.py +++ b/tests/test_function_call_non_object_args.py @@ -35,3 +35,27 @@ def test_non_object_arguments_do_not_crash(arguments): assert block is not None assert block.tool_type == "bash" assert block.content == "" + + +def test_edit_document_skips_non_object_edit_items(): + block = function_call_to_tool_block( + "edit_document", + '{"edits": ["bad", 42, null, {"find": "old", "replace": "new"}]}', + ) + + assert block is not None + assert block.tool_type == "edit_document" + assert block.content == "<<>>\nold\n<<>>\nnew\n<<>>" + + +def test_suggest_document_skips_non_object_suggestion_items(): + block = function_call_to_tool_block( + "suggest_document", + '{"suggestions": ["bad", 42, null, {"find": "old", "replace": "new", "reason": "clearer"}]}', + ) + + assert block is not None + assert block.tool_type == "suggest_document" + assert block.content == ( + "<<>>\nold\n<<>>\nnew\n<<>>\nclearer\n<<>>" + )