Skip to content

Wrong implementation of MethodToolCallback.validateToolContextSupport #3466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jcgouveia opened this issue Jun 7, 2025 · 5 comments
Open

Comments

@jcgouveia
Copy link

jcgouveia commented Jun 7, 2025

Consider the current implementation of validateToolContextSupport compared from 1.0.0 and 1.0.0-M6

	private void validateToolContextSupport(@Nullable ToolContext toolContext) {
		var isNonEmptyToolContextProvided = toolContext != null && !CollectionUtils.isEmpty(toolContext.getContext());
		var isToolContextAcceptedByMethod = Stream.of(this.toolMethod.getParameterTypes())
			.anyMatch(type -> ClassUtils.isAssignable(type, ToolContext.class));
		if (isToolContextAcceptedByMethod && !isNonEmptyToolContextProvided) {
			throw new IllegalArgumentException("ToolContext is required by the method as an argument");
		}
	}

M6

	private void validateToolContextSupport(@Nullable ToolContext toolContext) {
		var isToolContextRequired = toolContext != null && !CollectionUtils.isEmpty(toolContext.getContext());
		var isToolContextAcceptedByMethod = Stream.of(toolMethod.getParameterTypes())
			.anyMatch(type -> ClassUtils.isAssignable(type, ToolContext.class));
		if (isToolContextRequired && !isToolContextAcceptedByMethod) {
			throw new IllegalArgumentException("ToolContext is not supported by the method as an argument");
		}
	}
  1. Both have the same serious bug also refered in The isFunctionalType method of MethodToolVNet Provider is incorrect, resulting in some cases where the tool cannot be registered #3355 , it seems that the writer does not know the semantics of ClassUtils.isAssignable(left, right) => right is assinable to left, so left is the "super" type. All this code has the arguments in incorrect order.

  2. More, in the case of a toolContext not being provided, the change in the validation logic now make it fail due to error 1
    M6 : No context
    => isToolContextRequired = false
    => isToolContextRequired && !isToolContextAcceptedByMethod = false => no exception
    1.0.0 : No context
    => isNonEmptyToolContextProvided = false + isNonEmptyToolContextProvided = true (because of error 1)
    => isToolContextAcceptedByMethod && !isNonEmptyToolContextProvided = true
    => exception is thrown !

sunyuhan1998 added a commit to sunyuhan1998/spring-ai that referenced this issue Jun 9, 2025
…lidateToolContextSupport` method caused by incorrect parameter order.

Signed-off-by: Sun Yuhan <[email protected]>
@sunyuhan1998
Copy link
Contributor

Hi @jcgouveia , I checked the code and I agree with you and pushed a PR to try to fix it :#3478, can you help to review this PR?thanks.

@ilayaperumalg
Copy link
Member

@jcgouveia Thanks for reporting the issue and the detailed writeup! Please feel free to contribute your suggestions as pull request as well.

@sunyuhan1998 Thanks for the PR!

ilayaperumalg pushed a commit that referenced this issue Jun 11, 2025
…od caused by incorrect parameter order.

Fixes #GH-3466

Signed-off-by: Sun Yuhan <[email protected]>
ilayaperumalg pushed a commit that referenced this issue Jun 11, 2025
…od caused by incorrect parameter order.

Fixes #GH-3466

Signed-off-by: Sun Yuhan <[email protected]>
@ilayaperumalg
Copy link
Member

Hi @jcgouveia @sunyuhan1998, I want to bring up a specific use case into discussion related to the logic applied as part of this change. With this tool context validation check, if a chat client has multiple Method tool callbacks but one of them doesn't need tool context to be processed, with a non-empty tool context value, the validation would fail.

@sunyuhan1998
Copy link
Contributor

sunyuhan1998 commented Jun 12, 2025

Hi @jcgouveia @sunyuhan1998, I want to bring up a specific use case into discussion related to the logic applied as part of this change. With this tool context validation check, if a chat client has multiple Method tool callbacks but one of them doesn't need tool context to be processed, with a non-empty tool context value, the validation would fail.

I think I understand what you mean. I believe the key issue lies in the following code:

String toolResult;
try {
toolResult = toolCallback.call(toolInputArguments, toolContext);
}
catch (ToolExecutionException ex) {
toolResult = this.toolExecutionExceptionProcessor.process(ex);
}
observationContext.setToolCallResult(toolResult);
return toolResult;

It does not take into account whether the Method of the ToolCallback itself accepts ToolContext as a parameter.

I think we have two ways to solve this issue:

  1. Adjust the call(String toolInput, @Nullable ToolContext toolContext) method in MethodToolCallback so that if toolContext is null, it internally converts to a call to call(String toolInput).

  2. Modify the DefaultToolCallingManager to determine which call method to invoke based on the actual situation during execution.

I prefer the second approach because the first one violates the definition in the ToolCallback interface, which specifies that toolContext should be non-null in the call(String toolInput, @Nullable ToolContext toolContext) method.

I think I can submit a PR to try to fix this issue, do we need to open a new issue?

sunyuhan1998 added a commit to sunyuhan1998/spring-ai that referenced this issue Jun 12, 2025
…validateToolContextSupport` method failed to validate correctly when some `MethodToolCallback` instances accepted a `ToolContext` parameter while others did not, even though the `ToolContext` itself was not null during model request invocation.

Signed-off-by: Sun Yuhan <[email protected]>
@sunyuhan1998
Copy link
Contributor

if a chat client has multiple Method tool callbacks but one of them doesn't need tool context to be processed, with a non-empty tool context value, the validation would fail.

Hi @ilayaperumalg , I have submitted an additional PR #3521 to try and fix the issue, could you help review it?thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment