refactor(client): rename overloaded tools methods in prompt builder
Renames the ambiguous overloaded `tools` methods in `ChatClient.PromptRequestSpec` to `toolNames` and `toolCallbacks` respectively. This improves clarity and prevents potential issues with method dispatching based on argument types. Updates relevant code examples and adds documentation to upgrade notes. Signed-off-by: Mark Pollack <mark.pollack@broadcom.com>
This commit is contained in:
@@ -60,7 +60,7 @@ public class FunctionCallbackInPrompt2IT {
|
||||
|
||||
String content = ChatClient.builder(chatModel).build().prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris?")
|
||||
.tools(FunctionToolCallback
|
||||
.toolCallbacks(FunctionToolCallback
|
||||
.builder("CurrentWeatherService", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
@@ -88,7 +88,7 @@ public class FunctionCallbackInPrompt2IT {
|
||||
// @formatter:off
|
||||
String content = ChatClient.builder(chatModel).build().prompt()
|
||||
.user("Turn the light on in the kitchen and in the living room!")
|
||||
.tools(FunctionToolCallback
|
||||
.toolCallbacks(FunctionToolCallback
|
||||
.builder("turnLight", (LightInfo lightInfo) -> {
|
||||
logger.info("Turning light to [" + lightInfo.isOn + "] in " + lightInfo.roomName());
|
||||
state.put(lightInfo.roomName(), lightInfo.isOn());
|
||||
@@ -114,7 +114,7 @@ public class FunctionCallbackInPrompt2IT {
|
||||
// @formatter:off
|
||||
String content = ChatClient.builder(chatModel).build().prompt()
|
||||
.user("What's the weather like in Amsterdam?")
|
||||
.tools(FunctionToolCallback
|
||||
.toolCallbacks(FunctionToolCallback
|
||||
.builder("CurrentWeatherService", input -> "18 degrees Celsius")
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
@@ -138,7 +138,7 @@ public class FunctionCallbackInPrompt2IT {
|
||||
// @formatter:off
|
||||
String content = ChatClient.builder(chatModel).build().prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris?")
|
||||
.tools(FunctionToolCallback
|
||||
.toolCallbacks(FunctionToolCallback
|
||||
.builder("CurrentWeatherService", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
|
||||
@@ -174,7 +174,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
|
||||
ChatClient chatClient = ChatClient.builder(chatModel).build();
|
||||
|
||||
String content = chatClient.prompt("What's the weather like in San Francisco, Tokyo, and Paris?")
|
||||
.tools("weatherFunctionWithContext")
|
||||
.toolNames("weatherFunctionWithContext")
|
||||
.toolContext(Map.of("sessionId", "123"))
|
||||
.call()
|
||||
.content();
|
||||
@@ -206,7 +206,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
|
||||
ChatClient chatClient = ChatClient.builder(chatModel).build();
|
||||
|
||||
String content = chatClient.prompt("What's the weather like in San Francisco, Tokyo, and Paris?")
|
||||
.tools("weatherFunctionWithClassBiFunction")
|
||||
.toolNames("weatherFunctionWithClassBiFunction")
|
||||
.toolContext(Map.of("sessionId", "123"))
|
||||
.call()
|
||||
.content();
|
||||
|
||||
@@ -55,7 +55,7 @@ public class OpenAiFunctionCallback2IT {
|
||||
|
||||
// @formatter:off
|
||||
ChatClient chatClient = ChatClient.builder(chatModel)
|
||||
.defaultTools("WeatherInfo")
|
||||
.defaultToolNames("WeatherInfo")
|
||||
.defaultUser(u -> u.text("What's the weather like in {cities}?"))
|
||||
.build();
|
||||
|
||||
@@ -78,7 +78,7 @@ public class OpenAiFunctionCallback2IT {
|
||||
|
||||
// @formatter:off
|
||||
String content = ChatClient.builder(chatModel).build().prompt()
|
||||
.tools("WeatherInfo")
|
||||
.toolNames("WeatherInfo")
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris?")
|
||||
.stream().content()
|
||||
.collectList().block().stream().collect(Collectors.joining());
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -213,7 +212,7 @@ class AnthropicChatClientIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
.call()
|
||||
@@ -231,7 +230,7 @@ class AnthropicChatClientIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeatherInLocation", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeatherInLocation", new MockWeatherService())
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
.call()
|
||||
@@ -248,7 +247,7 @@ class AnthropicChatClientIT {
|
||||
|
||||
// @formatter:off
|
||||
String response = ChatClient.builder(this.chatModel)
|
||||
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -270,7 +269,7 @@ class AnthropicChatClientIT {
|
||||
// @formatter:off
|
||||
Flux<String> response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
|
||||
@@ -67,7 +67,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
|
||||
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod).build())
|
||||
.toolMethod(toolMethod)
|
||||
.build())
|
||||
@@ -89,7 +89,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
|
||||
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -116,7 +116,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
|
||||
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("Turn light on in the living room.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(turnLightMethod)
|
||||
.description("Turn light on in the living room.")
|
||||
.build())
|
||||
@@ -144,7 +144,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
|
||||
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -171,7 +171,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
|
||||
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -202,7 +202,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
|
||||
|
||||
assertThatThrownBy(() -> ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -227,7 +227,7 @@ class AnthropicChatClientMethodInvokingFunctionCallbackIT {
|
||||
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("Turn light on in the living room.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolMethod(toolMethod)
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Can turn lights on in the Living Room")
|
||||
|
||||
@@ -212,7 +212,7 @@ class BedrockConverseChatClientIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel)
|
||||
.prompt("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -231,7 +231,7 @@ class BedrockConverseChatClientIT {
|
||||
// @formatter:off
|
||||
ChatResponse response = ChatClient.create(this.chatModel)
|
||||
.prompt("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -265,7 +265,7 @@ class BedrockConverseChatClientIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel)
|
||||
.prompt("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -284,7 +284,7 @@ class BedrockConverseChatClientIT {
|
||||
|
||||
// @formatter:off
|
||||
String response = ChatClient.builder(this.chatModel)
|
||||
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -306,7 +306,7 @@ class BedrockConverseChatClientIT {
|
||||
// @formatter:off
|
||||
Flux<ChatResponse> response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Return the temperature in Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -347,7 +347,7 @@ class BedrockConverseChatClientIT {
|
||||
// @formatter:off
|
||||
Flux<String> response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in Paris? Return the temperature in Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
|
||||
@@ -141,7 +141,7 @@ public class BedrockNovaChatClientIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", (WeatherRequest request) -> {
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", (WeatherRequest request) -> {
|
||||
if (request.location().contains("Paris")) {
|
||||
return new WeatherResponse(15, request.unit());
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ class MistralAiChatClientIT {
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.options(MistralAiChatOptions.builder().model(MistralAiApi.ChatModel.SMALL).toolChoice(ToolChoice.AUTO).build())
|
||||
.user(u -> u.text("What's the weather like in San Francisco, Tokyo, and Paris? Use parallel function calling if required. Response should be in Celsius."))
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -249,7 +249,7 @@ class MistralAiChatClientIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.builder(this.chatModel)
|
||||
.defaultOptions(MistralAiChatOptions.builder().model(MistralAiApi.ChatModel.SMALL).build())
|
||||
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -272,7 +272,7 @@ class MistralAiChatClientIT {
|
||||
Flux<String> response = ChatClient.create(this.chatModel).prompt()
|
||||
.options(MistralAiChatOptions.builder().model(MistralAiApi.ChatModel.SMALL).build())
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use parallel function calling if required. Response should be in Celsius.")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
|
||||
@@ -69,7 +69,7 @@ class OpenAiChatModelFunctionCallingIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("Turn the light on in the living room")
|
||||
.tools(FunctionToolCallback.builder("turnsLightOnInTheLivingRoom", () -> state.put("Light", "ON"))
|
||||
.toolCallbacks(FunctionToolCallback.builder("turnsLightOnInTheLivingRoom", () -> state.put("Light", "ON"))
|
||||
.build())
|
||||
.call()
|
||||
.content();
|
||||
|
||||
@@ -82,7 +82,7 @@ public class OpenAiPaymentTransactionIT {
|
||||
public void transactionPaymentStatuses(String functionName) {
|
||||
List<TransactionStatusResponse> content = this.chatClient.prompt()
|
||||
.advisors(new LoggingAdvisor())
|
||||
.tools(functionName)
|
||||
.toolNames(functionName)
|
||||
.user("""
|
||||
What is the status of my payment transactions 001, 002 and 003?
|
||||
""")
|
||||
@@ -113,7 +113,7 @@ public class OpenAiPaymentTransactionIT {
|
||||
|
||||
Flux<String> flux = this.chatClient.prompt()
|
||||
.advisors(new LoggingAdvisor())
|
||||
.tools(functionName)
|
||||
.toolNames(functionName)
|
||||
.user(u -> u.text("""
|
||||
What is the status of my payment transactions 001, 002 and 003?
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ class OpenAiChatClientIT extends AbstractIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user(u -> u.text("What's the weather like in San Francisco, Tokyo, and Paris?"))
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -269,7 +269,7 @@ class OpenAiChatClientIT extends AbstractIT {
|
||||
|
||||
// @formatter:off
|
||||
String response = ChatClient.builder(this.chatModel)
|
||||
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -289,7 +289,7 @@ class OpenAiChatClientIT extends AbstractIT {
|
||||
// @formatter:off
|
||||
Flux<String> response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris?")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
|
||||
@@ -66,7 +66,7 @@ class OpenAiChatClientMethodInvokingFunctionCallbackIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -91,7 +91,7 @@ class OpenAiChatClientMethodInvokingFunctionCallbackIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("Turn light on in the living room.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Can turn lights on or off by room name")
|
||||
.build())
|
||||
@@ -119,7 +119,7 @@ class OpenAiChatClientMethodInvokingFunctionCallbackIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -146,7 +146,7 @@ class OpenAiChatClientMethodInvokingFunctionCallbackIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -175,7 +175,7 @@ class OpenAiChatClientMethodInvokingFunctionCallbackIT {
|
||||
// @formatter:off
|
||||
assertThatThrownBy(() -> ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris? Use Celsius.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Get the weather in location")
|
||||
.build())
|
||||
@@ -199,7 +199,7 @@ class OpenAiChatClientMethodInvokingFunctionCallbackIT {
|
||||
// @formatter:off
|
||||
String response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("Turn light on in the living room.")
|
||||
.tools(MethodToolCallback.builder()
|
||||
.toolCallbacks(MethodToolCallback.builder()
|
||||
.toolDefinition(ToolDefinition.builder(toolMethod)
|
||||
.description("Can turn lights on in the Living Room")
|
||||
.build())
|
||||
|
||||
@@ -84,7 +84,7 @@ class OpenAiChatClientMultipleFunctionCallsIT extends AbstractIT {
|
||||
// @formatter:off
|
||||
response = chatClientBuilder.build().prompt()
|
||||
.user(u -> u.text("What's the weather like in San Francisco, Tokyo, and Paris?"))
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -114,7 +114,7 @@ class OpenAiChatClientMultipleFunctionCallsIT extends AbstractIT {
|
||||
|
||||
// @formatter:off
|
||||
String response = ChatClient.builder(this.chatModel)
|
||||
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -156,7 +156,7 @@ class OpenAiChatClientMultipleFunctionCallsIT extends AbstractIT {
|
||||
|
||||
// @formatter:off
|
||||
String response = ChatClient.builder(this.chatModel)
|
||||
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", biFunction)
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("getCurrentWeather", biFunction)
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -199,7 +199,7 @@ class OpenAiChatClientMultipleFunctionCallsIT extends AbstractIT {
|
||||
|
||||
// @formatter:off
|
||||
String response = ChatClient.builder(this.chatModel)
|
||||
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", biFunction)
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("getCurrentWeather", biFunction)
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -221,7 +221,7 @@ class OpenAiChatClientMultipleFunctionCallsIT extends AbstractIT {
|
||||
// @formatter:off
|
||||
Flux<String> response = ChatClient.create(this.chatModel).prompt()
|
||||
.user("What's the weather like in San Francisco, Tokyo, and Paris?")
|
||||
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.toolCallbacks(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
|
||||
.description("Get the weather in location")
|
||||
.inputType(MockWeatherService.Request.class)
|
||||
.build())
|
||||
@@ -250,7 +250,7 @@ class OpenAiChatClientMultipleFunctionCallsIT extends AbstractIT {
|
||||
|
||||
String content = chatClient.prompt()
|
||||
.user("What's the weather like in Shanghai?")
|
||||
.tools(FunctionToolCallback.builder("currentTemp", function)
|
||||
.toolCallbacks(FunctionToolCallback.builder("currentTemp", function)
|
||||
.description("get current temp")
|
||||
.inputType(MyFunction.Req.class)
|
||||
.build())
|
||||
|
||||
@@ -76,7 +76,7 @@ public class VertexAiGeminiPaymentTransactionIT {
|
||||
// @formatter:off
|
||||
String content = this.chatClient.prompt()
|
||||
.advisors(new LoggingAdvisor())
|
||||
.tools("paymentStatus")
|
||||
.toolNames("paymentStatus")
|
||||
.user("""
|
||||
What is the status of my payment transactions 001, 002 and 003?
|
||||
If requred invoke the function per transaction.
|
||||
@@ -93,7 +93,7 @@ public class VertexAiGeminiPaymentTransactionIT {
|
||||
|
||||
Flux<String> streamContent = this.chatClient.prompt()
|
||||
.advisors(new LoggingAdvisor())
|
||||
.tools("paymentStatus")
|
||||
.toolNames("paymentStatus")
|
||||
.user("""
|
||||
What is the status of my payment transactions 001, 002 and 003?
|
||||
If requred invoke the function per transaction.
|
||||
|
||||
@@ -76,7 +76,7 @@ public class VertexAiGeminiPaymentTransactionMethodIT {
|
||||
@Test
|
||||
public void paymentStatuses() {
|
||||
|
||||
String content = this.chatClient.prompt().advisors(new LoggingAdvisor()).tools("paymentStatus").user("""
|
||||
String content = this.chatClient.prompt().advisors(new LoggingAdvisor()).toolNames("paymentStatus").user("""
|
||||
What is the status of my payment transactions 001, 002 and 003?
|
||||
If requred invoke the function per transaction.
|
||||
""").call().content();
|
||||
@@ -91,7 +91,7 @@ public class VertexAiGeminiPaymentTransactionMethodIT {
|
||||
|
||||
Flux<String> streamContent = this.chatClient.prompt()
|
||||
.advisors(new LoggingAdvisor())
|
||||
.tools("paymentStatus")
|
||||
.toolNames("paymentStatus")
|
||||
.user("""
|
||||
What is the status of my payment transactions 001, 002 and 003?
|
||||
If requred invoke the function per transaction.
|
||||
|
||||
@@ -220,15 +220,15 @@ public interface ChatClient {
|
||||
|
||||
<T extends ChatOptions> ChatClientRequestSpec options(T options);
|
||||
|
||||
ChatClientRequestSpec tools(String... toolNames);
|
||||
|
||||
ChatClientRequestSpec tools(ToolCallback... toolCallbacks);
|
||||
|
||||
ChatClientRequestSpec tools(List<ToolCallback> toolCallbacks);
|
||||
ChatClientRequestSpec toolNames(String... toolNames);
|
||||
|
||||
ChatClientRequestSpec tools(Object... toolObjects);
|
||||
|
||||
ChatClientRequestSpec tools(ToolCallbackProvider... toolCallbackProviders);
|
||||
ChatClientRequestSpec toolCallbacks(ToolCallback... toolCallbacks);
|
||||
|
||||
ChatClientRequestSpec toolCallbacks(List<ToolCallback> toolCallbacks);
|
||||
|
||||
ChatClientRequestSpec toolCallbacks(ToolCallbackProvider... toolCallbackProviders);
|
||||
|
||||
ChatClientRequestSpec toolContext(Map<String, Object> toolContext);
|
||||
|
||||
@@ -287,15 +287,15 @@ public interface ChatClient {
|
||||
|
||||
Builder defaultTemplateRenderer(TemplateRenderer templateRenderer);
|
||||
|
||||
Builder defaultTools(String... toolNames);
|
||||
|
||||
Builder defaultTools(ToolCallback... toolCallbacks);
|
||||
|
||||
Builder defaultTools(List<ToolCallback> toolCallbacks);
|
||||
Builder defaultToolNames(String... toolNames);
|
||||
|
||||
Builder defaultTools(Object... toolObjects);
|
||||
|
||||
Builder defaultTools(ToolCallbackProvider... toolCallbackProviders);
|
||||
Builder defaultToolCallbacks(ToolCallback... toolCallbacks);
|
||||
|
||||
Builder defaultToolCallbacks(List<ToolCallback> toolCallbacks);
|
||||
|
||||
Builder defaultToolCallbacks(ToolCallbackProvider... toolCallbackProviders);
|
||||
|
||||
Builder defaultToolContext(Map<String, Object> toolContext);
|
||||
|
||||
|
||||
@@ -768,7 +768,7 @@ public class DefaultChatClient implements ChatClient {
|
||||
public Builder mutate() {
|
||||
DefaultChatClientBuilder builder = (DefaultChatClientBuilder) ChatClient
|
||||
.builder(this.chatModel, this.observationRegistry, this.observationConvention)
|
||||
.defaultTools(StringUtils.toStringArray(this.toolNames));
|
||||
.defaultToolNames(StringUtils.toStringArray(this.toolNames));
|
||||
|
||||
if (StringUtils.hasText(this.userText)) {
|
||||
builder.defaultUser(
|
||||
@@ -834,7 +834,7 @@ public class DefaultChatClient implements ChatClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatClientRequestSpec tools(String... toolNames) {
|
||||
public ChatClientRequestSpec toolNames(String... toolNames) {
|
||||
Assert.notNull(toolNames, "toolNames cannot be null");
|
||||
Assert.noNullElements(toolNames, "toolNames cannot contain null elements");
|
||||
this.toolNames.addAll(List.of(toolNames));
|
||||
@@ -842,7 +842,7 @@ public class DefaultChatClient implements ChatClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatClientRequestSpec tools(ToolCallback... toolCallbacks) {
|
||||
public ChatClientRequestSpec toolCallbacks(ToolCallback... toolCallbacks) {
|
||||
Assert.notNull(toolCallbacks, "toolCallbacks cannot be null");
|
||||
Assert.noNullElements(toolCallbacks, "toolCallbacks cannot contain null elements");
|
||||
this.toolCallbacks.addAll(List.of(toolCallbacks));
|
||||
@@ -850,7 +850,7 @@ public class DefaultChatClient implements ChatClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatClientRequestSpec tools(List<ToolCallback> toolCallbacks) {
|
||||
public ChatClientRequestSpec toolCallbacks(List<ToolCallback> toolCallbacks) {
|
||||
Assert.notNull(toolCallbacks, "toolCallbacks cannot be null");
|
||||
Assert.noNullElements(toolCallbacks, "toolCallbacks cannot contain null elements");
|
||||
this.toolCallbacks.addAll(toolCallbacks);
|
||||
@@ -866,7 +866,7 @@ public class DefaultChatClient implements ChatClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatClientRequestSpec tools(ToolCallbackProvider... toolCallbackProviders) {
|
||||
public ChatClientRequestSpec toolCallbacks(ToolCallbackProvider... toolCallbackProviders) {
|
||||
Assert.notNull(toolCallbackProviders, "toolCallbackProviders cannot be null");
|
||||
Assert.noNullElements(toolCallbackProviders, "toolCallbackProviders cannot contain null elements");
|
||||
for (ToolCallbackProvider toolCallbackProvider : toolCallbackProviders) {
|
||||
|
||||
@@ -151,20 +151,20 @@ public class DefaultChatClientBuilder implements Builder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder defaultTools(String... toolNames) {
|
||||
this.defaultRequest.tools(toolNames);
|
||||
public Builder defaultToolNames(String... toolNames) {
|
||||
this.defaultRequest.toolNames(toolNames);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder defaultTools(ToolCallback... toolCallbacks) {
|
||||
this.defaultRequest.tools(toolCallbacks);
|
||||
public Builder defaultToolCallbacks(ToolCallback... toolCallbacks) {
|
||||
this.defaultRequest.toolCallbacks(toolCallbacks);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder defaultTools(List<ToolCallback> toolCallbacks) {
|
||||
this.defaultRequest.tools(toolCallbacks);
|
||||
public Builder defaultToolCallbacks(List<ToolCallback> toolCallbacks) {
|
||||
this.defaultRequest.toolCallbacks(toolCallbacks);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -175,14 +175,15 @@ public class DefaultChatClientBuilder implements Builder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder defaultTools(ToolCallbackProvider... toolCallbackProviders) {
|
||||
this.defaultRequest.tools(toolCallbackProviders);
|
||||
public Builder defaultToolCallbacks(ToolCallbackProvider... toolCallbackProviders) {
|
||||
this.defaultRequest.toolCallbacks(toolCallbackProviders);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated // Use defaultTools()
|
||||
public <I, O> Builder defaultFunction(String name, String description, java.util.function.Function<I, O> function) {
|
||||
this.defaultRequest.tools(FunctionToolCallback.builder(name, function).description(description).build());
|
||||
this.defaultRequest
|
||||
.toolCallbacks(FunctionToolCallback.builder(name, function).description(description).build());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -203,7 +204,7 @@ public class DefaultChatClientBuilder implements Builder {
|
||||
|
||||
void addToolCallbacks(List<ToolCallback> toolCallbacks) {
|
||||
Assert.notNull(toolCallbacks, "toolCallbacks cannot be null");
|
||||
this.defaultRequest.tools(toolCallbacks.toArray(ToolCallback[]::new));
|
||||
this.defaultRequest.toolCallbacks(toolCallbacks.toArray(ToolCallback[]::new));
|
||||
}
|
||||
|
||||
void addToolContext(Map<String, Object> toolContext) {
|
||||
|
||||
@@ -216,8 +216,8 @@ public class ChatClientTest {
|
||||
.defaultSystem(s -> s.text("Default system text {param1}, {param2}")
|
||||
.param("param1", "value1")
|
||||
.param("param2", "value2"))
|
||||
.defaultTools("fun1", "fun2")
|
||||
.defaultTools(FunctionToolCallback.builder("fun3", mockFunction)
|
||||
.defaultToolNames("fun1", "fun2")
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("fun3", mockFunction)
|
||||
.description("fun3description")
|
||||
.inputType(String.class)
|
||||
.build())
|
||||
@@ -276,7 +276,7 @@ public class ChatClientTest {
|
||||
// @formatter:off
|
||||
chatClient = chatClient.mutate()
|
||||
.defaultSystem("Mutated default system text {param1}, {param2}")
|
||||
.defaultTools("fun4")
|
||||
.defaultToolNames("fun4")
|
||||
.defaultUser("Mutated default user text {uparam1}, {uparam2}")
|
||||
.build();
|
||||
// @formatter:on
|
||||
@@ -346,8 +346,8 @@ public class ChatClientTest {
|
||||
.defaultSystem(s -> s.text("Default system text {param1}, {param2}")
|
||||
.param("param1", "value1")
|
||||
.param("param2", "value2"))
|
||||
.defaultTools("fun1", "fun2")
|
||||
.defaultTools(FunctionToolCallback.builder("fun3", mockFunction)
|
||||
.defaultToolNames("fun1", "fun2")
|
||||
.defaultToolCallbacks(FunctionToolCallback.builder("fun3", mockFunction)
|
||||
.description("fun3description")
|
||||
.inputType(String.class)
|
||||
.build())
|
||||
@@ -363,7 +363,7 @@ public class ChatClientTest {
|
||||
.system("New default system text {param1}, {param2}")
|
||||
.user(u -> u.param("uparam1", "userValue1")
|
||||
.param("uparam2", "userValue2"))
|
||||
.tools("fun5")
|
||||
.toolNames("fun5")
|
||||
.mutate().build() // mutate and build new prompt
|
||||
.prompt().call().content();
|
||||
// @formatter:on
|
||||
@@ -394,7 +394,7 @@ public class ChatClientTest {
|
||||
.system("New default system text {param1}, {param2}")
|
||||
.user(u -> u.param("uparam1", "userValue1")
|
||||
.param("uparam2", "userValue2"))
|
||||
.tools("fun5")
|
||||
.toolNames("fun5")
|
||||
.mutate().build() // mutate and build new prompt
|
||||
.prompt().stream().content());
|
||||
// @formatter:on
|
||||
@@ -523,7 +523,7 @@ public class ChatClientTest {
|
||||
// @formatter:off
|
||||
ChatClient client = ChatClient.builder(this.chatModel)
|
||||
.defaultSystem("System text")
|
||||
.defaultTools("function1")
|
||||
.defaultToolNames("function1")
|
||||
.build();
|
||||
|
||||
String response = client.prompt()
|
||||
|
||||
@@ -1457,7 +1457,7 @@ class DefaultChatClientTests {
|
||||
void whenToolNamesElementIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools("myTool", null)).isInstanceOf(IllegalArgumentException.class)
|
||||
assertThatThrownBy(() -> spec.toolNames("myTool", null)).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("toolNames cannot contain null elements");
|
||||
}
|
||||
|
||||
@@ -1466,7 +1466,7 @@ class DefaultChatClientTests {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
String toolName = "myTool";
|
||||
spec = spec.tools(toolName);
|
||||
spec = spec.toolNames(toolName);
|
||||
DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec;
|
||||
assertThat(defaultSpec.getToolNames()).contains(toolName);
|
||||
}
|
||||
@@ -1475,7 +1475,7 @@ class DefaultChatClientTests {
|
||||
void whenToolCallbacksElementIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools(mock(ToolCallback.class), null))
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(mock(ToolCallback.class), null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("toolCallbacks cannot contain null elements");
|
||||
}
|
||||
@@ -1485,7 +1485,7 @@ class DefaultChatClientTests {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
ToolCallback toolCallback = mock(ToolCallback.class);
|
||||
spec = spec.tools(toolCallback);
|
||||
spec = spec.toolCallbacks(toolCallback);
|
||||
DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec;
|
||||
assertThat(defaultSpec.getToolCallbacks()).contains(toolCallback);
|
||||
}
|
||||
@@ -1494,7 +1494,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionNameIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools(FunctionToolCallback.builder(null, input -> "hello")
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(FunctionToolCallback.builder(null, input -> "hello")
|
||||
.description("description")
|
||||
.inputType(String.class)
|
||||
.build())).isInstanceOf(IllegalArgumentException.class).hasMessage("name cannot be null or empty");
|
||||
@@ -1504,7 +1504,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionNameIsEmptyThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools(FunctionToolCallback.builder("", input -> "hello")
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(FunctionToolCallback.builder("", input -> "hello")
|
||||
.description("description")
|
||||
.inputType(String.class)
|
||||
.build())).isInstanceOf(IllegalArgumentException.class).hasMessage("name cannot be null or empty");
|
||||
@@ -1515,7 +1515,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionDescriptionIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools(FunctionToolCallback.builder("name", input -> "hello")
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(FunctionToolCallback.builder("name", input -> "hello")
|
||||
.description(null)
|
||||
.inputType(String.class)
|
||||
.build())).isInstanceOf(IllegalArgumentException.class).hasMessage("Description must not be empty");
|
||||
@@ -1526,7 +1526,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionDescriptionIsEmptyThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools(
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(
|
||||
FunctionToolCallback.builder("name", input -> "hello").description("").inputType(String.class).build()))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("Description must not be empty");
|
||||
@@ -1536,7 +1536,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionThenReturn() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
spec = spec.tools(FunctionToolCallback.builder("name", input -> "hello")
|
||||
spec = spec.toolCallbacks(FunctionToolCallback.builder("name", input -> "hello")
|
||||
.inputType(String.class)
|
||||
.description("description")
|
||||
.build());
|
||||
@@ -1549,7 +1549,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionAndInputTypeThenReturn() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
spec = spec.tools(FunctionToolCallback.builder("name", input -> "hello")
|
||||
spec = spec.toolCallbacks(FunctionToolCallback.builder("name", input -> "hello")
|
||||
.inputType(String.class)
|
||||
.description("description")
|
||||
.build());
|
||||
@@ -1562,8 +1562,8 @@ class DefaultChatClientTests {
|
||||
void whenBiFunctionNameIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec
|
||||
.tools(FunctionToolCallback.builder(null, (input, ctx) -> "hello").description("description").build()))
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(
|
||||
FunctionToolCallback.builder(null, (input, ctx) -> "hello").description("description").build()))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be null or empty");
|
||||
}
|
||||
@@ -1572,8 +1572,8 @@ class DefaultChatClientTests {
|
||||
void whenBiFunctionNameIsEmptyThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec
|
||||
.tools(FunctionToolCallback.builder("", (input, ctx) -> "hello").description("description").build()))
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(
|
||||
FunctionToolCallback.builder("", (input, ctx) -> "hello").description("description").build()))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("name cannot be null or empty");
|
||||
}
|
||||
@@ -1583,7 +1583,7 @@ class DefaultChatClientTests {
|
||||
void whenBiFunctionDescriptionIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools(FunctionToolCallback.builder("name", (input, ctx) -> "hello")
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(FunctionToolCallback.builder("name", (input, ctx) -> "hello")
|
||||
.inputType(String.class)
|
||||
.description(null)
|
||||
.build())).isInstanceOf(IllegalArgumentException.class).hasMessage("Description must not be empty");
|
||||
@@ -1594,8 +1594,8 @@ class DefaultChatClientTests {
|
||||
void whenBiFunctionDescriptionIsEmptyThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(
|
||||
() -> spec.tools(FunctionToolCallback.builder("name", (input, ctx) -> "hello").description("").build()))
|
||||
assertThatThrownBy(() -> spec
|
||||
.toolCallbacks(FunctionToolCallback.builder("name", (input, ctx) -> "hello").description("").build()))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("Description must not be empty");
|
||||
}
|
||||
@@ -1604,7 +1604,7 @@ class DefaultChatClientTests {
|
||||
void whenBiFunctionThenReturn() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
spec = spec.tools(FunctionToolCallback.builder("name", (input, ctx) -> "hello")
|
||||
spec = spec.toolCallbacks(FunctionToolCallback.builder("name", (input, ctx) -> "hello")
|
||||
.description("description")
|
||||
.inputType(String.class)
|
||||
.build());
|
||||
@@ -1617,7 +1617,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionBeanNamesElementIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools("myFunction", null)).isInstanceOf(IllegalArgumentException.class)
|
||||
assertThatThrownBy(() -> spec.toolNames("myFunction", null)).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("toolNames cannot contain null elements");
|
||||
}
|
||||
|
||||
@@ -1626,7 +1626,7 @@ class DefaultChatClientTests {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
String functionBeanName = "myFunction";
|
||||
spec = spec.tools(functionBeanName);
|
||||
spec = spec.toolNames(functionBeanName);
|
||||
DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec;
|
||||
assertThat(defaultSpec.getToolNames()).contains(functionBeanName);
|
||||
}
|
||||
@@ -1635,7 +1635,7 @@ class DefaultChatClientTests {
|
||||
void whenFunctionToolCallbacksElementIsNullThenThrow() {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
assertThatThrownBy(() -> spec.tools(mock(FunctionToolCallback.class), null))
|
||||
assertThatThrownBy(() -> spec.toolCallbacks(mock(FunctionToolCallback.class), null))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("toolCallbacks cannot contain null elements");
|
||||
}
|
||||
@@ -1645,7 +1645,7 @@ class DefaultChatClientTests {
|
||||
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
|
||||
ChatClient.ChatClientRequestSpec spec = chatClient.prompt();
|
||||
FunctionToolCallback functionToolCallback = mock(FunctionToolCallback.class);
|
||||
spec = spec.tools(functionToolCallback);
|
||||
spec = spec.toolCallbacks(functionToolCallback);
|
||||
DefaultChatClient.DefaultChatClientRequestSpec defaultSpec = (DefaultChatClient.DefaultChatClientRequestSpec) spec;
|
||||
assertThat(defaultSpec.getToolCallbacks()).contains(functionToolCallback);
|
||||
}
|
||||
|
||||
@@ -124,6 +124,13 @@ Prompt augmentedPrompt = originalPrompt.augmentUserMessage(userMessage ->
|
||||
|
||||
This approach offers more control when you need to conditionally change parts of the `UserMessage` or work with its media and metadata, rather than just replacing the text content.
|
||||
|
||||
* The overloaded `tools` methods in the `ChatClient` prompt builder API have been renamed for clarity and to avoid ambiguity in method dispatching based on argument types.
|
||||
|
||||
* `ChatClient.PromptRequestSpec#tools(String... toolNames)` has been renamed to `ChatClient.PromptRequestSpec#toolNames(String... toolNames)`. Use this method to specify the names of tool functions (registered elsewhere, e.g., via `@Bean` definitions with `@Description`) that the model is allowed to call.
|
||||
* `ChatClient.PromptRequestSpec#tools(ToolCallback... toolCallbacks)` has been renamed to `ChatClient.PromptRequestSpec#toolCallbacks(ToolCallback... toolCallbacks)`. Use this method to provide inline `ToolCallback` instances, which include the function implementation, name, description, and input type definition.
|
||||
|
||||
This change addresses potential confusion where the Java compiler might not select the intended overload based on the provided arguments.
|
||||
|
||||
=== Prompt Templating and Advisors
|
||||
|
||||
Several classes and methods related to prompt creation and advisor customization have been deprecated in favor of more flexible approaches using the builder pattern and the `TemplateRenderer` interface.
|
||||
|
||||
@@ -66,7 +66,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("Welcome the users to the library")
|
||||
.tools(Tools.WELCOME)
|
||||
.toolNames(Tools.WELCOME)
|
||||
.call()
|
||||
.content();
|
||||
assertThat(content).isNotEmpty();
|
||||
@@ -78,7 +78,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("Welcome the users to the library")
|
||||
.tools(FunctionToolCallback.builder("sayWelcome",
|
||||
.toolCallbacks(FunctionToolCallback.builder("sayWelcome",
|
||||
(Consumer<Object>) input -> logger.info("CALLBACK - Welcoming users to the library"))
|
||||
.description("Welcome users to the library")
|
||||
.inputType(Void.class)
|
||||
@@ -94,7 +94,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("Welcome %s to the library".formatted("James Bond"))
|
||||
.tools(Tools.WELCOME_USER)
|
||||
.toolNames(Tools.WELCOME_USER)
|
||||
.call()
|
||||
.content();
|
||||
assertThat(content).isNotEmpty();
|
||||
@@ -106,7 +106,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("Welcome %s to the library".formatted("James Bond"))
|
||||
.tools(FunctionToolCallback.builder("welcomeUser",
|
||||
.toolCallbacks(FunctionToolCallback.builder("welcomeUser",
|
||||
(Consumer<Object>) user -> logger.info("CALLBACK - Welcoming {} to the library", ((User) user).name()))
|
||||
.description("Welcome a specific user to the library")
|
||||
.inputType(User.class)
|
||||
@@ -122,7 +122,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("What books written by %s are available in the library?".formatted("J.R.R. Tolkien"))
|
||||
.tools(Tools.BOOKS_BY_AUTHOR)
|
||||
.toolNames(Tools.BOOKS_BY_AUTHOR)
|
||||
.call()
|
||||
.content();
|
||||
assertThat(content).isNotEmpty()
|
||||
@@ -141,7 +141,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("What books written by %s are available in the library?".formatted("J.R.R. Tolkien"))
|
||||
.tools(FunctionToolCallback.builder("availableBooksByAuthor", function)
|
||||
.toolCallbacks(FunctionToolCallback.builder("availableBooksByAuthor", function)
|
||||
.description("Get the list of books written by the given author available in the library")
|
||||
.inputType(Author.class)
|
||||
.build())
|
||||
@@ -159,7 +159,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("What authors wrote the books %s and %s available in the library?".formatted("The Hobbit", "The Lion, the Witch and the Wardrobe"))
|
||||
.tools(Tools.AUTHORS_BY_BOOKS)
|
||||
.toolNames(Tools.AUTHORS_BY_BOOKS)
|
||||
.call()
|
||||
.content();
|
||||
assertThat(content).isNotEmpty().contains("J.R.R. Tolkien").contains("C.S. Lewis");
|
||||
@@ -175,7 +175,7 @@ public class FunctionToolCallbackTests {
|
||||
.build()
|
||||
.prompt()
|
||||
.user("What authors wrote the books %s and %s available in the library?".formatted("The Hobbit", "The Lion, the Witch and the Wardrobe"))
|
||||
.tools(FunctionToolCallback.builder("authorsByAvailableBooks", function)
|
||||
.toolCallbacks(FunctionToolCallback.builder("authorsByAvailableBooks", function)
|
||||
.description("Get the list of authors who wrote the given books available in the library")
|
||||
.inputType(Books.class)
|
||||
.build())
|
||||
|
||||
@@ -112,7 +112,7 @@ public class MethodToolCallbackTests {
|
||||
.prompt()
|
||||
.user("What authors wrote the books %s and %s available in the library?".formatted("The Hobbit",
|
||||
"The Lion, the Witch and the Wardrobe"))
|
||||
.tools(ToolCallbacks.from(this.tools))
|
||||
.toolCallbacks(ToolCallbacks.from(this.tools))
|
||||
.call()
|
||||
.content();
|
||||
assertThat(content).isNotEmpty().contains("J.R.R. Tolkien").contains("C.S. Lewis");
|
||||
|
||||
Reference in New Issue
Block a user