chatclient

This commit is contained in:
Josh Long
2024-05-17 19:40:29 +02:00
parent a2147e8572
commit 981ea68b00
97 changed files with 409 additions and 253 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -59,7 +59,7 @@ public class MockAzureOpenAiTestConfiguration {
}
@Bean
AzureOpenAiChatConnector azureOpenAiChatClient(OpenAIClient microsoftAzureOpenAiClient) {
AzureOpenAiChatConnector azureOpenAiChatClient(OpenAIClient microsoftAzureOpenAiClient) {
return new AzureOpenAiChatConnector(microsoftAzureOpenAiClient);
}

View File

@@ -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));

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");

View File

@@ -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");
}

View File

@@ -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");

View File

@@ -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");

View File

@@ -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();

View File

@@ -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

View File

@@ -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 -> {

View File

@@ -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?");

View File

@@ -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

View File

@@ -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));

View File

@@ -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");

View File

@@ -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");

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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");

View File

@@ -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

View File

@@ -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)))

View File

@@ -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)))

View File

@@ -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)))

View File

@@ -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()),

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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.

View File

@@ -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(

View File

@@ -55,7 +55,7 @@ public class VertexAiPaLm2ChatConnector implements ChatConnector {
}
@Override
public ChatResponse execute(Prompt prompt) {
public ChatResponse call(Prompt prompt) {
GenerateMessageRequest request = createRequest(prompt);

View File

@@ -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");

View File

@@ -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);

View File

@@ -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());

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -30,6 +30,6 @@ public interface ChatConnector {
* return (generation != null) ? generation.getOutput().getContent() : ""; }
*/
ChatResponse execute(Prompt prompt);
ChatResponse call(Prompt prompt);
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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++) {

View File

@@ -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();

View File

@@ -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"))));

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());
}

View File

@@ -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());
}

View File

@@ -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());
}

View File

@@ -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());
}

View File

@@ -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());
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());
}

View File

@@ -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);
});

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");
});
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");
});
}

View File

@@ -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");
});
}

View File

@@ -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");
});
}

View File

@@ -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");
});
}

View File

@@ -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");
});
}

View File

@@ -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");
});
}

View File

@@ -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);
});

View File

@@ -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")

View File

@@ -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")

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");
});
}

View File

@@ -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);
});

View File

@@ -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);

View File

@@ -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);
});

View File

@@ -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);

View File

@@ -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);
});

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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);
}