-
Notifications
You must be signed in to change notification settings - Fork 824
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
userText cannot be null or empty caused by incomplete/incorrect check for messages in DefaultChatClientClass #1665
Comments
@github2atauhiq thanks for reporting this. Could you elaborate a bit more on this specific use case where there is no user message as the last one in a list of messages sent to an LLM?
Besides ensuring a clear and consistent behaviour for |
Hello Thomas, thank you for your feedback. Of course, it is no problem for us to change the order (we are already doing that), but the behavior of spring-ai regarding this topic clearly changed between last week and this week and that was reason enough for me to indicate this to you. Best regards Manuel |
Thanks a lot for providing additional context. Before, this same behaviour was happening, but in case no user message was found, one was created with empty content, which was leading to unpredictable outcomes (especially when using Advisors). Now, there is a check to ensure a proper user message is identified, so to ensure consistency and no surprises in the resulting behaviour. You can blame me for this change :) I'm also working on some additional documentation and release notes before this change is released in the upcoming milestone. The underlying I wonder if there could be a way to make this more flexible, while maintaining the null-safety and predictability of the API. For example, would it work having ChatClient accept a lambda to use for customising the "user message identification" strategy? What do you think? |
DefaultChatClientClass is assuming that the last message in the messages array is of type "USER".
If the last message is not of type USER, userText is not being set and the subsequent null check will fail, although a USER message has been provided:
Pseudo-Code that causes the problem:
chatClient .prompt( new Prompt( List.of( createUserMessage(request), createSystemMessage() ))) .call() .chatResponse();
will result in :
java.lang.IllegalArgumentException: userText cannot be null or empty
at org.springframework.util.Assert.hasText(Assert.java:240) ~[spring-core-6.1.10.jar:6.1.10]
at org.springframework.ai.chat.client.advisor.api.AdvisedRequest.(AdvisedRequest.java:87) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient.toAdvisedRequest(DefaultChatClient.java:129) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetChatResponse(DefaultChatClient.java:483) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatResponse$1(DefaultChatClient.java:477) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at io.micrometer.observation.Observation.observe(Observation.java:565) ~[micrometer-observation-1.13.1.jar:1.13.1]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatResponse(DefaultChatClient.java:477) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetChatResponse(DefaultChatClient.java:461) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.chatResponse(DefaultChatClient.java:505) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
Offending lines from DefaultChatClient, method toAdvisedRequest ll 109ff
List<Message> messages = inputRequest.messages; if (!StringUtils.hasText(userText) && !CollectionUtils.isEmpty(messages)) { Message lastMessage = (Message)messages.get(messages.size() - 1); if (lastMessage.getMessageType() == MessageType.USER) { UserMessage userMessage = (UserMessage)lastMessage; if (StringUtils.hasText(userMessage.getContent())) { userText = lastMessage.getContent(); }
Please make no assumptions about the order of messages an external caller to your API may provide.
The text was updated successfully, but these errors were encountered: