Description
Bug description
When a method annotated with @tool inherits from a parent class which is a generic class, and the method's input parameter is modified by the subclass. In this situation, when retrieving the declaredMethod, we get both a method with an Object
type input parameter and a method with the actual subclass type input parameter (i.e., the bridge method). Currently, since there is no filtering of the bridge method, both of these methods are judged to have the @tool annotation, which will then throw an exception: java.lang.IllegalStateException: Multiple tools with the same name
.
Steps to reproduce
- Create a generic parent class with a method that can be overridden by a subclass.
- Create a subclass that inherits from the generic parent class and modifies the input parameter of the overridden method.
- Annotate the overridden method in the subclass with @tool.
- Try to retrieve the declaredMethod for the method in the subclass.
- Observe that both the method with
Object
type input parameter and the bridge method (with the actual subclass type input parameter) are considered to have the @tool annotation, and thejava.lang.IllegalStateException: Multiple tools with the same name
exception is thrown.
Expected behavior
Only the actual method in the subclass with the correct input parameter type (the one that should be considered the valid implementation with the @tool annotation) should be recognized as having the @tool annotation, and the bridge method should be filtered out to avoid the situation where multiple methods with the same annotation lead to the IllegalStateException
.
Minimal Complete Reproducible example
class MethodToolCallbackProviderTest {
abstract class TestObjectClass<T> {
public abstract String test(T input);
}
class TestObjectSuperClass extends TestObjectClass<String> {
@Tool
public String test(String input) {
return input;
}
}
@Test
public void buildToolsWithBridgeMethodReturnOnlyUserDeclaredMethods() {
MethodToolCallbackProvider provider = MethodToolCallbackProvider.builder().toolObjects(new TestObjectSuperClass()).build();
ToolCallback[] toolCallbacks = provider.getToolCallbacks();
}
}
`