chatclient
This commit is contained in:
@@ -117,7 +117,7 @@ public class AnthropicChatConnector extends
|
||||
* @param retryTemplate the retry template used to retry the Anthropic API calls.
|
||||
*/
|
||||
public AnthropicChatConnector(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions,
|
||||
RetryTemplate retryTemplate) {
|
||||
RetryTemplate retryTemplate) {
|
||||
this(anthropicApi, defaultOptions, retryTemplate, null);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public class AnthropicChatConnector extends
|
||||
* state of the function calls.
|
||||
*/
|
||||
public AnthropicChatConnector(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions,
|
||||
RetryTemplate retryTemplate, FunctionCallbackContext functionCallbackContext) {
|
||||
RetryTemplate retryTemplate, FunctionCallbackContext functionCallbackContext) {
|
||||
|
||||
super(functionCallbackContext);
|
||||
|
||||
@@ -144,7 +144,7 @@ public class AnthropicChatConnector extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
ChatCompletionRequest request = createRequest(prompt, false);
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class AnthropicChatConnectorIT {
|
||||
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
|
||||
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
ChatResponse response = chatConnector.execute(prompt);
|
||||
ChatResponse response = chatConnector.call(prompt);
|
||||
assertThat(response.getResults()).hasSize(1);
|
||||
assertThat(response.getMetadata().getUsage().getGenerationTokens()).isGreaterThan(0);
|
||||
assertThat(response.getMetadata().getUsage().getPromptTokens()).isGreaterThan(0);
|
||||
@@ -102,7 +102,7 @@ class AnthropicChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.chatConnector.execute(prompt).getResult();
|
||||
Generation generation = this.chatConnector.call(prompt).getResult();
|
||||
|
||||
List<String> list = listOutputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -120,7 +120,7 @@ class AnthropicChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatConnector.execute(prompt).getResult();
|
||||
Generation generation = chatConnector.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = mapOutputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -142,7 +142,7 @@ class AnthropicChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatConnector.execute(prompt).getResult();
|
||||
Generation generation = chatConnector.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = beanOutputConverter.convert(generation.getOutput().getContent());
|
||||
logger.info("" + actorsFilms);
|
||||
@@ -187,14 +187,14 @@ class AnthropicChatConnectorIT {
|
||||
var userMessage = new UserMessage("Explain what do you see on this picture?",
|
||||
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
|
||||
|
||||
var response = chatConnector.execute(new Prompt(List.of(userMessage)));
|
||||
var response = chatConnector.call(new Prompt(List.of(userMessage)));
|
||||
|
||||
logger.info(response.getResult().getOutput().getContent());
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("bananas", "apple", "basket");
|
||||
}
|
||||
|
||||
@Test
|
||||
void functionExecuteTest() {
|
||||
void functionCallTest() {
|
||||
|
||||
UserMessage userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, Tokyo and Paris? Return the result in Celsius.");
|
||||
@@ -209,7 +209,7 @@ class AnthropicChatConnectorIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatConnector.execute(new Prompt(messages, promptOptions));
|
||||
ChatResponse response = chatConnector.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public class AzureOpenAiChatConnector
|
||||
}
|
||||
|
||||
public AzureOpenAiChatConnector(OpenAIClient microsoftOpenAiClient, AzureOpenAiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
super(functionCallbackContext);
|
||||
Assert.notNull(microsoftOpenAiClient, "com.azure.ai.openai.OpenAIClient must not be null");
|
||||
Assert.notNull(options, "AzureOpenAiChatOptions must not be null");
|
||||
@@ -131,7 +131,7 @@ public class AzureOpenAiChatConnector
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
ChatCompletionsOptions options = toAzureChatCompletionsOptions(prompt);
|
||||
options.setStream(false);
|
||||
|
||||
@@ -69,7 +69,7 @@ class AzureOpenAiChatConnectorIT {
|
||||
UserMessage userMessage = new UserMessage("Generate the names of 5 famous pirates.");
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
ChatResponse response = chatClient.execute(prompt);
|
||||
ChatResponse response = chatClient.call(prompt);
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class AzureOpenAiChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatClient.execute(prompt).getResult();
|
||||
Generation generation = chatClient.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -105,7 +105,7 @@ class AzureOpenAiChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatClient.execute(prompt).getResult();
|
||||
Generation generation = chatClient.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -124,7 +124,7 @@ class AzureOpenAiChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatClient.execute(prompt).getResult();
|
||||
Generation generation = chatClient.call(prompt).getResult();
|
||||
|
||||
ActorsFilms actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isNotNull();
|
||||
@@ -145,7 +145,7 @@ class AzureOpenAiChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatClient.execute(prompt).getResult();
|
||||
Generation generation = chatClient.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
System.out.println(actorsFilms);
|
||||
|
||||
@@ -59,7 +59,7 @@ public class MockAzureOpenAiTestConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
AzureOpenAiChatConnector azureOpenAiChatClient(OpenAIClient microsoftAzureOpenAiClient) {
|
||||
AzureOpenAiChatConnector azureOpenAiChatClient(OpenAIClient microsoftAzureOpenAiClient) {
|
||||
return new AzureOpenAiChatConnector(microsoftAzureOpenAiClient);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class AzureOpenAiChatConnectorFunctionCallIT {
|
||||
private AzureOpenAiChatConnector chatClient;
|
||||
|
||||
@Test
|
||||
void functionExecuteTest() {
|
||||
void functionCallTest() {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, in Tokyo, and in Paris?");
|
||||
|
||||
@@ -75,7 +75,7 @@ class AzureOpenAiChatConnectorFunctionCallIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(messages, promptOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -85,7 +85,7 @@ class AzureOpenAiChatConnectorFunctionCallIT {
|
||||
}
|
||||
|
||||
@Test
|
||||
void streamFunctionExecuteTest() {
|
||||
void streamFunctionCallTest() {
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
|
||||
|
||||
List<Message> messages = new ArrayList<>(List.of(userMessage));
|
||||
|
||||
@@ -75,7 +75,7 @@ class AzureOpenAiChatConnectorMetadataTests {
|
||||
|
||||
Prompt prompt = new Prompt("Can I fly like a bird?");
|
||||
|
||||
ChatResponse response = this.aiClient.execute(prompt);
|
||||
ChatResponse response = this.aiClient.call(prompt);
|
||||
|
||||
assertThat(response).isNotNull();
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public class BedrockAnthropicChatConnector implements ChatConnector, StreamingCh
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
AnthropicChatRequest request = createRequest(prompt);
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class BedrockAnthropic3ChatConnector implements ChatConnector, StreamingC
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
AnthropicChatRequest request = createRequest(prompt);
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ public class BedrockCohereChatConnector implements ChatConnector, StreamingChatC
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
CohereChatResponse response = this.chatApi.chatCompletion(this.createRequest(prompt, false));
|
||||
List<Generation> generations = response.generations().stream().map(g -> {
|
||||
return new Generation(g.text());
|
||||
|
||||
@@ -41,7 +41,7 @@ public class BedrockAi21Jurassic2ChatConnector implements ChatConnector {
|
||||
private final BedrockAi21Jurassic2ChatOptions defaultOptions;
|
||||
|
||||
public BedrockAi21Jurassic2ChatConnector(Ai21Jurassic2ChatBedrockApi chatApi,
|
||||
BedrockAi21Jurassic2ChatOptions options) {
|
||||
BedrockAi21Jurassic2ChatOptions options) {
|
||||
Assert.notNull(chatApi, "Ai21Jurassic2ChatBedrockApi must not be null");
|
||||
Assert.notNull(options, "BedrockAi21Jurassic2ChatOptions must not be null");
|
||||
|
||||
@@ -59,7 +59,7 @@ public class BedrockAi21Jurassic2ChatConnector implements ChatConnector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
var request = createRequest(prompt);
|
||||
var response = this.chatApi.chatCompletion(request);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public class BedrockLlamaChatConnector implements ChatConnector, StreamingChatCl
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
var request = createRequest(prompt);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public class BedrockTitanChatConnector implements ChatConnector, StreamingChatCl
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
TitanChatResponse response = this.chatApi.chatCompletion(this.createRequest(prompt));
|
||||
List<Generation> generations = response.results().stream().map(result -> {
|
||||
return new Generation(result.outputText());
|
||||
|
||||
@@ -101,7 +101,7 @@ class BedrockAnthropicChatConnectorIT {
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
@@ -119,7 +119,7 @@ class BedrockAnthropicChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputParser.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -137,7 +137,7 @@ class BedrockAnthropicChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -161,7 +161,7 @@ class BedrockAnthropicChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConvert.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
|
||||
@@ -105,7 +105,7 @@ class BedrockAnthropic3ChatConnectorIT {
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
@@ -123,7 +123,7 @@ class BedrockAnthropic3ChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -142,7 +142,7 @@ class BedrockAnthropic3ChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -166,7 +166,7 @@ class BedrockAnthropic3ChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
@@ -211,7 +211,7 @@ class BedrockAnthropic3ChatConnectorIT {
|
||||
var userMessage = new UserMessage("Explain what do you see o this picture?",
|
||||
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
|
||||
|
||||
var response = client.execute(new Prompt(List.of(userMessage)));
|
||||
var response = client.call(new Prompt(List.of(userMessage)));
|
||||
|
||||
logger.info(response.getResult().getOutput().getContent());
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("bananas", "apple", "basket");
|
||||
|
||||
@@ -98,7 +98,7 @@ class BedrockCohereChatConnectorIT {
|
||||
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
|
||||
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ class BedrockCohereChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -134,7 +134,7 @@ class BedrockCohereChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -157,7 +157,7 @@ class BedrockCohereChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
|
||||
@@ -66,7 +66,7 @@ class BedrockAi21Jurassic2ChatConnectorIT {
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
@@ -83,7 +83,7 @@ class BedrockAi21Jurassic2ChatConnectorIT {
|
||||
UserMessage userMessage = new UserMessage("Can you express happiness using an emoji like 😄 ?");
|
||||
Prompt prompt = new Prompt(List.of(userMessage), options);
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).matches(content -> content.contains("😄"));
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class BedrockAi21Jurassic2ChatConnectorIT {
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage), options);
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).doesNotContain("😄");
|
||||
}
|
||||
@@ -120,7 +120,7 @@ class BedrockAi21Jurassic2ChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -135,7 +135,7 @@ class BedrockAi21Jurassic2ChatConnectorIT {
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("AI");
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ class BedrockLlamaChatConnectorIT {
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
@@ -116,7 +116,7 @@ class BedrockLlamaChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -134,7 +134,7 @@ class BedrockLlamaChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -158,7 +158,7 @@ class BedrockLlamaChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
|
||||
@@ -99,7 +99,7 @@ class BedrockTitanChatConnectorIT {
|
||||
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
|
||||
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class BedrockTitanChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -138,7 +138,7 @@ class BedrockTitanChatConnectorIT {
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -162,7 +162,7 @@ class BedrockTitanChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
|
||||
@@ -86,7 +86,7 @@ public class HuggingfaceChatConnector implements ChatConnector {
|
||||
* @return ChatResponse containing the generated text and other related details.
|
||||
*/
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
GenerateRequest generateRequest = new GenerateRequest();
|
||||
generateRequest.setInputs(prompt.getContents());
|
||||
GenerateParameters generateParameters = new GenerateParameters();
|
||||
|
||||
@@ -46,7 +46,7 @@ public class ClientIT {
|
||||
[/INST]
|
||||
""";
|
||||
Prompt prompt = new Prompt(mistral7bInstruct);
|
||||
ChatResponse chatResponse = huggingfaceChatClient.execute(prompt);
|
||||
ChatResponse chatResponse = huggingfaceChatClient.call(prompt);
|
||||
assertThat(chatResponse.getResult().getOutput().getContent()).isNotEmpty();
|
||||
String expectedResponse = """
|
||||
```json
|
||||
|
||||
@@ -83,7 +83,7 @@ public class MistralAiChatConnector extends
|
||||
}
|
||||
|
||||
public MistralAiChatConnector(MistralAiApi mistralAiApi, MistralAiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
|
||||
FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
|
||||
super(functionCallbackContext);
|
||||
Assert.notNull(mistralAiApi, "MistralAiApi must not be null");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
@@ -94,7 +94,7 @@ public class MistralAiChatConnector extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
var request = createRequest(prompt, false);
|
||||
|
||||
return retryTemplate.execute(ctx -> {
|
||||
|
||||
@@ -25,9 +25,9 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -90,7 +90,7 @@ class MistralAiChatConnectorIT {
|
||||
// NOTE: Mistral expects the system message to be before the user message or will
|
||||
// fail with 400 error.
|
||||
Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
|
||||
ChatResponse response = chatConnector.execute(prompt);
|
||||
ChatResponse response = chatConnector.call(prompt);
|
||||
assertThat(response.getResults()).hasSize(1);
|
||||
assertThat(response.getResults().get(0).getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
@@ -108,7 +108,7 @@ class MistralAiChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.chatConnector.execute(prompt).getResult();
|
||||
Generation generation = this.chatConnector.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -126,7 +126,7 @@ class MistralAiChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatConnector.execute(prompt).getResult();
|
||||
Generation generation = chatConnector.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -148,7 +148,7 @@ class MistralAiChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatConnector.execute(prompt).getResult();
|
||||
Generation generation = chatConnector.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
logger.info("" + actorsFilms);
|
||||
@@ -186,7 +186,7 @@ class MistralAiChatConnectorIT {
|
||||
}
|
||||
|
||||
@Test
|
||||
void functionExecuteTest() {
|
||||
void functionCallTest() {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco?");
|
||||
|
||||
@@ -201,7 +201,7 @@ class MistralAiChatConnectorIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatConnector.execute(new Prompt(messages, promptOptions));
|
||||
ChatResponse response = chatConnector.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -209,7 +209,7 @@ class MistralAiChatConnectorIT {
|
||||
}
|
||||
|
||||
@Test
|
||||
void streamFunctionExecuteTest() {
|
||||
void streamFunctionCallTest() {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in Tokyo, Japan?");
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ public class MistralAiRetryTests {
|
||||
.thenThrow(new TransientAiException("Transient Error 2"))
|
||||
.thenReturn(ResponseEntity.of(Optional.of(expectedChatCompletion)));
|
||||
|
||||
var result = chatClient.execute(new Prompt("text"));
|
||||
var result = chatClient.call(new Prompt("text"));
|
||||
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getResult().getOutput().getContent()).isSameAs("Response");
|
||||
@@ -130,7 +130,7 @@ public class MistralAiRetryTests {
|
||||
public void mistralAiChatNonTransientError() {
|
||||
when(mistralAiApi.chatCompletionEntity(isA(ChatCompletionRequest.class)))
|
||||
.thenThrow(new RuntimeException("Non Transient Error"));
|
||||
assertThrows(RuntimeException.class, () -> chatClient.execute(new Prompt("text")));
|
||||
assertThrows(RuntimeException.class, () -> chatClient.call(new Prompt("text")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -18,10 +18,10 @@ package org.springframework.ai.ollama;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import org.springframework.ai.ollama.metadata.OllamaChatResponseMetadata;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -94,7 +94,7 @@ public class OllamaChatConnector implements ChatConnector, StreamingChatClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
OllamaApi.ChatResponse response = this.chatApi.chat(ollamaChatRequest(prompt, false));
|
||||
|
||||
|
||||
@@ -95,13 +95,13 @@ class OllamaChatConnectorIT {
|
||||
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage), portableOptions);
|
||||
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
|
||||
// ollama specific options
|
||||
var ollamaOptions = new OllamaOptions().withLowVRAM(true);
|
||||
|
||||
response = client.execute(new Prompt(List.of(userMessage, systemMessage), ollamaOptions));
|
||||
response = client.call(new Prompt(List.of(userMessage, systemMessage), ollamaOptions));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
|
||||
}
|
||||
@@ -109,7 +109,7 @@ class OllamaChatConnectorIT {
|
||||
@Test
|
||||
void usageTest() {
|
||||
Prompt prompt = new Prompt("Tell me a joke");
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
Usage usage = response.getMetadata().getUsage();
|
||||
|
||||
assertThat(usage).isNotNull();
|
||||
@@ -131,7 +131,7 @@ class OllamaChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -151,7 +151,7 @@ class OllamaChatConnectorIT {
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -173,7 +173,7 @@ class OllamaChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
|
||||
@@ -75,7 +75,7 @@ class OllamaChatConnectorMultimodalIT {
|
||||
var userMessage = new UserMessage("Explain what do you see on this picture?",
|
||||
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
|
||||
|
||||
var response = client.execute(new Prompt(List.of(userMessage)));
|
||||
var response = client.call(new Prompt(List.of(userMessage)));
|
||||
|
||||
logger.info(response.getResult().getOutput().getContent());
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("bananas", "apple", "basket");
|
||||
|
||||
@@ -123,7 +123,7 @@ public class OpenAiChatConnector extends
|
||||
* @param retryTemplate The retry template.
|
||||
*/
|
||||
public OpenAiChatConnector(OpenAiApi openAiApi, OpenAiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
|
||||
FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
|
||||
super(functionCallbackContext);
|
||||
Assert.notNull(openAiApi, "OpenAiApi must not be null");
|
||||
Assert.notNull(options, "Options must not be null");
|
||||
@@ -134,7 +134,7 @@ public class OpenAiChatConnector extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
ChatCompletionRequest request = createRequest(prompt, false);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
class ChatClientTest {
|
||||
class ChatConnectorTest {
|
||||
|
||||
@Configuration
|
||||
static class ChatClientTestConfiguration {
|
||||
@@ -28,7 +28,7 @@ class ChatClientTest {
|
||||
|
||||
private final ChatClient singularity;
|
||||
|
||||
ChatClientTest(@Autowired ChatClient singularity) {
|
||||
ChatConnectorTest(@Autowired ChatClient singularity) {
|
||||
this.singularity = singularity;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class AcmeIT extends AbstractIT {
|
||||
logger.info("Asking AI generative to reply to question.");
|
||||
Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
|
||||
logger.info("AI responded.");
|
||||
ChatResponse response = chatClient.execute(prompt);
|
||||
ChatResponse response = chatClient.call(prompt);
|
||||
|
||||
evaluateQuestionAndAnswer(userQuery, response, true);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class OpenAiChatClientWithChatResponseMetadataTests {
|
||||
|
||||
Prompt prompt = new Prompt("Reach for the sky.");
|
||||
|
||||
ChatResponse response = this.openAiChatClient.execute(prompt);
|
||||
ChatResponse response = this.openAiChatClient.call(prompt);
|
||||
|
||||
assertThat(response).isNotNull();
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ public class OpenAiChatConnector2IT {
|
||||
.withResponseFormat(new ChatCompletionRequest.ResponseFormat("json_object"))
|
||||
.build());
|
||||
|
||||
ChatResponse response = this.openAiChatClient.execute(prompt);
|
||||
ChatResponse response = this.openAiChatClient.call(prompt);
|
||||
|
||||
assertThat(response).isNotNull();
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
|
||||
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
ChatResponse response = chatConnector.execute(prompt);
|
||||
ChatResponse response = chatConnector.call(prompt);
|
||||
assertThat(response.getResults()).hasSize(1);
|
||||
assertThat(response.getResults().get(0).getOutput().getContent()).contains("Blackbeard");
|
||||
// needs fine tuning... evaluateQuestionAndAnswer(request, response, false);
|
||||
@@ -93,7 +93,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.chatConnector.execute(prompt).getResult();
|
||||
Generation generation = this.chatConnector.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -112,7 +112,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatConnector.execute(prompt).getResult();
|
||||
Generation generation = chatConnector.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -131,7 +131,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatConnector.execute(prompt).getResult();
|
||||
Generation generation = chatConnector.call(prompt).getResult();
|
||||
|
||||
ActorsFilms actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
}
|
||||
@@ -151,7 +151,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = chatConnector.execute(prompt).getResult();
|
||||
Generation generation = chatConnector.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
logger.info("" + actorsFilms);
|
||||
@@ -189,7 +189,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
}
|
||||
|
||||
@Test
|
||||
void functionExecuteTest() {
|
||||
void functionCallTest() {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
|
||||
|
||||
@@ -204,7 +204,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatConnector.execute(new Prompt(messages, promptOptions));
|
||||
ChatResponse response = chatConnector.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -214,7 +214,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
}
|
||||
|
||||
@Test
|
||||
void streamFunctionExecuteTest() {
|
||||
void streamFunctionCallTest() {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
|
||||
|
||||
@@ -256,7 +256,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
|
||||
|
||||
var response = chatConnector
|
||||
.execute(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
|
||||
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
|
||||
|
||||
logger.info(response.getResult().getOutput().getContent());
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("bananas", "apple");
|
||||
@@ -272,7 +272,7 @@ class OpenAiChatConnectorIT extends AbstractIT {
|
||||
new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png"))));
|
||||
|
||||
ChatResponse response = chatConnector
|
||||
.execute(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
|
||||
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
|
||||
|
||||
logger.info(response.getResult().getOutput().getContent());
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("bananas", "apple");
|
||||
|
||||
@@ -23,20 +23,14 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.ai.openai.*;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.ai.document.MetadataMode;
|
||||
import org.springframework.ai.image.ImageMessage;
|
||||
import org.springframework.ai.image.ImagePrompt;
|
||||
import org.springframework.ai.openai.OpenAiAudioTranscriptionClient;
|
||||
import org.springframework.ai.openai.OpenAiAudioTranscriptionOptions;
|
||||
import org.springframework.ai.openai.OpenAiChatConnector;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingClient;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingOptions;
|
||||
import org.springframework.ai.openai.OpenAiImageClient;
|
||||
import org.springframework.ai.openai.OpenAiImageOptions;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletion;
|
||||
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionChunk;
|
||||
@@ -146,7 +140,7 @@ public class OpenAiRetryTests {
|
||||
.thenThrow(new TransientAiException("Transient Error 2"))
|
||||
.thenReturn(ResponseEntity.of(Optional.of(expectedChatCompletion)));
|
||||
|
||||
var result = chatClient.execute(new Prompt("text"));
|
||||
var result = chatClient.call(new Prompt("text"));
|
||||
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getResult().getOutput().getContent()).isSameAs("Response");
|
||||
@@ -158,7 +152,7 @@ public class OpenAiRetryTests {
|
||||
public void openAiChatNonTransientError() {
|
||||
when(openAiApi.chatCompletionEntity(isA(ChatCompletionRequest.class)))
|
||||
.thenThrow(new RuntimeException("Non Transient Error"));
|
||||
assertThrows(RuntimeException.class, () -> chatClient.execute(new Prompt("text")));
|
||||
assertThrows(RuntimeException.class, () -> chatClient.call(new Prompt("text")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -99,7 +99,7 @@ public class ChatMemoryLongTermSystemPromptIT extends BaseMemoryTest {
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiChatConnector chatClient, VectorStore vectorStore,
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
.withRetrievers(List.of(new VectorStoreChatMemoryRetriever(vectorStore, 10)))
|
||||
@@ -111,7 +111,7 @@ public class ChatMemoryLongTermSystemPromptIT extends BaseMemoryTest {
|
||||
|
||||
@Bean
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiChatConnector streamingChatClient,
|
||||
VectorStore vectorStore, TokenCountEstimator tokenCountEstimator) {
|
||||
VectorStore vectorStore, TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return StreamingPromptTransformingChatService.builder(streamingChatClient)
|
||||
.withRetrievers(List.of(new VectorStoreChatMemoryRetriever(vectorStore, 10)))
|
||||
|
||||
@@ -75,7 +75,7 @@ public class ChatMemoryShortTermMessageListIT extends BaseMemoryTest {
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiChatConnector chatClient, ChatMemory chatHistory,
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
.withRetrievers(List.of(new ChatMemoryRetriever(chatHistory)))
|
||||
@@ -87,7 +87,7 @@ public class ChatMemoryShortTermMessageListIT extends BaseMemoryTest {
|
||||
|
||||
@Bean
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiChatConnector streamingChatClient,
|
||||
ChatMemory chatHistory, TokenCountEstimator tokenCountEstimator) {
|
||||
ChatMemory chatHistory, TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return StreamingPromptTransformingChatService.builder(streamingChatClient)
|
||||
.withRetrievers(List.of(new ChatMemoryRetriever(chatHistory)))
|
||||
|
||||
@@ -76,7 +76,7 @@ public class ChatMemoryShortTermSystemPromptIT extends BaseMemoryTest {
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiChatConnector chatClient, ChatMemory chatHistory,
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
.withRetrievers(List.of(new ChatMemoryRetriever(chatHistory)))
|
||||
@@ -88,7 +88,7 @@ public class ChatMemoryShortTermSystemPromptIT extends BaseMemoryTest {
|
||||
|
||||
@Bean
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiChatConnector streamingChatClient,
|
||||
ChatMemory chatHistory, TokenCountEstimator tokenCountEstimator) {
|
||||
ChatMemory chatHistory, TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return StreamingPromptTransformingChatService.builder(streamingChatClient)
|
||||
.withRetrievers(List.of(new ChatMemoryRetriever(chatHistory)))
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.chat.prompt.transformer.ChatServiceContext;
|
||||
import org.springframework.ai.chat.service.ChatService;
|
||||
import org.springframework.ai.chat.service.PromptTransformingChatService;
|
||||
import org.springframework.ai.openai.OpenAiChatConnector;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
@@ -52,7 +53,6 @@ import org.springframework.ai.document.DocumentTransformer;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.evaluation.EvaluationResponse;
|
||||
import org.springframework.ai.evaluation.RelevancyEvaluator;
|
||||
import org.springframework.ai.openai.OpenAiChatConnector;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingClient;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.reader.JsonReader;
|
||||
@@ -187,7 +187,7 @@ public class LongShortTermChatMemoryWithRagIT {
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiChatConnector chatClient, VectorStore vectorStore,
|
||||
TokenCountEstimator tokenCountEstimator, ChatMemory chatHistory) {
|
||||
TokenCountEstimator tokenCountEstimator, ChatMemory chatHistory) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
.withRetrievers(List.of(new VectorStoreRetriever(vectorStore, SearchRequest.defaults()),
|
||||
|
||||
@@ -82,7 +82,7 @@ public class OpenAiPromptTransformingChatServiceIT {
|
||||
|
||||
@Autowired
|
||||
public OpenAiPromptTransformingChatServiceIT(ChatConnector chatConnector, ChatService chatService,
|
||||
VectorStore vectorStore) {
|
||||
VectorStore vectorStore) {
|
||||
this.chatConnector = chatConnector;
|
||||
this.chatService = chatService;
|
||||
this.vectorStore = vectorStore;
|
||||
|
||||
@@ -85,12 +85,12 @@ public abstract class AbstractIT {
|
||||
}
|
||||
Message userMessage = userPromptTemplate.createMessage();
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
String yesOrNo = chatConnector.execute(prompt).getResult().getOutput().getContent();
|
||||
String yesOrNo = chatConnector.call(prompt).getResult().getOutput().getContent();
|
||||
logger.info("Is Answer related to question: " + yesOrNo);
|
||||
if (yesOrNo.equalsIgnoreCase("no")) {
|
||||
SystemMessage notRelatedSystemMessage = new SystemMessage(qaEvaluatorNotRelatedResource);
|
||||
prompt = new Prompt(List.of(userMessage, notRelatedSystemMessage));
|
||||
String reasonForFailure = chatConnector.execute(prompt).getResult().getOutput().getContent();
|
||||
String reasonForFailure = chatConnector.call(prompt).getResult().getOutput().getContent();
|
||||
fail(reasonForFailure);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -130,7 +130,7 @@ public class VertexAiGeminiChatConnector
|
||||
}
|
||||
|
||||
public VertexAiGeminiChatConnector(VertexAI vertexAI, VertexAiGeminiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
|
||||
super(functionCallbackContext);
|
||||
|
||||
@@ -145,7 +145,7 @@ public class VertexAiGeminiChatConnector
|
||||
|
||||
// https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/gemini
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
var geminiRequest = createGeminiRequest(prompt);
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class VertexAiGeminiChatConnectorIT {
|
||||
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
|
||||
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class VertexAiGeminiChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputParser.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -106,7 +106,7 @@ class VertexAiGeminiChatConnectorIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -129,7 +129,7 @@ class VertexAiGeminiChatConnectorIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConvert.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
@@ -191,7 +191,7 @@ class VertexAiGeminiChatConnectorIT {
|
||||
var userMessage = new UserMessage("Explain what do you see o this picture?",
|
||||
List.of(new Media(MimeTypeUtils.IMAGE_PNG, data)));
|
||||
|
||||
var response = client.execute(new Prompt(List.of(userMessage)));
|
||||
var response = client.call(new Prompt(List.of(userMessage)));
|
||||
|
||||
// Response should contain something like:
|
||||
// I see a bunch of bananas in a golden basket. The bananas are ripe and yellow.
|
||||
|
||||
@@ -68,7 +68,7 @@ public class VertexAiGeminiChatConnectorFunctionCallingIT {
|
||||
|
||||
@Test
|
||||
// @Disabled("Google Vertex AI degraded support for parallel function calls")
|
||||
public void functionExecuteExplicitOpenApiSchema() {
|
||||
public void functionCallExplicitOpenApiSchema() {
|
||||
|
||||
UserMessage userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, in Paris and in Tokyo, Japan?"
|
||||
@@ -106,7 +106,7 @@ public class VertexAiGeminiChatConnectorFunctionCallingIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = vertexGeminiClient.execute(new Prompt(messages, promptOptions));
|
||||
ChatResponse response = vertexGeminiClient.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -118,7 +118,7 @@ public class VertexAiGeminiChatConnectorFunctionCallingIT {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void functionExecuteTestInferredOpenApiSchema() {
|
||||
public void functionCallTestInferredOpenApiSchema() {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in Paris? Use Celsius units.");
|
||||
|
||||
@@ -141,14 +141,14 @@ public class VertexAiGeminiChatConnectorFunctionCallingIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = vertexGeminiClient.execute(new Prompt(messages, promptOptions));
|
||||
ChatResponse response = vertexGeminiClient.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).containsAnyOf("15.0", "15");
|
||||
|
||||
ChatResponse response2 = vertexGeminiClient
|
||||
.execute(new Prompt("What is the payment status for transaction 696?", promptOptions));
|
||||
.call(new Prompt("What is the payment status for transaction 696?", promptOptions));
|
||||
|
||||
logger.info("Response: {}", response2);
|
||||
|
||||
@@ -157,7 +157,7 @@ public class VertexAiGeminiChatConnectorFunctionCallingIT {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void functionExecuteTestInferredOpenApiSchemaStream() {
|
||||
public void functionCallTestInferredOpenApiSchemaStream() {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco in Celsius units?");
|
||||
// UserMessage userMessage = new UserMessage(
|
||||
|
||||
@@ -55,7 +55,7 @@ public class VertexAiPaLm2ChatConnector implements ChatConnector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
GenerateMessageRequest request = createRequest(prompt);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class VertexAiPaLm2ChatGenerationClientIT {
|
||||
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);
|
||||
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Bartholomew");
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ class VertexAiPaLm2ChatGenerationClientIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors.", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.client.execute(prompt).getResult();
|
||||
Generation generation = this.client.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -98,7 +98,7 @@ class VertexAiPaLm2ChatGenerationClientIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "an array of numbers from 1 to 9 under they key name 'numbers'", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
Map<String, Object> result = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(result.get("numbers")).isEqualTo(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));
|
||||
@@ -120,7 +120,7 @@ class VertexAiPaLm2ChatGenerationClientIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = client.execute(prompt).getResult();
|
||||
Generation generation = client.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.springframework.ai.watsonx;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -76,7 +76,7 @@ public class WatsonxAiChatConnector implements ChatConnector, StreamingChatClien
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse execute(Prompt prompt) {
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
|
||||
WatsonxAiRequest request = request(prompt);
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ public class WatsonxAiChatConnectorTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecuteMethod() {
|
||||
public void testCallMethod() {
|
||||
WatsonxAiApi mockChatApi = mock(WatsonxAiApi.class);
|
||||
WatsonxAiChatConnector client = new WatsonxAiChatConnector(mockChatApi);
|
||||
|
||||
@@ -177,7 +177,7 @@ public class WatsonxAiChatConnectorTest {
|
||||
Map.of("warnings", List.of(Map.of("message", "the message", "id", "disclaimer_warning")))));
|
||||
|
||||
ChatResponse expectedResponse = new ChatResponse(List.of(expectedGenerator));
|
||||
ChatResponse response = client.execute(prompt);
|
||||
ChatResponse response = client.call(prompt);
|
||||
|
||||
Assert.assertEquals(expectedResponse.getResults().size(), response.getResults().size());
|
||||
Assert.assertEquals(expectedResponse.getResult().getOutput(), response.getResult().getOutput());
|
||||
|
||||
@@ -2,16 +2,28 @@ package org.springframework.ai.chat;
|
||||
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import org.springframework.ai.chat.messages.Media;
|
||||
import org.springframework.ai.chat.messages.Message;
|
||||
import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.MimeType;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
/**
|
||||
* todo follow WebClient -> DefaultWebClient
|
||||
* todo make sure ChatConnector also supports call(Prompt) and then mark as deprecated
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Christian Tsolov
|
||||
* @author Christian Tzolov
|
||||
* @author Josh Long
|
||||
*/
|
||||
|
||||
public class ChatClient {
|
||||
|
||||
private final ChatConnector connector;
|
||||
@@ -23,7 +35,7 @@ public class ChatClient {
|
||||
private final List<Media> media;
|
||||
|
||||
public ChatClient(ChatConnector connector, String defaultSystemPrompt, String defaultUserPrompt,
|
||||
List<String> defaultFunctions, List<Media> defaultMedia) {
|
||||
List<String> defaultFunctions, List<Media> defaultMedia) {
|
||||
this.connector = connector;
|
||||
this.userPrompt = defaultUserPrompt;
|
||||
this.systemPrompt = defaultSystemPrompt;
|
||||
@@ -36,14 +48,41 @@ public class ChatClient {
|
||||
return new ChatClientRequest(this.userPrompt, this.systemPrompt, this.functions, this.media);
|
||||
}
|
||||
|
||||
public ChatClientRequest userPrompt(String userPrompt, Map<String, String> params) {
|
||||
var ccr = new ChatClientRequest(userPrompt, this.systemPrompt, this.functions, this.media);
|
||||
ccr.userPromptParams(params);
|
||||
return ccr;
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChatClientRequest userPrompt(String userPrompt) {
|
||||
return new ChatClientRequest(userPrompt, this.systemPrompt, this.functions, this.media);
|
||||
public static class UserSpec {
|
||||
|
||||
|
||||
public UserSpec media(List<Media> media) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSpec media(URL url, MimeType mimeType) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSpec media(Resource resource, MimeType type) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSpec media(Media... m) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSpec params(Map<String, Object> p) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSpec param(String k, String v) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ChatClientRequest user(Consumer<UserSpec> consumer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ChatClientRequest {
|
||||
@@ -60,15 +99,15 @@ public class ChatClient {
|
||||
|
||||
private final Map<String, String> systemPromptParams = new HashMap<>();
|
||||
|
||||
List<Media> media() {
|
||||
List<Media> userMedia() {
|
||||
return this.media;
|
||||
}
|
||||
|
||||
String systemPrompt() {
|
||||
String systemText() {
|
||||
return this.systemPrompt;
|
||||
}
|
||||
|
||||
String userPrompt() {
|
||||
String userText() {
|
||||
return this.userPrompt;
|
||||
}
|
||||
|
||||
@@ -83,53 +122,119 @@ public class ChatClient {
|
||||
this.media.addAll(media);
|
||||
}
|
||||
|
||||
public ChatClientRequest userPromptParam(String key, String value) {
|
||||
this.userPromptParams.put(key, value);
|
||||
return this;
|
||||
public ChatClientRequest messages(Message... messages) {
|
||||
return null;
|
||||
}
|
||||
//
|
||||
// public ChatClientRequest userParam(String key, String value) {
|
||||
// this.userPromptParams.put(key, value);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public ChatClientRequest systemParam(String key, String value) {
|
||||
// this.systemPromptParams.put(key, value);
|
||||
// return this;
|
||||
// }
|
||||
|
||||
public ChatClientRequest systemPromptParam(String key, String value) {
|
||||
this.systemPromptParams.put(key, value);
|
||||
public <T extends ChatOptions> ChatClientRequest options(T options) {
|
||||
return this;
|
||||
}
|
||||
//
|
||||
// public ChatClientRequest systemParams(Map<String, String> systemPromptParams) {
|
||||
// this.systemPromptParams.putAll(systemPromptParams);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public ChatClientRequest userParams(Map<String, String> userPromptParams) {
|
||||
// this.userPromptParams.putAll(userPromptParams);
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public ChatClientRequest userText(Resource resource) {
|
||||
// return userText(resource, Charset.defaultCharset());
|
||||
// }
|
||||
|
||||
public ChatClientRequest systemPromptParams(Map<String, String> systemPromptParams) {
|
||||
this.systemPromptParams.putAll(systemPromptParams);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatClientRequest userPromptParams(Map<String, String> userPromptParams) {
|
||||
this.userPromptParams.putAll(userPromptParams);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatClientRequest userPrompt(String userPrompt) {
|
||||
this.userPrompt = userPrompt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatClientRequest systemPrompt(String systemPrompt) {
|
||||
this.systemPrompt = systemPrompt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatClientRequest media(Media... media) {
|
||||
this.media.addAll(Arrays.asList(media));
|
||||
return this;
|
||||
}
|
||||
// public ChatClientRequest userText(Resource resource, Charset charset) {
|
||||
// try {
|
||||
// this.userText(resource.getContentAsString(charset));
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public ChatClientRequest userText(String userPrompt) {
|
||||
// this.userPrompt = userPrompt;
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public ChatClientRequest systemText(Resource systemPrompt) {
|
||||
// return systemText(systemPrompt, Charset.defaultCharset());
|
||||
// }
|
||||
//
|
||||
// public ChatClientRequest systemText(Resource systemPrompt, Charset charset) {
|
||||
// try {
|
||||
// this.systemText(systemPrompt.getContentAsString(charset));
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public ChatClientRequest systemText(String systemPrompt) {
|
||||
// this.systemPrompt = systemPrompt;
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// public ChatClientRequest userMedia(Media... media) {
|
||||
// this.media.addAll(Arrays.asList(media));
|
||||
// return this;
|
||||
// }
|
||||
|
||||
public ChatClientRequest functions(String... functions) {
|
||||
this.functions.addAll(Arrays.asList(functions));
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> T chat(Class<T> clzz) {
|
||||
|
||||
public static class ChatResponseSpec {
|
||||
|
||||
public <T> T single(ParameterizedTypeReference<T> t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public <T> T single(Class<T> clzz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChatResponse chatResponse() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> Flux<T> stream(Class<T> t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> Flux<T> stream(ParameterizedTypeReference<T> t) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
public <T> Collection<T> list(Class<T> clzz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> Collection<T> list(ParameterizedTypeReference<Collection<T>> ptr) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ChatResponseSpec chat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T> T chat(ParameterizedTypeReference<T> clzz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.ai.chat;
|
||||
|
||||
|
||||
import org.springframework.ai.chat.connector.ChatConnector;
|
||||
import org.springframework.ai.chat.messages.Media;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class DefaultChatClient implements ChatClient {
|
||||
|
||||
private final ChatConnector connector;
|
||||
|
||||
private final String userPrompt, systemPrompt;
|
||||
|
||||
private final List<String> functions;
|
||||
|
||||
private final List<Media> media;
|
||||
|
||||
public DefaultChatClient(ChatConnector connector, String defaultSystemPrompt, String defaultUserPrompt,
|
||||
List<String> defaultFunctions, List<Media> defaultMedia) {
|
||||
this.connector = connector;
|
||||
this.userPrompt = defaultUserPrompt;
|
||||
this.systemPrompt = defaultSystemPrompt;
|
||||
this.functions = defaultFunctions;
|
||||
this.media = defaultMedia;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatClientRequest build() {
|
||||
return new ChatClientRequest(this.userPrompt, this.systemPrompt, this.functions, this.media);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponse call(Prompt prompt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatResponseSpec chat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public ChatClientRequest user(Consumer<UserSpec> consumer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ChatClientBuilder builder(ChatConnector connector) {
|
||||
return new ChatClientBuilder(connector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,6 @@ public interface ChatConnector {
|
||||
* return (generation != null) ? generation.getOutput().getContent() : ""; }
|
||||
*/
|
||||
|
||||
ChatResponse execute(Prompt prompt);
|
||||
ChatResponse call(Prompt prompt);
|
||||
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ public class PromptTransformingChatService implements ChatService {
|
||||
private List<ChatServiceListener> chatServiceListeners;
|
||||
|
||||
public PromptTransformingChatService(ChatConnector chatConnector, List<PromptTransformer> retrievers,
|
||||
List<PromptTransformer> documentPostProcessors, List<PromptTransformer> augmentors,
|
||||
List<ChatServiceListener> chatServiceListeners) {
|
||||
List<PromptTransformer> documentPostProcessors, List<PromptTransformer> augmentors,
|
||||
List<ChatServiceListener> chatServiceListeners) {
|
||||
Objects.requireNonNull(chatConnector, "chatConnector must not be null");
|
||||
this.chatConnector = chatConnector;
|
||||
this.retrievers = retrievers;
|
||||
@@ -86,7 +86,7 @@ public class PromptTransformingChatService implements ChatService {
|
||||
}
|
||||
|
||||
// Perform generation
|
||||
ChatResponse chatResponse = this.chatConnector.execute(chatServiceContext.getPrompt());
|
||||
ChatResponse chatResponse = this.chatConnector.call(chatServiceContext.getPrompt());
|
||||
|
||||
// Invoke Listeners onComplete
|
||||
ChatServiceResponse chatServiceResponse = new ChatServiceResponse(chatServiceContext, chatResponse);
|
||||
|
||||
@@ -52,7 +52,7 @@ public class RelevancyEvaluator implements Evaluator {
|
||||
Message message = promptTemplate
|
||||
.createMessage(Map.of("query", query, "response", response, "context", context));
|
||||
|
||||
ChatResponse chatResponse = this.chatConnector.execute(new Prompt(message, this.chatOptions));
|
||||
ChatResponse chatResponse = this.chatConnector.call(new Prompt(message, this.chatOptions));
|
||||
|
||||
var evaluationResponse = chatResponse.getResult().getOutput().getContent();
|
||||
boolean passing = false;
|
||||
|
||||
@@ -64,7 +64,7 @@ public class KeywordMetadataEnricher implements DocumentTransformer {
|
||||
|
||||
var template = new PromptTemplate(String.format(KEYWORDS_TEMPLATE, keywordCount));
|
||||
Prompt prompt = template.create(Map.of(CONTEXT_STR_PLACEHOLDER, document.getContent()));
|
||||
String keywords = this.chatConnector.execute(prompt).getResult().getOutput().getContent();
|
||||
String keywords = this.chatConnector.call(prompt).getResult().getOutput().getContent();
|
||||
document.getMetadata().putAll(Map.of(EXCERPT_KEYWORDS_METADATA_KEY, keywords));
|
||||
}
|
||||
return documents;
|
||||
|
||||
@@ -81,7 +81,7 @@ public class SummaryMetadataEnricher implements DocumentTransformer {
|
||||
}
|
||||
|
||||
public SummaryMetadataEnricher(ChatConnector chatConnector, List<SummaryType> summaryTypes, String summaryTemplate,
|
||||
MetadataMode metadataMode) {
|
||||
MetadataMode metadataMode) {
|
||||
Assert.notNull(chatConnector, "ChatConnector must not be null");
|
||||
Assert.hasText(summaryTemplate, "Summary template must not be empty");
|
||||
|
||||
@@ -101,7 +101,7 @@ public class SummaryMetadataEnricher implements DocumentTransformer {
|
||||
|
||||
Prompt prompt = new PromptTemplate(this.summaryTemplate)
|
||||
.create(Map.of(CONTEXT_STR_PLACEHOLDER, documentContext));
|
||||
documentSummaries.add(this.chatConnector.execute(prompt).getResult().getOutput().getContent());
|
||||
documentSummaries.add(this.chatConnector.call(prompt).getResult().getOutput().getContent());
|
||||
}
|
||||
|
||||
for (int i = 0; i < documentSummaries.size(); i++) {
|
||||
|
||||
@@ -65,7 +65,7 @@ class ChatConnectorTests {
|
||||
// ChatResponse response = spy(new
|
||||
// ChatResponse(Collections.singletonList(generation)));
|
||||
|
||||
doCallRealMethod().when(mockClient).execute(anyString());
|
||||
doCallRealMethod().when(mockClient).call(anyString());
|
||||
|
||||
doAnswer(invocationOnMock -> {
|
||||
|
||||
@@ -76,12 +76,12 @@ class ChatConnectorTests {
|
||||
|
||||
return response;
|
||||
|
||||
}).when(mockClient).execute(any(Prompt.class));
|
||||
}).when(mockClient).call(any(Prompt.class));
|
||||
|
||||
assertThat(mockClient.execute(userMessage)).isEqualTo(responseMessage);
|
||||
assertThat(mockClient.call(userMessage)).isEqualTo(responseMessage);
|
||||
|
||||
verify(mockClient, times(1)).execute(eq(userMessage));
|
||||
verify(mockClient, times(1)).execute(isA(Prompt.class));
|
||||
verify(mockClient, times(1)).call(eq(userMessage));
|
||||
verify(mockClient, times(1)).call(isA(Prompt.class));
|
||||
verify(response, times(1)).getResult();
|
||||
verify(generation, times(1)).getOutput();
|
||||
verify(mockAssistantMessage, times(1)).getContent();
|
||||
|
||||
@@ -48,7 +48,7 @@ import static org.mockito.Mockito.when;
|
||||
public class ChatMemoryTests {
|
||||
|
||||
@Mock
|
||||
ChatConnector chatConnector;
|
||||
ChatConnector chatConnector;
|
||||
|
||||
@Mock
|
||||
StreamingChatClient streamingChatClient;
|
||||
@@ -90,7 +90,7 @@ public class ChatMemoryTests {
|
||||
|
||||
public void chatClientUserMessages(PromptTransformingChatService chatService, ChatMemory chatHistory) {
|
||||
|
||||
when(chatConnector.execute(promptCaptor.capture()))
|
||||
when(chatConnector.call(promptCaptor.capture()))
|
||||
.thenReturn(new ChatResponse(List.of(new Generation("assistant:1"))))
|
||||
.thenReturn(new ChatResponse(List.of(new Generation("assistant:2"))))
|
||||
.thenReturn(new ChatResponse(List.of(new Generation("assistant:3"))));
|
||||
|
||||
@@ -58,8 +58,8 @@ public class AnthropicAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AnthropicChatConnector anthropicChatClient(AnthropicApi anthropicApi, AnthropicChatProperties chatProperties,
|
||||
RetryTemplate retryTemplate, FunctionCallbackContext functionCallbackContext,
|
||||
List<FunctionCallback> toolFunctionCallbacks) {
|
||||
RetryTemplate retryTemplate, FunctionCallbackContext functionCallbackContext,
|
||||
List<FunctionCallback> toolFunctionCallbacks) {
|
||||
|
||||
if (!CollectionUtils.isEmpty(toolFunctionCallbacks)) {
|
||||
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
|
||||
|
||||
@@ -59,8 +59,8 @@ public class AzureOpenAiAutoConfiguration {
|
||||
@ConditionalOnProperty(prefix = AzureOpenAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public AzureOpenAiChatConnector azureOpenAiChatClient(OpenAIClient openAIClient,
|
||||
AzureOpenAiChatProperties chatProperties, List<FunctionCallback> toolFunctionCallbacks,
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
AzureOpenAiChatProperties chatProperties, List<FunctionCallback> toolFunctionCallbacks,
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
|
||||
if (!CollectionUtils.isEmpty(toolFunctionCallbacks)) {
|
||||
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
|
||||
|
||||
@@ -60,7 +60,7 @@ public class BedrockAnthropicChatAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnBean(AnthropicChatBedrockApi.class)
|
||||
public BedrockAnthropicChatConnector anthropicChatClient(AnthropicChatBedrockApi anthropicApi,
|
||||
BedrockAnthropicChatProperties properties) {
|
||||
BedrockAnthropicChatProperties properties) {
|
||||
return new BedrockAnthropicChatConnector(anthropicApi, properties.getOptions());
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class BedrockAnthropic3ChatAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnBean(Anthropic3ChatBedrockApi.class)
|
||||
public BedrockAnthropic3ChatConnector anthropic3ChatClient(Anthropic3ChatBedrockApi anthropicApi,
|
||||
BedrockAnthropic3ChatProperties properties) {
|
||||
BedrockAnthropic3ChatProperties properties) {
|
||||
return new BedrockAnthropic3ChatConnector(anthropicApi, properties.getOptions());
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ public class BedrockCohereChatAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnBean(CohereChatBedrockApi.class)
|
||||
public BedrockCohereChatConnector cohereChatClient(CohereChatBedrockApi cohereChatApi,
|
||||
BedrockCohereChatProperties properties) {
|
||||
BedrockCohereChatProperties properties) {
|
||||
|
||||
return new BedrockCohereChatConnector(cohereChatApi, properties.getOptions());
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class BedrockLlamaChatAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnBean(LlamaChatBedrockApi.class)
|
||||
public BedrockLlamaChatConnector llamaChatClient(LlamaChatBedrockApi llamaApi,
|
||||
BedrockLlamaChatProperties properties) {
|
||||
BedrockLlamaChatProperties properties) {
|
||||
|
||||
return new BedrockLlamaChatConnector(llamaApi, properties.getOptions());
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class BedrockTitanChatAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnBean(TitanChatBedrockApi.class)
|
||||
public BedrockTitanChatConnector titanChatClient(TitanChatBedrockApi titanChatApi,
|
||||
BedrockTitanChatProperties properties) {
|
||||
BedrockTitanChatProperties properties) {
|
||||
|
||||
return new BedrockTitanChatConnector(titanChatApi, properties.getOptions());
|
||||
}
|
||||
|
||||
@@ -70,9 +70,9 @@ public class MistralAiAutoConfiguration {
|
||||
@ConditionalOnProperty(prefix = MistralAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public MistralAiChatConnector mistralAiChatClient(MistralAiCommonProperties commonProperties,
|
||||
MistralAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
|
||||
MistralAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
|
||||
|
||||
var mistralAiApi = mistralAiApi(chatProperties.getApiKey(), commonProperties.getApiKey(),
|
||||
chatProperties.getBaseUrl(), commonProperties.getBaseUrl(), restClientBuilder, responseErrorHandler);
|
||||
|
||||
@@ -55,9 +55,9 @@ public class OpenAiAutoConfiguration {
|
||||
@ConditionalOnProperty(prefix = OpenAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public OpenAiChatConnector openAiChatClient(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
|
||||
OpenAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
|
||||
|
||||
var openAiApi = openAiApi(chatProperties.getBaseUrl(), commonProperties.getBaseUrl(),
|
||||
chatProperties.getApiKey(), commonProperties.getApiKey(), restClientBuilder, responseErrorHandler);
|
||||
|
||||
@@ -75,8 +75,8 @@ public class VertexAiGeminiAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public VertexAiGeminiChatConnector vertexAiGeminiChat(VertexAI vertexAi,
|
||||
VertexAiGeminiChatProperties chatProperties, List<FunctionCallback> toolFunctionCallbacks,
|
||||
ApplicationContext context) {
|
||||
VertexAiGeminiChatProperties chatProperties, List<FunctionCallback> toolFunctionCallbacks,
|
||||
ApplicationContext context) {
|
||||
|
||||
FunctionCallbackContext functionCallbackContext = springAiFunctionManager(context);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class VertexAiPalm2AutoConfiguration {
|
||||
@ConditionalOnProperty(prefix = VertexAiPlam2ChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public VertexAiPaLm2ChatConnector vertexAiChatClient(VertexAiPaLm2Api vertexAiApi,
|
||||
VertexAiPlam2ChatProperties chatProperties) {
|
||||
VertexAiPlam2ChatProperties chatProperties) {
|
||||
return new VertexAiPaLm2ChatConnector(vertexAiApi, chatProperties.getOptions());
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class AnthropicAutoConfigurationIT {
|
||||
void generate() {
|
||||
contextRunner.run(context -> {
|
||||
AnthropicChatConnector chatClient = context.getBean(AnthropicChatConnector.class);
|
||||
String response = chatClient.execute("Hello");
|
||||
String response = chatClient.call("Hello");
|
||||
assertThat(response).isNotEmpty();
|
||||
logger.info("Response: " + response);
|
||||
});
|
||||
|
||||
@@ -66,14 +66,14 @@ class FunctionCallWithFunctionBeanIT {
|
||||
var userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, in Paris, France and in Tokyo, Japan? Return the temperature in Celsius.");
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage),
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage),
|
||||
AnthropicChatOptions.builder().withFunction("weatherFunction").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("30", "10", "15");
|
||||
|
||||
response = chatClient.execute(new Prompt(List.of(userMessage),
|
||||
response = chatClient.call(new Prompt(List.of(userMessage),
|
||||
AnthropicChatOptions.builder().withFunction("weatherFunction3").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -66,7 +66,7 @@ public class FunctionCallWithPromptFunctionIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage), promptOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage), promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiChatConnector;
|
||||
import org.springframework.ai.chat.messages.AssistantMessage;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfiguration;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiChatConnector;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingClient;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
@@ -78,7 +78,7 @@ public class AzureOpenAiAutoConfigurationIT {
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
AzureOpenAiChatConnector chatClient = context.getBean(AzureOpenAiChatConnector.class);
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -62,14 +62,14 @@ class FunctionCallWithFunctionBeanIT {
|
||||
UserMessage userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, Paris and in Tokyo? Use Multi-turn function calling.");
|
||||
|
||||
ChatResponse response = chatConnector.execute(new Prompt(List.of(userMessage),
|
||||
ChatResponse response = chatConnector.call(new Prompt(List.of(userMessage),
|
||||
AzureOpenAiChatOptions.builder().withFunction("weatherFunction").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("30", "10", "15");
|
||||
|
||||
response = chatConnector.execute(new Prompt(List.of(userMessage),
|
||||
response = chatConnector.call(new Prompt(List.of(userMessage),
|
||||
AzureOpenAiChatOptions.builder().withFunction("weatherFunction3").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -61,7 +61,7 @@ public class FunctionCallWithFunctionWrapperIT {
|
||||
UserMessage userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, Paris and in Tokyo?");
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage),
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage),
|
||||
AzureOpenAiChatOptions.builder().withFunction("WeatherInfo").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class FunctionCallWithPromptFunctionIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage), promptOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage), promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public class BedrockAnthropicChatAutoConfigurationIT {
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
BedrockAnthropicChatConnector anthropicChatClient = context.getBean(BedrockAnthropicChatConnector.class);
|
||||
ChatResponse response = anthropicChatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = anthropicChatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class BedrockAnthropic3ChatAutoConfigurationIT {
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
BedrockAnthropic3ChatConnector anthropicChatClient = context.getBean(BedrockAnthropic3ChatConnector.class);
|
||||
ChatResponse response = anthropicChatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = anthropicChatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class BedrockCohereChatAutoConfigurationIT {
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
BedrockCohereChatConnector cohereChatClient = context.getBean(BedrockCohereChatConnector.class);
|
||||
ChatResponse response = cohereChatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = cohereChatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class BedrockAi21Jurassic2ChatAutoConfigurationIT {
|
||||
contextRunner.run(context -> {
|
||||
BedrockAi21Jurassic2ChatConnector ai21Jurassic2ChatClient = context
|
||||
.getBean(BedrockAi21Jurassic2ChatConnector.class);
|
||||
ChatResponse response = ai21Jurassic2ChatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = ai21Jurassic2ChatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class BedrockLlamaChatAutoConfigurationIT {
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
BedrockLlamaChatConnector llamaChatClient = context.getBean(BedrockLlamaChatConnector.class);
|
||||
ChatResponse response = llamaChatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = llamaChatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class BedrockTitanChatAutoConfigurationIT {
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
BedrockTitanChatConnector chatClient = context.getBean(BedrockTitanChatConnector.class);
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class MistralAiAutoConfigurationIT {
|
||||
void generate() {
|
||||
contextRunner.run(context -> {
|
||||
MistralAiChatConnector client = context.getBean(MistralAiChatConnector.class);
|
||||
String response = client.execute("Hello");
|
||||
String response = client.call("Hello");
|
||||
assertThat(response).isNotEmpty();
|
||||
logger.info("Response: " + response);
|
||||
});
|
||||
|
||||
@@ -63,7 +63,7 @@ class PaymentStatusBeanIT {
|
||||
MistralAiChatConnector chatClient = context.getBean(MistralAiChatConnector.class);
|
||||
|
||||
ChatResponse response = chatClient
|
||||
.execute(new Prompt(List.of(new UserMessage("What's the status of my transaction with id T1001?")),
|
||||
.call(new Prompt(List.of(new UserMessage("What's the status of my transaction with id T1001?")),
|
||||
MistralAiChatOptions.builder()
|
||||
.withFunction("retrievePaymentStatus")
|
||||
.withFunction("retrievePaymentDate")
|
||||
|
||||
@@ -70,7 +70,7 @@ class PaymentStatusBeanOpenAiIT {
|
||||
OpenAiChatConnector chatClient = context.getBean(OpenAiChatConnector.class);
|
||||
|
||||
ChatResponse response = chatClient
|
||||
.execute(new Prompt(List.of(new UserMessage("What's the status of my transaction with id T1001?")),
|
||||
.call(new Prompt(List.of(new UserMessage("What's the status of my transaction with id T1001?")),
|
||||
OpenAiChatOptions.builder()
|
||||
.withFunction("retrievePaymentStatus")
|
||||
.withFunction("retrievePaymentDate")
|
||||
|
||||
@@ -86,7 +86,7 @@ public class PaymentStatusPromptIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage), promptOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage), promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public class WeatherServicePromptIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage), promptOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage), promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ public class OllamaChatAutoConfigurationIT {
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
OllamaChatConnector chatClient = context.getBean(OllamaChatConnector.class);
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage, systemMessage)));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class OpenAiAutoConfigurationIT {
|
||||
void generate() {
|
||||
contextRunner.run(context -> {
|
||||
OpenAiChatConnector client = context.getBean(OpenAiChatConnector.class);
|
||||
String response = client.execute("Hello");
|
||||
String response = client.call("Hello");
|
||||
assertThat(response).isNotEmpty();
|
||||
logger.info("Response: " + response);
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@ public class FunctionCallbackInPromptIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage), promptOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage), promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
|
||||
// Test weatherFunction
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage),
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage),
|
||||
OpenAiChatOptions.builder().withFunction("weatherFunction").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
@@ -73,7 +73,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("30", "10", "15");
|
||||
|
||||
// Test weatherFunctionTwo
|
||||
response = chatClient.execute(new Prompt(List.of(userMessage),
|
||||
response = chatClient.call(new Prompt(List.of(userMessage),
|
||||
OpenAiChatOptions.builder().withFunction("weatherFunctionTwo").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
@@ -96,7 +96,7 @@ class FunctionCallbackWithPlainFunctionBeanIT {
|
||||
.withFunction("weatherFunction")
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(userMessage), functionOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage), functionOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
});
|
||||
|
||||
@@ -62,7 +62,7 @@ public class FunctionCallbackWrapperIT {
|
||||
|
||||
UserMessage userMessage = new UserMessage("What's the weather like in San Francisco, Tokyo, and Paris?");
|
||||
|
||||
ChatResponse response = chatClient.execute(
|
||||
ChatResponse response = chatClient.call(
|
||||
new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withFunction("WeatherInfo").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -47,7 +47,7 @@ public class VertexAiGeminiAutoConfigurationIT {
|
||||
void generate() {
|
||||
contextRunner.run(context -> {
|
||||
VertexAiGeminiChatConnector client = context.getBean(VertexAiGeminiChatConnector.class);
|
||||
String response = client.execute("Hello");
|
||||
String response = client.call("Hello");
|
||||
assertThat(response).isNotEmpty();
|
||||
logger.info("Response: " + response);
|
||||
});
|
||||
|
||||
@@ -72,7 +72,7 @@ class FunctionCallWithFunctionBeanIT {
|
||||
// Please let me know how many function calls you've preformed.");
|
||||
"What's the weather like in San Francisco, Paris and in Tokyo?");
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(systemMessage, userMessage),
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(systemMessage, userMessage),
|
||||
VertexAiGeminiChatOptions.builder().withFunction("weatherFunction").build()));
|
||||
// ChatResponse response = chatConnector.call(new
|
||||
// Prompt(List.of(userMessage),
|
||||
@@ -84,7 +84,7 @@ class FunctionCallWithFunctionBeanIT {
|
||||
|
||||
Thread.sleep(10000);
|
||||
|
||||
response = chatClient.execute(new Prompt(List.of(systemMessage, userMessage),
|
||||
response = chatClient.call(new Prompt(List.of(systemMessage, userMessage),
|
||||
VertexAiGeminiChatOptions.builder().withFunction("weatherFunction3").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
@@ -92,7 +92,7 @@ class FunctionCallWithFunctionBeanIT {
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("30", "10", "15");
|
||||
|
||||
response = chatClient
|
||||
.execute(new Prompt(List.of(systemMessage, userMessage), VertexAiGeminiChatOptions.builder().build()));
|
||||
.call(new Prompt(List.of(systemMessage, userMessage), VertexAiGeminiChatOptions.builder().build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ public class FunctionCallWithFunctionWrapperIT {
|
||||
""");
|
||||
var userMessage = new UserMessage("What's the weather like in San Francisco, Paris and in Tokyo?");
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(systemMessage, userMessage),
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(systemMessage, userMessage),
|
||||
VertexAiGeminiChatOptions.builder().withFunction("WeatherInfo").build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class FunctionCallWithPromptFunctionIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = chatClient.execute(new Prompt(List.of(systemMessage, userMessage), promptOptions));
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(systemMessage, userMessage), promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class FunctionCallWithPromptFunctionIT {
|
||||
|
||||
// Verify that no function call is made.
|
||||
response = chatClient
|
||||
.execute(new Prompt(List.of(systemMessage, userMessage), VertexAiGeminiChatOptions.builder().build()));
|
||||
.call(new Prompt(List.of(systemMessage, userMessage), VertexAiGeminiChatOptions.builder().build()));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class VertexAiPaLm2AutoConfigurationIT {
|
||||
contextRunner.run(context -> {
|
||||
VertexAiPaLm2ChatConnector client = context.getBean(VertexAiPaLm2ChatConnector.class);
|
||||
|
||||
String response = client.execute("Hello");
|
||||
String response = client.call("Hello");
|
||||
|
||||
assertThat(response).isNotEmpty();
|
||||
logger.info("Response: " + response);
|
||||
|
||||
@@ -68,12 +68,12 @@ public class BasicEvaluationTest {
|
||||
}
|
||||
Message userMessage = userPromptTemplate.createMessage();
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
String yesOrNo = openAiChatConnector.execute(prompt).getResult().getOutput().getContent();
|
||||
String yesOrNo = openAiChatConnector.call(prompt).getResult().getOutput().getContent();
|
||||
logger.info("Is Answer related to question: " + yesOrNo);
|
||||
if (yesOrNo.equalsIgnoreCase("no")) {
|
||||
SystemMessage notRelatedSystemMessage = new SystemMessage(qaEvaluatorNotRelatedResource);
|
||||
prompt = new Prompt(List.of(userMessage, notRelatedSystemMessage));
|
||||
String reasonForFailure = openAiChatConnector.execute(prompt).getResult().getOutput().getContent();
|
||||
String reasonForFailure = openAiChatConnector.call(prompt).getResult().getOutput().getContent();
|
||||
fail(reasonForFailure);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -88,7 +88,7 @@ public class CricketWorldCupHanaController {
|
||||
|
||||
var userMessage = new UserMessage(message);
|
||||
Prompt prompt = new Prompt(List.of(similarDocsMessage, userMessage));
|
||||
String generation = chatConnector.execute(prompt).getResult().getOutput().getContent();
|
||||
String generation = chatConnector.call(prompt).getResult().getOutput().getContent();
|
||||
logger.info("Generation: {}", generation);
|
||||
return Map.of("generation", generation);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user