@@ -633,3 +633,117 @@ def get_scores() -> dict[str, int]:
633
633
# Test converted result
634
634
result = await manager .call_tool ("get_scores" , {})
635
635
assert result == expected
636
+
637
+
638
+ class TestRemoveTools :
639
+ """Test tool removal functionality in the tool manager."""
640
+
641
+ def test_remove_existing_tool (self , caplog : pytest .LogCaptureFixture ):
642
+ """Test removing an existing tool."""
643
+ def add (a : int , b : int ) -> int :
644
+ """Add two numbers."""
645
+ return a + b
646
+
647
+ manager = ToolManager ()
648
+ manager .add_tool (add )
649
+
650
+ # Verify tool exists
651
+ assert manager .get_tool ("add" ) is not None
652
+ assert len (manager .list_tools ()) == 1
653
+
654
+ # Remove the tool
655
+ with caplog .at_level (logging .WARNING ):
656
+ manager .remove_tool ("add" )
657
+ # Should not log a warning for removing existing tool
658
+ assert "Tried to remove unknown tool: add" not in caplog .text
659
+
660
+ # Verify tool is removed
661
+ assert manager .get_tool ("add" ) is None
662
+ assert len (manager .list_tools ()) == 0
663
+
664
+ def test_remove_nonexistent_tool (self , caplog : pytest .LogCaptureFixture ):
665
+ """Test removing a non-existent tool logs a warning."""
666
+ manager = ToolManager ()
667
+
668
+ with caplog .at_level (logging .WARNING ):
669
+ manager .remove_tool ("nonexistent" )
670
+ assert "Tried to remove unknown tool: nonexistent" in caplog .text
671
+
672
+ def test_remove_tool_from_multiple_tools (self ):
673
+ """Test removing one tool when multiple tools exist."""
674
+ def add (a : int , b : int ) -> int :
675
+ """Add two numbers."""
676
+ return a + b
677
+
678
+ def multiply (a : int , b : int ) -> int :
679
+ """Multiply two numbers."""
680
+ return a * b
681
+
682
+ def divide (a : int , b : int ) -> float :
683
+ """Divide two numbers."""
684
+ return a / b
685
+
686
+ manager = ToolManager ()
687
+ manager .add_tool (add )
688
+ manager .add_tool (multiply )
689
+ manager .add_tool (divide )
690
+
691
+ # Verify all tools exist
692
+ assert len (manager .list_tools ()) == 3
693
+ assert manager .get_tool ("add" ) is not None
694
+ assert manager .get_tool ("multiply" ) is not None
695
+ assert manager .get_tool ("divide" ) is not None
696
+
697
+ # Remove middle tool
698
+ manager .remove_tool ("multiply" )
699
+
700
+ # Verify only multiply is removed
701
+ assert len (manager .list_tools ()) == 2
702
+ assert manager .get_tool ("add" ) is not None
703
+ assert manager .get_tool ("multiply" ) is None
704
+ assert manager .get_tool ("divide" ) is not None
705
+
706
+ @pytest .mark .anyio
707
+ async def test_call_removed_tool_raises_error (self ):
708
+ """Test that calling a removed tool raises ToolError."""
709
+ def greet (name : str ) -> str :
710
+ """Greet someone."""
711
+ return f"Hello, { name } !"
712
+
713
+ manager = ToolManager ()
714
+ manager .add_tool (greet )
715
+
716
+ # Verify tool works before removal
717
+ result = await manager .call_tool ("greet" , {"name" : "World" })
718
+ assert result == "Hello, World!"
719
+
720
+ # Remove the tool
721
+ manager .remove_tool ("greet" )
722
+
723
+ # Verify calling removed tool raises error
724
+ with pytest .raises (ToolError , match = "Unknown tool: greet" ):
725
+ await manager .call_tool ("greet" , {"name" : "World" })
726
+
727
+ def test_remove_tool_case_sensitive (self , caplog : pytest .LogCaptureFixture ):
728
+ """Test that tool removal is case-sensitive."""
729
+ def test_func () -> str :
730
+ """Test function."""
731
+ return "test"
732
+
733
+ manager = ToolManager ()
734
+ manager .add_tool (test_func )
735
+
736
+ # Verify tool exists
737
+ assert manager .get_tool ("test_func" ) is not None
738
+
739
+ # Try to remove with different case
740
+ with caplog .at_level (logging .WARNING ):
741
+ manager .remove_tool ("Test_Func" )
742
+ assert "Tried to remove unknown tool: Test_Func" in caplog .text
743
+
744
+ # Verify original tool still exists
745
+ assert manager .get_tool ("test_func" ) is not None
746
+
747
+ # Remove with correct case
748
+ manager .remove_tool ("test_func" )
749
+ assert manager .get_tool ("test_func" ) is None
0 commit comments