-
Notifications
You must be signed in to change notification settings - Fork 259
Open
Description
Description
When a tool method has a parameter with a generic type like List<MyClass>, the ToolMethodInvoker.convertSingleParameter method fails to properly deserialize it, resulting in a ClassCastException:
java.util.LinkedHashMap cannot be cast to class MyClass
(java.util.LinkedHashMap is in module java.base of loader 'bootstrap';
MyClass is in unnamed module of loader 'app')
Root Cause
In ToolMethodInvoker.java line 298:
Class<?> paramType = parameter.getType();This only returns the raw type (List.class) and loses the generic type argument (<MyClass>).
When Jackson's convertValue(value, List.class) is called, it doesn't know the element type and defaults to LinkedHashMap.
Reproduction
public class MyTool {
@Tool(name = my_tool, description = ...)
public ToolResultBlock doSomething(
@ToolParam(name = items) List<MyItem> items) {
// ClassCastException when iterating items
for (MyItem item : items) { ... }
}
}Suggested Fix
Use parameter.getParameterizedType() instead of parameter.getType() to preserve generic type information:
private Object convertSingleParameter(Parameter parameter, Map<String, Object> input) {
// ... existing code ...
Type paramType = parameter.getParameterizedType(); // Changed from getType()
// Handle generic types
if (paramType instanceof ParameterizedType) {
JavaType javaType = mapper.getTypeFactory().constructType(paramType);
return mapper.convertValue(value, javaType);
}
// Fallback for non-generic types
return JsonUtils.getJsonCodec().convertValue(value, parameter.getType());
}Alternatively, add a new method to JsonCodec interface:
<T> T convertValue(Object from, Type type);Workaround
Currently, users can work around this by:
- Using
Objectas parameter type and manually converting withTypeReference - Creating a wrapper class instead of using
List<T>directly
Environment
- agentscope-java version: latest main branch
- Java version: 21
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
Backlog