**Please make sure you read the contribution guide and file the issues in the
right place. **
Contribution guide.
馃敶 Required Information
Describe the Bug:
When using Spring AI for the model and when a tool is used, the tool result isn't sent in the 2nd request to the LLM, resulting in an error.
Steps to Reproduce:
Please provide a numbered list of steps to reproduce the behavior:
- Recreate the Hello Time example, but using Spring AI integration and passing the SpringAI object to the agent as the model. The behavior seems consistent across any of Spring AI's model abstractions (I tested with OpenAI, Anthropic, Mistral, and Ollama).
- Run the application and ask about the time in any city.
Expected Behavior:
I would expect to be told that the time is 10:30
Observed Behavior:
Instead of being told that the time is 10:30, I get an error indicating that there is an inconsistency between the tool calls and tool responses. The error differs depending on which underlying model abstraction is used. For OpenAI, this is the error:
Caused by: com.openai.errors.BadRequestException: 400: An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. The following tool_call_ids did not have response messages: call_hWpFYVJKxctwGganJdgV3uoH
at com.openai.errors.BadRequestException$Builder.build(BadRequestException.kt:98) ~[openai-java-core-4.39.1.jar:4.39.1]
at com.openai.core.handlers.ErrorHandler$errorHandler$1.handle(ErrorHandler.kt:54) ~[openai-java-core-4.39.1.jar:4.39.1]
at com.openai.core.handlers.ErrorHandler$errorHandler$1.handle(ErrorHandler.kt:46) ~[openai-java-core-4.39.1.jar:4.39.1]
at com.openai.services.blocking.chat.ChatCompletionServiceImpl$WithRawResponseImpl.create(ChatCompletionServiceImpl.kt:141) ~[openai-java-core-4.39.1.jar:4.39.1]
at com.openai.services.blocking.chat.ChatCompletionServiceImpl.create(ChatCompletionServiceImpl.kt:63) ~[openai-java-core-4.39.1.jar:4.39.1]
at com.openai.services.blocking.chat.ChatCompletionService.create(ChatCompletionService.kt:64) ~[openai-java-core-4.39.1.jar:4.39.1]
at org.springframework.ai.openai.OpenAiChatModel.lambda$internalCall$2(OpenAiChatModel.java:217) ~[spring-ai-openai-2.0.0.jar:2.0.0]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.17.0.jar:1.17.0]
For Anthropic, this is the error:
Caused by: com.anthropic.errors.BadRequestException: 400: {"type":"error","error":{"type":"invalid_request_error","message":"messages.2: user messages must have non-empty content"},"request_id":"req_011Cduj6JTe7pohNu8mAPvor"}
at com.anthropic.errors.BadRequestException$Builder.build(BadRequestException.kt:78) ~[anthropic-java-core-2.40.1.jar:2.40.1]
at com.anthropic.core.handlers.ErrorHandler$errorHandler$1.handle(ErrorHandler.kt:45) ~[anthropic-java-core-2.40.1.jar:2.40.1]
at com.anthropic.core.handlers.ErrorHandler$errorHandler$1.handle(ErrorHandler.kt:37) ~[anthropic-java-core-2.40.1.jar:2.40.1]
at com.anthropic.services.blocking.MessageServiceImpl$WithRawResponseImpl.create(MessageServiceImpl.kt:111) ~[anthropic-java-core-2.40.1.jar:2.40.1]
at com.anthropic.services.blocking.MessageService$WithRawResponse.create(MessageService.kt:154) ~[anthropic-java-core-2.40.1.jar:2.40.1]
at org.springframework.ai.anthropic.AnthropicChatModel.lambda$internalCall$14(AnthropicChatModel.java:547) ~[spring-ai-anthropic-2.0.0.jar:2.0.0]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.17.0.jar:1.17.0]
at org.springframework.ai.anthropic.AnthropicChatModel.internalCall(AnthropicChatModel.java:543) ~[spring-ai-anthropic-2.0.0.jar:2.0.0]
For Mistral, this is the error:
Caused by: org.springframework.ai.retry.NonTransientAiException: HTTP 400 - {"object":"error","message":"Not the same number of function calls and responses","type":"invalid_request_message_order","param":null,"code":"3230","raw_status_code":400}
at org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration$2.handleError(SpringAiRetryAutoConfiguration.java:125) ~[spring-ai-autoconfigure-retry-2.0.0.jar:2.0.0]
at org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration$2.handleError(SpringAiRetryAutoConfiguration.java:102) ~[spring-ai-autoconfigure-retry-2.0.0.jar:2.0.0]
at org.springframework.web.client.StatusHandler.lambda$fromErrorHandler$0(StatusHandler.java:98) ~[spring-web-7.0.8.jar:7.0.8]
at org.springframework.web.client.StatusHandler.handle(StatusHandler.java:75) ~[spring-web-7.0.8.jar:7.0.8]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.applyStatusHandlers(DefaultRestClient.java:943) ~[spring-web-7.0.8.jar:7.0.8]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.lambda$readBody$0(DefaultRestClient.java:932) ~[spring-web-7.0.8.jar:7.0.8]
at org.springframework.web.client.DefaultRestClient.readWithMessageConverters(DefaultRestClient.java:224) ~[spring-web-7.0.8.jar:7.0.8]
at org.springframework.web.client.DefaultRestClient$DefaultResponseSpec.readBody(DefaultRestClient.java:931) ~[spring-web-7.0.8.jar:7.0.8]
Ollama is a bit more peculiar, but seems to be somewhat the same problem. Instead of getting an error, the response includes the tool parameters:
To get the current time in Denver, I would use the 'getCurrentTime' tool and provide it with the city name "Denver". Let me check that for you:
[{"name": "getCurrentTime", "arguments": {"city":"Denver"}}]
Environment Details:
- ADK Library Version: 1.7.1
- Spring AI version: 2.0.0
- OS: MacOS
Model Information:
- In the cases of OpenAI, Anthropic, and Mistral, it is the default models in the Spring AI model abstraction dependencies.
- In the case of Ollama, I was using mistral:latest
馃煛 Optional Information
Providing this information greatly speeds up the resolution process.
Regression:
Did this work in a previous version of ADK? (Yes/No) If so, which one?
I do not know. I did try this with older versions and Spring Boot 1.1.8, but saw a different set of problems and reverted to SB 2.0.0 and ADK 1.7.1.
Logs:
The relevant logs are pasted above.
Minimal Reproduction Code:
I have this bean configured:
@Bean
public BaseAgent initAgent(SpringAI springAi) {
return LlmAgent.builder()
.name("hello-time-agent")
.description("Tells the current time in a specified city")
.instruction("""
You are a helpful assistant that tells the current time in a city.
Use the 'getCurrentTime' tool for this purpose.
""")
.model(springAi)
.tools(FunctionTool.create(HelloTimeAgent.class, "getCurrentTime"))
.build();
}
Which relies on the ADK's Spring AI auto-confuration to give the SpringAI object. Because of an ordering issue with that auto-configuration, I had to create the following bridge configuration to force the ChatModel to be created before trying to auto-configure the SpringAI object (which is itself a separate issue):
@AutoConfiguration
@AutoConfigureAfter(OllamaChatAutoConfiguration.class)
@AutoConfigureBefore(SpringAIAutoConfiguration.class)
public class SpringAIAutoConfigurationBridge {
}
Everything else about the project I'm trying this in is the same as the Java implementation of the Hello Time agent.
How often has this issue occurred?:
**Please make sure you read the contribution guide and file the issues in the
right place. **
Contribution guide.
馃敶 Required Information
Describe the Bug:
When using Spring AI for the model and when a tool is used, the tool result isn't sent in the 2nd request to the LLM, resulting in an error.
Steps to Reproduce:
Please provide a numbered list of steps to reproduce the behavior:
Expected Behavior:
I would expect to be told that the time is 10:30
Observed Behavior:
Instead of being told that the time is 10:30, I get an error indicating that there is an inconsistency between the tool calls and tool responses. The error differs depending on which underlying model abstraction is used. For OpenAI, this is the error:
For Anthropic, this is the error:
For Mistral, this is the error:
Ollama is a bit more peculiar, but seems to be somewhat the same problem. Instead of getting an error, the response includes the tool parameters:
Environment Details:
Model Information:
馃煛 Optional Information
Providing this information greatly speeds up the resolution process.
Regression:
Did this work in a previous version of ADK? (Yes/No) If so, which one?
I do not know. I did try this with older versions and Spring Boot 1.1.8, but saw a different set of problems and reverted to SB 2.0.0 and ADK 1.7.1.
Logs:
The relevant logs are pasted above.
Minimal Reproduction Code:
I have this bean configured:
Which relies on the ADK's Spring AI auto-confuration to give the
SpringAIobject. Because of an ordering issue with that auto-configuration, I had to create the following bridge configuration to force theChatModelto be created before trying to auto-configure theSpringAIobject (which is itself a separate issue):Everything else about the project I'm trying this in is the same as the Java implementation of the Hello Time agent.
How often has this issue occurred?: