From efeac1a84d325e56e0e6e1a96bb7eeb053ca3d3e Mon Sep 17 00:00:00 2001 From: Thomas Vitale Date: Sat, 2 Nov 2024 16:38:46 +0100 Subject: [PATCH] Make ChatClient APIs null-safe and predictable * Introduced null-safety for all ChatClient APIs and verified via extensive auto-tests. * Made the final message list computed by ChatClient consistent and predictable across the different options for providing messages (prompt(), messages(), user(), prompt()) and verified via extensive auto-tests. * Added even more auto-tests to cover as many scenarios and edge cases as possible. Signed-off-by: Thomas Vitale --- .../ai/chat/client/ChatClient.java | 16 +- .../ai/chat/client/DefaultChatClient.java | 365 ++-- .../chat/client/DefaultChatClientBuilder.java | 14 +- .../ai/chat/client/ResponseEntity.java | 7 +- .../client/advisor/api/AdvisedRequest.java | 15 + .../client/advisor/api/AdvisedResponse.java | 9 +- .../ai/chat/client/package-info.java | 22 + .../ai/chat/prompt/Prompt.java | 5 + .../ai/chat/client/ChatClientTest.java | 282 ++- .../client/DefaultChatClientBuilderTests.java | 81 + .../chat/client/DefaultChatClientTests.java | 1771 +++++++++++++++++ .../advisor/api/AdvisedRequestTests.java | 148 ++ .../advisor/api/AdvisedResponseTests.java | 88 + .../src/test/resources/system-prompt.txt | 1 + .../src/test/resources/tabby-cat.png | Bin 0 -> 245664 bytes .../src/test/resources/user-prompt.txt | 1 + 16 files changed, 2687 insertions(+), 138 deletions(-) create mode 100644 spring-ai-core/src/main/java/org/springframework/ai/chat/client/package-info.java create mode 100644 spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientBuilderTests.java create mode 100644 spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java create mode 100644 spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequestTests.java create mode 100644 spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseTests.java create mode 100644 spring-ai-core/src/test/resources/system-prompt.txt create mode 100644 spring-ai-core/src/test/resources/tabby-cat.png create mode 100644 spring-ai-core/src/test/resources/user-prompt.txt diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ChatClient.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ChatClient.java index fd282fd319d..d53e998967a 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ChatClient.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ChatClient.java @@ -38,6 +38,8 @@ import org.springframework.ai.model.function.FunctionCallback; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.Resource; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.MimeType; /** @@ -49,6 +51,7 @@ * @author Christian Tzolov * @author Josh Long * @author Arjen Poutsma + * @author Thomas Vitale * @since 1.0.0 */ public interface ChatClient { @@ -62,7 +65,9 @@ static ChatClient create(ChatModel chatModel, ObservationRegistry observationReg } static ChatClient create(ChatModel chatModel, ObservationRegistry observationRegistry, - ChatClientObservationConvention observationConvention) { + @Nullable ChatClientObservationConvention observationConvention) { + Assert.notNull(chatModel, "chatModel cannot be null"); + Assert.notNull(observationRegistry, "observationRegistry cannot be null"); return builder(chatModel, observationRegistry, observationConvention).build(); } @@ -71,7 +76,9 @@ static Builder builder(ChatModel chatModel) { } static Builder builder(ChatModel chatModel, ObservationRegistry observationRegistry, - ChatClientObservationConvention customObservationConvention) { + @Nullable ChatClientObservationConvention customObservationConvention) { + Assert.notNull(chatModel, "chatModel cannot be null"); + Assert.notNull(observationRegistry, "observationRegistry cannot be null"); return new DefaultChatClientBuilder(chatModel, observationRegistry, customObservationConvention); } @@ -136,14 +143,19 @@ interface AdvisorSpec { interface CallResponseSpec { + @Nullable T entity(ParameterizedTypeReference type); + @Nullable T entity(StructuredOutputConverter structuredOutputConverter); + @Nullable T entity(Class type); + @Nullable ChatResponse chatResponse(); + @Nullable String content(); ResponseEntity responseEntity(Class type); diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java index c0b2d5a8d22..6f46f2749b0 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClient.java @@ -21,6 +21,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -63,6 +64,7 @@ import org.springframework.core.Ordered; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.Resource; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.MimeType; @@ -88,18 +90,44 @@ public class DefaultChatClient implements ChatClient { private final DefaultChatClientRequestSpec defaultChatClientRequest; public DefaultChatClient(DefaultChatClientRequestSpec defaultChatClientRequest) { + Assert.notNull(defaultChatClientRequest, "defaultChatClientRequest cannot be null"); this.defaultChatClientRequest = defaultChatClientRequest; } - private static AdvisedRequest toAdvisedRequest(DefaultChatClientRequestSpec inputRequest, String formatParam) { + private static AdvisedRequest toAdvisedRequest(DefaultChatClientRequestSpec inputRequest, + @Nullable String formatParam) { + Assert.notNull(inputRequest, "inputRequest cannot be null"); + Map advisorContext = new ConcurrentHashMap<>(inputRequest.getAdvisorParams()); if (StringUtils.hasText(formatParam)) { advisorContext.put("formatParam", formatParam); } - return new AdvisedRequest(inputRequest.chatModel, inputRequest.userText, inputRequest.systemText, - inputRequest.chatOptions, inputRequest.media, inputRequest.functionNames, - inputRequest.functionCallbacks, inputRequest.messages, inputRequest.userParams, + // Process userText, media and messages before creating the AdvisedRequest. + String userText = inputRequest.userText; + List media = inputRequest.media; + List messages = inputRequest.messages; + + // If the userText is empty, then try extracting the userText from the last + // message + // in the messages list and remove it from the messages list. + if (!StringUtils.hasText(userText) && !CollectionUtils.isEmpty(messages)) { + Message lastMessage = messages.get(messages.size() - 1); + if (lastMessage.getMessageType() == MessageType.USER) { + UserMessage userMessage = (UserMessage) lastMessage; + if (StringUtils.hasText(userMessage.getContent())) { + userText = lastMessage.getContent(); + } + Collection messageMedia = userMessage.getMedia(); + if (!CollectionUtils.isEmpty(messageMedia)) { + media.addAll(messageMedia); + } + messages = messages.subList(0, messages.size() - 1); + } + } + + return new AdvisedRequest(inputRequest.chatModel, userText, inputRequest.systemText, inputRequest.chatOptions, + media, inputRequest.functionNames, inputRequest.functionCallbacks, messages, inputRequest.userParams, inputRequest.systemParams, inputRequest.advisors, inputRequest.advisorParams, advisorContext, inputRequest.toolContext); } @@ -122,10 +150,13 @@ public ChatClientRequestSpec prompt() { @Override public ChatClientRequestSpec prompt(String content) { + Assert.hasText(content, "content cannot be null or empty"); return prompt(new Prompt(content)); } + @Override public ChatClientRequestSpec prompt(Prompt prompt) { + Assert.notNull(prompt, "prompt cannot be null"); DefaultChatClientRequestSpec spec = new DefaultChatClientRequestSpec(this.defaultChatClientRequest); @@ -135,26 +166,10 @@ public ChatClientRequestSpec prompt(Prompt prompt) { } // Messages - List messages = prompt.getInstructions(); - - if (!CollectionUtils.isEmpty(messages)) { - var lastMessage = messages.get(messages.size() - 1); - if (lastMessage.getMessageType() == MessageType.USER) { - // Unzip the last message - var userMessage = (UserMessage) lastMessage; - if (StringUtils.hasText(userMessage.getContent())) { - spec.user(lastMessage.getContent()); - } - var media = userMessage.getMedia(); - if (!CollectionUtils.isEmpty(media)) { - spec.user(u -> u.media(media.toArray(new Media[media.size()]))); - } - messages = messages.subList(0, messages.size() - 1); - } + if (prompt.getInstructions() != null) { + spec.messages(prompt.getInstructions()); } - spec.messages(messages); - return spec; } @@ -173,34 +188,44 @@ public static class DefaultPromptUserSpec implements PromptUserSpec { private final List media = new ArrayList<>(); - private String text = ""; + @Nullable + private String text; @Override public PromptUserSpec media(Media... media) { + Assert.notNull(media, "media cannot be null"); + Assert.noNullElements(media, "media cannot contain null elements"); this.media.addAll(Arrays.asList(media)); return this; } @Override public PromptUserSpec media(MimeType mimeType, URL url) { + Assert.notNull(mimeType, "mimeType cannot be null"); + Assert.notNull(url, "url cannot be null"); this.media.add(new Media(mimeType, url)); return this; } @Override public PromptUserSpec media(MimeType mimeType, Resource resource) { + Assert.notNull(mimeType, "mimeType cannot be null"); + Assert.notNull(resource, "resource cannot be null"); this.media.add(new Media(mimeType, resource)); return this; } @Override public PromptUserSpec text(String text) { + Assert.hasText(text, "text cannot be null or empty"); this.text = text; return this; } @Override public PromptUserSpec text(Resource text, Charset charset) { + Assert.notNull(text, "text cannot be null"); + Assert.notNull(charset, "charset cannot be null"); try { this.text(text.getContentAsString(charset)); } @@ -212,22 +237,29 @@ public PromptUserSpec text(Resource text, Charset charset) { @Override public PromptUserSpec text(Resource text) { + Assert.notNull(text, "text cannot be null"); this.text(text, Charset.defaultCharset()); return this; } @Override - public PromptUserSpec param(String k, Object v) { - this.params.put(k, v); + public PromptUserSpec param(String key, Object value) { + Assert.hasText(key, "key cannot be null or empty"); + Assert.notNull(value, "value cannot be null"); + this.params.put(key, value); return this; } @Override - public PromptUserSpec params(Map p) { - this.params.putAll(p); + public PromptUserSpec params(Map params) { + Assert.notNull(params, "params cannot be null"); + Assert.noNullElements(params.keySet(), "param keys cannot contain null elements"); + Assert.noNullElements(params.values(), "param values cannot contain null elements"); + this.params.putAll(params); return this; } + @Nullable protected String text() { return this.text; } @@ -246,16 +278,20 @@ public static class DefaultPromptSystemSpec implements PromptSystemSpec { private final Map params = new HashMap<>(); - private String text = ""; + @Nullable + private String text; @Override public PromptSystemSpec text(String text) { + Assert.hasText(text, "text cannot be null or empty"); this.text = text; return this; } @Override public PromptSystemSpec text(Resource text, Charset charset) { + Assert.notNull(text, "text cannot be null"); + Assert.notNull(charset, "charset cannot be null"); try { this.text(text.getContentAsString(charset)); } @@ -267,22 +303,29 @@ public PromptSystemSpec text(Resource text, Charset charset) { @Override public PromptSystemSpec text(Resource text) { + Assert.notNull(text, "text cannot be null"); this.text(text, Charset.defaultCharset()); return this; } @Override - public PromptSystemSpec param(String k, Object v) { - this.params.put(k, v); + public PromptSystemSpec param(String key, Object value) { + Assert.hasText(key, "key cannot be null or empty"); + Assert.notNull(value, "value cannot be null"); + this.params.put(key, value); return this; } @Override - public PromptSystemSpec params(Map p) { - this.params.putAll(p); + public PromptSystemSpec params(Map params) { + Assert.notNull(params, "params cannot be null"); + Assert.noNullElements(params.keySet(), "param keys cannot contain null elements"); + Assert.noNullElements(params.values(), "param values cannot contain null elements"); + this.params.putAll(params); return this; } + @Nullable protected String text() { return this.text; } @@ -299,22 +342,35 @@ public static class DefaultAdvisorSpec implements AdvisorSpec { private final Map params = new HashMap<>(); - public AdvisorSpec param(String k, Object v) { - this.params.put(k, v); + @Override + public AdvisorSpec param(String key, Object value) { + Assert.hasText(key, "key cannot be null or empty"); + Assert.notNull(value, "value cannot be null"); + this.params.put(key, value); return this; } - public AdvisorSpec params(Map p) { - this.params.putAll(p); + @Override + public AdvisorSpec params(Map params) { + Assert.notNull(params, "params cannot be null"); + Assert.noNullElements(params.keySet(), "param keys cannot contain null elements"); + Assert.noNullElements(params.values(), "param values cannot contain null elements"); + this.params.putAll(params); return this; } + @Override public AdvisorSpec advisors(Advisor... advisors) { + Assert.notNull(advisors, "advisors cannot be null"); + Assert.noNullElements(advisors, "advisors cannot contain null elements"); this.advisors.addAll(List.of(advisors)); return this; } + @Override public AdvisorSpec advisors(List advisors) { + Assert.notNull(advisors, "advisors cannot be null"); + Assert.noNullElements(advisors, "advisors cannot contain null elements"); this.advisors.addAll(advisors); return this; } @@ -334,57 +390,80 @@ public static class DefaultCallResponseSpec implements CallResponseSpec { private final DefaultChatClientRequestSpec request; public DefaultCallResponseSpec(DefaultChatClientRequestSpec request) { + Assert.notNull(request, "request cannot be null"); this.request = request; } + @Override public ResponseEntity responseEntity(Class type) { - Assert.notNull(type, "the class must be non-null"); + Assert.notNull(type, "type cannot be null"); return doResponseEntity(new BeanOutputConverter(type)); } + @Override public ResponseEntity responseEntity(ParameterizedTypeReference type) { + Assert.notNull(type, "type cannot be null"); return doResponseEntity(new BeanOutputConverter(type)); } + @Override public ResponseEntity responseEntity( StructuredOutputConverter structuredOutputConverter) { + Assert.notNull(structuredOutputConverter, "structuredOutputConverter cannot be null"); return doResponseEntity(structuredOutputConverter); } - protected ResponseEntity doResponseEntity(StructuredOutputConverter boc) { - var chatResponse = doGetObservableChatResponse(this.request, boc.getFormat()); - var responseContent = chatResponse.getResult().getOutput().getContent(); - T entity = boc.convert(responseContent); - + protected ResponseEntity doResponseEntity(StructuredOutputConverter outputConverter) { + Assert.notNull(outputConverter, "structuredOutputConverter cannot be null"); + var chatResponse = doGetObservableChatResponse(this.request, outputConverter.getFormat()); + var responseContent = getContentFromChatResponse(chatResponse); + if (responseContent == null) { + return new ResponseEntity<>(chatResponse, null); + } + T entity = outputConverter.convert(responseContent); return new ResponseEntity<>(chatResponse, entity); } + @Override + @Nullable public T entity(ParameterizedTypeReference type) { - return doSingleWithBeanOutputConverter(new BeanOutputConverter(type)); + Assert.notNull(type, "type cannot be null"); + return doSingleWithBeanOutputConverter(new BeanOutputConverter<>(type)); } + @Override + @Nullable public T entity(StructuredOutputConverter structuredOutputConverter) { + Assert.notNull(structuredOutputConverter, "structuredOutputConverter cannot be null"); return doSingleWithBeanOutputConverter(structuredOutputConverter); } - private T doSingleWithBeanOutputConverter(StructuredOutputConverter boc) { - var chatResponse = doGetObservableChatResponse(this.request, boc.getFormat()); - var stringResponse = chatResponse.getResult().getOutput().getContent(); - return boc.convert(stringResponse); + @Override + @Nullable + public T entity(Class type) { + Assert.notNull(type, "type cannot be null"); + var outputConverter = new BeanOutputConverter<>(type); + return doSingleWithBeanOutputConverter(outputConverter); } - public T entity(Class type) { - Assert.notNull(type, "the class must be non-null"); - var boc = new BeanOutputConverter(type); - return doSingleWithBeanOutputConverter(boc); + @Nullable + private T doSingleWithBeanOutputConverter(StructuredOutputConverter outputConverter) { + var chatResponse = doGetObservableChatResponse(this.request, outputConverter.getFormat()); + var stringResponse = getContentFromChatResponse(chatResponse); + if (stringResponse == null) { + return null; + } + return outputConverter.convert(stringResponse); } + @Nullable private ChatResponse doGetChatResponse() { - return this.doGetObservableChatResponse(this.request, ""); + return this.doGetObservableChatResponse(this.request, null); } + @Nullable private ChatResponse doGetObservableChatResponse(DefaultChatClientRequestSpec inputRequest, - String formatParam) { + @Nullable String formatParam) { ChatClientObservationContext observationContext = ChatClientObservationContext.builder() .withRequest(inputRequest) @@ -395,19 +474,15 @@ private ChatResponse doGetObservableChatResponse(DefaultChatClientRequestSpec in var observation = ChatClientObservationDocumentation.AI_CHAT_CLIENT.observation( inputRequest.getCustomObservationConvention(), DEFAULT_CHAT_CLIENT_OBSERVATION_CONVENTION, () -> observationContext, inputRequest.getObservationRegistry()); - return observation.observe(() -> { - ChatResponse chatResponse = doGetChatResponse(inputRequest, formatParam, observation); - return chatResponse; - }); - + return observation.observe(() -> doGetChatResponse(inputRequest, formatParam, observation)); } - private ChatResponse doGetChatResponse(DefaultChatClientRequestSpec inputRequestSpec, String formatParam, - Observation parentObservation) { + private ChatResponse doGetChatResponse(DefaultChatClientRequestSpec inputRequestSpec, + @Nullable String formatParam, Observation parentObservation) { AdvisedRequest advisedRequest = toAdvisedRequest(inputRequestSpec, formatParam); - // Apply the around advisor chain that terminates with the, last, model call + // Apply the around advisor chain that terminates with the last model call // advisor. AdvisedResponse advisedResponse = inputRequestSpec.aroundAdvisorChainBuilder.build() .nextAroundCall(advisedRequest); @@ -415,12 +490,26 @@ private ChatResponse doGetChatResponse(DefaultChatClientRequestSpec inputRequest return advisedResponse.response(); } + @Nullable + private static String getContentFromChatResponse(@Nullable ChatResponse chatResponse) { + if (chatResponse == null || chatResponse.getResult() == null || chatResponse.getResult().getOutput() == null + || chatResponse.getResult().getOutput().getContent() == null) { + return null; + } + return chatResponse.getResult().getOutput().getContent(); + } + + @Override + @Nullable public ChatResponse chatResponse() { return doGetChatResponse(); } + @Override + @Nullable public String content() { - return doGetChatResponse().getResult().getOutput().getContent(); + ChatResponse chatResponse = doGetChatResponse(); + return getContentFromChatResponse(chatResponse); } } @@ -430,6 +519,7 @@ public static class DefaultStreamResponseSpec implements StreamResponseSpec { private final DefaultChatClientRequestSpec request; public DefaultStreamResponseSpec(DefaultChatClientRequestSpec request) { + Assert.notNull(request, "request cannot be null"); this.request = request; } @@ -448,11 +538,10 @@ private Flux doGetObservableFluxChatResponse(DefaultChatClientRequ observation.parentObservation(contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null)) .start(); - var initialAdvisedRequest = toAdvisedRequest(inputRequest, ""); + var initialAdvisedRequest = toAdvisedRequest(inputRequest, null); // @formatter:off - // Apply the around advisor chain that terminates with the, last, - // model call advisor. + // Apply the around advisor chain that terminates with the last model call advisor. Flux stream = inputRequest.aroundAdvisorChainBuilder.build().nextAroundStream(initialAdvisedRequest); return stream @@ -464,10 +553,12 @@ private Flux doGetObservableFluxChatResponse(DefaultChatClientRequ }); } + @Override public Flux chatResponse() { return doGetObservableFluxChatResponse(this.request); } + @Override public Flux content() { return doGetObservableFluxChatResponse(this.request).map(r -> { if (r.getResult() == null || r.getResult().getOutput() == null @@ -508,10 +599,13 @@ public static class DefaultChatClientRequestSpec implements ChatClientRequestSpe private final Map toolContext = new HashMap<>(); - private String userText = ""; + @Nullable + private String userText; - private String systemText = ""; + @Nullable + private String systemText; + @Nullable private ChatOptions chatOptions; /* copy constructor */ @@ -521,11 +615,25 @@ public static class DefaultChatClientRequestSpec implements ChatClientRequestSpe ccr.observationRegistry, ccr.customObservationConvention, ccr.toolContext); } - public DefaultChatClientRequestSpec(ChatModel chatModel, String userText, Map userParams, - String systemText, Map systemParams, List functionCallbacks, - List messages, List functionNames, List media, ChatOptions chatOptions, - List advisors, Map advisorParams, ObservationRegistry observationRegistry, - ChatClientObservationConvention customObservationConvention, Map toolContext) { + public DefaultChatClientRequestSpec(ChatModel chatModel, @Nullable String userText, + Map userParams, @Nullable String systemText, Map systemParams, + List functionCallbacks, List messages, List functionNames, + List media, @Nullable ChatOptions chatOptions, List advisors, + Map advisorParams, ObservationRegistry observationRegistry, + @Nullable ChatClientObservationConvention customObservationConvention, + Map toolContext) { + + Assert.notNull(chatModel, "chatModel cannot be null"); + Assert.notNull(userParams, "userParams cannot be null"); + Assert.notNull(systemParams, "systemParams cannot be null"); + Assert.notNull(functionCallbacks, "functionCallbacks cannot be null"); + Assert.notNull(messages, "messages cannot be null"); + Assert.notNull(functionNames, "functionNames cannot be null"); + Assert.notNull(media, "media cannot be null"); + Assert.notNull(advisors, "advisors cannot be null"); + Assert.notNull(advisorParams, "advisorParams cannot be null"); + Assert.notNull(observationRegistry, "observationRegistry cannot be null"); + Assert.notNull(toolContext, "toolContext cannot be null"); this.chatModel = chatModel; this.chatOptions = chatOptions != null ? chatOptions.copy() @@ -543,7 +651,8 @@ public DefaultChatClientRequestSpec(ChatModel chatModel, String userText, Map getUserParams() { return this.userParams; } + @Nullable public String getSystemText() { return this.systemText; } @@ -616,6 +727,7 @@ public Map getSystemParams() { return this.systemParams; } + @Nullable public ChatOptions getChatOptions() { return this.chatOptions; } @@ -655,13 +767,21 @@ public Map getToolContext() { public Builder mutate() { DefaultChatClientBuilder builder = (DefaultChatClientBuilder) ChatClient .builder(this.chatModel, this.observationRegistry, this.customObservationConvention) - .defaultSystem(s -> s.text(this.systemText).params(this.systemParams)) - .defaultUser(u -> u.text(this.userText) - .params(this.userParams) - .media(this.media.toArray(new Media[this.media.size()]))) - .defaultOptions(this.chatOptions) .defaultFunctions(StringUtils.toStringArray(this.functionNames)); + if (StringUtils.hasText(this.userText)) { + builder.defaultUser( + u -> u.text(this.userText).params(this.userParams).media(this.media.toArray(new Media[0]))); + } + + if (StringUtils.hasText(this.systemText)) { + builder.defaultSystem(s -> s.text(this.systemText).params(this.systemParams)); + } + + if (this.chatOptions != null) { + builder.defaultOptions(this.chatOptions); + } + // workaround to set the missing fields. builder.defaultRequest.getMessages().addAll(this.messages); builder.defaultRequest.getFunctionCallbacks().addAll(this.functionCallbacks); @@ -671,43 +791,47 @@ public Builder mutate() { } public ChatClientRequestSpec advisors(Consumer consumer) { - Assert.notNull(consumer, "the consumer must be non-null"); - var as = new DefaultAdvisorSpec(); - consumer.accept(as); - this.advisorParams.putAll(as.getParams()); - this.advisors.addAll(as.getAdvisors()); - this.aroundAdvisorChainBuilder.pushAll(as.getAdvisors()); + Assert.notNull(consumer, "consumer cannot be null"); + var advisorSpec = new DefaultAdvisorSpec(); + consumer.accept(advisorSpec); + this.advisorParams.putAll(advisorSpec.getParams()); + this.advisors.addAll(advisorSpec.getAdvisors()); + this.aroundAdvisorChainBuilder.pushAll(advisorSpec.getAdvisors()); return this; } public ChatClientRequestSpec advisors(Advisor... advisors) { - Assert.notNull(advisors, "the advisors must be non-null"); + Assert.notNull(advisors, "advisors cannot be null"); + Assert.noNullElements(advisors, "advisors cannot contain null elements"); this.advisors.addAll(Arrays.asList(advisors)); this.aroundAdvisorChainBuilder.pushAll(Arrays.asList(advisors)); return this; } public ChatClientRequestSpec advisors(List advisors) { - Assert.notNull(advisors, "the advisors must be non-null"); + Assert.notNull(advisors, "advisors cannot be null"); + Assert.noNullElements(advisors, "advisors cannot contain null elements"); this.advisors.addAll(advisors); this.aroundAdvisorChainBuilder.pushAll(advisors); return this; } public ChatClientRequestSpec messages(Message... messages) { - Assert.notNull(messages, "the messages must be non-null"); + Assert.notNull(messages, "messages cannot be null"); + Assert.noNullElements(messages, "messages cannot contain null elements"); this.messages.addAll(List.of(messages)); return this; } public ChatClientRequestSpec messages(List messages) { - Assert.notNull(messages, "the messages must be non-null"); + Assert.notNull(messages, "messages cannot be null"); + Assert.noNullElements(messages, "messages cannot contain null elements"); this.messages.addAll(messages); return this; } public ChatClientRequestSpec options(T options) { - Assert.notNull(options, "the options must be non-null"); + Assert.notNull(options, "options cannot be null"); this.chatOptions = options; return this; } @@ -720,9 +844,9 @@ public ChatClientRequestSpec function(String name, String description, public ChatClientRequestSpec function(String name, String description, java.util.function.BiFunction biFunction) { - Assert.hasText(name, "the name must be non-null and non-empty"); - Assert.hasText(description, "the description must be non-null and non-empty"); - Assert.notNull(biFunction, "the biFunction must be non-null"); + Assert.hasText(name, "name cannot be null or empty"); + Assert.hasText(description, "description cannot be null or empty"); + Assert.notNull(biFunction, "biFunction cannot be null"); FunctionCallbackWrapper fcw = FunctionCallbackWrapper.builder(biFunction) .withDescription(description) @@ -733,12 +857,12 @@ public ChatClientRequestSpec function(String name, String description, return this; } - public ChatClientRequestSpec function(String name, String description, Class inputType, + public ChatClientRequestSpec function(String name, String description, @Nullable Class inputType, java.util.function.Function function) { - Assert.hasText(name, "the name must be non-null and non-empty"); - Assert.hasText(description, "the description must be non-null and non-empty"); - Assert.notNull(function, "the function must be non-null"); + Assert.hasText(name, "name cannot be null or empty"); + Assert.hasText(description, "description cannot be null or empty"); + Assert.notNull(function, "function cannot be null"); var fcw = FunctionCallbackWrapper.builder(function) .withDescription(description) @@ -751,36 +875,39 @@ public ChatClientRequestSpec function(String name, String description, Cl } public ChatClientRequestSpec functions(String... functionBeanNames) { - Assert.notNull(functionBeanNames, "the functionBeanNames must be non-null"); + Assert.notNull(functionBeanNames, "functionBeanNames cannot be null"); + Assert.noNullElements(functionBeanNames, "functionBeanNames cannot contain null elements"); this.functionNames.addAll(List.of(functionBeanNames)); return this; } public ChatClientRequestSpec functions(FunctionCallback... functionCallbacks) { - Assert.notNull(functionCallbacks, "the functionCallbacks must be non-null"); + Assert.notNull(functionCallbacks, "functionCallbacks cannot be null"); + Assert.noNullElements(functionCallbacks, "functionCallbacks cannot contain null elements"); this.functionCallbacks.addAll(Arrays.asList(functionCallbacks)); return this; } public ChatClientRequestSpec toolContext(Map toolContext) { - Assert.notNull(toolContext, "the toolContext must be non-null"); + Assert.notNull(toolContext, "toolContext cannot be null"); + Assert.noNullElements(toolContext.keySet(), "toolContext keys cannot contain null elements"); + Assert.noNullElements(toolContext.values(), "toolContext values cannot contain null elements"); this.toolContext.putAll(toolContext); return this; } public ChatClientRequestSpec system(String text) { - Assert.notNull(text, "the text must be non-null"); + Assert.hasText(text, "text cannot be null or empty"); this.systemText = text; return this; } - public ChatClientRequestSpec system(Resource textResource, Charset charset) { - - Assert.notNull(textResource, "the text resource must be non-null"); - Assert.notNull(charset, "the charset must be non-null"); + public ChatClientRequestSpec system(Resource text, Charset charset) { + Assert.notNull(text, "text cannot be null"); + Assert.notNull(charset, "charset cannot be null"); try { - this.systemText = textResource.getContentAsString(charset); + this.systemText = text.getContentAsString(charset); } catch (IOException e) { throw new RuntimeException(e); @@ -789,32 +916,30 @@ public ChatClientRequestSpec system(Resource textResource, Charset charset) { } public ChatClientRequestSpec system(Resource text) { - Assert.notNull(text, "the text resource must be non-null"); + Assert.notNull(text, "text cannot be null"); return this.system(text, Charset.defaultCharset()); } public ChatClientRequestSpec system(Consumer consumer) { + Assert.notNull(consumer, "consumer cannot be null"); - Assert.notNull(consumer, "the consumer must be non-null"); - - var ss = new DefaultPromptSystemSpec(); - consumer.accept(ss); - this.systemText = StringUtils.hasText(ss.text()) ? ss.text() : this.systemText; - this.systemParams.putAll(ss.params()); + var systemSpec = new DefaultPromptSystemSpec(); + consumer.accept(systemSpec); + this.systemText = StringUtils.hasText(systemSpec.text()) ? systemSpec.text() : this.systemText; + this.systemParams.putAll(systemSpec.params()); return this; } public ChatClientRequestSpec user(String text) { - Assert.notNull(text, "the text must be non-null"); + Assert.hasText(text, "text cannot be null or empty"); this.userText = text; return this; } public ChatClientRequestSpec user(Resource text, Charset charset) { - - Assert.notNull(text, "the text resource must be non-null"); - Assert.notNull(charset, "the charset must be non-null"); + Assert.notNull(text, "text cannot be null"); + Assert.notNull(charset, "charset cannot be null"); try { this.userText = text.getContentAsString(charset); @@ -826,12 +951,12 @@ public ChatClientRequestSpec user(Resource text, Charset charset) { } public ChatClientRequestSpec user(Resource text) { - Assert.notNull(text, "the text resource must be non-null"); + Assert.notNull(text, "text cannot be null"); return this.user(text, Charset.defaultCharset()); } public ChatClientRequestSpec user(Consumer consumer) { - Assert.notNull(consumer, "the consumer must be non-null"); + Assert.notNull(consumer, "consumer cannot be null"); var us = new DefaultPromptUserSpec(); consumer.accept(us); @@ -860,6 +985,8 @@ public static class DefaultCallPromptResponseSpec implements CallPromptResponseS private final Prompt prompt; public DefaultCallPromptResponseSpec(ChatModel chatModel, Prompt prompt) { + Assert.notNull(chatModel, "chatModel cannot be null"); + Assert.notNull(prompt, "prompt cannot be null"); this.chatModel = chatModel; this.prompt = prompt; } @@ -889,6 +1016,8 @@ public static class DefaultStreamPromptResponseSpec implements StreamPromptRespo private final StreamingChatModel chatModel; public DefaultStreamPromptResponseSpec(StreamingChatModel streamingChatModel, Prompt prompt) { + Assert.notNull(streamingChatModel, "streamingChatModel cannot be null"); + Assert.notNull(prompt, "prompt cannot be null"); this.chatModel = streamingChatModel; this.prompt = prompt; } diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClientBuilder.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClientBuilder.java index 6b03d8e2a40..4ae3833d868 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClientBuilder.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/DefaultChatClientBuilder.java @@ -35,6 +35,7 @@ import org.springframework.ai.chat.prompt.ChatOptions; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.core.io.Resource; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -46,6 +47,7 @@ * @author Christian Tzolov * @author Josh Long * @author Arjen Poutsma + * @author Thomas Vitale * @since 1.0.0 */ public class DefaultChatClientBuilder implements Builder { @@ -57,10 +59,10 @@ public class DefaultChatClientBuilder implements Builder { } public DefaultChatClientBuilder(ChatModel chatModel, ObservationRegistry observationRegistry, - ChatClientObservationConvention customObservationConvention) { + @Nullable ChatClientObservationConvention customObservationConvention) { Assert.notNull(chatModel, "the " + ChatModel.class.getName() + " must be non-null"); Assert.notNull(observationRegistry, "the " + ObservationRegistry.class.getName() + " must be non-null"); - this.defaultRequest = new DefaultChatClientRequestSpec(chatModel, "", Map.of(), "", Map.of(), List.of(), + this.defaultRequest = new DefaultChatClientRequestSpec(chatModel, null, Map.of(), null, Map.of(), List.of(), List.of(), List.of(), List.of(), null, List.of(), Map.of(), observationRegistry, customObservationConvention, Map.of()); } @@ -69,8 +71,8 @@ public ChatClient build() { return new DefaultChatClient(this.defaultRequest); } - public Builder defaultAdvisors(Advisor... advisor) { - this.defaultRequest.advisors(advisor); + public Builder defaultAdvisors(Advisor... advisors) { + this.defaultRequest.advisors(advisors); return this; } @@ -95,6 +97,8 @@ public Builder defaultUser(String text) { } public Builder defaultUser(Resource text, Charset charset) { + Assert.notNull(text, "text cannot be null"); + Assert.notNull(charset, "charset cannot be null"); try { this.defaultRequest.user(text.getContentAsString(charset)); } @@ -119,6 +123,8 @@ public Builder defaultSystem(String text) { } public Builder defaultSystem(Resource text, Charset charset) { + Assert.notNull(text, "text cannot be null"); + Assert.notNull(charset, "charset cannot be null"); try { this.defaultRequest.system(text.getContentAsString(charset)); } diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ResponseEntity.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ResponseEntity.java index b6ab8fedda7..bd454d55999 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ResponseEntity.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/ResponseEntity.java @@ -16,6 +16,8 @@ package org.springframework.ai.chat.client; +import org.springframework.lang.Nullable; + /** * Represents a {@link org.springframework.ai.model.Model} response that includes the * entire response along withe specified response entity type. @@ -25,14 +27,17 @@ * @param response the entire response object. * @param entity the converted entity object. * @author Christian Tzolov + * @author Thomas Vitale * @since 1.0.0 */ -public record ResponseEntity(R response, E entity) { +public record ResponseEntity(@Nullable R response, @Nullable E entity) { + @Nullable public R getResponse() { return this.response; } + @Nullable public E getEntity() { return this.entity; } diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequest.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequest.java index 08e1aa276e7..7bc48c7723e 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequest.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequest.java @@ -86,15 +86,30 @@ public record AdvisedRequest( Assert.notNull(chatModel, "chatModel cannot be null"); Assert.hasText(userText, "userText cannot be null or empty"); Assert.notNull(media, "media cannot be null"); + Assert.noNullElements(media, "media cannot contain null elements"); Assert.notNull(functionNames, "functionNames cannot be null"); + Assert.noNullElements(functionNames, "functionNames cannot contain null elements"); Assert.notNull(functionCallbacks, "functionCallbacks cannot be null"); + Assert.noNullElements(functionCallbacks, "functionCallbacks cannot contain null elements"); Assert.notNull(messages, "messages cannot be null"); + Assert.noNullElements(messages, "messages cannot contain null elements"); Assert.notNull(userParams, "userParams cannot be null"); + Assert.noNullElements(userParams.keySet(), "userParams keys cannot contain null elements"); + Assert.noNullElements(userParams.values(), "userParams values cannot contain null elements"); Assert.notNull(systemParams, "systemParams cannot be null"); + Assert.noNullElements(systemParams.keySet(), "systemParams keys cannot contain null elements"); + Assert.noNullElements(systemParams.values(), "systemParams values cannot contain null elements"); Assert.notNull(advisors, "advisors cannot be null"); + Assert.noNullElements(advisors, "advisors cannot contain null elements"); Assert.notNull(advisorParams, "advisorParams cannot be null"); + Assert.noNullElements(advisorParams.keySet(), "advisorParams keys cannot contain null elements"); + Assert.noNullElements(advisorParams.values(), "advisorParams values cannot contain null elements"); Assert.notNull(adviseContext, "adviseContext cannot be null"); + Assert.noNullElements(adviseContext.keySet(), "adviseContext keys cannot contain null elements"); + Assert.noNullElements(adviseContext.values(), "adviseContext values cannot contain null elements"); Assert.notNull(toolContext, "toolContext cannot be null"); + Assert.noNullElements(toolContext.keySet(), "toolContext keys cannot contain null elements"); + Assert.noNullElements(toolContext.values(), "toolContext values cannot contain null elements"); } public static Builder builder() { diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponse.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponse.java index 8bb383c1cc5..d6e329310ea 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponse.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponse.java @@ -22,6 +22,7 @@ import java.util.function.Function; import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -31,11 +32,12 @@ * @author Thomas Vitale * @since 1.0.0 */ -public record AdvisedResponse(ChatResponse response, Map adviseContext) { +public record AdvisedResponse(@Nullable ChatResponse response, Map adviseContext) { public AdvisedResponse { - Assert.notNull(response, "response cannot be null"); Assert.notNull(adviseContext, "adviseContext cannot be null"); + Assert.noNullElements(adviseContext.keySet(), "adviseContext keys cannot be null"); + Assert.noNullElements(adviseContext.values(), "adviseContext values cannot be null"); } public static Builder builder() { @@ -55,6 +57,7 @@ public AdvisedResponse updateContext(Function, Map adviseContext; @@ -62,7 +65,7 @@ public static final class Builder { private Builder() { } - public Builder withResponse(ChatResponse response) { + public Builder withResponse(@Nullable ChatResponse response) { this.response = response; return this; } diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/package-info.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/package-info.java new file mode 100644 index 00000000000..9e66e8de1b4 --- /dev/null +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@NonNullApi +@NonNullFields +package org.springframework.ai.chat.client; + +import org.springframework.lang.NonNullApi; +import org.springframework.lang.NonNullFields; diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java index 743314f8d4a..99a6f89c135 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/prompt/Prompt.java @@ -17,6 +17,7 @@ package org.springframework.ai.chat.prompt; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -54,6 +55,10 @@ public Prompt(List messages) { this(messages, null); } + public Prompt(Message... messages) { + this(Arrays.asList(messages), null); + } + public Prompt(String contents, ChatOptions chatOptions) { this(new UserMessage(contents), chatOptions); } diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/ChatClientTest.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/ChatClientTest.java index 44824f10323..1f9d407c38a 100644 --- a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/ChatClientTest.java +++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/ChatClientTest.java @@ -33,6 +33,7 @@ import org.springframework.ai.chat.messages.AssistantMessage; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.MessageType; +import org.springframework.ai.chat.messages.SystemMessage; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.model.ChatResponse; @@ -46,6 +47,7 @@ import org.springframework.util.MimeTypeUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.BDDMockito.given; /** @@ -69,7 +71,7 @@ private String join(Flux fluxContent) { // ChatClient Builder Tests @Test - public void defaultSystemText() { + void defaultSystemText() { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -118,7 +120,7 @@ public void defaultSystemText() { } @Test - public void defaultSystemTextLambda() { + void defaultSystemTextLambda() { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -194,7 +196,7 @@ public void defaultSystemTextLambda() { } @Test - public void mutateDefaults() { + void mutateDefaults() { PortableFunctionCallingOptions options = new FunctionCallingOptionsBuilder().build(); given(this.chatModel.getDefaultOptions()).willReturn(options); @@ -322,7 +324,7 @@ public void mutateDefaults() { } @Test - public void mutatePrompt() { + void mutatePrompt() { PortableFunctionCallingOptions options = new FunctionCallingOptionsBuilder().build(); given(this.chatModel.getDefaultOptions()).willReturn(options); @@ -412,7 +414,7 @@ public void mutatePrompt() { } @Test - public void defaultUserText() { + void defaultUserText() { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -437,7 +439,7 @@ public void defaultUserText() { } @Test - public void simpleUserPromptAsString() { + void simpleUserPromptAsString() { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -450,7 +452,7 @@ public void simpleUserPromptAsString() { } @Test - public void simpleUserPrompt() { + void simpleUserPrompt() { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -463,7 +465,7 @@ public void simpleUserPrompt() { } @Test - public void simpleUserPromptObject() throws MalformedURLException { + void simpleUserPromptObject() { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -482,7 +484,7 @@ public void simpleUserPromptObject() throws MalformedURLException { } @Test - public void simpleSystemPrompt() throws MalformedURLException { + void simpleSystemPrompt() { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -503,7 +505,7 @@ public void simpleSystemPrompt() throws MalformedURLException { } @Test - public void complexCall() throws MalformedURLException { + void complexCall() throws MalformedURLException { given(this.chatModel.call(this.promptCaptor.capture())) .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); @@ -545,4 +547,264 @@ public void complexCall() throws MalformedURLException { assertThat(options.getFunctions()).isEmpty(); } + // Constructors + + @Test + void whenCreateAndChatModelIsNullThenThrow() { + assertThatThrownBy(() -> ChatClient.create(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("chatModel cannot be null"); + } + + @Test + void whenCreateAndObservationRegistryIsNullThenThrow() { + assertThatThrownBy(() -> ChatClient.create(this.chatModel, null, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("observationRegistry cannot be null"); + } + + @Test + void whenBuilderAndChatModelIsNullThenThrow() { + assertThatThrownBy(() -> ChatClient.builder(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("chatModel cannot be null"); + } + + @Test + void whenBuilderAndObservationRegistryIsNullThenThrow() { + assertThatThrownBy(() -> ChatClient.builder(this.chatModel, null, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("observationRegistry cannot be null"); + } + + // Prompt Tests - User + + @Test + void whenPromptWithStringContent() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var content = chatClient.prompt("my question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(1); + var userMessage = this.promptCaptor.getValue().getInstructions().get(0); + assertThat(userMessage.getContent()).isEqualTo("my question"); + assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER); + } + + @Test + void whenPromptWithMessages() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + var content = chatClient.prompt(prompt).call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(2); + var userMessage = this.promptCaptor.getValue().getInstructions().get(1); + assertThat(userMessage.getContent()).isEqualTo("my question"); + assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER); + } + + @Test + void whenPromptWithStringContentAndUserText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var content = chatClient.prompt("my question").user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(2); + var userMessage = this.promptCaptor.getValue().getInstructions().get(1); + assertThat(userMessage.getContent()).isEqualTo("another question"); + assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER); + } + + @Test + void whenPromptWithHistoryAndUserText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var prompt = new Prompt(new UserMessage("my question"), new AssistantMessage("your answer")); + var content = chatClient.prompt(prompt).user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(3); + var userMessage = this.promptCaptor.getValue().getInstructions().get(2); + assertThat(userMessage.getContent()).isEqualTo("another question"); + assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER); + } + + @Test + void whenPromptWithUserMessageAndUserText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var prompt = new Prompt(new UserMessage("my question")); + var content = chatClient.prompt(prompt).user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(2); + var userMessage = this.promptCaptor.getValue().getInstructions().get(1); + assertThat(userMessage.getContent()).isEqualTo("another question"); + assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER); + } + + @Test + void whenMessagesWithHistoryAndUserText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + List messages = List.of(new UserMessage("my question"), new AssistantMessage("your answer")); + var content = chatClient.prompt().messages(messages).user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(3); + var userMessage = this.promptCaptor.getValue().getInstructions().get(2); + assertThat(userMessage.getContent()).isEqualTo("another question"); + } + + @Test + void whenMessagesWithUserMessageAndUserText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + List messages = List.of(new UserMessage("my question")); + var content = chatClient.prompt().messages(messages).user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(2); + var userMessage = this.promptCaptor.getValue().getInstructions().get(1); + assertThat(userMessage.getContent()).isEqualTo("another question"); + assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER); + } + + // Prompt Tests - System + + @Test + void whenPromptWithMessagesAndSystemText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var prompt = new Prompt(new UserMessage("my question"), new AssistantMessage("your answer")); + var content = chatClient.prompt(prompt).system("instructions").user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(4); + var systemMessage = this.promptCaptor.getValue().getInstructions().get(2); + assertThat(systemMessage.getContent()).isEqualTo("instructions"); + assertThat(systemMessage.getMessageType()).isEqualTo(MessageType.SYSTEM); + } + + @Test + void whenPromptWithSystemMessageAndNoSystemText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + var content = chatClient.prompt(prompt).user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(3); + var systemMessage = this.promptCaptor.getValue().getInstructions().get(0); + assertThat(systemMessage.getContent()).isEqualTo("instructions"); + assertThat(systemMessage.getMessageType()).isEqualTo(MessageType.SYSTEM); + } + + @Test + void whenPromptWithSystemMessageAndSystemText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + var prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + var content = chatClient.prompt(prompt).system("other instructions").user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(4); + var systemMessage = this.promptCaptor.getValue().getInstructions().get(2); + assertThat(systemMessage.getContent()).isEqualTo("other instructions"); + assertThat(systemMessage.getMessageType()).isEqualTo(MessageType.SYSTEM); + } + + @Test + void whenMessagesAndSystemText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + List messages = List.of(new UserMessage("my question"), new AssistantMessage("your answer")); + var content = chatClient.prompt() + .messages(messages) + .system("instructions") + .user("another question") + .call() + .content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(4); + var systemMessage = this.promptCaptor.getValue().getInstructions().get(2); + assertThat(systemMessage.getContent()).isEqualTo("instructions"); + assertThat(systemMessage.getMessageType()).isEqualTo(MessageType.SYSTEM); + } + + @Test + void whenMessagesWithSystemMessageAndNoSystemText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + List messages = List.of(new SystemMessage("instructions"), new UserMessage("my question")); + var content = chatClient.prompt().messages(messages).user("another question").call().content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(3); + var systemMessage = this.promptCaptor.getValue().getInstructions().get(0); + assertThat(systemMessage.getContent()).isEqualTo("instructions"); + assertThat(systemMessage.getMessageType()).isEqualTo(MessageType.SYSTEM); + } + + @Test + void whenMessagesWithSystemMessageAndSystemText() { + given(this.chatModel.call(this.promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + var chatClient = ChatClient.builder(this.chatModel).build(); + List messages = List.of(new SystemMessage("instructions"), new UserMessage("my question")); + var content = chatClient.prompt() + .messages(messages) + .system("other instructions") + .user("another question") + .call() + .content(); + + assertThat(content).isEqualTo("response"); + + assertThat(this.promptCaptor.getValue().getInstructions()).hasSize(4); + var systemMessage = this.promptCaptor.getValue().getInstructions().get(2); + assertThat(systemMessage.getContent()).isEqualTo("other instructions"); + assertThat(systemMessage.getMessageType()).isEqualTo(MessageType.SYSTEM); + } + } diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientBuilderTests.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientBuilderTests.java new file mode 100644 index 00000000000..d17998e706f --- /dev/null +++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientBuilderTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.chat.client; + +import java.nio.charset.Charset; + +import org.junit.jupiter.api.Test; + +import org.springframework.ai.chat.model.ChatModel; +import org.springframework.core.io.ClassPathResource; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; + +/** + * Unit tests for {@link DefaultChatClientBuilder}. + * + * @author Thomas Vitale + */ +class DefaultChatClientBuilderTests { + + @Test + void whenChatModelIsNullThenThrows() { + assertThatThrownBy(() -> new DefaultChatClientBuilder(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("the org.springframework.ai.chat.model.ChatModel must be non-null"); + } + + @Test + void whenObservationRegistryIsNullThenThrows() { + assertThatThrownBy(() -> new DefaultChatClientBuilder(mock(ChatModel.class), null, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("the io.micrometer.observation.ObservationRegistry must be non-null"); + } + + @Test + void whenUserResourceIsNullThenThrows() { + DefaultChatClientBuilder builder = new DefaultChatClientBuilder(mock(ChatModel.class)); + assertThatThrownBy(() -> builder.defaultUser(null, Charset.defaultCharset())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenUserCharsetIsNullThenThrows() { + DefaultChatClientBuilder builder = new DefaultChatClientBuilder(mock(ChatModel.class)); + assertThatThrownBy(() -> builder.defaultUser(new ClassPathResource("user-prompt.txt"), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("charset cannot be null"); + } + + @Test + void whenSystemResourceIsNullThenThrows() { + DefaultChatClientBuilder builder = new DefaultChatClientBuilder(mock(ChatModel.class)); + assertThatThrownBy(() -> builder.defaultSystem(null, Charset.defaultCharset())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenSystemCharsetIsNullThenThrows() { + DefaultChatClientBuilder builder = new DefaultChatClientBuilder(mock(ChatModel.class)); + assertThatThrownBy(() -> builder.defaultSystem(new ClassPathResource("system-prompt.txt"), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("charset cannot be null"); + } + +} diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java new file mode 100644 index 00000000000..269fa7812dd --- /dev/null +++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/DefaultChatClientTests.java @@ -0,0 +1,1771 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.chat.client; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +import io.micrometer.observation.ObservationRegistry; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import reactor.core.publisher.Flux; + +import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor; +import org.springframework.ai.chat.client.advisor.api.Advisor; +import org.springframework.ai.chat.messages.AssistantMessage; +import org.springframework.ai.chat.messages.Message; +import org.springframework.ai.chat.messages.SystemMessage; +import org.springframework.ai.chat.messages.UserMessage; +import org.springframework.ai.chat.model.ChatModel; +import org.springframework.ai.chat.model.ChatResponse; +import org.springframework.ai.chat.model.Generation; +import org.springframework.ai.chat.prompt.ChatOptions; +import org.springframework.ai.chat.prompt.ChatOptionsBuilder; +import org.springframework.ai.chat.prompt.Prompt; +import org.springframework.ai.converter.ListOutputConverter; +import org.springframework.ai.converter.StructuredOutputConverter; +import org.springframework.ai.model.Media; +import org.springframework.ai.model.function.FunctionCallback; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.util.MimeTypeUtils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Unit tests for {@link DefaultChatClient}. + * + * @author Thomas Vitale + */ +class DefaultChatClientTests { + + // Constructor + + @Test + void whenChatClientRequestIsNullThenThrow() { + assertThatThrownBy(() -> new DefaultChatClient(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("defaultChatClientRequest cannot be null"); + } + + // ChatClient + + @Test + void whenPromptThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThat(spec).isNotNull(); + } + + @Test + void whenPromptContentIsEmptyThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + assertThatThrownBy(() -> chatClient.prompt("")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("content cannot be null or empty"); + } + + @Test + void whenPromptContentThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec spec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + assertThat(spec.getMessages()).hasSize(1); + assertThat(spec.getMessages().get(0).getContent()).isEqualTo("my question"); + } + + @Test + void whenPromptWithMessagesThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + Prompt prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + DefaultChatClient.DefaultChatClientRequestSpec spec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(prompt); + assertThat(spec.getMessages()).hasSize(2); + assertThat(spec.getMessages().get(0).getContent()).isEqualTo("instructions"); + assertThat(spec.getMessages().get(1).getContent()).isEqualTo("my question"); + assertThat(spec.getChatOptions()).isNull(); + } + + @Test + void whenPromptWithOptionsThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatOptions chatOptions = ChatOptionsBuilder.builder().build(); + Prompt prompt = new Prompt(List.of(), chatOptions); + DefaultChatClient.DefaultChatClientRequestSpec spec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(prompt); + assertThat(spec.getMessages()).isEmpty(); + assertThat(spec.getChatOptions()).isEqualTo(chatOptions); + } + + @Test + void whenMutateChatClientRequest() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec spec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt() + .user("my question"); + + ChatClient.Builder newChatClientBuilder = spec.mutate(); + newChatClientBuilder.defaultUser("another question"); + ChatClient newChatClient = newChatClientBuilder.build(); + DefaultChatClient.DefaultChatClientRequestSpec newSpec = (DefaultChatClient.DefaultChatClientRequestSpec) newChatClient + .prompt(); + + assertThat(spec.getUserText()).isEqualTo("my question"); + assertThat(newSpec.getUserText()).isEqualTo("another question"); + } + + // DefaultPromptUserSpec + + @Test + void buildPromptUserSpec() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThat(spec).isNotNull(); + assertThat(spec.media()).isNotNull(); + assertThat(spec.params()).isNotNull(); + assertThat(spec.text()).isNull(); + } + + @Test + void whenUserMediaIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.media((Media[]) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("media cannot be null"); + } + + @Test + void whenUserMediaContainsNullElementsThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.media(null, (Media) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("media cannot contain null elements"); + } + + @Test + void whenUserMediaThenReturn() throws MalformedURLException { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + URL mediaUrl = URI.create("http://example.com/image.png").toURL(); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.media(new Media(MimeTypeUtils.IMAGE_PNG, mediaUrl)); + assertThat(spec.media()).hasSize(1); + assertThat(spec.media().get(0).getMimeType()).isEqualTo(MimeTypeUtils.IMAGE_PNG); + assertThat(spec.media().get(0).getData()).isEqualTo(mediaUrl.toString()); + } + + @Test + void whenUserMediaMimeTypeIsNullWithUrlThenThrow() throws MalformedURLException { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + URL mediaUrl = URI.create("http://example.com/image.png").toURL(); + assertThatThrownBy(() -> spec.media(null, mediaUrl)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("mimeType cannot be null"); + } + + @Test + void whenUserMediaUrlIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.media(MimeTypeUtils.IMAGE_PNG, (URL) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("url cannot be null"); + } + + @Test + void whenUserMediaMimeTypeAndUrlThenReturn() throws MalformedURLException { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + URL mediaUrl = URI.create("http://example.com/image.png").toURL(); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.media(MimeTypeUtils.IMAGE_PNG, mediaUrl); + assertThat(spec.media()).hasSize(1); + assertThat(spec.media().get(0).getMimeType()).isEqualTo(MimeTypeUtils.IMAGE_PNG); + assertThat(spec.media().get(0).getData()).isEqualTo(mediaUrl.toString()); + } + + @Test + void whenUserMediaMimeTypeIsNullWithResourceThenThrow() throws MalformedURLException { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.media(null, new ClassPathResource("image.png"))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("mimeType cannot be null"); + } + + @Test + void whenUserMediaResourceIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.media(MimeTypeUtils.IMAGE_PNG, (Resource) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("resource cannot be null"); + } + + @Test + void whenUserMediaMimeTypeAndResourceThenReturn() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + Resource imageResource = new ClassPathResource("tabby-cat.png"); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.media(MimeTypeUtils.IMAGE_PNG, imageResource); + assertThat(spec.media()).hasSize(1); + assertThat(spec.media().get(0).getMimeType()).isEqualTo(MimeTypeUtils.IMAGE_PNG); + assertThat(spec.media().get(0).getData()).isNotNull(); + } + + @Test + void whenUserTextStringIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.text((String) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenUserTextStringIsEmptyThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.text("")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenUserTextStringThenReturn() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.text("my question"); + assertThat(spec.text()).isEqualTo("my question"); + } + + @Test + void whenUserTextResourceIsNullWithCharsetThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.text(null, Charset.defaultCharset())).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenUserTextCharsetIsNullWithResourceThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + Resource textResource = new ClassPathResource("user-prompt.txt"); + assertThatThrownBy(() -> spec.text(textResource, null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("charset cannot be null"); + } + + @Test + void whenUserTextResourceAndCharsetThenReturn() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + Resource textResource = new ClassPathResource("user-prompt.txt"); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.text(textResource, Charset.defaultCharset()); + assertThat(spec.text()).isEqualTo("my question"); + } + + @Test + void whenUserTextResourceIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.text((Resource) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenUserTextResourceThenReturn() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + Resource textResource = new ClassPathResource("user-prompt.txt"); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.text(textResource); + assertThat(spec.text()).isEqualTo("my question"); + } + + @Test + void whenUserParamKeyIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.param(null, "value")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("key cannot be null or empty"); + } + + @Test + void whenUserParamKeyIsEmptyThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.param("", "value")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("key cannot be null or empty"); + } + + @Test + void whenUserParamValueIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.param("key", null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("value cannot be null"); + } + + @Test + void whenUserParamKeyValueThenReturn() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.param("key", "value"); + assertThat(spec.params()).containsEntry("key", "value"); + } + + @Test + void whenUserParamsIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + assertThatThrownBy(() -> spec.params(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("params cannot be null"); + } + + @Test + void whenUserParamsKeyIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + Map params = new HashMap<>(); + params.put(null, "value"); + assertThatThrownBy(() -> spec.params(params)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("param keys cannot contain null elements"); + } + + @Test + void whenUserParamsValueIsNullThenThrow() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + Map params = new HashMap<>(); + params.put("key", null); + assertThatThrownBy(() -> spec.params(params)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("param values cannot contain null elements"); + } + + @Test + void whenUserParamsThenReturn() { + DefaultChatClient.DefaultPromptUserSpec spec = new DefaultChatClient.DefaultPromptUserSpec(); + spec = (DefaultChatClient.DefaultPromptUserSpec) spec.params(Map.of("key", "value")); + assertThat(spec.params()).containsEntry("key", "value"); + } + + // DefaultPromptSystemSpec + + @Test + void buildPromptSystemSpec() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThat(spec).isNotNull(); + assertThat(spec.params()).isNotNull(); + assertThat(spec.text()).isNull(); + } + + @Test + void whenSystemTextStringIsNullThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.text((String) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenSystemTextStringIsEmptyThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.text("")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenSystemTextStringThenReturn() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + spec = (DefaultChatClient.DefaultPromptSystemSpec) spec.text("instructions"); + assertThat(spec.text()).isEqualTo("instructions"); + } + + @Test + void whenSystemTextResourceIsNullWithCharsetThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.text(null, Charset.defaultCharset())).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenSystemTextCharsetIsNullWithResourceThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + Resource textResource = new ClassPathResource("system-prompt.txt"); + assertThatThrownBy(() -> spec.text(textResource, null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("charset cannot be null"); + } + + @Test + void whenSystemTextResourceAndCharsetThenReturn() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + Resource textResource = new ClassPathResource("system-prompt.txt"); + spec = (DefaultChatClient.DefaultPromptSystemSpec) spec.text(textResource, Charset.defaultCharset()); + assertThat(spec.text()).isEqualTo("instructions"); + } + + @Test + void whenSystemTextResourceIsNullThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.text((Resource) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenSystemTextResourceThenReturn() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + Resource textResource = new ClassPathResource("system-prompt.txt"); + spec = (DefaultChatClient.DefaultPromptSystemSpec) spec.text(textResource); + assertThat(spec.text()).isEqualTo("instructions"); + } + + @Test + void whenSystemParamKeyIsNullThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.param(null, "value")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("key cannot be null or empty"); + } + + @Test + void whenSystemParamKeyIsEmptyThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.param("", "value")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("key cannot be null or empty"); + } + + @Test + void whenSystemParamValueIsNullThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.param("key", null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("value cannot be null"); + } + + @Test + void whenSystemParamKeyValueThenReturn() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + spec = (DefaultChatClient.DefaultPromptSystemSpec) spec.param("key", "value"); + assertThat(spec.params()).containsEntry("key", "value"); + } + + @Test + void whenSystemParamsIsNullThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + assertThatThrownBy(() -> spec.params(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("params cannot be null"); + } + + @Test + void whenSystemParamsKeyIsNullThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + Map params = new HashMap<>(); + params.put(null, "value"); + assertThatThrownBy(() -> spec.params(params)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("param keys cannot contain null elements"); + } + + @Test + void whenSystemParamsValueIsNullThenThrow() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + Map params = new HashMap<>(); + params.put("key", null); + assertThatThrownBy(() -> spec.params(params)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("param values cannot contain null elements"); + } + + @Test + void whenSystemParamsThenReturn() { + DefaultChatClient.DefaultPromptSystemSpec spec = new DefaultChatClient.DefaultPromptSystemSpec(); + spec = (DefaultChatClient.DefaultPromptSystemSpec) spec.params(Map.of("key", "value")); + assertThat(spec.params()).containsEntry("key", "value"); + } + + // DefaultAdvisorSpec + + @Test + void buildAdvisorSpec() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThat(spec).isNotNull(); + assertThat(spec.getAdvisors()).isNotNull(); + assertThat(spec.getParams()).isNotNull(); + } + + @Test + void whenAdvisorParamKeyIsNullThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThatThrownBy(() -> spec.param(null, "value")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("key cannot be null or empty"); + } + + @Test + void whenAdvisorParamKeyIsEmptyThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThatThrownBy(() -> spec.param("", "value")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("key cannot be null or empty"); + } + + @Test + void whenAdvisorParamValueIsNullThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThatThrownBy(() -> spec.param("key", null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("value cannot be null"); + } + + @Test + void whenAdvisorParamKeyValueThenReturn() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + spec = (DefaultChatClient.DefaultAdvisorSpec) spec.param("key", "value"); + assertThat(spec.getParams()).containsEntry("key", "value"); + } + + @Test + void whenAdvisorParamsIsNullThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThatThrownBy(() -> spec.params(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("params cannot be null"); + } + + @Test + void whenAdvisorKeyIsNullThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + Map params = new HashMap<>(); + params.put(null, "value"); + assertThatThrownBy(() -> spec.params(params)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("param keys cannot contain null elements"); + } + + @Test + void whenAdvisorParamsValueIsNullThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + Map params = new HashMap<>(); + params.put("key", null); + assertThatThrownBy(() -> spec.params(params)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("param values cannot contain null elements"); + } + + @Test + void whenAdvisorParamsThenReturn() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + spec = (DefaultChatClient.DefaultAdvisorSpec) spec.params(Map.of("key", "value")); + assertThat(spec.getParams()).containsEntry("key", "value"); + } + + @Test + void whenAdvisorsIsNullThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThatThrownBy(() -> spec.advisors((Advisor[]) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot be null"); + } + + @Test + void whenAdvisorsContainsNullElementsThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThatThrownBy(() -> spec.advisors(null, null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot contain null elements"); + } + + @Test + void whenAdvisorsThenReturn() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + Advisor advisor = new SimpleLoggerAdvisor(); + spec = (DefaultChatClient.DefaultAdvisorSpec) spec.advisors(advisor); + assertThat(spec.getAdvisors()).hasSize(1); + assertThat(spec.getAdvisors().get(0)).isEqualTo(advisor); + } + + @Test + void whenAdvisorListIsNullThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + assertThatThrownBy(() -> spec.advisors((List) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot be null"); + } + + @Test + void whenAdvisorListContainsNullElementsThenThrow() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + List advisors = new ArrayList<>(); + advisors.add(null); + assertThatThrownBy(() -> spec.advisors(advisors)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot contain null elements"); + } + + @Test + void whenAdvisorListThenReturn() { + DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec(); + Advisor advisor = new SimpleLoggerAdvisor(); + spec = (DefaultChatClient.DefaultAdvisorSpec) spec.advisors(List.of(advisor)); + assertThat(spec.getAdvisors()).hasSize(1); + assertThat(spec.getAdvisors().get(0)).isEqualTo(advisor); + } + + // DefaultCallResponseSpec + + @Test + void buildCallResponseSpec() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + assertThat(spec).isNotNull(); + } + + @Test + void buildCallResponseSpecWithNullRequest() { + assertThatThrownBy(() -> new DefaultChatClient.DefaultCallResponseSpec(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("request cannot be null"); + } + + @Test + void whenSimplePromptThenChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(1); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("my question"); + } + + @Test + void whenFullPromptThenChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + Prompt prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(prompt); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(2); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("instructions"); + assertThat(actualPrompt.getInstructions().get(1).getContent()).isEqualTo("my question"); + } + + @Test + void whenPromptAndUserTextThenChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + Prompt prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(prompt) + .user("another question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(3); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("instructions"); + assertThat(actualPrompt.getInstructions().get(1).getContent()).isEqualTo("my question"); + assertThat(actualPrompt.getInstructions().get(2).getContent()).isEqualTo("another question"); + } + + @Test + void whenUserTextAndMessagesThenChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response"))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + List messages = List.of(new SystemMessage("instructions"), new UserMessage("my question")); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt() + .user("another question") + .messages(messages); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(3); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("instructions"); + assertThat(actualPrompt.getInstructions().get(1).getContent()).isEqualTo("my question"); + assertThat(actualPrompt.getInstructions().get(2).getContent()).isEqualTo("another question"); + } + + @Test + void whenChatResponseIsNull() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())).willReturn(null); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse(); + assertThat(chatResponse).isNull(); + } + + @Test + void whenChatResponseContentIsNull() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(null))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + String content = spec.content(); + assertThat(content).isNull(); + } + + @Test + void whenResponseEntityWithParameterizedTypeIsNull() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + assertThatThrownBy(() -> spec.responseEntity((ParameterizedTypeReference) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("type cannot be null"); + } + + @Test + void whenResponseEntityWithParameterizedTypeAndChatResponseContentNull() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(null))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ResponseEntity> responseEntity = spec + .responseEntity(new ParameterizedTypeReference<>() { + }); + assertThat(responseEntity).isNotNull(); + assertThat(responseEntity.response()).isNotNull(); + assertThat(responseEntity.entity()).isNull(); + } + + @Test + void whenResponseEntityWithParameterizedType() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(""" + [ + { "name": "James Bond" }, + { "name": "Ethan Hunt" }, + { "name": "Jason Bourne" } + ] + """))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ResponseEntity> responseEntity = spec + .responseEntity(new ParameterizedTypeReference<>() { + }); + assertThat(responseEntity.response()).isNotNull(); + assertThat(responseEntity.entity()).hasSize(3); + } + + @Test + void whenResponseEntityWithConverterIsNull() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + assertThatThrownBy(() -> spec.responseEntity((StructuredOutputConverter) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("structuredOutputConverter cannot be null"); + } + + @Test + void whenResponseEntityWithConverterAndChatResponseContentNull() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(null))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ResponseEntity> responseEntity = spec + .responseEntity(new ListOutputConverter(new DefaultConversionService())); + assertThat(responseEntity.response()).isNotNull(); + assertThat(responseEntity.entity()).isNull(); + } + + @Test + void whenResponseEntityWithConverter() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(""" + James Bond, Ethan Hunt, Jason Bourne + """))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ResponseEntity> responseEntity = spec + .responseEntity(new ListOutputConverter(new DefaultConversionService())); + assertThat(responseEntity.response()).isNotNull(); + assertThat(responseEntity.entity()).hasSize(3); + } + + @Test + void whenResponseEntityWithTypeIsNull() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + assertThatThrownBy(() -> spec.responseEntity((Class) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("type cannot be null"); + } + + @Test + void whenResponseEntityWithTypeAndChatResponseContentNull() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(null))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ResponseEntity responseEntity = spec.responseEntity(String.class); + assertThat(responseEntity.response()).isNotNull(); + assertThat(responseEntity.entity()).isNull(); + } + + @Test + void whenResponseEntityWithType() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(""" + { "name": "James Bond" } + """))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + ResponseEntity responseEntity = spec.responseEntity(Person.class); + assertThat(responseEntity.response()).isNotNull(); + assertThat(responseEntity.entity()).isNotNull(); + assertThat(responseEntity.entity().name).isEqualTo("James Bond"); + } + + @Test + void whenEntityWithParameterizedTypeIsNull() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + assertThatThrownBy(() -> spec.entity((ParameterizedTypeReference) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("type cannot be null"); + } + + @Test + void whenEntityWithParameterizedTypeAndChatResponseContentNull() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(null))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + List entity = spec.entity(new ParameterizedTypeReference<>() { + }); + assertThat(entity).isNull(); + } + + @Test + void whenEntityWithParameterizedType() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(""" + [ + { "name": "James Bond" }, + { "name": "Ethan Hunt" }, + { "name": "Jason Bourne" } + ] + """))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + List entity = spec.entity(new ParameterizedTypeReference<>() { + }); + assertThat(entity).hasSize(3); + } + + @Test + void whenEntityWithConverterIsNull() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + assertThatThrownBy(() -> spec.entity((StructuredOutputConverter) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("structuredOutputConverter cannot be null"); + } + + @Test + void whenEntityWithConverterAndChatResponseContentNull() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + List entity = spec.entity(new ListOutputConverter(new DefaultConversionService())); + assertThat(entity).isNull(); + } + + @Test + void whenEntityWithConverter() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(""" + James Bond, Ethan Hunt, Jason Bourne + """))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + List entity = spec.entity(new ListOutputConverter(new DefaultConversionService())); + assertThat(entity).hasSize(3); + } + + @Test + void whenEntityWithTypeIsNull() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + assertThatThrownBy(() -> spec.entity((Class) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("type cannot be null"); + } + + @Test + void whenEntityWithTypeAndChatResponseContentNull() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(null))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + String entity = spec.entity(String.class); + assertThat(entity).isNull(); + } + + @Test + void whenEntityWithType() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.call(promptCaptor.capture())) + .willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(""" + { "name": "James Bond" } + """))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultCallResponseSpec spec = new DefaultChatClient.DefaultCallResponseSpec( + chatClientRequestSpec); + + Person entity = spec.entity(Person.class); + assertThat(entity).isNotNull(); + assertThat(entity.name()).isEqualTo("James Bond"); + } + + // DefaultStreamResponseSpec + + @Test + void buildStreamResponseSpec() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(); + DefaultChatClient.DefaultStreamResponseSpec spec = new DefaultChatClient.DefaultStreamResponseSpec( + chatClientRequestSpec); + assertThat(spec).isNotNull(); + } + + @Test + void buildStreamResponseSpecWithNullRequest() { + assertThatThrownBy(() -> new DefaultChatClient.DefaultStreamResponseSpec(null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("request cannot be null"); + } + + @Test + void whenSimplePromptThenFluxChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.stream(promptCaptor.capture())) + .willReturn(Flux.just(new ChatResponse(List.of(new Generation(new AssistantMessage("response")))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultStreamResponseSpec spec = new DefaultChatClient.DefaultStreamResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse().blockLast(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(1); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("my question"); + } + + @Test + void whenFullPromptThenFluxChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.stream(promptCaptor.capture())) + .willReturn(Flux.just(new ChatResponse(List.of(new Generation(new AssistantMessage("response")))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + Prompt prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(prompt); + DefaultChatClient.DefaultStreamResponseSpec spec = new DefaultChatClient.DefaultStreamResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse().blockLast(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(2); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("instructions"); + assertThat(actualPrompt.getInstructions().get(1).getContent()).isEqualTo("my question"); + } + + @Test + void whenPromptAndUserTextThenFluxChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.stream(promptCaptor.capture())) + .willReturn(Flux.just(new ChatResponse(List.of(new Generation(new AssistantMessage("response")))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + Prompt prompt = new Prompt(new SystemMessage("instructions"), new UserMessage("my question")); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt(prompt) + .user("another question"); + DefaultChatClient.DefaultStreamResponseSpec spec = new DefaultChatClient.DefaultStreamResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse().blockLast(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(3); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("instructions"); + assertThat(actualPrompt.getInstructions().get(1).getContent()).isEqualTo("my question"); + assertThat(actualPrompt.getInstructions().get(2).getContent()).isEqualTo("another question"); + } + + @Test + void whenUserTextAndMessagesThenFluxChatResponse() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.stream(promptCaptor.capture())) + .willReturn(Flux.just(new ChatResponse(List.of(new Generation(new AssistantMessage("response")))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + List messages = List.of(new SystemMessage("instructions"), new UserMessage("my question")); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt() + .user("another question") + .messages(messages); + DefaultChatClient.DefaultStreamResponseSpec spec = new DefaultChatClient.DefaultStreamResponseSpec( + chatClientRequestSpec); + + ChatResponse chatResponse = spec.chatResponse().blockLast(); + assertThat(chatResponse).isNotNull(); + assertThat(chatResponse.getResult().getOutput().getContent()).isEqualTo("response"); + + Prompt actualPrompt = promptCaptor.getValue(); + assertThat(actualPrompt.getInstructions()).hasSize(3); + assertThat(actualPrompt.getInstructions().get(0).getContent()).isEqualTo("instructions"); + assertThat(actualPrompt.getInstructions().get(1).getContent()).isEqualTo("my question"); + assertThat(actualPrompt.getInstructions().get(2).getContent()).isEqualTo("another question"); + } + + @Test + void whenChatResponseContentIsNullThenReturnFlux() { + ChatModel chatModel = mock(ChatModel.class); + ArgumentCaptor promptCaptor = ArgumentCaptor.forClass(Prompt.class); + given(chatModel.stream(promptCaptor.capture())) + .willReturn(Flux.just(new ChatResponse(List.of(new Generation(new AssistantMessage(null)))))); + + ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build(); + DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient + .prompt("my question"); + DefaultChatClient.DefaultStreamResponseSpec spec = new DefaultChatClient.DefaultStreamResponseSpec( + chatClientRequestSpec); + + String content = spec.content().blockLast(); + assertThat(content).isNull(); + } + + // DefaultChatClientRequestSpec + + @Test + void buildChatClientRequestSpec() { + ChatModel chatModel = mock(ChatModel.class); + DefaultChatClient.DefaultChatClientRequestSpec spec = new DefaultChatClient.DefaultChatClientRequestSpec( + chatModel, null, Map.of(), null, Map.of(), List.of(), List.of(), List.of(), List.of(), null, List.of(), + Map.of(), ObservationRegistry.NOOP, null, Map.of()); + assertThat(spec).isNotNull(); + } + + @Test + void whenChatModelIsNullThenThrow() { + assertThatThrownBy(() -> new DefaultChatClient.DefaultChatClientRequestSpec(null, null, Map.of(), null, + Map.of(), List.of(), List.of(), List.of(), List.of(), null, List.of(), Map.of(), + ObservationRegistry.NOOP, null, Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("chatModel cannot be null"); + } + + @Test + void whenObservationRegistryIsNullThenThrow() { + assertThatThrownBy(() -> new DefaultChatClient.DefaultChatClientRequestSpec(mock(ChatModel.class), null, + Map.of(), null, Map.of(), List.of(), List.of(), List.of(), List.of(), null, List.of(), Map.of(), null, + null, Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("observationRegistry cannot be null"); + } + + @Test + void whenAdvisorConsumerIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.advisors((Consumer) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("consumer cannot be null"); + } + + @Test + void whenAdvisorConsumerThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + Advisor loggerAdvisor = new SimpleLoggerAdvisor(); + spec = spec.advisors(advisor -> advisor.advisors(loggerAdvisor).param("topic", "AI")); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getAdvisors()).contains(loggerAdvisor); + assertThat(defaultSpec.getAdvisorParams()).containsEntry("topic", "AI"); + } + + @Test + void whenRequestAdvisorsWithNullElementsThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.advisors((Advisor) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot contain null elements"); + } + + @Test + void whenRequestAdvisorsThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + Advisor advisor = new SimpleLoggerAdvisor(); + spec = spec.advisors(advisor); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getAdvisors()).contains(advisor); + } + + @Test + void whenRequestAdvisorListIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.advisors((List) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot be null"); + } + + @Test + void whenRequestAdvisorListWithNullElementsThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + List advisors = new ArrayList<>(); + advisors.add(null); + assertThatThrownBy(() -> spec.advisors(advisors)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot contain null elements"); + } + + @Test + void whenRequestAdvisorListThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + List advisors = List.of(new SimpleLoggerAdvisor()); + spec = spec.advisors(advisors); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getAdvisors()).containsAll(advisors); + } + + @Test + void whenMessagesWithNullElementsThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.messages((Message) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("messages cannot contain null elements"); + } + + @Test + void whenMessagesThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + Message message = new UserMessage("question"); + spec = spec.messages(message); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getMessages()).contains(message); + } + + @Test + void whenMessageListIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.messages((List) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("messages cannot be null"); + } + + @Test + void whenMessageListWithNullElementsThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + List messages = new ArrayList<>(); + messages.add(null); + assertThatThrownBy(() -> spec.messages(messages)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("messages cannot contain null elements"); + } + + @Test + void whenMessageListThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + List messages = List.of(new UserMessage("question")); + spec = spec.messages(messages); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getMessages()).containsAll(messages); + } + + @Test + void whenOptionsIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.options(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("options cannot be null"); + } + + @Test + void whenOptionsThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + ChatOptions options = ChatOptionsBuilder.builder().build(); + spec = spec.options(options); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getChatOptions()).isEqualTo(options); + } + + @Test + void whenFunctionNameIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function(null, "description", input -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("name cannot be null or empty"); + } + + @Test + void whenFunctionNameIsEmptyThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("", "description", input -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("name cannot be null or empty"); + } + + @Test + void whenFunctionDescriptionIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("name", null, input -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("description cannot be null or empty"); + } + + @Test + void whenFunctionDescriptionIsEmptyThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("name", "", input -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("description cannot be null or empty"); + } + + @Test + void whenFunctionLambdaIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("name", "description", (Function) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("function cannot be null"); + } + + @Test + void whenFunctionThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.function("name", "description", input -> "hello"); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getFunctionCallbacks()).anyMatch(callback -> callback.getName().equals("name")); + } + + @Test + void whenFunctionAndInputTypeThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.function("name", "description", String.class, input -> "hello"); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getFunctionCallbacks()).anyMatch(callback -> callback.getName().equals("name")); + } + + @Test + void whenBiFunctionNameIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function(null, "description", (input, ctx) -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("name cannot be null or empty"); + } + + @Test + void whenBiFunctionNameIsEmptyThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("", "description", (input, ctx) -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("name cannot be null or empty"); + } + + @Test + void whenBiFunctionDescriptionIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("name", null, (input, ctx) -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("description cannot be null or empty"); + } + + @Test + void whenBiFunctionDescriptionIsEmptyThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("name", "", (input, ctx) -> "hello")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("description cannot be null or empty"); + } + + @Test + void whenBiFunctionLambdaIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.function("name", "description", (BiFunction) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("biFunction cannot be null"); + } + + @Test + void whenBiFunctionThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.function("name", "description", (input, ctx) -> "hello"); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getFunctionCallbacks()).anyMatch(callback -> callback.getName().equals("name")); + } + + @Test + void whenFunctionBeanNamesElementIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.functions("myFunction", null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("functionBeanNames cannot contain null elements"); + } + + @Test + void whenFunctionBeanNamesThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + String functionBeanName = "myFunction"; + spec = spec.functions(functionBeanName); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getFunctionNames()).contains(functionBeanName); + } + + @Test + void whenFunctionCallbacksElementIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.functions(mock(FunctionCallback.class), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("functionCallbacks cannot contain null elements"); + } + + @Test + void whenFunctionCallbacksThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + FunctionCallback functionCallback = mock(FunctionCallback.class); + spec = spec.functions(functionCallback); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getFunctionCallbacks()).contains(functionCallback); + } + + @Test + void whenToolContextIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.toolContext(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("toolContext cannot be null"); + } + + @Test + void whenToolContextKeyIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + Map toolContext = new HashMap<>(); + toolContext.put(null, "value"); + assertThatThrownBy(() -> spec.toolContext(toolContext)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("toolContext keys cannot contain null elements"); + } + + @Test + void whenToolContextValueIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + Map toolContext = new HashMap<>(); + toolContext.put("key", null); + assertThatThrownBy(() -> spec.toolContext(toolContext)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("toolContext values cannot contain null elements"); + } + + @Test + void whenToolContextThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + Map toolContext = Map.of("key", "value"); + spec = spec.toolContext(toolContext); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getToolContext()).containsEntry("key", "value"); + } + + @Test + void whenSystemTextIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.system((String) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenSystemTextIsEmptyThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.system("")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenSystemTextThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.system(system -> system.text("instructions")); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getSystemText()).isEqualTo("instructions"); + } + + @Test + void whenSystemResourceIsNullWithCharsetThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.system(null, Charset.defaultCharset())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenSystemCharsetIsNullWithResourceThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.system(new ClassPathResource("system-prompt.txt"), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("charset cannot be null"); + } + + @Test + void whenSystemResourceAndCharsetThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.system(system -> system.text(new ClassPathResource("system-prompt.txt"), Charset.defaultCharset())); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getSystemText()).isEqualTo("instructions"); + } + + @Test + void whenSystemResourceIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.system((Resource) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenSystemResourceThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.system(systemSpec -> systemSpec.text(new ClassPathResource("system-prompt.txt"))); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getSystemText()).isEqualTo("instructions"); + } + + @Test + void whenSystemConsumerIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.system((Consumer) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("consumer cannot be null"); + } + + @Test + void whenSystemConsumerThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.system(system -> system.text("my instruction about {topic}").param("topic", "AI")); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getSystemText()).isEqualTo("my instruction about {topic}"); + assertThat(defaultSpec.getSystemParams()).containsEntry("topic", "AI"); + } + + @Test + void whenSystemConsumerWithExistingSystemTextThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt().system("my instruction"); + spec = spec.system(system -> system.text("my instruction about {topic}").param("topic", "AI")); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getSystemText()).isEqualTo("my instruction about {topic}"); + assertThat(defaultSpec.getSystemParams()).containsEntry("topic", "AI"); + } + + @Test + void whenSystemConsumerWithoutSystemTextThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt().system("my instruction about {topic}"); + spec = spec.system(system -> system.param("topic", "AI")); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getSystemText()).isEqualTo("my instruction about {topic}"); + assertThat(defaultSpec.getSystemParams()).containsEntry("topic", "AI"); + } + + @Test + void whenUserTextIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.user((String) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenUserTextIsEmptyThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.user("")).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null or empty"); + } + + @Test + void whenUserTextThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.user(user -> user.text("my question")); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getUserText()).isEqualTo("my question"); + } + + @Test + void whenUserResourceIsNullWithCharsetThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.user(null, Charset.defaultCharset())).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenUserCharsetIsNullWithResourceThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.user(new ClassPathResource("user-prompt.txt"), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("charset cannot be null"); + } + + @Test + void whenUserResourceAndCharsetThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.user(user -> user.text(new ClassPathResource("user-prompt.txt"), Charset.defaultCharset())); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getUserText()).isEqualTo("my question"); + } + + @Test + void whenUserResourceIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.user((Resource) null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("text cannot be null"); + } + + @Test + void whenUserResourceThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.user(user -> user.text(new ClassPathResource("user-prompt.txt"))); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getUserText()).isEqualTo("my question"); + } + + @Test + void whenUserConsumerIsNullThenThrow() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + assertThatThrownBy(() -> spec.user((Consumer) null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("consumer cannot be null"); + } + + @Test + void whenUserConsumerThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt(); + spec = spec.user(user -> user.text("my question about {topic}") + .param("topic", "AI") + .media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("tabby-cat.png"))); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getUserText()).isEqualTo("my question about {topic}"); + assertThat(defaultSpec.getUserParams()).containsEntry("topic", "AI"); + assertThat(defaultSpec.getMedia()).hasSize(1); + } + + @Test + void whenUserConsumerWithExistingUserTextThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt().user("my question"); + spec = spec.user(user -> user.text("my question about {topic}") + .param("topic", "AI") + .media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("tabby-cat.png"))); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getUserText()).isEqualTo("my question about {topic}"); + assertThat(defaultSpec.getUserParams()).containsEntry("topic", "AI"); + assertThat(defaultSpec.getMedia()).hasSize(1); + } + + @Test + void whenUserConsumerWithoutUserTextThenReturn() { + ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build(); + ChatClient.ChatClientRequestSpec spec = chatClient.prompt().user("my question about {topic}"); + spec = spec.user(user -> user.param("topic", "AI") + .media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("tabby-cat.png"))); + DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec; + assertThat(defaultSpec.getUserText()).isEqualTo("my question about {topic}"); + assertThat(defaultSpec.getUserParams()).containsEntry("topic", "AI"); + assertThat(defaultSpec.getMedia()).hasSize(1); + } + + record Person(String name) { + } + +} diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequestTests.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequestTests.java new file mode 100644 index 00000000000..8d392814f4f --- /dev/null +++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedRequestTests.java @@ -0,0 +1,148 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.chat.client.advisor.api; + +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import org.springframework.ai.chat.model.ChatModel; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; + +/** + * Unit tests for {@link AdvisedRequest}. + * + * @author Thomas Vitale + */ +class AdvisedRequestTests { + + @Test + void buildAdvisedRequest() { + AdvisedRequest request = new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of()); + assertThat(request).isNotNull(); + } + + @Test + void whenChatModelIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(null, "user", null, null, List.of(), List.of(), List.of(), + List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("chatModel cannot be null"); + } + + @Test + void whenUserTextIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), null, null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("userText cannot be null or empty"); + } + + @Test + void whenUserTextIsEmptyThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "", null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("userText cannot be null or empty"); + } + + @Test + void whenMediaIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, null, List.of(), + List.of(), List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("media cannot be null"); + } + + @Test + void whenFunctionNamesIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), null, + List.of(), List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("functionNames cannot be null"); + } + + @Test + void whenFunctionCallbacksIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + null, List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("functionCallbacks cannot be null"); + } + + @Test + void whenMessagesIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), null, Map.of(), Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("messages cannot be null"); + } + + @Test + void whenUserParamsIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), List.of(), null, Map.of(), List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("userParams cannot be null"); + } + + @Test + void whenSystemParamsIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), null, List.of(), Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("systemParams cannot be null"); + } + + @Test + void whenAdvisorsIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), Map.of(), null, Map.of(), Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisors cannot be null"); + } + + @Test + void whenAdvisorParamsIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), Map.of(), List.of(), null, Map.of(), Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisorParams cannot be null"); + } + + @Test + void whenAdviseContextIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), Map.of(), List.of(), Map.of(), null, Map.of())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("adviseContext cannot be null"); + } + + @Test + void whenToolContextIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedRequest(mock(ChatModel.class), "user", null, null, List.of(), List.of(), + List.of(), List.of(), Map.of(), Map.of(), List.of(), Map.of(), Map.of(), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("toolContext cannot be null"); + } + +} diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseTests.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseTests.java new file mode 100644 index 00000000000..ccf3637da82 --- /dev/null +++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/api/AdvisedResponseTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2023-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.chat.client.advisor.api; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import org.springframework.ai.chat.model.ChatResponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; + +/** + * Unit tests for {@link AdvisedResponse}. + * + * @author Thomas Vitale + */ +class AdvisedResponseTests { + + @Test + void buildAdvisedResponse() { + AdvisedResponse advisedResponse = new AdvisedResponse(mock(ChatResponse.class), Map.of()); + assertThat(advisedResponse).isNotNull(); + } + + @Test + void whenAdviseContextIsNullThenThrows() { + assertThatThrownBy(() -> new AdvisedResponse(mock(ChatResponse.class), null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("adviseContext cannot be null"); + } + + @Test + void whenAdviseContextKeysIsNullThenThrows() { + Map adviseContext = new HashMap<>(); + adviseContext.put(null, "value"); + assertThatThrownBy(() -> new AdvisedResponse(mock(ChatResponse.class), adviseContext)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("adviseContext keys cannot be null"); + } + + @Test + void whenAdviseContextValuesIsNullThenThrows() { + Map adviseContext = new HashMap<>(); + adviseContext.put("key", null); + assertThatThrownBy(() -> new AdvisedResponse(mock(ChatResponse.class), adviseContext)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("adviseContext values cannot be null"); + } + + @Test + void whenBuildFromNullAdvisedResponseThenThrows() { + assertThatThrownBy(() -> AdvisedResponse.from(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("advisedResponse cannot be null"); + } + + @Test + void buildFromAdvisedResponse() { + AdvisedResponse advisedResponse = new AdvisedResponse(mock(ChatResponse.class), Map.of()); + AdvisedResponse.Builder builder = AdvisedResponse.from(advisedResponse); + assertThat(builder).isNotNull(); + } + + @Test + void whenUpdateFromNullContextThenThrows() { + AdvisedResponse advisedResponse = new AdvisedResponse(mock(ChatResponse.class), Map.of()); + assertThatThrownBy(() -> advisedResponse.updateContext(null)).isInstanceOf(IllegalArgumentException.class) + .hasMessage("contextTransform cannot be null"); + } + +} diff --git a/spring-ai-core/src/test/resources/system-prompt.txt b/spring-ai-core/src/test/resources/system-prompt.txt new file mode 100644 index 00000000000..e468cde2e7d --- /dev/null +++ b/spring-ai-core/src/test/resources/system-prompt.txt @@ -0,0 +1 @@ +instructions \ No newline at end of file diff --git a/spring-ai-core/src/test/resources/tabby-cat.png b/spring-ai-core/src/test/resources/tabby-cat.png new file mode 100644 index 0000000000000000000000000000000000000000..4c564e4fb74ca99a708451f7877fb123e1be3165 GIT binary patch literal 245664 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≪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

?Q_^n?GOk3o!DZ;XfA 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 }koRz31N>A8rnfF_^f6>!$wIYZBXn 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 s?To>;8=2&-X7@Q