Fix ChatClient structured output flow. Add OpenAiChatClientIT. Rename Call to Caller
This commit is contained in:
@@ -26,7 +26,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.anthropic.api.AnthropicApi;
|
||||
@@ -56,16 +56,16 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* The {@link ModelCall} implementation for the Anthropic service.
|
||||
* The {@link ChatCaller} implementation for the Anthropic service.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class AnthropicModelCall extends
|
||||
public class AnthropicModelCaller extends
|
||||
AbstractFunctionCallSupport<AnthropicApi.RequestMessage, AnthropicApi.ChatCompletionRequest, ResponseEntity<AnthropicApi.ChatCompletion>>
|
||||
implements ModelCall, StreamingChatClient {
|
||||
implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AnthropicModelCall.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(AnthropicModelCaller.class);
|
||||
|
||||
public static final String DEFAULT_MODEL_NAME = AnthropicApi.ChatModel.CLAUDE_3_OPUS.getValue();
|
||||
|
||||
@@ -89,10 +89,10 @@ public class AnthropicModelCall extends
|
||||
public final RetryTemplate retryTemplate;
|
||||
|
||||
/**
|
||||
* Construct a new {@link AnthropicModelCall} instance.
|
||||
* Construct a new {@link AnthropicModelCaller} instance.
|
||||
* @param anthropicApi the lower-level API for the Anthropic service.
|
||||
*/
|
||||
public AnthropicModelCall(AnthropicApi anthropicApi) {
|
||||
public AnthropicModelCaller(AnthropicApi anthropicApi) {
|
||||
this(anthropicApi,
|
||||
AnthropicChatOptions.builder()
|
||||
.withModel(DEFAULT_MODEL_NAME)
|
||||
@@ -102,34 +102,34 @@ public class AnthropicModelCall extends
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link AnthropicModelCall} instance.
|
||||
* Construct a new {@link AnthropicModelCaller} instance.
|
||||
* @param anthropicApi the lower-level API for the Anthropic service.
|
||||
* @param defaultOptions the default options used for the chat completion requests.
|
||||
*/
|
||||
public AnthropicModelCall(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions) {
|
||||
public AnthropicModelCaller(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions) {
|
||||
this(anthropicApi, defaultOptions, RetryUtils.DEFAULT_RETRY_TEMPLATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link AnthropicModelCall} instance.
|
||||
* Construct a new {@link AnthropicModelCaller} instance.
|
||||
* @param anthropicApi the lower-level API for the Anthropic service.
|
||||
* @param defaultOptions the default options used for the chat completion requests.
|
||||
* @param retryTemplate the retry template used to retry the Anthropic API calls.
|
||||
*/
|
||||
public AnthropicModelCall(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions,
|
||||
public AnthropicModelCaller(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions,
|
||||
RetryTemplate retryTemplate) {
|
||||
this(anthropicApi, defaultOptions, retryTemplate, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link AnthropicModelCall} instance.
|
||||
* Construct a new {@link AnthropicModelCaller} instance.
|
||||
* @param anthropicApi the lower-level API for the Anthropic service.
|
||||
* @param defaultOptions the default options used for the chat completion requests.
|
||||
* @param retryTemplate the retry template used to retry the Anthropic API calls.
|
||||
* @param functionCallbackContext the function callback context used to store the
|
||||
* state of the function calls.
|
||||
*/
|
||||
public AnthropicModelCall(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions,
|
||||
public AnthropicModelCaller(AnthropicApi anthropicApi, AnthropicChatOptions defaultOptions,
|
||||
RetryTemplate retryTemplate, FunctionCallbackContext functionCallbackContext) {
|
||||
|
||||
super(functionCallbackContext);
|
||||
@@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.anthropic.api.AnthropicApi;
|
||||
import org.springframework.ai.anthropic.api.tool.MockWeatherService;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -56,12 +56,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = AnthropicTestConfiguration.class, properties = "spring.ai.retry.on-http-codes=429")
|
||||
@EnabledIfEnvironmentVariable(named = "ANTHROPIC_API_KEY", matches = ".+")
|
||||
class AnthropicModelCallIT {
|
||||
class AnthropicModelCallerIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AnthropicModelCallIT.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(AnthropicModelCallerIT.class);
|
||||
|
||||
@Autowired
|
||||
protected ModelCall modelCall;
|
||||
protected ChatCaller modelCall;
|
||||
|
||||
@Autowired
|
||||
protected StreamingChatClient streamingChatClient;
|
||||
@@ -38,8 +38,8 @@ public class AnthropicTestConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AnthropicModelCall openAiChatClient(AnthropicApi api) {
|
||||
AnthropicModelCall anthropicChatClient = new AnthropicModelCall(api);
|
||||
public AnthropicModelCaller openAiChatClient(AnthropicApi api) {
|
||||
AnthropicModelCaller anthropicChatClient = new AnthropicModelCaller(api);
|
||||
return anthropicChatClient;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class ChatCompletionRequestTests {
|
||||
@Test
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new AnthropicModelCall(new AnthropicApi("TEST"),
|
||||
var client = new AnthropicModelCaller(new AnthropicApi("TEST"),
|
||||
AnthropicChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6f).build());
|
||||
|
||||
var request = client.createRequest(new Prompt("Test message content"), false);
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.azure.openai.metadata.AzureOpenAiChatResponseMetadata;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -63,7 +63,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* {@link ModelCall} implementation for {@literal Microsoft Azure AI} backed by
|
||||
* {@link ChatCaller} implementation for {@literal Microsoft Azure AI} backed by
|
||||
* {@link OpenAIClient}.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
@@ -71,12 +71,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* @author John Blum
|
||||
* @author Christian Tzolov
|
||||
* @author Grogdunn
|
||||
* @see ModelCall
|
||||
* @see ChatCaller
|
||||
* @see com.azure.ai.openai.OpenAIClient
|
||||
*/
|
||||
public class AzureOpenAiModelCall
|
||||
public class AzureOpenAiModelCaller
|
||||
extends AbstractFunctionCallSupport<ChatRequestMessage, ChatCompletionsOptions, ChatCompletions>
|
||||
implements ModelCall, StreamingChatClient {
|
||||
implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private static final String DEFAULT_DEPLOYMENT_NAME = "gpt-35-turbo";
|
||||
|
||||
@@ -94,7 +94,7 @@ public class AzureOpenAiModelCall
|
||||
*/
|
||||
private final OpenAIClient openAIClient;
|
||||
|
||||
public AzureOpenAiModelCall(OpenAIClient microsoftOpenAiClient) {
|
||||
public AzureOpenAiModelCaller(OpenAIClient microsoftOpenAiClient) {
|
||||
this(microsoftOpenAiClient,
|
||||
AzureOpenAiChatOptions.builder()
|
||||
.withDeploymentName(DEFAULT_DEPLOYMENT_NAME)
|
||||
@@ -102,11 +102,11 @@ public class AzureOpenAiModelCall
|
||||
.build());
|
||||
}
|
||||
|
||||
public AzureOpenAiModelCall(OpenAIClient microsoftOpenAiClient, AzureOpenAiChatOptions options) {
|
||||
public AzureOpenAiModelCaller(OpenAIClient microsoftOpenAiClient, AzureOpenAiChatOptions options) {
|
||||
this(microsoftOpenAiClient, options, null);
|
||||
}
|
||||
|
||||
public AzureOpenAiModelCall(OpenAIClient microsoftOpenAiClient, AzureOpenAiChatOptions options,
|
||||
public AzureOpenAiModelCaller(OpenAIClient microsoftOpenAiClient, AzureOpenAiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
super(functionCallbackContext);
|
||||
Assert.notNull(microsoftOpenAiClient, "com.azure.ai.openai.OpenAIClient must not be null");
|
||||
@@ -120,7 +120,7 @@ public class AzureOpenAiModelCall
|
||||
* {@link #AzureOpenAiModelCall(OpenAIClient, AzureOpenAiChatOptions)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "0.8.0")
|
||||
public AzureOpenAiModelCall withDefaultOptions(AzureOpenAiChatOptions defaultOptions) {
|
||||
public AzureOpenAiModelCaller withDefaultOptions(AzureOpenAiChatOptions defaultOptions) {
|
||||
Assert.notNull(defaultOptions, "DefaultOptions must not be null");
|
||||
this.defaultOptions = defaultOptions;
|
||||
return this;
|
||||
@@ -53,7 +53,7 @@ public class AzureChatCompletionsOptionsTests {
|
||||
.withUser("user")
|
||||
.build();
|
||||
|
||||
var client = new AzureOpenAiModelCall(mockClient, defaultOptions);
|
||||
var client = new AzureOpenAiModelCaller(mockClient, defaultOptions);
|
||||
|
||||
var requestOptions = client.toAzureChatCompletionsOptions(new Prompt("Test message content"));
|
||||
|
||||
|
||||
@@ -46,13 +46,13 @@ import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = AzureOpenAiModelCallIT.TestConfiguration.class)
|
||||
@SpringBootTest(classes = AzureOpenAiModelCallIerT.TestConfiguration.class)
|
||||
@EnabledIfEnvironmentVariable(named = "AZURE_OPENAI_API_KEY", matches = ".+")
|
||||
@EnabledIfEnvironmentVariable(named = "AZURE_OPENAI_ENDPOINT", matches = ".+")
|
||||
class AzureOpenAiModelCallIT {
|
||||
class AzureOpenAiModelCallIerT {
|
||||
|
||||
@Autowired
|
||||
private AzureOpenAiModelCall chatClient;
|
||||
private AzureOpenAiModelCaller chatClient;
|
||||
|
||||
record ActorsFilms(String actor, List<String> movies) {
|
||||
}
|
||||
@@ -194,8 +194,8 @@ class AzureOpenAiModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AzureOpenAiModelCall azureOpenAiChatClient(OpenAIClient openAIClient) {
|
||||
return new AzureOpenAiModelCall(openAIClient,
|
||||
public AzureOpenAiModelCaller azureOpenAiChatClient(OpenAIClient openAIClient) {
|
||||
return new AzureOpenAiModelCaller(openAIClient,
|
||||
AzureOpenAiChatOptions.builder().withDeploymentName("gpt-35-turbo").withMaxTokens(200).build());
|
||||
|
||||
}
|
||||
@@ -59,8 +59,8 @@ public class MockAzureOpenAiTestConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
AzureOpenAiModelCall azureOpenAiChatClient(OpenAIClient microsoftAzureOpenAiClient) {
|
||||
return new AzureOpenAiModelCall(microsoftAzureOpenAiClient);
|
||||
AzureOpenAiModelCaller azureOpenAiChatClient(OpenAIClient microsoftAzureOpenAiClient) {
|
||||
return new AzureOpenAiModelCaller(microsoftAzureOpenAiClient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCall;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCaller;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
@@ -57,7 +57,7 @@ class AzureOpenAiModelCallFunctionCallIT {
|
||||
private String selectedModel;
|
||||
|
||||
@Autowired
|
||||
private AzureOpenAiModelCall chatClient;
|
||||
private AzureOpenAiModelCaller chatClient;
|
||||
|
||||
@Test
|
||||
void functionCallTest() {
|
||||
@@ -129,8 +129,8 @@ class AzureOpenAiModelCallFunctionCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AzureOpenAiModelCall azureOpenAiChatClient(OpenAIClient openAIClient, String selectedModel) {
|
||||
return new AzureOpenAiModelCall(openAIClient,
|
||||
public AzureOpenAiModelCaller azureOpenAiChatClient(OpenAIClient openAIClient, String selectedModel) {
|
||||
return new AzureOpenAiModelCaller(openAIClient,
|
||||
AzureOpenAiChatOptions.builder().withDeploymentName(selectedModel).withMaxTokens(500).build());
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import com.azure.ai.openai.models.ContentFilterResultsForChoice;
|
||||
import com.azure.ai.openai.models.ContentFilterSeverity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCall;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCaller;
|
||||
import org.springframework.ai.azure.openai.MockAzureOpenAiTestConfiguration;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
@@ -55,7 +55,7 @@ import org.springframework.web.context.request.WebRequest;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Unit Tests for {@link AzureOpenAiModelCall} asserting AI metadata.
|
||||
* Unit Tests for {@link AzureOpenAiModelCaller} asserting AI metadata.
|
||||
*
|
||||
* @author John Blum
|
||||
* @author Christian Tzolov
|
||||
@@ -68,7 +68,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class AzureOpenAiModelCallMetadataTests {
|
||||
|
||||
@Autowired
|
||||
private AzureOpenAiModelCall aiClient;
|
||||
private AzureOpenAiModelCaller aiClient;
|
||||
|
||||
@Test
|
||||
void azureOpenAiMetadataCapturedDuringGeneration() {
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.ai.bedrock.anthropic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
|
||||
@@ -33,19 +33,19 @@ import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.ai.model.ModelOptionsUtils;
|
||||
|
||||
/**
|
||||
* Java {@link ModelCall} and {@link StreamingChatClient} for the Bedrock Anthropic chat
|
||||
* Java {@link ChatCaller} and {@link StreamingChatClient} for the Bedrock Anthropic chat
|
||||
* generative.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
public class BedrockAnthropicModelCall implements ModelCall, StreamingChatClient {
|
||||
public class BedrockAnthropicModelCaller implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private final AnthropicChatBedrockApi anthropicChatApi;
|
||||
|
||||
private final AnthropicChatOptions defaultOptions;
|
||||
|
||||
public BedrockAnthropicModelCall(AnthropicChatBedrockApi chatApi) {
|
||||
public BedrockAnthropicModelCaller(AnthropicChatBedrockApi chatApi) {
|
||||
this(chatApi,
|
||||
AnthropicChatOptions.builder()
|
||||
.withTemperature(0.8f)
|
||||
@@ -55,7 +55,7 @@ public class BedrockAnthropicModelCall implements ModelCall, StreamingChatClient
|
||||
.build());
|
||||
}
|
||||
|
||||
public BedrockAnthropicModelCall(AnthropicChatBedrockApi chatApi, AnthropicChatOptions options) {
|
||||
public BedrockAnthropicModelCaller(AnthropicChatBedrockApi chatApi, AnthropicChatOptions options) {
|
||||
this.anthropicChatApi = chatApi;
|
||||
this.defaultOptions = options;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.springframework.ai.bedrock.anthropic3.api.Anthropic3ChatBedrockApi.An
|
||||
import org.springframework.ai.bedrock.anthropic3.api.Anthropic3ChatBedrockApi.MediaContent;
|
||||
import org.springframework.ai.bedrock.anthropic3.api.Anthropic3ChatBedrockApi.ChatCompletionMessage;
|
||||
import org.springframework.ai.bedrock.anthropic3.api.Anthropic3ChatBedrockApi.ChatCompletionMessage.Role;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -43,20 +43,20 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Java {@link ModelCall} and {@link StreamingChatClient} for the Bedrock Anthropic chat
|
||||
* Java {@link ChatCaller} and {@link StreamingChatClient} for the Bedrock Anthropic chat
|
||||
* generative.
|
||||
*
|
||||
* @author Ben Middleton
|
||||
* @author Christian Tzolov
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class BedrockAnthropic3ModelCall implements ModelCall, StreamingChatClient {
|
||||
public class BedrockAnthropic3ModelCaller implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private final Anthropic3ChatBedrockApi anthropicChatApi;
|
||||
|
||||
private final Anthropic3ChatOptions defaultOptions;
|
||||
|
||||
public BedrockAnthropic3ModelCall(Anthropic3ChatBedrockApi chatApi) {
|
||||
public BedrockAnthropic3ModelCaller(Anthropic3ChatBedrockApi chatApi) {
|
||||
this(chatApi,
|
||||
Anthropic3ChatOptions.builder()
|
||||
.withTemperature(0.8f)
|
||||
@@ -66,7 +66,7 @@ public class BedrockAnthropic3ModelCall implements ModelCall, StreamingChatClien
|
||||
.build());
|
||||
}
|
||||
|
||||
public BedrockAnthropic3ModelCall(Anthropic3ChatBedrockApi chatApi, Anthropic3ChatOptions options) {
|
||||
public BedrockAnthropic3ModelCaller(Anthropic3ChatBedrockApi chatApi, Anthropic3ChatOptions options) {
|
||||
this.anthropicChatApi = chatApi;
|
||||
this.defaultOptions = options;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import org.springframework.ai.bedrock.MessageToPromptConverter;
|
||||
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi;
|
||||
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi.CohereChatRequest;
|
||||
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi.CohereChatResponse;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
@@ -39,17 +39,17 @@ import org.springframework.util.Assert;
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
public class BedrockCohereModelCall implements ModelCall, StreamingChatClient {
|
||||
public class BedrockCohereModelCaller implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private final CohereChatBedrockApi chatApi;
|
||||
|
||||
private final BedrockCohereChatOptions defaultOptions;
|
||||
|
||||
public BedrockCohereModelCall(CohereChatBedrockApi chatApi) {
|
||||
public BedrockCohereModelCaller(CohereChatBedrockApi chatApi) {
|
||||
this(chatApi, BedrockCohereChatOptions.builder().build());
|
||||
}
|
||||
|
||||
public BedrockCohereModelCall(CohereChatBedrockApi chatApi, BedrockCohereChatOptions options) {
|
||||
public BedrockCohereModelCaller(CohereChatBedrockApi chatApi, BedrockCohereChatOptions options) {
|
||||
Assert.notNull(chatApi, "CohereChatBedrockApi must not be null");
|
||||
Assert.notNull(options, "BedrockCohereChatOptions must not be null");
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.springframework.ai.bedrock.jurassic2;
|
||||
import org.springframework.ai.bedrock.MessageToPromptConverter;
|
||||
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
|
||||
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi.Ai21Jurassic2ChatRequest;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
|
||||
@@ -29,18 +29,19 @@ import org.springframework.ai.model.ModelOptionsUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Java {@link ModelCall} for the Bedrock Jurassic2 chat generative model.
|
||||
* Java {@link ChatCaller} for the Bedrock Jurassic2 chat generative model.
|
||||
*
|
||||
* @author Ahmed Yousri
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class BedrockAi21Jurassic2ModelCall implements ModelCall {
|
||||
public class BedrockAi21Jurassic2ModelCaller implements ChatCaller {
|
||||
|
||||
private final Ai21Jurassic2ChatBedrockApi chatApi;
|
||||
|
||||
private final BedrockAi21Jurassic2ChatOptions defaultOptions;
|
||||
|
||||
public BedrockAi21Jurassic2ModelCall(Ai21Jurassic2ChatBedrockApi chatApi, BedrockAi21Jurassic2ChatOptions options) {
|
||||
public BedrockAi21Jurassic2ModelCaller(Ai21Jurassic2ChatBedrockApi chatApi,
|
||||
BedrockAi21Jurassic2ChatOptions options) {
|
||||
Assert.notNull(chatApi, "Ai21Jurassic2ChatBedrockApi must not be null");
|
||||
Assert.notNull(options, "BedrockAi21Jurassic2ChatOptions must not be null");
|
||||
|
||||
@@ -48,7 +49,7 @@ public class BedrockAi21Jurassic2ModelCall implements ModelCall {
|
||||
this.defaultOptions = options;
|
||||
}
|
||||
|
||||
public BedrockAi21Jurassic2ModelCall(Ai21Jurassic2ChatBedrockApi chatApi) {
|
||||
public BedrockAi21Jurassic2ModelCaller(Ai21Jurassic2ChatBedrockApi chatApi) {
|
||||
this(chatApi,
|
||||
BedrockAi21Jurassic2ChatOptions.builder()
|
||||
.withTemperature(0.8f)
|
||||
@@ -113,8 +114,8 @@ public class BedrockAi21Jurassic2ModelCall implements ModelCall {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BedrockAi21Jurassic2ModelCall build() {
|
||||
return new BedrockAi21Jurassic2ModelCall(chatApi,
|
||||
public BedrockAi21Jurassic2ModelCaller build() {
|
||||
return new BedrockAi21Jurassic2ModelCaller(chatApi,
|
||||
options != null ? options : BedrockAi21Jurassic2ChatOptions.builder().build());
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.ai.bedrock.MessageToPromptConverter;
|
||||
import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi;
|
||||
import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatRequest;
|
||||
import org.springframework.ai.bedrock.llama.api.LlamaChatBedrockApi.LlamaChatResponse;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
@@ -35,25 +35,25 @@ import org.springframework.ai.model.ModelOptionsUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Java {@link ModelCall} and {@link StreamingChatClient} for the Bedrock Llama chat
|
||||
* Java {@link ChatCaller} and {@link StreamingChatClient} for the Bedrock Llama chat
|
||||
* generative.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @author Wei Jiang
|
||||
* @since 0.8.0
|
||||
*/
|
||||
public class BedrockLlamaModelCall implements ModelCall, StreamingChatClient {
|
||||
public class BedrockLlamaModelCaller implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private final LlamaChatBedrockApi chatApi;
|
||||
|
||||
private final BedrockLlamaChatOptions defaultOptions;
|
||||
|
||||
public BedrockLlamaModelCall(LlamaChatBedrockApi chatApi) {
|
||||
public BedrockLlamaModelCaller(LlamaChatBedrockApi chatApi) {
|
||||
this(chatApi,
|
||||
BedrockLlamaChatOptions.builder().withTemperature(0.8f).withTopP(0.9f).withMaxGenLen(100).build());
|
||||
}
|
||||
|
||||
public BedrockLlamaModelCall(LlamaChatBedrockApi chatApi, BedrockLlamaChatOptions options) {
|
||||
public BedrockLlamaModelCaller(LlamaChatBedrockApi chatApi, BedrockLlamaChatOptions options) {
|
||||
Assert.notNull(chatApi, "LlamaChatBedrockApi must not be null");
|
||||
Assert.notNull(options, "BedrockLlamaChatOptions must not be null");
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi;
|
||||
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatRequest;
|
||||
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatResponse;
|
||||
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatResponseChunk;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
@@ -39,17 +39,17 @@ import org.springframework.util.Assert;
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
public class BedrockTitanModelCall implements ModelCall, StreamingChatClient {
|
||||
public class BedrockTitanModelCaller implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private final TitanChatBedrockApi chatApi;
|
||||
|
||||
private final BedrockTitanChatOptions defaultOptions;
|
||||
|
||||
public BedrockTitanModelCall(TitanChatBedrockApi chatApi) {
|
||||
public BedrockTitanModelCaller(TitanChatBedrockApi chatApi) {
|
||||
this(chatApi, BedrockTitanChatOptions.builder().withTemperature(0.8f).build());
|
||||
}
|
||||
|
||||
public BedrockTitanModelCall(TitanChatBedrockApi chatApi, BedrockTitanChatOptions defaultOptions) {
|
||||
public BedrockTitanModelCaller(TitanChatBedrockApi chatApi, BedrockTitanChatOptions defaultOptions) {
|
||||
Assert.notNull(chatApi, "ChatApi must not be null");
|
||||
Assert.notNull(defaultOptions, "DefaultOptions must not be null");
|
||||
this.chatApi = chatApi;
|
||||
@@ -38,7 +38,7 @@ public class BedrockAnthropicCreateRequestTests {
|
||||
@Test
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new BedrockAnthropicModelCall(anthropicChatApi,
|
||||
var client = new BedrockAnthropicModelCaller(anthropicChatApi,
|
||||
AnthropicChatOptions.builder()
|
||||
.withTemperature(66.6f)
|
||||
.withTopK(66)
|
||||
|
||||
@@ -55,12 +55,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
|
||||
class BedrockAnthropicModelCallIT {
|
||||
class BedrockAnthropicModelCallerIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BedrockAnthropicModelCallIT.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(BedrockAnthropicModelCallerIT.class);
|
||||
|
||||
@Autowired
|
||||
private BedrockAnthropicModelCall client;
|
||||
private BedrockAnthropicModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -209,8 +209,8 @@ class BedrockAnthropicModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BedrockAnthropicModelCall anthropicChatClient(AnthropicChatBedrockApi anthropicApi) {
|
||||
return new BedrockAnthropicModelCall(anthropicApi);
|
||||
public BedrockAnthropicModelCaller anthropicChatClient(AnthropicChatBedrockApi anthropicApi) {
|
||||
return new BedrockAnthropicModelCaller(anthropicApi);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public class BedrockAnthropic3CreateRequestTests {
|
||||
@Test
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new BedrockAnthropic3ModelCall(anthropicChatApi,
|
||||
var client = new BedrockAnthropic3ModelCaller(anthropicChatApi,
|
||||
Anthropic3ChatOptions.builder()
|
||||
.withTemperature(66.6f)
|
||||
.withTopK(66)
|
||||
|
||||
@@ -59,12 +59,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
|
||||
class BedrockAnthropic3ModelCallIT {
|
||||
class BedrockAnthropic3ModelCallerIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BedrockAnthropic3ModelCallIT.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(BedrockAnthropic3ModelCallerIT.class);
|
||||
|
||||
@Autowired
|
||||
private BedrockAnthropic3ModelCall client;
|
||||
private BedrockAnthropic3ModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -228,8 +228,8 @@ class BedrockAnthropic3ModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BedrockAnthropic3ModelCall anthropicChatClient(Anthropic3ChatBedrockApi anthropicApi) {
|
||||
return new BedrockAnthropic3ModelCall(anthropicApi);
|
||||
public BedrockAnthropic3ModelCaller anthropicChatClient(Anthropic3ChatBedrockApi anthropicApi) {
|
||||
return new BedrockAnthropic3ModelCaller(anthropicApi);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,7 +45,7 @@ public class BedrockCohereChatCreateRequestTests {
|
||||
@Test
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new BedrockCohereModelCall(chatApi,
|
||||
var client = new BedrockCohereModelCaller(chatApi,
|
||||
BedrockCohereChatOptions.builder()
|
||||
.withTemperature(66.6f)
|
||||
.withTopK(66)
|
||||
|
||||
@@ -54,10 +54,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
|
||||
class BedrockCohereModelCallIT {
|
||||
class BedrockCohereModelCallerIT {
|
||||
|
||||
@Autowired
|
||||
private BedrockCohereModelCall client;
|
||||
private BedrockCohereModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -205,8 +205,8 @@ class BedrockCohereModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BedrockCohereModelCall cohereChatClient(CohereChatBedrockApi cohereApi) {
|
||||
return new BedrockCohereModelCall(cohereApi);
|
||||
public BedrockCohereModelCaller cohereChatClient(CohereChatBedrockApi cohereApi) {
|
||||
return new BedrockCohereModelCaller(cohereApi);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,10 +49,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
|
||||
class BedrockAi21Jurassic2ModelCallIT {
|
||||
class BedrockAi21Jurassic2ModelCallerIT {
|
||||
|
||||
@Autowired
|
||||
private BedrockAi21Jurassic2ModelCall client;
|
||||
private BedrockAi21Jurassic2ModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -152,9 +152,9 @@ class BedrockAi21Jurassic2ModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BedrockAi21Jurassic2ModelCall bedrockAi21Jurassic2ChatClient(
|
||||
public BedrockAi21Jurassic2ModelCaller bedrockAi21Jurassic2ChatClient(
|
||||
Ai21Jurassic2ChatBedrockApi jurassic2ChatBedrockApi) {
|
||||
return new BedrockAi21Jurassic2ModelCall(jurassic2ChatBedrockApi,
|
||||
return new BedrockAi21Jurassic2ModelCaller(jurassic2ChatBedrockApi,
|
||||
BedrockAi21Jurassic2ChatOptions.builder()
|
||||
.withTemperature(0.5f)
|
||||
.withMaxTokens(100)
|
||||
@@ -45,7 +45,7 @@ public class BedrockLlamaCreateRequestTests {
|
||||
@Test
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new BedrockLlamaModelCall(api,
|
||||
var client = new BedrockLlamaModelCaller(api,
|
||||
BedrockLlamaChatOptions.builder().withTemperature(66.6f).withMaxGenLen(666).withTopP(0.66f).build());
|
||||
|
||||
var request = client.createRequest(new Prompt("Test message content"));
|
||||
|
||||
@@ -54,10 +54,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
|
||||
class BedrockLlamaModelCallIT {
|
||||
class BedrockLlamaModelCallerIT {
|
||||
|
||||
@Autowired
|
||||
private BedrockLlamaModelCall client;
|
||||
private BedrockLlamaModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -206,8 +206,8 @@ class BedrockLlamaModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BedrockLlamaModelCall llamaChatClient(LlamaChatBedrockApi llamaApi) {
|
||||
return new BedrockLlamaModelCall(llamaApi,
|
||||
public BedrockLlamaModelCaller llamaChatClient(LlamaChatBedrockApi llamaApi) {
|
||||
return new BedrockLlamaModelCaller(llamaApi,
|
||||
BedrockLlamaChatOptions.builder().withTemperature(0.5f).withMaxGenLen(100).withTopP(0.9f).build());
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class BedrockTitanChatCreateRequestTests {
|
||||
@Test
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new BedrockTitanModelCall(api,
|
||||
var client = new BedrockTitanModelCaller(api,
|
||||
BedrockTitanChatOptions.builder()
|
||||
.withTemperature(66.6f)
|
||||
.withTopP(0.66f)
|
||||
|
||||
@@ -55,10 +55,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_ACCESS_KEY_ID", matches = ".*")
|
||||
@EnabledIfEnvironmentVariable(named = "AWS_SECRET_ACCESS_KEY", matches = ".*")
|
||||
class BedrockTitanModelCallIT {
|
||||
class BedrockTitanModelCalerlIT {
|
||||
|
||||
@Autowired
|
||||
private BedrockTitanModelCall client;
|
||||
private BedrockTitanModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -211,8 +211,8 @@ class BedrockTitanModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BedrockTitanModelCall titanChatClient(TitanChatBedrockApi titanApi) {
|
||||
return new BedrockTitanModelCall(titanApi);
|
||||
public BedrockTitanModelCaller titanChatClient(TitanChatBedrockApi titanApi) {
|
||||
return new BedrockTitanModelCaller(titanApi);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.huggingface.api.TextGenerationInferenceApi;
|
||||
@@ -34,12 +34,12 @@ import org.springframework.ai.huggingface.model.GenerateResponse;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
|
||||
/**
|
||||
* An implementation of {@link ModelCall} that interfaces with HuggingFace Inference
|
||||
* An implementation of {@link ChatCaller} that interfaces with HuggingFace Inference
|
||||
* Endpoints for text generation.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
*/
|
||||
public class HuggingfaceModelCall implements ModelCall {
|
||||
public class HuggingfaceModelCaller implements ChatCaller {
|
||||
|
||||
/**
|
||||
* Token required for authenticating with the HuggingFace Inference API.
|
||||
@@ -72,7 +72,7 @@ public class HuggingfaceModelCall implements ModelCall {
|
||||
* @param apiToken The API token for HuggingFace.
|
||||
* @param basePath The base path for API requests.
|
||||
*/
|
||||
public HuggingfaceModelCall(final String apiToken, String basePath) {
|
||||
public HuggingfaceModelCaller(final String apiToken, String basePath) {
|
||||
this.apiToken = apiToken;
|
||||
this.apiClient.setBasePath(basePath);
|
||||
this.apiClient.addDefaultHeader("Authorization", "Bearer " + this.apiToken);
|
||||
@@ -23,7 +23,7 @@ import org.springframework.util.StringUtils;
|
||||
public class HuggingfaceTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public HuggingfaceModelCall huggingfaceChatClient() {
|
||||
public HuggingfaceModelCaller huggingfaceChatClient() {
|
||||
String apiKey = System.getenv("HUGGINGFACE_API_KEY");
|
||||
if (!StringUtils.hasText(apiKey)) {
|
||||
throw new IllegalArgumentException(
|
||||
@@ -31,7 +31,7 @@ public class HuggingfaceTestConfiguration {
|
||||
}
|
||||
// Created aws-mistral-7b-instruct-v0-1-805 via
|
||||
// https://ui.endpoints.huggingface.co/
|
||||
HuggingfaceModelCall huggingfaceChatClient = new HuggingfaceModelCall(apiKey,
|
||||
HuggingfaceModelCaller huggingfaceChatClient = new HuggingfaceModelCaller(apiKey,
|
||||
"https://f6hg7b3cvlmntp5i.us-east-1.aws.endpoints.huggingface.cloud");
|
||||
return huggingfaceChatClient;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.huggingface.HuggingfaceModelCall;
|
||||
import org.springframework.ai.huggingface.HuggingfaceModelCaller;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
public class ClientIT {
|
||||
|
||||
@Autowired
|
||||
protected HuggingfaceModelCall huggingfaceChatClient;
|
||||
protected HuggingfaceModelCaller huggingfaceChatClient;
|
||||
|
||||
@Test
|
||||
void helloWorldCompletion() {
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.ai.mistralai;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -55,9 +55,9 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* @author Grogdunn
|
||||
* @since 0.8.1
|
||||
*/
|
||||
public class MistralAiModelCall extends
|
||||
public class MistralAiModelCaller extends
|
||||
AbstractFunctionCallSupport<MistralAiApi.ChatCompletionMessage, MistralAiApi.ChatCompletionRequest, ResponseEntity<MistralAiApi.ChatCompletion>>
|
||||
implements ModelCall, StreamingChatClient {
|
||||
implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@@ -73,7 +73,7 @@ public class MistralAiModelCall extends
|
||||
|
||||
private final RetryTemplate retryTemplate;
|
||||
|
||||
public MistralAiModelCall(MistralAiApi mistralAiApi) {
|
||||
public MistralAiModelCaller(MistralAiApi mistralAiApi) {
|
||||
this(mistralAiApi,
|
||||
MistralAiChatOptions.builder()
|
||||
.withTemperature(0.7f)
|
||||
@@ -83,11 +83,11 @@ public class MistralAiModelCall extends
|
||||
.build());
|
||||
}
|
||||
|
||||
public MistralAiModelCall(MistralAiApi mistralAiApi, MistralAiChatOptions options) {
|
||||
public MistralAiModelCaller(MistralAiApi mistralAiApi, MistralAiChatOptions options) {
|
||||
this(mistralAiApi, options, null, RetryUtils.DEFAULT_RETRY_TEMPLATE);
|
||||
}
|
||||
|
||||
public MistralAiModelCall(MistralAiApi mistralAiApi, MistralAiChatOptions options,
|
||||
public MistralAiModelCaller(MistralAiApi mistralAiApi, MistralAiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
|
||||
super(functionCallbackContext);
|
||||
Assert.notNull(mistralAiApi, "MistralAiApi must not be null");
|
||||
@@ -32,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@EnabledIfEnvironmentVariable(named = "MISTRAL_AI_API_KEY", matches = ".+")
|
||||
public class MistralAiChatCompletionRequestTest {
|
||||
|
||||
MistralAiModelCall chatClient = new MistralAiModelCall(new MistralAiApi("test"));
|
||||
MistralAiModelCaller chatClient = new MistralAiModelCaller(new MistralAiApi("test"));
|
||||
|
||||
@Test
|
||||
void chatCompletionDefaultRequestTest() {
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -56,12 +56,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
@SpringBootTest(classes = MistralAiTestConfiguration.class)
|
||||
@EnabledIfEnvironmentVariable(named = "MISTRAL_AI_API_KEY", matches = ".+")
|
||||
class MistralAiModelCallIT {
|
||||
class MistralAiModelCallerIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MistralAiModelCallIT.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(MistralAiModelCallerIT.class);
|
||||
|
||||
@Autowired
|
||||
protected ModelCall modelCall;
|
||||
protected ChatCaller modelCall;
|
||||
|
||||
@Autowired
|
||||
protected StreamingChatClient streamingChatClient;
|
||||
@@ -82,7 +82,7 @@ public class MistralAiRetryTests {
|
||||
|
||||
private @Mock MistralAiApi mistralAiApi;
|
||||
|
||||
private MistralAiModelCall chatClient;
|
||||
private MistralAiModelCaller chatClient;
|
||||
|
||||
private MistralAiEmbeddingClient embeddingClient;
|
||||
|
||||
@@ -92,7 +92,7 @@ public class MistralAiRetryTests {
|
||||
retryListener = new TestRetryListener();
|
||||
retryTemplate.registerListener(retryListener);
|
||||
|
||||
chatClient = new MistralAiModelCall(mistralAiApi,
|
||||
chatClient = new MistralAiModelCaller(mistralAiApi,
|
||||
MistralAiChatOptions.builder()
|
||||
.withTemperature(0.7f)
|
||||
.withTopP(1f)
|
||||
|
||||
@@ -41,8 +41,8 @@ public class MistralAiTestConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MistralAiModelCall mistralAiChatClient(MistralAiApi mistralAiApi) {
|
||||
return new MistralAiModelCall(mistralAiApi,
|
||||
public MistralAiModelCaller mistralAiChatClient(MistralAiApi mistralAiApi) {
|
||||
return new MistralAiModelCaller(mistralAiApi,
|
||||
MistralAiChatOptions.builder().withModel(MistralAiApi.ChatModel.MIXTRAL.getValue()).build());
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.ollama;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.ollama.metadata.OllamaChatResponseMetadata;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link ModelCall} implementation for {@literal Ollama}.
|
||||
* {@link ChatCaller} implementation for {@literal Ollama}.
|
||||
*
|
||||
* Ollama allows developers to run large language models and generate embeddings locally.
|
||||
* It supports open-source models available on [Ollama AI
|
||||
@@ -52,7 +52,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
public class OllamaModelCall implements ModelCall, StreamingChatClient {
|
||||
public class OllamaModelCaller implements ChatCaller, StreamingChatClient {
|
||||
|
||||
/**
|
||||
* Low-level Ollama API library.
|
||||
@@ -64,11 +64,11 @@ public class OllamaModelCall implements ModelCall, StreamingChatClient {
|
||||
*/
|
||||
private OllamaOptions defaultOptions;
|
||||
|
||||
public OllamaModelCall(OllamaApi chatApi) {
|
||||
public OllamaModelCaller(OllamaApi chatApi) {
|
||||
this(chatApi, OllamaOptions.create().withModel(OllamaOptions.DEFAULT_MODEL));
|
||||
}
|
||||
|
||||
public OllamaModelCall(OllamaApi chatApi, OllamaOptions defaultOptions) {
|
||||
public OllamaModelCaller(OllamaApi chatApi, OllamaOptions defaultOptions) {
|
||||
Assert.notNull(chatApi, "OllamaApi must not be null");
|
||||
Assert.notNull(defaultOptions, "DefaultOptions must not be null");
|
||||
this.chatApi = chatApi;
|
||||
@@ -79,7 +79,7 @@ public class OllamaModelCall implements ModelCall, StreamingChatClient {
|
||||
* @deprecated Use {@link OllamaOptions#setModel} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public OllamaModelCall withModel(String model) {
|
||||
public OllamaModelCaller withModel(String model) {
|
||||
this.defaultOptions.setModel(model);
|
||||
return this;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public class OllamaModelCall implements ModelCall, StreamingChatClient {
|
||||
* @deprecated Use {@link OllamaOptions} constructor instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public OllamaModelCall withDefaultOptions(OllamaOptions options) {
|
||||
public OllamaModelCaller withDefaultOptions(OllamaOptions options) {
|
||||
this.defaultOptions = options;
|
||||
return this;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
public class OllamaChatRequestTests {
|
||||
|
||||
OllamaModelCall client = new OllamaModelCall(new OllamaApi(),
|
||||
OllamaModelCaller client = new OllamaModelCaller(new OllamaApi(),
|
||||
new OllamaOptions().withModel("MODEL_NAME").withTopK(99).withTemperature(66.6f).withNumGPU(1));
|
||||
|
||||
@Test
|
||||
@@ -105,7 +105,7 @@ public class OllamaChatRequestTests {
|
||||
@Test
|
||||
public void createRequestWithDefaultOptionsModelOverride() {
|
||||
|
||||
OllamaModelCall client2 = new OllamaModelCall(new OllamaApi(),
|
||||
OllamaModelCaller client2 = new OllamaModelCaller(new OllamaApi(),
|
||||
new OllamaOptions().withModel("DEFAULT_OPTIONS_MODEL"));
|
||||
|
||||
var request = client2.ollamaChatRequest(new Prompt("Test message content"), true);
|
||||
|
||||
@@ -56,11 +56,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@Testcontainers
|
||||
@Disabled("For manual smoke testing only.")
|
||||
class OllamaModelCallIT {
|
||||
class OllamaModelCallerIT {
|
||||
|
||||
private static String MODEL = "mistral";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(OllamaModelCallIT.class);
|
||||
private static final Log logger = LogFactory.getLog(OllamaModelCallerIT.class);
|
||||
|
||||
@Container
|
||||
static OllamaContainer ollamaContainer = new OllamaContainer("ollama/ollama:0.1.32");
|
||||
@@ -77,7 +77,7 @@ class OllamaModelCallIT {
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private OllamaModelCall client;
|
||||
private OllamaModelCaller client;
|
||||
|
||||
@Test
|
||||
void roleTest() {
|
||||
@@ -219,8 +219,8 @@ class OllamaModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OllamaModelCall ollamaChat(OllamaApi ollamaApi) {
|
||||
return new OllamaModelCall(ollamaApi, OllamaOptions.create().withModel(MODEL).withTemperature(0.9f));
|
||||
public OllamaModelCaller ollamaChat(OllamaApi ollamaApi) {
|
||||
return new OllamaModelCaller(ollamaApi, OllamaOptions.create().withModel(MODEL).withTemperature(0.9f));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,11 +44,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@Testcontainers
|
||||
@Disabled("For manual smoke testing only.")
|
||||
class OllamaModelCallMultimodalIT {
|
||||
class OllamaModelCallerMultimodalIT {
|
||||
|
||||
private static String MODEL = "llava";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(OllamaModelCallIT.class);
|
||||
private static final Log logger = LogFactory.getLog(OllamaModelCallerIT.class);
|
||||
|
||||
@Container
|
||||
static OllamaContainer ollamaContainer = new OllamaContainer("ollama/ollama:0.1.32");
|
||||
@@ -65,7 +65,7 @@ class OllamaModelCallMultimodalIT {
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private OllamaModelCall client;
|
||||
private OllamaModelCaller client;
|
||||
|
||||
@Test
|
||||
void multiModalityTest() throws IOException {
|
||||
@@ -90,8 +90,8 @@ class OllamaModelCallMultimodalIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OllamaModelCall ollamaChat(OllamaApi ollamaApi) {
|
||||
return new OllamaModelCall(ollamaApi, OllamaOptions.create().withModel(MODEL).withTemperature(0.9f));
|
||||
public OllamaModelCaller ollamaChat(OllamaApi ollamaApi) {
|
||||
return new OllamaModelCaller(ollamaApi, OllamaOptions.create().withModel(MODEL).withTemperature(0.9f));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@ package org.springframework.ai.openai;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -58,7 +58,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* {@link ModelCall} and {@link StreamingChatClient} implementation for {@literal OpenAI}
|
||||
* {@link ChatCaller} and {@link StreamingChatClient} implementation for {@literal OpenAI}
|
||||
* backed by {@link OpenAiApi}.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
@@ -68,15 +68,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* @author Josh Long
|
||||
* @author Jemin Huh
|
||||
* @author Grogdunn
|
||||
* @see ModelCall
|
||||
* @see ChatCaller
|
||||
* @see StreamingChatClient
|
||||
* @see OpenAiApi
|
||||
*/
|
||||
public class OpenAiModelCall extends
|
||||
public class OpenAiModelCaller extends
|
||||
AbstractFunctionCallSupport<ChatCompletionMessage, OpenAiApi.ChatCompletionRequest, ResponseEntity<ChatCompletion>>
|
||||
implements ModelCall, StreamingChatClient {
|
||||
implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(OpenAiModelCall.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(OpenAiModelCaller.class);
|
||||
|
||||
/**
|
||||
* The default options used for the chat completion requests.
|
||||
@@ -99,7 +99,7 @@ public class OpenAiModelCall extends
|
||||
* Chat API.
|
||||
* @throws IllegalArgumentException if openAiApi is null
|
||||
*/
|
||||
public OpenAiModelCall(OpenAiApi openAiApi) {
|
||||
public OpenAiModelCaller(OpenAiApi openAiApi) {
|
||||
this(openAiApi,
|
||||
OpenAiChatOptions.builder().withModel(OpenAiApi.DEFAULT_CHAT_MODEL).withTemperature(0.7f).build());
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class OpenAiModelCall extends
|
||||
* Chat API.
|
||||
* @param options The OpenAiChatOptions to configure the chat client.
|
||||
*/
|
||||
public OpenAiModelCall(OpenAiApi openAiApi, OpenAiChatOptions options) {
|
||||
public OpenAiModelCaller(OpenAiApi openAiApi, OpenAiChatOptions options) {
|
||||
this(openAiApi, options, null, RetryUtils.DEFAULT_RETRY_TEMPLATE);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ public class OpenAiModelCall extends
|
||||
* @param functionCallbackContext The function callback context.
|
||||
* @param retryTemplate The retry template.
|
||||
*/
|
||||
public OpenAiModelCall(OpenAiApi openAiApi, OpenAiChatOptions options,
|
||||
public OpenAiModelCaller(OpenAiApi openAiApi, OpenAiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext, RetryTemplate retryTemplate) {
|
||||
super(functionCallbackContext);
|
||||
Assert.notNull(openAiApi, "OpenAiApi must not be null");
|
||||
@@ -34,7 +34,7 @@ public class ChatCompletionRequestTests {
|
||||
@Test
|
||||
public void createRequestWithChatOptions() {
|
||||
|
||||
var client = new OpenAiModelCall(new OpenAiApi("TEST"),
|
||||
var client = new OpenAiModelCaller(new OpenAiApi("TEST"),
|
||||
OpenAiChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6f).build());
|
||||
|
||||
var request = client.createRequest(new Prompt("Test message content"), false);
|
||||
@@ -60,7 +60,7 @@ public class ChatCompletionRequestTests {
|
||||
|
||||
final String TOOL_FUNCTION_NAME = "CurrentWeather";
|
||||
|
||||
var client = new OpenAiModelCall(new OpenAiApi("TEST"),
|
||||
var client = new OpenAiModelCaller(new OpenAiApi("TEST"),
|
||||
OpenAiChatOptions.builder().withModel("DEFAULT_MODEL").build());
|
||||
|
||||
var request = client.createRequest(new Prompt("Test message content",
|
||||
@@ -90,7 +90,7 @@ public class ChatCompletionRequestTests {
|
||||
|
||||
final String TOOL_FUNCTION_NAME = "CurrentWeather";
|
||||
|
||||
var client = new OpenAiModelCall(new OpenAiApi("TEST"),
|
||||
var client = new OpenAiModelCaller(new OpenAiApi("TEST"),
|
||||
OpenAiChatOptions.builder()
|
||||
.withModel("DEFAULT_MODEL")
|
||||
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
|
||||
|
||||
@@ -51,8 +51,8 @@ public class OpenAiTestConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiChatClient(OpenAiApi api) {
|
||||
OpenAiModelCall openAiChatClient = new OpenAiModelCall(api);
|
||||
public OpenAiModelCaller openAiChatClient(OpenAiApi api) {
|
||||
OpenAiModelCaller openAiChatClient = new OpenAiModelCaller(api);
|
||||
return openAiChatClient;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.OpenAiTestConfiguration;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingClient;
|
||||
import org.springframework.ai.openai.testutils.AbstractIT;
|
||||
@@ -61,7 +61,7 @@ public class AcmeIT extends AbstractIT {
|
||||
private OpenAiEmbeddingClient embeddingClient;
|
||||
|
||||
@Autowired
|
||||
private OpenAiModelCall chatClient;
|
||||
private OpenAiModelCaller chatClient;
|
||||
|
||||
@Test
|
||||
void beanTest() {
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* Copyright 2023 - 2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ai.openai.chat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.ChatClient;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.messages.AssistantMessage;
|
||||
import org.springframework.ai.chat.messages.Media;
|
||||
import org.springframework.ai.chat.messages.Message;
|
||||
import org.springframework.ai.chat.messages.UserMessage;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.ai.chat.prompt.PromptTemplate;
|
||||
import org.springframework.ai.converter.BeanOutputConverter;
|
||||
import org.springframework.ai.model.function.FunctionCallbackWrapper;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.springframework.ai.openai.OpenAiTestConfiguration;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.openai.api.tool.MockWeatherService;
|
||||
import org.springframework.ai.openai.testutils.AbstractIT;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = OpenAiTestConfiguration.class)
|
||||
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
|
||||
class OpenAiChatClientIT extends AbstractIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(OpenAiModelCallerIT.class);
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemTextResource;
|
||||
|
||||
@Test
|
||||
void roleTest() {
|
||||
|
||||
ChatResponse response = ChatClient.builder(modelCaller).build().call()
|
||||
.system(s -> s.text(systemTextResource).param("name", "Bob").param("voice", "pirate"))
|
||||
.user(u -> u.text("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did"))
|
||||
.chat().chatResponse();
|
||||
|
||||
System.out.println(response);
|
||||
// UserMessage userMessage = new UserMessage(
|
||||
// "Tell me about 3 famous pirates from the Golden Age of Piracy and what they
|
||||
// did.");
|
||||
// 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 = modelCaller.call(prompt);
|
||||
assertThat(response.getResults()).hasSize(1);
|
||||
assertThat(response.getResults().get(0).getOutput().getContent()).contains("Blackbeard");
|
||||
// needs fine tuning... evaluateQuestionAndAnswer(request, response, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void listOutputConverter() {
|
||||
|
||||
// TODO: there is a problem here.
|
||||
Collection<String> list = ChatClient.builder(modelCaller).build().call()
|
||||
.user(u -> u.text("List five {subject}").param("subject", "ice cream flavors"))
|
||||
.chat().list(String.class);
|
||||
|
||||
// DefaultConversionService conversionService = new DefaultConversionService();
|
||||
// ListOutputConverter outputConverter = new
|
||||
// ListOutputConverter(conversionService);
|
||||
|
||||
// String format = outputConverter.getFormat();
|
||||
// String template = """
|
||||
// List five {subject}
|
||||
// {format}
|
||||
// """;
|
||||
// PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
// Map.of("subject", "ice cream flavors", "format", format));
|
||||
// Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
// Generation generation = this.modelCaller.call(prompt).getResult();
|
||||
|
||||
// List<String> list =
|
||||
// outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapOutputConverter() {
|
||||
|
||||
Map<String, Object> result = ChatClient.builder(modelCaller).build().call()
|
||||
.user(u -> u.text("Provide me a List of {subject}")
|
||||
.param("subject", "an array of numbers from 1 to 9 under they key name 'numbers'"))
|
||||
.chat().single(new ParameterizedTypeReference<Map<String, Object>>() {
|
||||
});
|
||||
|
||||
// MapOutputConverter outputConverter = new MapOutputConverter();
|
||||
|
||||
// String format = outputConverter.getFormat();
|
||||
// String template = """
|
||||
// Provide me a List of {subject}
|
||||
// {format}
|
||||
// """;
|
||||
// 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 = modelCaller.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));
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanOutputConverter() {
|
||||
|
||||
ActorsFilms actorsFilms = ChatClient.builder(modelCaller).build().call()
|
||||
.user(u -> u.text("Generate the filmography for a random actor."))
|
||||
.chat().single(ActorsFilms.class);
|
||||
|
||||
// BeanOutputConverter<ActorsFilms> outputConverter = new
|
||||
// BeanOutputConverter<>(ActorsFilms.class);
|
||||
|
||||
// String format = outputConverter.getFormat();
|
||||
// String template = """
|
||||
// Generate the filmography for a random actor.
|
||||
// {format}
|
||||
// """;
|
||||
// PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format",
|
||||
// format));
|
||||
// Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
// Generation generation = modelCaller.call(prompt).getResult();
|
||||
|
||||
// ActorsFilms actorsFilms =
|
||||
// outputConverter.convert(generation.getOutput().getContent());
|
||||
logger.info("" + actorsFilms);
|
||||
assertThat(actorsFilms.getActor()).isNotBlank();
|
||||
}
|
||||
|
||||
record ActorsFilmsRecord(String actor, List<String> movies) {
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanOutputConverterRecords() {
|
||||
|
||||
ActorsFilmsRecord actorsFilms = ChatClient.builder(modelCaller)
|
||||
.build().call()
|
||||
.user(u -> u.text("Generate the filmography of 5 movies for Tom Hanks."))
|
||||
.chat().single(ActorsFilmsRecord.class);
|
||||
|
||||
// BeanOutputConverter<ActorsFilmsRecord> outputConverter = new
|
||||
// BeanOutputConverter<>(ActorsFilmsRecord.class);
|
||||
|
||||
// String format = outputConverter.getFormat();
|
||||
// String template = """
|
||||
// Generate the filmography of 5 movies for Tom Hanks.
|
||||
// {format}
|
||||
// """;
|
||||
// PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format",
|
||||
// format));
|
||||
// Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
// Generation generation = modelCaller.call(prompt).getResult();
|
||||
|
||||
// ActorsFilmsRecord actorsFilms =
|
||||
// outputConverter.convert(generation.getOutput().getContent());
|
||||
logger.info("" + actorsFilms);
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
assertThat(actorsFilms.movies()).hasSize(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void beanStreamOutputConverterRecords() {
|
||||
|
||||
BeanOutputConverter<ActorsFilmsRecord> outputConverter = new BeanOutputConverter<>(ActorsFilmsRecord.class);
|
||||
|
||||
String format = outputConverter.getFormat();
|
||||
String template = """
|
||||
Generate the filmography of 5 movies for Tom Hanks.
|
||||
{format}
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
|
||||
String generationTextFromStream = streamingChatClient.stream(prompt)
|
||||
.collectList()
|
||||
.block()
|
||||
.stream()
|
||||
.map(ChatResponse::getResults)
|
||||
.flatMap(List::stream)
|
||||
.map(Generation::getOutput)
|
||||
.map(AssistantMessage::getContent)
|
||||
.collect(Collectors.joining());
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generationTextFromStream);
|
||||
logger.info("" + actorsFilms);
|
||||
assertThat(actorsFilms.actor()).isEqualTo("Tom Hanks");
|
||||
assertThat(actorsFilms.movies()).hasSize(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void functionCallTest() {
|
||||
|
||||
ChatResponse response = ChatClient.builder(modelCaller)
|
||||
.build()
|
||||
.call()
|
||||
.user(u -> u.text("What's the weather like in San Francisco, Tokyo, and Paris?"))
|
||||
// TODO how to use the protable function calling options internally.
|
||||
// Perhaps the ModelCaller a emptyOptions() method needs to be provided.
|
||||
.options(OpenAiChatOptions.builder().build())
|
||||
.function("getCurrentWeather", "Get the weather in location", new MockWeatherService())
|
||||
.chat()
|
||||
.chatResponse();
|
||||
|
||||
// UserMessage userMessage = new UserMessage("What's the weather like in San
|
||||
// Francisco, Tokyo, and Paris?");
|
||||
|
||||
// List<Message> messages = new ArrayList<>(List.of(userMessage));
|
||||
|
||||
// var promptOptions = OpenAiChatOptions.builder()
|
||||
// .withModel(OpenAiApi.ChatModel.GPT_4_TURBO_PREVIEW.getValue())
|
||||
// .withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new
|
||||
// MockWeatherService())
|
||||
// .withName("getCurrentWeather")
|
||||
// .withDescription("Get the weather in location")
|
||||
// .withResponseConverter((response) -> "" + response.temp() + response.unit())
|
||||
// .build()))
|
||||
// .build();
|
||||
|
||||
// ChatResponse response = modelCaller.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
assertThat(response.getResult().getOutput().getContent()).containsAnyOf("30.0", "30");
|
||||
assertThat(response.getResult().getOutput().getContent()).containsAnyOf("10.0", "10");
|
||||
assertThat(response.getResult().getOutput().getContent()).containsAnyOf("15.0", "15");
|
||||
}
|
||||
|
||||
@Test
|
||||
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));
|
||||
|
||||
var promptOptions = OpenAiChatOptions.builder()
|
||||
// .withModel(OpenAiApi.ChatModel.GPT_4_TURBO_PREVIEW.getValue())
|
||||
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
|
||||
.withName("getCurrentWeather")
|
||||
.withDescription("Get the weather in location")
|
||||
.withResponseConverter((response) -> "" + response.temp() + response.unit())
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
Flux<ChatResponse> response = streamingChatClient.stream(new Prompt(messages, promptOptions));
|
||||
|
||||
String content = response.collectList()
|
||||
.block()
|
||||
.stream()
|
||||
.map(ChatResponse::getResults)
|
||||
.flatMap(List::stream)
|
||||
.map(Generation::getOutput)
|
||||
.map(AssistantMessage::getContent)
|
||||
.collect(Collectors.joining());
|
||||
logger.info("Response: {}", content);
|
||||
|
||||
assertThat(content).containsAnyOf("30.0", "30");
|
||||
assertThat(content).containsAnyOf("10.0", "10");
|
||||
assertThat(content).containsAnyOf("15.0", "15");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "{0} : {displayName} ")
|
||||
@ValueSource(strings = { "gpt-4-vision-preview", "gpt-4o" })
|
||||
void multiModalityEmbeddedImage(String modelName) throws IOException {
|
||||
|
||||
ChatResponse response = ChatClient.builder(modelCaller)
|
||||
.build()
|
||||
.call()
|
||||
// TODO consider adding model(...) method to ChatClient as a shortcut to
|
||||
// OpenAiChatOptions.builder().withModel(modelName).build()
|
||||
.options(OpenAiChatOptions.builder().withModel(modelName).build())
|
||||
.user(u -> u.text("Explain what do you see on this picture?")
|
||||
.media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("/test.png")))
|
||||
.chat()
|
||||
.chatResponse();
|
||||
|
||||
// var imageData = new ClassPathResource("/test.png");
|
||||
|
||||
// var userMessage = new UserMessage("Explain what do you see on this picture?",
|
||||
// List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
|
||||
|
||||
// var response = modelCaller
|
||||
// .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");
|
||||
assertThat(response.getResult().getOutput().getContent()).containsAnyOf("bowl", "basket");
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "{0} : {displayName} ")
|
||||
@ValueSource(strings = { "gpt-4-vision-preview", "gpt-4o" })
|
||||
void multiModalityImageUrl(String modelName) throws IOException {
|
||||
|
||||
// TODO: add url method that wrapps the checked exception.
|
||||
URL url = new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png");
|
||||
|
||||
ChatResponse response = ChatClient.builder(modelCaller)
|
||||
.build()
|
||||
.call()
|
||||
// TODO consider adding model(...) method to ChatClient as a shortcut to
|
||||
// OpenAiChatOptions.builder().withModel(modelName).build()
|
||||
.options(OpenAiChatOptions.builder().withModel(modelName).build())
|
||||
.user(u -> u.text("Explain what do you see on this picture?").media(MimeTypeUtils.IMAGE_PNG, url))
|
||||
.chat()
|
||||
.chatResponse();
|
||||
|
||||
// var userMessage = new UserMessage("Explain what do you see on this picture?",
|
||||
// List
|
||||
// .of(new Media(MimeTypeUtils.IMAGE_PNG,
|
||||
// new
|
||||
// URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png"))));
|
||||
|
||||
// ChatResponse response = modelCaller
|
||||
// .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");
|
||||
assertThat(response.getResult().getOutput().getContent()).containsAnyOf("bowl", "basket");
|
||||
}
|
||||
|
||||
@Test
|
||||
void streamingMultiModalityImageUrl() throws IOException {
|
||||
|
||||
var userMessage = new UserMessage("Explain what do you see on this picture?", List
|
||||
.of(new Media(MimeTypeUtils.IMAGE_PNG,
|
||||
new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png"))));
|
||||
|
||||
Flux<ChatResponse> response = streamingChatClient.stream(new Prompt(List.of(userMessage),
|
||||
OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_VISION_PREVIEW.getValue()).build()));
|
||||
|
||||
String content = response.collectList()
|
||||
.block()
|
||||
.stream()
|
||||
.map(ChatResponse::getResults)
|
||||
.flatMap(List::stream)
|
||||
.map(Generation::getOutput)
|
||||
.map(AssistantMessage::getContent)
|
||||
.collect(Collectors.joining());
|
||||
logger.info("Response: {}", content);
|
||||
assertThat(content).contains("bananas", "apple");
|
||||
assertThat(content).containsAnyOf("bowl", "basket");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import org.springframework.ai.chat.metadata.PromptMetadata;
|
||||
import org.springframework.ai.chat.metadata.RateLimit;
|
||||
import org.springframework.ai.chat.metadata.Usage;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.metadata.support.OpenAiApiResponseHeaders;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -57,7 +57,7 @@ public class OpenAiChatClientWithChatResponseMetadataTests {
|
||||
private static String TEST_API_KEY = "sk-1234567890";
|
||||
|
||||
@Autowired
|
||||
private OpenAiModelCall openAiChatClient;
|
||||
private OpenAiModelCaller openAiChatClient;
|
||||
|
||||
@Autowired
|
||||
private MockRestServiceServer server;
|
||||
@@ -171,8 +171,8 @@ public class OpenAiChatClientWithChatResponseMetadataTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCall(openAiApi);
|
||||
public OpenAiModelCaller openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCaller(openAiApi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest;
|
||||
@@ -41,14 +41,14 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@SpringBootTest(classes = OpenAiModelCall2IT.Config.class)
|
||||
@SpringBootTest(classes = OpenAiModelCaller2IT.Config.class)
|
||||
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
|
||||
public class OpenAiModelCall2IT {
|
||||
public class OpenAiModelCaller2IT {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private OpenAiModelCall openAiChatClient;
|
||||
private OpenAiModelCaller openAiChatClient;
|
||||
|
||||
@Test
|
||||
void responseFormatTest() throws JsonMappingException, JsonProcessingException {
|
||||
@@ -99,8 +99,8 @@ public class OpenAiModelCall2IT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCall(openAiApi);
|
||||
public OpenAiModelCaller openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCaller(openAiApi);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.ChatClient;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.messages.AssistantMessage;
|
||||
@@ -60,9 +61,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = OpenAiTestConfiguration.class)
|
||||
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
|
||||
class OpenAiModelCallIT extends AbstractIT {
|
||||
class OpenAiModelCallerIT extends AbstractIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(OpenAiModelCallIT.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(OpenAiModelCallerIT.class);
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -74,7 +75,7 @@ class OpenAiModelCallIT 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 = modelCall.call(prompt);
|
||||
ChatResponse response = modelCaller.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 +94,7 @@ class OpenAiModelCallIT extends AbstractIT {
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template,
|
||||
Map.of("subject", "ice cream flavors", "format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = this.modelCall.call(prompt).getResult();
|
||||
Generation generation = this.modelCaller.call(prompt).getResult();
|
||||
|
||||
List<String> list = outputConverter.convert(generation.getOutput().getContent());
|
||||
assertThat(list).hasSize(5);
|
||||
@@ -112,7 +113,7 @@ class OpenAiModelCallIT 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 = modelCall.call(prompt).getResult();
|
||||
Generation generation = modelCaller.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 +132,7 @@ class OpenAiModelCallIT extends AbstractIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = modelCall.call(prompt).getResult();
|
||||
Generation generation = modelCaller.call(prompt).getResult();
|
||||
|
||||
ActorsFilms actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
}
|
||||
@@ -151,7 +152,7 @@ class OpenAiModelCallIT extends AbstractIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = modelCall.call(prompt).getResult();
|
||||
Generation generation = modelCaller.call(prompt).getResult();
|
||||
|
||||
ActorsFilmsRecord actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
logger.info("" + actorsFilms);
|
||||
@@ -204,7 +205,7 @@ class OpenAiModelCallIT extends AbstractIT {
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
ChatResponse response = modelCall.call(new Prompt(messages, promptOptions));
|
||||
ChatResponse response = modelCaller.call(new Prompt(messages, promptOptions));
|
||||
|
||||
logger.info("Response: {}", response);
|
||||
|
||||
@@ -255,7 +256,7 @@ class OpenAiModelCallIT extends AbstractIT {
|
||||
var userMessage = new UserMessage("Explain what do you see on this picture?",
|
||||
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));
|
||||
|
||||
var response = modelCall
|
||||
var response = modelCaller
|
||||
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
|
||||
|
||||
logger.info(response.getResult().getOutput().getContent());
|
||||
@@ -271,7 +272,7 @@ class OpenAiModelCallIT extends AbstractIT {
|
||||
.of(new Media(MimeTypeUtils.IMAGE_PNG,
|
||||
new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png"))));
|
||||
|
||||
ChatResponse response = modelCall
|
||||
ChatResponse response = modelCaller
|
||||
.call(new Prompt(List.of(userMessage), OpenAiChatOptions.builder().withModel(modelName).build()));
|
||||
|
||||
logger.info(response.getResult().getOutput().getContent());
|
||||
@@ -39,10 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(classes = OpenAiTestConfiguration.class)
|
||||
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
|
||||
class OpenAiModelCallTypeReferenceBeanOutputConverterIT extends AbstractIT {
|
||||
class OpenAiModelCallerTypeReferenceBeanOutputConverterIT extends AbstractIT {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(OpenAiModelCallTypeReferenceBeanOutputConverterIT.class);
|
||||
.getLogger(OpenAiModelCallerTypeReferenceBeanOutputConverterIT.class);
|
||||
|
||||
record ActorsFilmsRecord(String actor, List<String> movies) {
|
||||
}
|
||||
@@ -61,7 +61,7 @@ class OpenAiModelCallTypeReferenceBeanOutputConverterIT extends AbstractIT {
|
||||
""";
|
||||
PromptTemplate promptTemplate = new PromptTemplate(template, Map.of("format", format));
|
||||
Prompt prompt = new Prompt(promptTemplate.createMessage());
|
||||
Generation generation = modelCall.call(prompt).getResult();
|
||||
Generation generation = modelCaller.call(prompt).getResult();
|
||||
|
||||
List<ActorsFilmsRecord> actorsFilms = outputConverter.convert(generation.getOutput().getContent());
|
||||
logger.info("" + actorsFilms);
|
||||
@@ -31,7 +31,7 @@ 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.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingClient;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingOptions;
|
||||
@@ -107,7 +107,7 @@ public class OpenAiRetryTests {
|
||||
|
||||
private @Mock OpenAiImageApi openAiImageApi;
|
||||
|
||||
private OpenAiModelCall chatClient;
|
||||
private OpenAiModelCaller chatClient;
|
||||
|
||||
private OpenAiEmbeddingClient embeddingClient;
|
||||
|
||||
@@ -121,7 +121,7 @@ public class OpenAiRetryTests {
|
||||
retryListener = new TestRetryListener();
|
||||
retryTemplate.registerListener(retryListener);
|
||||
|
||||
chatClient = new OpenAiModelCall(openAiApi, OpenAiChatOptions.builder().build(), null, retryTemplate);
|
||||
chatClient = new OpenAiModelCaller(openAiApi, OpenAiChatOptions.builder().build(), null, retryTemplate);
|
||||
embeddingClient = new OpenAiEmbeddingClient(openAiApi, MetadataMode.EMBED,
|
||||
OpenAiEmbeddingOptions.builder().build(), retryTemplate);
|
||||
audioTranscriptionClient = new OpenAiAudioTranscriptionClient(openAiAudioApi,
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.springframework.ai.chat.memory.SystemPromptChatMemoryAugmentor;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.evaluation.BaseMemoryTest;
|
||||
import org.springframework.ai.evaluation.RelevancyEvaluator;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingClient;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator;
|
||||
@@ -75,8 +75,8 @@ public class ChatMemoryLongTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCall(openAiApi);
|
||||
public OpenAiModelCaller openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCaller(openAiApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -98,7 +98,7 @@ public class ChatMemoryLongTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiModelCall chatClient, VectorStore vectorStore,
|
||||
public ChatService memoryChatService(OpenAiModelCaller chatClient, VectorStore vectorStore,
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
@@ -110,7 +110,7 @@ public class ChatMemoryLongTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiModelCall streamingChatClient,
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiModelCaller streamingChatClient,
|
||||
VectorStore vectorStore, TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return StreamingPromptTransformingChatService.builder(streamingChatClient)
|
||||
@@ -122,7 +122,7 @@ public class ChatMemoryLongTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCall chatClient) {
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCaller chatClient) {
|
||||
return new RelevancyEvaluator(chatClient);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.springframework.ai.chat.memory.LastMaxTokenSizeContentTransformer;
|
||||
import org.springframework.ai.chat.memory.MessageChatMemoryAugmentor;
|
||||
import org.springframework.ai.evaluation.BaseMemoryTest;
|
||||
import org.springframework.ai.evaluation.RelevancyEvaluator;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator;
|
||||
import org.springframework.ai.tokenizer.TokenCountEstimator;
|
||||
@@ -59,8 +59,8 @@ public class ChatMemoryShortTermMessageListIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCall(openAiApi);
|
||||
public OpenAiModelCaller openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCaller(openAiApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -74,7 +74,7 @@ public class ChatMemoryShortTermMessageListIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiModelCall chatClient, ChatMemory chatHistory,
|
||||
public ChatService memoryChatService(OpenAiModelCaller chatClient, ChatMemory chatHistory,
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
@@ -86,7 +86,7 @@ public class ChatMemoryShortTermMessageListIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiModelCall streamingChatClient,
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiModelCaller streamingChatClient,
|
||||
ChatMemory chatHistory, TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return StreamingPromptTransformingChatService.builder(streamingChatClient)
|
||||
@@ -98,7 +98,7 @@ public class ChatMemoryShortTermMessageListIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCall chatClient) {
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCaller chatClient) {
|
||||
return new RelevancyEvaluator(chatClient);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.ai.chat.memory.LastMaxTokenSizeContentTransformer;
|
||||
import org.springframework.ai.chat.memory.SystemPromptChatMemoryAugmentor;
|
||||
import org.springframework.ai.evaluation.BaseMemoryTest;
|
||||
import org.springframework.ai.evaluation.RelevancyEvaluator;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator;
|
||||
import org.springframework.ai.tokenizer.TokenCountEstimator;
|
||||
@@ -60,8 +60,8 @@ public class ChatMemoryShortTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCall(openAiApi);
|
||||
public OpenAiModelCaller openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCaller(openAiApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -75,7 +75,7 @@ public class ChatMemoryShortTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiModelCall chatClient, ChatMemory chatHistory,
|
||||
public ChatService memoryChatService(OpenAiModelCaller chatClient, ChatMemory chatHistory,
|
||||
TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
@@ -87,7 +87,7 @@ public class ChatMemoryShortTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiModelCall streamingChatClient,
|
||||
public StreamingChatService memoryStreamingChatService(OpenAiModelCaller streamingChatClient,
|
||||
ChatMemory chatHistory, TokenCountEstimator tokenCountEstimator) {
|
||||
|
||||
return StreamingPromptTransformingChatService.builder(streamingChatClient)
|
||||
@@ -99,7 +99,7 @@ public class ChatMemoryShortTermSystemPromptIT extends BaseMemoryTest {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCall chatClient) {
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCaller chatClient) {
|
||||
return new RelevancyEvaluator(chatClient);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ 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.OpenAiChatOptions;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
import org.testcontainers.qdrant.QdrantContainer;
|
||||
@@ -163,8 +163,8 @@ public class LongShortTermChatMemoryWithRagIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCall(openAiApi);
|
||||
public OpenAiModelCaller openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCaller(openAiApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -186,7 +186,7 @@ public class LongShortTermChatMemoryWithRagIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChatService memoryChatService(OpenAiModelCall chatClient, VectorStore vectorStore,
|
||||
public ChatService memoryChatService(OpenAiModelCaller chatClient, VectorStore vectorStore,
|
||||
TokenCountEstimator tokenCountEstimator, ChatMemory chatHistory) {
|
||||
|
||||
return PromptTransformingChatService.builder(chatClient)
|
||||
@@ -240,7 +240,7 @@ public class LongShortTermChatMemoryWithRagIT {
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCall chatClient) {
|
||||
public RelevancyEvaluator relevancyEvaluator(OpenAiModelCaller chatClient) {
|
||||
// Use GPT 4 as a better model for determining relevancy. gpt 3.5 makes basic
|
||||
// mistakes
|
||||
OpenAiChatOptions openAiChatOptions = OpenAiChatOptions.builder()
|
||||
|
||||
@@ -23,7 +23,7 @@ import io.qdrant.client.QdrantClient;
|
||||
import io.qdrant.client.QdrantGrpcClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.service.ChatService;
|
||||
import org.springframework.ai.chat.prompt.transformer.TransformerContentType;
|
||||
import org.springframework.ai.document.Document;
|
||||
@@ -41,7 +41,7 @@ import org.springframework.ai.chat.prompt.transformer.VectorStoreRetriever;
|
||||
import org.springframework.ai.embedding.EmbeddingClient;
|
||||
import org.springframework.ai.evaluation.EvaluationResponse;
|
||||
import org.springframework.ai.evaluation.RelevancyEvaluator;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.OpenAiEmbeddingClient;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.reader.JsonReader;
|
||||
@@ -71,7 +71,7 @@ public class OpenAiPromptTransformingChatServiceIT {
|
||||
@Container
|
||||
static QdrantContainer qdrantContainer = new QdrantContainer("qdrant/qdrant:v1.9.2");
|
||||
|
||||
private final ModelCall modelCall;
|
||||
private final ChatCaller modelCall;
|
||||
|
||||
private final VectorStore vectorStore;
|
||||
|
||||
@@ -81,7 +81,7 @@ public class OpenAiPromptTransformingChatServiceIT {
|
||||
private ChatService chatService;
|
||||
|
||||
@Autowired
|
||||
public OpenAiPromptTransformingChatServiceIT(ModelCall modelCall, ChatService chatService,
|
||||
public OpenAiPromptTransformingChatServiceIT(ChatCaller modelCall, ChatService chatService,
|
||||
VectorStore vectorStore) {
|
||||
this.modelCall = modelCall;
|
||||
this.chatService = chatService;
|
||||
@@ -145,8 +145,8 @@ public class OpenAiPromptTransformingChatServiceIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ModelCall openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCall(openAiApi);
|
||||
public ChatCaller openAiClient(OpenAiApi openAiApi) {
|
||||
return new OpenAiModelCaller(openAiApi);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -163,7 +163,7 @@ public class OpenAiPromptTransformingChatServiceIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ChatService chatService(ModelCall modelCall, VectorStore vectorStore) {
|
||||
public ChatService chatService(ChatCaller modelCall, VectorStore vectorStore) {
|
||||
return PromptTransformingChatService.builder(modelCall)
|
||||
.withRetrievers(List.of(new VectorStoreRetriever(vectorStore, SearchRequest.defaults())))
|
||||
.withAugmentors(List.of(new QuestionContextAugmentor()))
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
@@ -43,7 +43,7 @@ public abstract class AbstractIT {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractIT.class);
|
||||
|
||||
@Autowired
|
||||
protected ModelCall modelCall;
|
||||
protected ChatCaller modelCaller;
|
||||
|
||||
@Autowired
|
||||
protected StreamingChatClient streamingChatClient;
|
||||
@@ -85,12 +85,12 @@ public abstract class AbstractIT {
|
||||
}
|
||||
Message userMessage = userPromptTemplate.createMessage();
|
||||
Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
|
||||
String yesOrNo = modelCall.call(prompt).getResult().getOutput().getContent();
|
||||
String yesOrNo = modelCaller.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 = modelCall.call(prompt).getResult().getOutput().getContent();
|
||||
String reasonForFailure = modelCaller.call(prompt).getResult().getOutput().getContent();
|
||||
fail(reasonForFailure);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.ai.document.DefaultContentFormatter;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.transformer.ContentFormatTransformer;
|
||||
import org.springframework.ai.transformer.KeywordMetadataEnricher;
|
||||
@@ -163,18 +163,18 @@ public class MetadataTransformerIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OpenAiModelCall openAiChatClient(OpenAiApi openAiApi) {
|
||||
OpenAiModelCall openAiChatClient = new OpenAiModelCall(openAiApi);
|
||||
public OpenAiModelCaller openAiChatClient(OpenAiApi openAiApi) {
|
||||
OpenAiModelCaller openAiChatClient = new OpenAiModelCaller(openAiApi);
|
||||
return openAiChatClient;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KeywordMetadataEnricher keywordMetadata(OpenAiModelCall aiClient) {
|
||||
public KeywordMetadataEnricher keywordMetadata(OpenAiModelCaller aiClient) {
|
||||
return new KeywordMetadataEnricher(aiClient, 5);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SummaryMetadataEnricher summaryMetadata(OpenAiModelCall aiClient) {
|
||||
public SummaryMetadataEnricher summaryMetadata(OpenAiModelCaller aiClient) {
|
||||
return new SummaryMetadataEnricher(aiClient,
|
||||
List.of(SummaryType.PREVIOUS, SummaryType.CURRENT, SummaryType.NEXT));
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
import org.springframework.ai.model.function.FunctionCallback;
|
||||
import org.springframework.ai.model.function.FunctionCallingOptions;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCall.ChatModel;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCaller.ChatModel;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.google.cloud.vertexai.generativeai.PartMaker;
|
||||
import com.google.cloud.vertexai.generativeai.ResponseStream;
|
||||
import com.google.protobuf.Struct;
|
||||
import com.google.protobuf.util.JsonFormat;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -65,9 +65,9 @@ import java.util.stream.Collectors;
|
||||
* @author Grogdunn
|
||||
* @since 0.8.1
|
||||
*/
|
||||
public class VertexAiGeminiModelCall
|
||||
extends AbstractFunctionCallSupport<Content, VertexAiGeminiModelCall.GeminiRequest, GenerateContentResponse>
|
||||
implements ModelCall, StreamingChatClient, DisposableBean {
|
||||
public class VertexAiGeminiModelCaller
|
||||
extends AbstractFunctionCallSupport<Content, VertexAiGeminiModelCaller.GeminiRequest, GenerateContentResponse>
|
||||
implements ChatCaller, StreamingChatClient, DisposableBean {
|
||||
|
||||
private final static boolean IS_RUNTIME_CALL = true;
|
||||
|
||||
@@ -117,7 +117,7 @@ public class VertexAiGeminiModelCall
|
||||
|
||||
}
|
||||
|
||||
public VertexAiGeminiModelCall(VertexAI vertexAI) {
|
||||
public VertexAiGeminiModelCaller(VertexAI vertexAI) {
|
||||
this(vertexAI,
|
||||
VertexAiGeminiChatOptions.builder()
|
||||
.withModel(ChatModel.GEMINI_PRO_VISION)
|
||||
@@ -125,11 +125,11 @@ public class VertexAiGeminiModelCall
|
||||
.build());
|
||||
}
|
||||
|
||||
public VertexAiGeminiModelCall(VertexAI vertexAI, VertexAiGeminiChatOptions options) {
|
||||
public VertexAiGeminiModelCaller(VertexAI vertexAI, VertexAiGeminiChatOptions options) {
|
||||
this(vertexAI, options, null);
|
||||
}
|
||||
|
||||
public VertexAiGeminiModelCall(VertexAI vertexAI, VertexAiGeminiChatOptions options,
|
||||
public VertexAiGeminiModelCaller(VertexAI vertexAI, VertexAiGeminiChatOptions options,
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
|
||||
super(functionCallbackContext);
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.vertexai.gemini.aot;
|
||||
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCall;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCaller;
|
||||
import org.springframework.aot.hint.MemberCategory;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.RuntimeHintsRegistrar;
|
||||
@@ -34,7 +34,7 @@ public class VertexAiGeminiRuntimeHints implements RuntimeHintsRegistrar {
|
||||
@Override
|
||||
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
|
||||
var mcs = MemberCategory.values();
|
||||
for (var tr : findJsonAnnotatedClassesInPackage(VertexAiGeminiModelCall.class))
|
||||
for (var tr : findJsonAnnotatedClassesInPackage(VertexAiGeminiModelCaller.class))
|
||||
hints.reflection().registerType(tr, mcs);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,10 +53,10 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@SpringBootTest
|
||||
@EnabledIfEnvironmentVariable(named = "VERTEX_AI_GEMINI_PROJECT_ID", matches = ".*")
|
||||
@EnabledIfEnvironmentVariable(named = "VERTEX_AI_GEMINI_LOCATION", matches = ".*")
|
||||
class VertexAiGeminiModelCallIT {
|
||||
class VertexAiGeminiModelCallerIT {
|
||||
|
||||
@Autowired
|
||||
private VertexAiGeminiModelCall client;
|
||||
private VertexAiGeminiModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -231,10 +231,10 @@ class VertexAiGeminiModelCallIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public VertexAiGeminiModelCall vertexAiEmbedding(VertexAI vertexAi) {
|
||||
return new VertexAiGeminiModelCall(vertexAi,
|
||||
public VertexAiGeminiModelCaller vertexAiEmbedding(VertexAI vertexAi) {
|
||||
return new VertexAiGeminiModelCaller(vertexAi,
|
||||
VertexAiGeminiChatOptions.builder()
|
||||
.withModel(VertexAiGeminiModelCall.ChatModel.GEMINI_PRO_VISION)
|
||||
.withModel(VertexAiGeminiModelCaller.ChatModel.GEMINI_PRO_VISION)
|
||||
.build());
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCall;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCaller;
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
|
||||
@@ -38,7 +38,7 @@ class VertexAiGeminiRuntimeHintsTests {
|
||||
RuntimeHints runtimeHints = new RuntimeHints();
|
||||
VertexAiGeminiRuntimeHints vertexAiGeminiRuntimeHints = new VertexAiGeminiRuntimeHints();
|
||||
vertexAiGeminiRuntimeHints.registerHints(runtimeHints, null);
|
||||
Set<TypeReference> jsonAnnotatedClasses = findJsonAnnotatedClassesInPackage(VertexAiGeminiModelCall.class);
|
||||
Set<TypeReference> jsonAnnotatedClasses = findJsonAnnotatedClassesInPackage(VertexAiGeminiModelCaller.class);
|
||||
for (TypeReference jsonAnnotatedClass : jsonAnnotatedClasses) {
|
||||
assertThat(runtimeHints).matches(reflection().onType(jsonAnnotatedClass));
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ 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.vertexai.gemini.VertexAiGeminiModelCall;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCaller;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
@@ -55,7 +55,7 @@ public class VertexAiGeminiModelCallFunctionCallingIT {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Autowired
|
||||
private VertexAiGeminiModelCall vertexGeminiClient;
|
||||
private VertexAiGeminiModelCaller vertexGeminiClient;
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
@@ -98,7 +98,7 @@ public class VertexAiGeminiModelCallFunctionCallingIT {
|
||||
""";
|
||||
|
||||
var promptOptions = VertexAiGeminiChatOptions.builder()
|
||||
.withModel(VertexAiGeminiModelCall.ChatModel.GEMINI_PRO)
|
||||
.withModel(VertexAiGeminiModelCaller.ChatModel.GEMINI_PRO)
|
||||
// .withModel(VertexAiGeminiModelCall.ChatModel.GEMINI_PRO_1_5_PRO)
|
||||
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
|
||||
.withName("get_current_weather")
|
||||
@@ -127,7 +127,7 @@ public class VertexAiGeminiModelCallFunctionCallingIT {
|
||||
|
||||
var promptOptions = VertexAiGeminiChatOptions.builder()
|
||||
// .withModel(VertexAiGeminiModelCall.ChatModel.GEMINI_PRO_1_5_PRO)
|
||||
.withModel(VertexAiGeminiModelCall.ChatModel.GEMINI_PRO.getValue())
|
||||
.withModel(VertexAiGeminiModelCaller.ChatModel.GEMINI_PRO.getValue())
|
||||
.withFunctionCallbacks(List.of(
|
||||
FunctionCallbackWrapper.builder(new MockWeatherService())
|
||||
.withSchemaType(SchemaType.OPEN_API_SCHEMA)
|
||||
@@ -168,7 +168,7 @@ public class VertexAiGeminiModelCallFunctionCallingIT {
|
||||
List<Message> messages = new ArrayList<>(List.of(userMessage));
|
||||
|
||||
var promptOptions = VertexAiGeminiChatOptions.builder()
|
||||
.withModel(VertexAiGeminiModelCall.ChatModel.GEMINI_PRO)
|
||||
.withModel(VertexAiGeminiModelCaller.ChatModel.GEMINI_PRO)
|
||||
.withFunctionCallbacks(List.of(FunctionCallbackWrapper.builder(new MockWeatherService())
|
||||
.withSchemaType(SchemaType.OPEN_API_SCHEMA)
|
||||
.withName("getCurrentWeather")
|
||||
@@ -224,10 +224,10 @@ public class VertexAiGeminiModelCallFunctionCallingIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public VertexAiGeminiModelCall vertexAiEmbedding(VertexAI vertexAi) {
|
||||
return new VertexAiGeminiModelCall(vertexAi,
|
||||
public VertexAiGeminiModelCaller vertexAiEmbedding(VertexAI vertexAi) {
|
||||
return new VertexAiGeminiModelCaller(vertexAi,
|
||||
VertexAiGeminiChatOptions.builder()
|
||||
.withModel(VertexAiGeminiModelCall.ChatModel.GEMINI_PRO)
|
||||
.withModel(VertexAiGeminiModelCaller.ChatModel.GEMINI_PRO)
|
||||
.withTemperature(0.9f)
|
||||
.build());
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.vertexai.palm2;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.prompt.ChatOptions;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
@@ -35,18 +35,18 @@ import org.springframework.util.CollectionUtils;
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class VertexAiPaLm2ModelCall implements ModelCall {
|
||||
public class VertexAiPaLm2ModelCaller implements ChatCaller {
|
||||
|
||||
private final VertexAiPaLm2Api vertexAiApi;
|
||||
|
||||
private final VertexAiPaLm2ChatOptions defaultOptions;
|
||||
|
||||
public VertexAiPaLm2ModelCall(VertexAiPaLm2Api vertexAiApi) {
|
||||
public VertexAiPaLm2ModelCaller(VertexAiPaLm2Api vertexAiApi) {
|
||||
this(vertexAiApi,
|
||||
VertexAiPaLm2ChatOptions.builder().withTemperature(0.7f).withCandidateCount(1).withTopK(20).build());
|
||||
}
|
||||
|
||||
public VertexAiPaLm2ModelCall(VertexAiPaLm2Api vertexAiApi, VertexAiPaLm2ChatOptions defaultOptions) {
|
||||
public VertexAiPaLm2ModelCaller(VertexAiPaLm2Api vertexAiApi, VertexAiPaLm2ChatOptions defaultOptions) {
|
||||
Assert.notNull(defaultOptions, "Default options must not be null!");
|
||||
Assert.notNull(vertexAiApi, "VertexAiPaLm2Api must not be null!");
|
||||
|
||||
@@ -48,7 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class VertexAiPaLm2ChatGenerationClientIT {
|
||||
|
||||
@Autowired
|
||||
private VertexAiPaLm2ModelCall client;
|
||||
private VertexAiPaLm2ModelCaller client;
|
||||
|
||||
@Value("classpath:/prompts/system-message.st")
|
||||
private Resource systemResource;
|
||||
@@ -136,8 +136,8 @@ class VertexAiPaLm2ChatGenerationClientIT {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public VertexAiPaLm2ModelCall vertexAiEmbedding(VertexAiPaLm2Api vertexAiApi) {
|
||||
return new VertexAiPaLm2ModelCall(vertexAiApi);
|
||||
public VertexAiPaLm2ModelCaller vertexAiEmbedding(VertexAiPaLm2Api vertexAiApi) {
|
||||
return new VertexAiPaLm2ModelCaller(vertexAiApi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*/
|
||||
public class VertexAiPaLm2ChatRequestTests {
|
||||
|
||||
VertexAiPaLm2ModelCall client = new VertexAiPaLm2ModelCall(new VertexAiPaLm2Api("bla"));
|
||||
VertexAiPaLm2ModelCaller client = new VertexAiPaLm2ModelCaller(new VertexAiPaLm2Api("bla"));
|
||||
|
||||
@Test
|
||||
public void createRequestWithDefaultOptions() {
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.watsonx;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
@@ -35,7 +35,7 @@ import org.springframework.ai.watsonx.utils.MessageToPromptConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ModelCall} implementation for {@literal watsonx.ai}.
|
||||
* {@link ChatCaller} implementation for {@literal watsonx.ai}.
|
||||
*
|
||||
* watsonx.ai allows developers to use large language models within a SaaS service. It
|
||||
* supports multiple open-source models as well as IBM created models
|
||||
@@ -48,13 +48,13 @@ import org.springframework.util.Assert;
|
||||
* @author Christian Tzolov
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class WatsonxAiModelCall implements ModelCall, StreamingChatClient {
|
||||
public class WatsonxAiModelCaller implements ChatCaller, StreamingChatClient {
|
||||
|
||||
private final WatsonxAiApi watsonxAiApi;
|
||||
|
||||
private final WatsonxAiChatOptions defaultOptions;
|
||||
|
||||
public WatsonxAiModelCall(WatsonxAiApi watsonxAiApi) {
|
||||
public WatsonxAiModelCaller(WatsonxAiApi watsonxAiApi) {
|
||||
this(watsonxAiApi,
|
||||
WatsonxAiChatOptions.builder()
|
||||
.withTemperature(0.7f)
|
||||
@@ -68,7 +68,7 @@ public class WatsonxAiModelCall implements ModelCall, StreamingChatClient {
|
||||
.build());
|
||||
}
|
||||
|
||||
public WatsonxAiModelCall(WatsonxAiApi watsonxAiApi, WatsonxAiChatOptions defaultOptions) {
|
||||
public WatsonxAiModelCaller(WatsonxAiApi watsonxAiApi, WatsonxAiChatOptions defaultOptions) {
|
||||
Assert.notNull(watsonxAiApi, "watsonxAiApi cannot be null");
|
||||
Assert.notNull(defaultOptions, "defaultOptions cannot be null");
|
||||
this.watsonxAiApi = watsonxAiApi;
|
||||
@@ -46,9 +46,9 @@ import static org.mockito.Mockito.when;
|
||||
* @author Pablo Sanchidrian Herrera
|
||||
* @author John Jairo Moreno Rojas
|
||||
*/
|
||||
public class WatsonxAiModelCallTest {
|
||||
public class WatsonxAiModelCallerTest {
|
||||
|
||||
WatsonxAiModelCall chatClient = new WatsonxAiModelCall(mock(WatsonxAiApi.class));
|
||||
WatsonxAiModelCaller chatClient = new WatsonxAiModelCaller(mock(WatsonxAiApi.class));
|
||||
|
||||
@Test
|
||||
public void testCreateRequestWithNoModelId() {
|
||||
@@ -157,7 +157,7 @@ public class WatsonxAiModelCallTest {
|
||||
@Test
|
||||
public void testCallMethod() {
|
||||
WatsonxAiApi mockChatApi = mock(WatsonxAiApi.class);
|
||||
WatsonxAiModelCall client = new WatsonxAiModelCall(mockChatApi);
|
||||
WatsonxAiModelCaller client = new WatsonxAiModelCaller(mockChatApi);
|
||||
|
||||
Prompt prompt = new Prompt(List.of(new SystemMessage("Your prompt here")),
|
||||
WatsonxAiChatOptions.builder().withModel("google/flan-ul2").build());
|
||||
@@ -186,7 +186,7 @@ public class WatsonxAiModelCallTest {
|
||||
@Test
|
||||
public void testStreamMethod() {
|
||||
WatsonxAiApi mockChatApi = mock(WatsonxAiApi.class);
|
||||
WatsonxAiModelCall client = new WatsonxAiModelCall(mockChatApi);
|
||||
WatsonxAiModelCaller client = new WatsonxAiModelCaller(mockChatApi);
|
||||
|
||||
Prompt prompt = new Prompt(List.of(new SystemMessage("Your prompt here")),
|
||||
WatsonxAiChatOptions.builder().withModel("google/flan-ul2").build());
|
||||
@@ -24,7 +24,7 @@ import org.springframework.ai.chat.messages.UserMessage;
|
||||
import org.springframework.ai.model.ModelClient;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ModelCall extends ModelClient<Prompt, ChatResponse> {
|
||||
public interface ChatCaller extends ModelClient<Prompt, ChatResponse> {
|
||||
|
||||
default String call(String message) {
|
||||
Prompt prompt = new Prompt(new UserMessage(message));
|
||||
@@ -25,10 +25,12 @@ import org.springframework.ai.chat.prompt.PromptTemplate;
|
||||
import org.springframework.ai.converter.BeanOutputConverter;
|
||||
import org.springframework.ai.model.function.FunctionCallback;
|
||||
import org.springframework.ai.model.function.FunctionCallbackWrapper;
|
||||
import org.springframework.ai.model.function.FunctionCallingOptions;
|
||||
import org.springframework.ai.model.function.FunctionCallingOptionsBuilder;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -49,8 +51,8 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public interface ChatClient {
|
||||
|
||||
static ChatClientBuilder builder(ModelCall connector) {
|
||||
return new ChatClientBuilder(connector);
|
||||
static ChatClientBuilder builder(ChatCaller caller) {
|
||||
return new ChatClientBuilder(caller);
|
||||
}
|
||||
|
||||
ChatResponse call(Prompt prompt);
|
||||
@@ -165,7 +167,7 @@ public interface ChatClient {
|
||||
|
||||
class ChatClientRequest {
|
||||
|
||||
private final ModelCall connector;
|
||||
private final ChatCaller caller;
|
||||
|
||||
private String userText = "";
|
||||
|
||||
@@ -173,6 +175,8 @@ public interface ChatClient {
|
||||
|
||||
private ChatOptions chatOptions;
|
||||
|
||||
private FunctionCallingOptions functionCallingOptions;
|
||||
|
||||
private final List<Media> media = new ArrayList<>();
|
||||
|
||||
private final List<String> functionNames = new ArrayList<>();
|
||||
@@ -187,15 +191,15 @@ public interface ChatClient {
|
||||
|
||||
/* copy constructor */
|
||||
ChatClientRequest(ChatClientRequest ccr) {
|
||||
this(ccr.connector, ccr.userText, ccr.systemText, ccr.functionCallbacks, ccr.functionNames, ccr.media,
|
||||
this(ccr.caller, ccr.userText, ccr.systemText, ccr.functionCallbacks, ccr.functionNames, ccr.media,
|
||||
ccr.chatOptions);
|
||||
}
|
||||
|
||||
public ChatClientRequest(ModelCall connector, String userText, String systemText,
|
||||
public ChatClientRequest(ChatCaller caller, String userText, String systemText,
|
||||
List<FunctionCallback> functionCallbacks, List<String> functionNames, List<Media> media,
|
||||
ChatOptions chatOptions) {
|
||||
|
||||
this.connector = connector;
|
||||
this.caller = caller;
|
||||
this.chatOptions = chatOptions;
|
||||
|
||||
this.userText = userText;
|
||||
@@ -258,9 +262,9 @@ public interface ChatClient {
|
||||
|
||||
private final ChatClientRequest request;
|
||||
|
||||
private final ModelCall modelCall;
|
||||
private final ChatCaller modelCall;
|
||||
|
||||
public ChatResponseSpec(ModelCall modelCall, ChatClientRequest request) {
|
||||
public ChatResponseSpec(ChatCaller modelCall, ChatClientRequest request) {
|
||||
this.modelCall = modelCall;
|
||||
this.request = request;
|
||||
}
|
||||
@@ -272,8 +276,8 @@ public interface ChatClient {
|
||||
|
||||
private <T> T doSingleWithBeanOutputConverter(BeanOutputConverter<T> boc) {
|
||||
var processedUserText = this.request.userText + System.lineSeparator() + System.lineSeparator()
|
||||
+ boc.getFormat();
|
||||
var chatResponse = doGetChatResponse(processedUserText);
|
||||
+ "{format}";
|
||||
var chatResponse = doGetChatResponse(processedUserText, boc.getFormat());
|
||||
var stringResponse = chatResponse.getResult().getOutput().getContent();
|
||||
return boc.convert(stringResponse);
|
||||
}
|
||||
@@ -285,6 +289,15 @@ public interface ChatClient {
|
||||
}
|
||||
|
||||
private ChatResponse doGetChatResponse(String processedUserText) {
|
||||
return this.doGetChatResponse(processedUserText, "");
|
||||
}
|
||||
|
||||
private ChatResponse doGetChatResponse(String processedUserText, String formatParam) {
|
||||
Map<String, Object> userParams = new HashMap<>(this.request.userParams);
|
||||
if (StringUtils.hasText(formatParam)) {
|
||||
userParams.put("format", formatParam);
|
||||
}
|
||||
|
||||
var messages = new ArrayList<Message>();
|
||||
var textsAreValid = (StringUtils.hasText(processedUserText)
|
||||
|| StringUtils.hasText(this.request.systemText));
|
||||
@@ -292,18 +305,28 @@ public interface ChatClient {
|
||||
Assert.state(!(messagesAreValid && textsAreValid), "you must specify either " + Message.class.getName()
|
||||
+ " instances or user/system texts, but not both");
|
||||
if (textsAreValid) {
|
||||
var userMessage = new UserMessage(
|
||||
new PromptTemplate(processedUserText, this.request.userParams).render(),
|
||||
this.request.media);
|
||||
var systemMessage = new SystemMessage(
|
||||
new PromptTemplate(this.request.systemText, this.request.systemParams).render());
|
||||
messages.add(systemMessage);
|
||||
UserMessage userMessage = null;
|
||||
if (!CollectionUtils.isEmpty(userParams)) {
|
||||
userMessage = new UserMessage(new PromptTemplate(processedUserText, userParams).render(),
|
||||
this.request.media);
|
||||
}
|
||||
else {
|
||||
userMessage = new UserMessage(processedUserText, this.request.media);
|
||||
}
|
||||
if (StringUtils.hasText(this.request.systemText) || !this.request.systemParams.isEmpty()) {
|
||||
var systemMessage = new SystemMessage(
|
||||
new PromptTemplate(this.request.systemText, this.request.systemParams).render());
|
||||
messages.add(systemMessage);
|
||||
}
|
||||
messages.add(userMessage);
|
||||
}
|
||||
else {
|
||||
messages.addAll(this.request.messages);
|
||||
}
|
||||
if (this.request.chatOptions instanceof FunctionCallingOptionsBuilder.PortableFunctionCallingOptions functionCallingOptions) {
|
||||
if (this.request.chatOptions instanceof FunctionCallingOptions functionCallingOptions) {
|
||||
// if (this.request.chatOptions instanceof
|
||||
// FunctionCallingOptionsBuilder.PortableFunctionCallingOptions
|
||||
// functionCallingOptions) {
|
||||
if (!this.request.functionNames.isEmpty()) {
|
||||
functionCallingOptions.setFunctions(new HashSet<>(this.request.functionNames));
|
||||
}
|
||||
@@ -336,7 +359,7 @@ public interface ChatClient {
|
||||
}
|
||||
|
||||
public ChatResponseSpec chat() {
|
||||
return new ChatResponseSpec(this.connector, this);
|
||||
return new ChatResponseSpec(this.caller, this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -345,10 +368,10 @@ public interface ChatClient {
|
||||
|
||||
private final ChatClientRequest defaultRequest;
|
||||
|
||||
private final ModelCall modelCall;
|
||||
private final ChatCaller modelCall;
|
||||
|
||||
ChatClientBuilder(ModelCall modelCall) {
|
||||
Assert.notNull(modelCall, "the " + ModelCall.class.getName() + " must be non-null");
|
||||
ChatClientBuilder(ChatCaller modelCall) {
|
||||
Assert.notNull(modelCall, "the " + ChatCaller.class.getName() + " must be non-null");
|
||||
this.modelCall = modelCall;
|
||||
this.defaultRequest = new ChatClientRequest(modelCall, "", "", List.of(), List.of(), List.of(), null);
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ import org.springframework.ai.chat.prompt.Prompt;
|
||||
*/
|
||||
class DefaultChatClient implements ChatClient {
|
||||
|
||||
private final ModelCall modelCall;
|
||||
private final ChatCaller modelCall;
|
||||
|
||||
private final ChatClientRequest defaultChatClientRequest;
|
||||
|
||||
public DefaultChatClient(ModelCall modelCall, ChatClientRequest defaultChatClientRequest) {
|
||||
public DefaultChatClient(ChatCaller modelCall, ChatClientRequest defaultChatClientRequest) {
|
||||
this.modelCall = modelCall;
|
||||
this.defaultChatClientRequest = defaultChatClientRequest;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.chat.service;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.prompt.transformer.ChatServiceContext;
|
||||
import org.springframework.ai.chat.prompt.transformer.PromptTransformer;
|
||||
@@ -35,7 +35,7 @@ import java.util.Objects;
|
||||
*/
|
||||
public class PromptTransformingChatService implements ChatService {
|
||||
|
||||
private ModelCall modelCall;
|
||||
private ChatCaller modelCall;
|
||||
|
||||
private List<PromptTransformer> retrievers;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class PromptTransformingChatService implements ChatService {
|
||||
|
||||
private List<ChatServiceListener> chatServiceListeners;
|
||||
|
||||
public PromptTransformingChatService(ModelCall modelCall, List<PromptTransformer> retrievers,
|
||||
public PromptTransformingChatService(ChatCaller modelCall, List<PromptTransformer> retrievers,
|
||||
List<PromptTransformer> documentPostProcessors, List<PromptTransformer> augmentors,
|
||||
List<ChatServiceListener> chatServiceListeners) {
|
||||
Objects.requireNonNull(modelCall, "modelCall must not be null");
|
||||
@@ -56,7 +56,7 @@ public class PromptTransformingChatService implements ChatService {
|
||||
this.chatServiceListeners = chatServiceListeners;
|
||||
}
|
||||
|
||||
public static Builder builder(ModelCall modelCall) {
|
||||
public static Builder builder(ChatCaller modelCall) {
|
||||
return new Builder().withChatClient(modelCall);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class PromptTransformingChatService implements ChatService {
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private ModelCall modelCall;
|
||||
private ChatCaller modelCall;
|
||||
|
||||
private List<PromptTransformer> retrievers = new ArrayList<>();
|
||||
|
||||
@@ -108,7 +108,7 @@ public class PromptTransformingChatService implements ChatService {
|
||||
|
||||
private List<ChatServiceListener> chatServiceListeners = new ArrayList<>();
|
||||
|
||||
public Builder withChatClient(ModelCall modelCall) {
|
||||
public Builder withChatClient(ChatCaller modelCall) {
|
||||
this.modelCall = modelCall;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.springframework.ai.evaluation;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.messages.Message;
|
||||
import org.springframework.ai.chat.messages.MessageType;
|
||||
@@ -31,13 +31,13 @@ public class RelevancyEvaluator implements Evaluator {
|
||||
|
||||
private final ChatOptions chatOptions;
|
||||
|
||||
private ModelCall modelCall;
|
||||
private ChatCaller modelCall;
|
||||
|
||||
public RelevancyEvaluator(ModelCall modelCall) {
|
||||
public RelevancyEvaluator(ChatCaller modelCall) {
|
||||
this(modelCall, ChatOptionsBuilder.builder().build());
|
||||
}
|
||||
|
||||
public RelevancyEvaluator(ModelCall modelCall, ChatOptions chatOptions) {
|
||||
public RelevancyEvaluator(ChatCaller modelCall, ChatOptions chatOptions) {
|
||||
this.modelCall = modelCall;
|
||||
this.chatOptions = chatOptions;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.transformer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.document.DocumentTransformer;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
@@ -43,14 +43,14 @@ public class KeywordMetadataEnricher implements DocumentTransformer {
|
||||
/**
|
||||
* Model predictor
|
||||
*/
|
||||
private final ModelCall modelCall;
|
||||
private final ChatCaller modelCall;
|
||||
|
||||
/**
|
||||
* The number of keywords to extract.
|
||||
*/
|
||||
private final int keywordCount;
|
||||
|
||||
public KeywordMetadataEnricher(ModelCall modelCall, int keywordCount) {
|
||||
public KeywordMetadataEnricher(ChatCaller modelCall, int keywordCount) {
|
||||
Assert.notNull(modelCall, "ModelCall must not be null");
|
||||
Assert.isTrue(keywordCount >= 1, "Document count must be >= 1");
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.document.Document;
|
||||
import org.springframework.ai.document.DocumentTransformer;
|
||||
import org.springframework.ai.document.MetadataMode;
|
||||
@@ -62,7 +62,7 @@ public class SummaryMetadataEnricher implements DocumentTransformer {
|
||||
/**
|
||||
* AI client.
|
||||
*/
|
||||
private final ModelCall modelCall;
|
||||
private final ChatCaller modelCall;
|
||||
|
||||
/**
|
||||
* Number of documents from front to use for title extraction.
|
||||
@@ -76,11 +76,11 @@ public class SummaryMetadataEnricher implements DocumentTransformer {
|
||||
*/
|
||||
private final String summaryTemplate;
|
||||
|
||||
public SummaryMetadataEnricher(ModelCall modelCall, List<SummaryType> summaryTypes) {
|
||||
public SummaryMetadataEnricher(ChatCaller modelCall, List<SummaryType> summaryTypes) {
|
||||
this(modelCall, summaryTypes, DEFAULT_SUMMARY_EXTRACT_TEMPLATE, MetadataMode.ALL);
|
||||
}
|
||||
|
||||
public SummaryMetadataEnricher(ModelCall modelCall, List<SummaryType> summaryTypes, String summaryTemplate,
|
||||
public SummaryMetadataEnricher(ChatCaller modelCall, List<SummaryType> summaryTypes, String summaryTemplate,
|
||||
MetadataMode metadataMode) {
|
||||
Assert.notNull(modelCall, "ModelCall must not be null");
|
||||
Assert.hasText(summaryTemplate, "Summary template must not be empty");
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2024-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.ai.chat;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
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.core.io.DefaultResourceLoader;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class Main {
|
||||
|
||||
@Mock
|
||||
ChatCaller modelCaller;
|
||||
|
||||
@Test
|
||||
public void test() throws MalformedURLException {
|
||||
|
||||
var url = new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png");
|
||||
|
||||
ChatClient client = ChatClient.builder(modelCaller)
|
||||
.defaultSystem(s -> s.text("System text {music}"))
|
||||
.defaultUser(u -> u.param("music", "Jazz"))
|
||||
.defaultFunctions("function1")
|
||||
.build();
|
||||
|
||||
String response = client.call()
|
||||
.user(u -> u.text("User text {music}").param("music", "Rock").media(MimeTypeUtils.IMAGE_PNG, url))
|
||||
.chat()
|
||||
.single(String.class);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,7 +34,7 @@ import org.springframework.ai.chat.messages.AssistantMessage;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
|
||||
/**
|
||||
* Unit Tests for {@link ModelCall}.
|
||||
* Unit Tests for {@link ChatCaller}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 0.2.0
|
||||
@@ -47,7 +47,7 @@ class ModelCallTests {
|
||||
String userMessage = "Zero Wing";
|
||||
String responseMessage = "All your bases are belong to us";
|
||||
|
||||
ModelCall mockClient = Mockito.mock(ModelCall.class);
|
||||
ChatCaller mockClient = Mockito.mock(ChatCaller.class);
|
||||
|
||||
AssistantMessage mockAssistantMessage = Mockito.mock(AssistantMessage.class);
|
||||
when(mockAssistantMessage.getContent()).thenReturn(responseMessage);
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.Generation;
|
||||
import org.springframework.ai.chat.StreamingChatClient;
|
||||
@@ -48,7 +48,7 @@ import static org.mockito.Mockito.when;
|
||||
public class ChatMemoryTests {
|
||||
|
||||
@Mock
|
||||
ModelCall modelCall;
|
||||
ChatCaller modelCall;
|
||||
|
||||
@Mock
|
||||
StreamingChatClient streamingChatClient;
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.ai.autoconfigure.anthropic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ai.anthropic.AnthropicModelCall;
|
||||
import org.springframework.ai.anthropic.AnthropicModelCaller;
|
||||
import org.springframework.ai.anthropic.api.AnthropicApi;
|
||||
import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
|
||||
import org.springframework.ai.model.function.FunctionCallback;
|
||||
@@ -57,7 +57,7 @@ public class AnthropicAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AnthropicModelCall anthropicChatClient(AnthropicApi anthropicApi, AnthropicChatProperties chatProperties,
|
||||
public AnthropicModelCaller anthropicChatClient(AnthropicApi anthropicApi, AnthropicChatProperties chatProperties,
|
||||
RetryTemplate retryTemplate, FunctionCallbackContext functionCallbackContext,
|
||||
List<FunctionCallback> toolFunctionCallbacks) {
|
||||
|
||||
@@ -65,7 +65,7 @@ public class AnthropicAutoConfiguration {
|
||||
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
|
||||
}
|
||||
|
||||
return new AnthropicModelCall(anthropicApi, chatProperties.getOptions(), retryTemplate,
|
||||
return new AnthropicModelCaller(anthropicApi, chatProperties.getOptions(), retryTemplate,
|
||||
functionCallbackContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.autoconfigure.anthropic;
|
||||
|
||||
import org.springframework.ai.anthropic.AnthropicModelCall;
|
||||
import org.springframework.ai.anthropic.AnthropicModelCaller;
|
||||
import org.springframework.ai.anthropic.AnthropicChatOptions;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
@@ -43,9 +43,9 @@ public class AnthropicChatProperties {
|
||||
*/
|
||||
@NestedConfigurationProperty
|
||||
private AnthropicChatOptions options = AnthropicChatOptions.builder()
|
||||
.withModel(AnthropicModelCall.DEFAULT_MODEL_NAME)
|
||||
.withMaxTokens(AnthropicModelCall.DEFAULT_MAX_TOKENS)
|
||||
.withTemperature(AnthropicModelCall.DEFAULT_TEMPERATURE)
|
||||
.withModel(AnthropicModelCaller.DEFAULT_MODEL_NAME)
|
||||
.withMaxTokens(AnthropicModelCaller.DEFAULT_MAX_TOKENS)
|
||||
.withTemperature(AnthropicModelCaller.DEFAULT_TEMPERATURE)
|
||||
.build();
|
||||
|
||||
public AnthropicChatOptions getOptions() {
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.AzureKeyCredential;
|
||||
import com.azure.core.util.ClientOptions;
|
||||
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCall;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCaller;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingClient;
|
||||
import org.springframework.ai.model.function.FunctionCallback;
|
||||
import org.springframework.ai.model.function.FunctionCallbackContext;
|
||||
@@ -37,7 +37,7 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ OpenAIClientBuilder.class, AzureOpenAiModelCall.class })
|
||||
@ConditionalOnClass({ OpenAIClientBuilder.class, AzureOpenAiModelCaller.class })
|
||||
@EnableConfigurationProperties({ AzureOpenAiChatProperties.class, AzureOpenAiEmbeddingProperties.class,
|
||||
AzureOpenAiConnectionProperties.class })
|
||||
public class AzureOpenAiAutoConfiguration {
|
||||
@@ -58,7 +58,7 @@ public class AzureOpenAiAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = AzureOpenAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public AzureOpenAiModelCall azureOpenAiChatClient(OpenAIClient openAIClient,
|
||||
public AzureOpenAiModelCaller azureOpenAiChatClient(OpenAIClient openAIClient,
|
||||
AzureOpenAiChatProperties chatProperties, List<FunctionCallback> toolFunctionCallbacks,
|
||||
FunctionCallbackContext functionCallbackContext) {
|
||||
|
||||
@@ -66,8 +66,8 @@ public class AzureOpenAiAutoConfiguration {
|
||||
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
|
||||
}
|
||||
|
||||
AzureOpenAiModelCall azureOpenAiChatClient = new AzureOpenAiModelCall(openAIClient, chatProperties.getOptions(),
|
||||
functionCallbackContext);
|
||||
AzureOpenAiModelCaller azureOpenAiChatClient = new AzureOpenAiModelCaller(openAIClient,
|
||||
chatProperties.getOptions(), functionCallbackContext);
|
||||
|
||||
return azureOpenAiChatClient;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.autoconfigure.bedrock.anthropic;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
|
||||
import org.springframework.ai.bedrock.anthropic.BedrockAnthropicModelCall;
|
||||
import org.springframework.ai.bedrock.anthropic.BedrockAnthropicModelCaller;
|
||||
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -59,9 +59,9 @@ public class BedrockAnthropicChatAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AnthropicChatBedrockApi.class)
|
||||
public BedrockAnthropicModelCall anthropicChatClient(AnthropicChatBedrockApi anthropicApi,
|
||||
public BedrockAnthropicModelCaller anthropicChatClient(AnthropicChatBedrockApi anthropicApi,
|
||||
BedrockAnthropicChatProperties properties) {
|
||||
return new BedrockAnthropicModelCall(anthropicApi, properties.getOptions());
|
||||
return new BedrockAnthropicModelCaller(anthropicApi, properties.getOptions());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.autoconfigure.bedrock.anthropic3;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
|
||||
import org.springframework.ai.bedrock.anthropic3.BedrockAnthropic3ModelCall;
|
||||
import org.springframework.ai.bedrock.anthropic3.BedrockAnthropic3ModelCaller;
|
||||
import org.springframework.ai.bedrock.anthropic3.api.Anthropic3ChatBedrockApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -59,9 +59,9 @@ public class BedrockAnthropic3ChatAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(Anthropic3ChatBedrockApi.class)
|
||||
public BedrockAnthropic3ModelCall anthropic3ChatClient(Anthropic3ChatBedrockApi anthropicApi,
|
||||
public BedrockAnthropic3ModelCaller anthropic3ChatClient(Anthropic3ChatBedrockApi anthropicApi,
|
||||
BedrockAnthropic3ChatProperties properties) {
|
||||
return new BedrockAnthropic3ModelCall(anthropicApi, properties.getOptions());
|
||||
return new BedrockAnthropic3ModelCaller(anthropicApi, properties.getOptions());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.autoconfigure.bedrock.cohere;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
|
||||
import org.springframework.ai.bedrock.cohere.BedrockCohereModelCall;
|
||||
import org.springframework.ai.bedrock.cohere.BedrockCohereModelCaller;
|
||||
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -57,10 +57,10 @@ public class BedrockCohereChatAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(CohereChatBedrockApi.class)
|
||||
public BedrockCohereModelCall cohereChatClient(CohereChatBedrockApi cohereChatApi,
|
||||
public BedrockCohereModelCaller cohereChatClient(CohereChatBedrockApi cohereChatApi,
|
||||
BedrockCohereChatProperties properties) {
|
||||
|
||||
return new BedrockCohereModelCall(cohereChatApi, properties.getOptions());
|
||||
return new BedrockCohereModelCaller(cohereChatApi, properties.getOptions());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.springframework.ai.autoconfigure.bedrock.jurrasic2;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
|
||||
import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ModelCall;
|
||||
import org.springframework.ai.bedrock.jurassic2.BedrockAi21Jurassic2ModelCaller;
|
||||
import org.springframework.ai.bedrock.jurassic2.api.Ai21Jurassic2ChatBedrockApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -59,10 +59,10 @@ public class BedrockAi21Jurassic2ChatAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(Ai21Jurassic2ChatBedrockApi.class)
|
||||
public BedrockAi21Jurassic2ModelCall jurassic2ChatClient(Ai21Jurassic2ChatBedrockApi ai21Jurassic2ChatBedrockApi,
|
||||
public BedrockAi21Jurassic2ModelCaller jurassic2ChatClient(Ai21Jurassic2ChatBedrockApi ai21Jurassic2ChatBedrockApi,
|
||||
BedrockAi21Jurassic2ChatProperties properties) {
|
||||
|
||||
return BedrockAi21Jurassic2ModelCall.builder(ai21Jurassic2ChatBedrockApi)
|
||||
return BedrockAi21Jurassic2ModelCaller.builder(ai21Jurassic2ChatBedrockApi)
|
||||
.withOptions(properties.getOptions())
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.ai.autoconfigure.bedrock.llama;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.ai.bedrock.llama.BedrockLlamaModelCall;
|
||||
import org.springframework.ai.bedrock.llama.BedrockLlamaModelCaller;
|
||||
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
|
||||
import software.amazon.awssdk.regions.providers.AwsRegionProvider;
|
||||
|
||||
@@ -59,9 +59,10 @@ public class BedrockLlamaChatAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(LlamaChatBedrockApi.class)
|
||||
public BedrockLlamaModelCall llamaChatClient(LlamaChatBedrockApi llamaApi, BedrockLlamaChatProperties properties) {
|
||||
public BedrockLlamaModelCaller llamaChatClient(LlamaChatBedrockApi llamaApi,
|
||||
BedrockLlamaChatProperties properties) {
|
||||
|
||||
return new BedrockLlamaModelCall(llamaApi, properties.getOptions());
|
||||
return new BedrockLlamaModelCaller(llamaApi, properties.getOptions());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.autoconfigure.bedrock.titan;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionConfiguration;
|
||||
import org.springframework.ai.autoconfigure.bedrock.BedrockAwsConnectionProperties;
|
||||
import org.springframework.ai.bedrock.titan.BedrockTitanModelCall;
|
||||
import org.springframework.ai.bedrock.titan.BedrockTitanModelCaller;
|
||||
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -57,10 +57,10 @@ public class BedrockTitanChatAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(TitanChatBedrockApi.class)
|
||||
public BedrockTitanModelCall titanChatClient(TitanChatBedrockApi titanChatApi,
|
||||
public BedrockTitanModelCaller titanChatClient(TitanChatBedrockApi titanChatApi,
|
||||
BedrockTitanChatProperties properties) {
|
||||
|
||||
return new BedrockTitanModelCall(titanChatApi, properties.getOptions());
|
||||
return new BedrockTitanModelCaller(titanChatApi, properties.getOptions());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.autoconfigure.huggingface;
|
||||
|
||||
import org.springframework.ai.huggingface.HuggingfaceModelCall;
|
||||
import org.springframework.ai.huggingface.HuggingfaceModelCaller;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -24,7 +24,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(HuggingfaceModelCall.class)
|
||||
@ConditionalOnClass(HuggingfaceModelCaller.class)
|
||||
@EnableConfigurationProperties(HuggingfaceChatProperties.class)
|
||||
public class HuggingfaceChatAutoConfiguration {
|
||||
|
||||
@@ -32,8 +32,8 @@ public class HuggingfaceChatAutoConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = HuggingfaceChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public HuggingfaceModelCall huggingfaceChatClient(HuggingfaceChatProperties huggingfaceChatProperties) {
|
||||
return new HuggingfaceModelCall(huggingfaceChatProperties.getApiKey(), huggingfaceChatProperties.getUrl());
|
||||
public HuggingfaceModelCaller huggingfaceChatClient(HuggingfaceChatProperties huggingfaceChatProperties) {
|
||||
return new HuggingfaceModelCaller(huggingfaceChatProperties.getApiKey(), huggingfaceChatProperties.getUrl());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ai.autoconfigure.mistralai;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
|
||||
import org.springframework.ai.mistralai.MistralAiModelCall;
|
||||
import org.springframework.ai.mistralai.MistralAiModelCaller;
|
||||
import org.springframework.ai.mistralai.MistralAiEmbeddingClient;
|
||||
import org.springframework.ai.mistralai.api.MistralAiApi;
|
||||
import org.springframework.ai.model.function.FunctionCallback;
|
||||
@@ -69,7 +69,7 @@ public class MistralAiAutoConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = MistralAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public MistralAiModelCall mistralAiChatClient(MistralAiCommonProperties commonProperties,
|
||||
public MistralAiModelCaller mistralAiChatClient(MistralAiCommonProperties commonProperties,
|
||||
MistralAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
|
||||
@@ -81,7 +81,7 @@ public class MistralAiAutoConfiguration {
|
||||
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
|
||||
}
|
||||
|
||||
return new MistralAiModelCall(mistralAiApi, chatProperties.getOptions(), functionCallbackContext,
|
||||
return new MistralAiModelCaller(mistralAiApi, chatProperties.getOptions(), functionCallbackContext,
|
||||
retryTemplate);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.autoconfigure.ollama;
|
||||
|
||||
import org.springframework.ai.ollama.OllamaModelCall;
|
||||
import org.springframework.ai.ollama.OllamaModelCaller;
|
||||
import org.springframework.ai.ollama.OllamaEmbeddingClient;
|
||||
import org.springframework.ai.ollama.api.OllamaApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
@@ -56,8 +56,8 @@ public class OllamaAutoConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = OllamaChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public OllamaModelCall ollamaChatClient(OllamaApi ollamaApi, OllamaChatProperties properties) {
|
||||
return new OllamaModelCall(ollamaApi, properties.getOptions());
|
||||
public OllamaModelCaller ollamaChatClient(OllamaApi ollamaApi, OllamaChatProperties properties) {
|
||||
return new OllamaModelCaller(ollamaApi, properties.getOptions());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration
|
||||
import org.springframework.ai.model.function.FunctionCallback;
|
||||
import org.springframework.ai.model.function.FunctionCallbackContext;
|
||||
import org.springframework.ai.openai.*;
|
||||
import org.springframework.ai.openai.OpenAiModelCall;
|
||||
import org.springframework.ai.openai.OpenAiModelCaller;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.ai.openai.api.OpenAiAudioApi;
|
||||
import org.springframework.ai.openai.api.OpenAiImageApi;
|
||||
@@ -54,7 +54,7 @@ public class OpenAiAutoConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = OpenAiChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public OpenAiModelCall openAiChatClient(OpenAiConnectionProperties commonProperties,
|
||||
public OpenAiModelCaller openAiChatClient(OpenAiConnectionProperties commonProperties,
|
||||
OpenAiChatProperties chatProperties, RestClient.Builder restClientBuilder,
|
||||
List<FunctionCallback> toolFunctionCallbacks, FunctionCallbackContext functionCallbackContext,
|
||||
RetryTemplate retryTemplate, ResponseErrorHandler responseErrorHandler) {
|
||||
@@ -66,7 +66,7 @@ public class OpenAiAutoConfiguration {
|
||||
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
|
||||
}
|
||||
|
||||
return new OpenAiModelCall(openAiApi, chatProperties.getOptions(), functionCallbackContext, retryTemplate);
|
||||
return new OpenAiModelCaller(openAiApi, chatProperties.getOptions(), functionCallbackContext, retryTemplate);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.google.cloud.vertexai.VertexAI;
|
||||
import org.springframework.ai.model.function.FunctionCallback;
|
||||
import org.springframework.ai.model.function.FunctionCallbackContext;
|
||||
import org.springframework.ai.model.function.FunctionCallbackWrapper.Builder.SchemaType;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCall;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCaller;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -40,7 +40,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Christian Tzolov
|
||||
* @since 0.8.0
|
||||
*/
|
||||
@ConditionalOnClass({ VertexAI.class, VertexAiGeminiModelCall.class })
|
||||
@ConditionalOnClass({ VertexAI.class, VertexAiGeminiModelCaller.class })
|
||||
@EnableConfigurationProperties({ VertexAiGeminiChatProperties.class, VertexAiGeminiConnectionProperties.class })
|
||||
public class VertexAiGeminiAutoConfiguration {
|
||||
|
||||
@@ -74,7 +74,7 @@ public class VertexAiGeminiAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public VertexAiGeminiModelCall vertexAiGeminiChat(VertexAI vertexAi, VertexAiGeminiChatProperties chatProperties,
|
||||
public VertexAiGeminiModelCaller vertexAiGeminiChat(VertexAI vertexAi, VertexAiGeminiChatProperties chatProperties,
|
||||
List<FunctionCallback> toolFunctionCallbacks, ApplicationContext context) {
|
||||
|
||||
FunctionCallbackContext functionCallbackContext = springAiFunctionManager(context);
|
||||
@@ -83,7 +83,7 @@ public class VertexAiGeminiAutoConfiguration {
|
||||
chatProperties.getOptions().getFunctionCallbacks().addAll(toolFunctionCallbacks);
|
||||
}
|
||||
|
||||
return new VertexAiGeminiModelCall(vertexAi, chatProperties.getOptions(), functionCallbackContext);
|
||||
return new VertexAiGeminiModelCaller(vertexAi, chatProperties.getOptions(), functionCallbackContext);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.autoconfigure.vertexai.gemini;
|
||||
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCall;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiModelCaller;
|
||||
import org.springframework.ai.vertexai.gemini.VertexAiGeminiChatOptions;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@@ -30,7 +30,7 @@ public class VertexAiGeminiChatProperties {
|
||||
|
||||
public static final String CONFIG_PREFIX = "spring.ai.vertex.ai.gemini.chat";
|
||||
|
||||
public static final String DEFAULT_MODEL = VertexAiGeminiModelCall.ChatModel.GEMINI_PRO_VISION.getValue();
|
||||
public static final String DEFAULT_MODEL = VertexAiGeminiModelCaller.ChatModel.GEMINI_PRO_VISION.getValue();
|
||||
|
||||
/**
|
||||
* Vertex AI Gemini API generative options.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.autoconfigure.vertexai.palm2;
|
||||
|
||||
import org.springframework.ai.vertexai.palm2.VertexAiPaLm2ModelCall;
|
||||
import org.springframework.ai.vertexai.palm2.VertexAiPaLm2ModelCaller;
|
||||
import org.springframework.ai.vertexai.palm2.VertexAiPaLm2EmbeddingClient;
|
||||
import org.springframework.ai.vertexai.palm2.api.VertexAiPaLm2Api;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
@@ -47,9 +47,9 @@ public class VertexAiPalm2AutoConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(prefix = VertexAiPlam2ChatProperties.CONFIG_PREFIX, name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public VertexAiPaLm2ModelCall vertexAiChatClient(VertexAiPaLm2Api vertexAiApi,
|
||||
public VertexAiPaLm2ModelCaller vertexAiChatClient(VertexAiPaLm2Api vertexAiApi,
|
||||
VertexAiPlam2ChatProperties chatProperties) {
|
||||
return new VertexAiPaLm2ModelCall(vertexAiApi, chatProperties.getOptions());
|
||||
return new VertexAiPaLm2ModelCaller(vertexAiApi, chatProperties.getOptions());
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.ai.autoconfigure.watsonxai;
|
||||
|
||||
import org.springframework.ai.watsonx.WatsonxAiModelCall;
|
||||
import org.springframework.ai.watsonx.WatsonxAiModelCaller;
|
||||
import org.springframework.ai.watsonx.api.WatsonxAiApi;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
@@ -50,8 +50,8 @@ public class WatsonxAiAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WatsonxAiModelCall watsonxChatClient(WatsonxAiApi watsonxApi, WatsonxAiChatProperties chatProperties) {
|
||||
return new WatsonxAiModelCall(watsonxApi, chatProperties.getOptions());
|
||||
public WatsonxAiModelCaller watsonxChatClient(WatsonxAiApi watsonxApi, WatsonxAiChatProperties chatProperties) {
|
||||
return new WatsonxAiModelCaller(watsonxApi, chatProperties.getOptions());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.springframework.ai.anthropic.AnthropicModelCall;
|
||||
import org.springframework.ai.anthropic.AnthropicModelCaller;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
|
||||
@@ -50,7 +50,7 @@ public class AnthropicAutoConfigurationIT {
|
||||
@Test
|
||||
void generate() {
|
||||
contextRunner.run(context -> {
|
||||
AnthropicModelCall chatClient = context.getBean(AnthropicModelCall.class);
|
||||
AnthropicModelCaller chatClient = context.getBean(AnthropicModelCaller.class);
|
||||
String response = chatClient.call("Hello");
|
||||
assertThat(response).isNotEmpty();
|
||||
logger.info("Response: " + response);
|
||||
@@ -60,7 +60,7 @@ public class AnthropicAutoConfigurationIT {
|
||||
@Test
|
||||
void generateStreaming() {
|
||||
contextRunner.run(context -> {
|
||||
AnthropicModelCall chatClient = context.getBean(AnthropicModelCall.class);
|
||||
AnthropicModelCaller chatClient = context.getBean(AnthropicModelCaller.class);
|
||||
Flux<ChatResponse> responseFlux = chatClient.stream(new Prompt(new UserMessage("Hello")));
|
||||
|
||||
String response = responseFlux.collectList()
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.ai.autoconfigure.anthropic;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.ai.anthropic.AnthropicModelCall;
|
||||
import org.springframework.ai.anthropic.AnthropicModelCaller;
|
||||
import org.springframework.ai.autoconfigure.retry.SpringAiRetryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
@@ -102,7 +102,7 @@ public class AnthropicPropertiesTests {
|
||||
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(AnthropicModelCall.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(AnthropicModelCaller.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
// Explicitly enable the chat auto-configuration.
|
||||
@@ -111,7 +111,7 @@ public class AnthropicPropertiesTests {
|
||||
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(AnthropicModelCall.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(AnthropicModelCaller.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
// Explicitly disable the chat auto-configuration.
|
||||
@@ -120,7 +120,7 @@ public class AnthropicPropertiesTests {
|
||||
RestClientAutoConfiguration.class, AnthropicAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
assertThat(context.getBeansOfType(AnthropicChatProperties.class)).isEmpty();
|
||||
assertThat(context.getBeansOfType(AnthropicModelCall.class)).isEmpty();
|
||||
assertThat(context.getBeansOfType(AnthropicModelCaller.class)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.anthropic.AnthropicModelCall;
|
||||
import org.springframework.ai.anthropic.AnthropicModelCaller;
|
||||
import org.springframework.ai.anthropic.AnthropicChatOptions;
|
||||
import org.springframework.ai.anthropic.api.AnthropicApi;
|
||||
import org.springframework.ai.autoconfigure.anthropic.AnthropicAutoConfiguration;
|
||||
@@ -61,7 +61,7 @@ class FunctionCallWithFunctionBeanIT {
|
||||
"spring.ai.anthropic.chat.options.model=" + AnthropicApi.ChatModel.CLAUDE_3_OPUS.getValue())
|
||||
.run(context -> {
|
||||
|
||||
AnthropicModelCall chatClient = context.getBean(AnthropicModelCall.class);
|
||||
AnthropicModelCaller chatClient = context.getBean(AnthropicModelCaller.class);
|
||||
|
||||
var userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, in Paris, France and in Tokyo, Japan? Return the temperature in Celsius.");
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.anthropic.AnthropicModelCall;
|
||||
import org.springframework.ai.anthropic.AnthropicModelCaller;
|
||||
import org.springframework.ai.anthropic.AnthropicChatOptions;
|
||||
import org.springframework.ai.anthropic.api.AnthropicApi;
|
||||
import org.springframework.ai.autoconfigure.anthropic.AnthropicAutoConfiguration;
|
||||
@@ -54,7 +54,7 @@ public class FunctionCallWithPromptFunctionIT {
|
||||
"spring.ai.anthropic.chat.options.model=" + AnthropicApi.ChatModel.CLAUDE_3_OPUS.getValue())
|
||||
.run(context -> {
|
||||
|
||||
AnthropicModelCall chatClient = context.getBean(AnthropicModelCall.class);
|
||||
AnthropicModelCaller chatClient = context.getBean(AnthropicModelCaller.class);
|
||||
|
||||
UserMessage userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, in Paris and in Tokyo? Return the temperature in Celsius.");
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCall;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCaller;
|
||||
import org.springframework.ai.chat.messages.AssistantMessage;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class AzureOpenAiAutoConfigurationIT {
|
||||
@Test
|
||||
public void chatCompletion() {
|
||||
contextRunner.run(context -> {
|
||||
AzureOpenAiModelCall chatClient = context.getBean(AzureOpenAiModelCall.class);
|
||||
AzureOpenAiModelCaller chatClient = context.getBean(AzureOpenAiModelCaller.class);
|
||||
ChatResponse response = chatClient.call(new Prompt(List.of(userMessage, systemMessage)));
|
||||
assertThat(response.getResult().getOutput().getContent()).contains("Blackbeard");
|
||||
});
|
||||
@@ -87,7 +87,7 @@ public class AzureOpenAiAutoConfigurationIT {
|
||||
public void chatCompletionStreaming() {
|
||||
contextRunner.run(context -> {
|
||||
|
||||
AzureOpenAiModelCall chatClient = context.getBean(AzureOpenAiModelCall.class);
|
||||
AzureOpenAiModelCaller chatClient = context.getBean(AzureOpenAiModelCaller.class);
|
||||
|
||||
Flux<ChatResponse> response = chatClient.stream(new Prompt(List.of(userMessage, systemMessage)));
|
||||
|
||||
@@ -127,17 +127,17 @@ public class AzureOpenAiAutoConfigurationIT {
|
||||
|
||||
// Disable the chat auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.azure.openai.chat.enabled=false").run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiModelCall.class)).isEmpty();
|
||||
assertThat(context.getBeansOfType(AzureOpenAiModelCaller.class)).isEmpty();
|
||||
});
|
||||
|
||||
// The chat auto-configuration is enabled by default.
|
||||
contextRunner.run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiModelCall.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(AzureOpenAiModelCaller.class)).isNotEmpty();
|
||||
});
|
||||
|
||||
// Explicitly enable the chat auto-configuration.
|
||||
contextRunner.withPropertyValues("spring.ai.azure.openai.chat.enabled=true").run(context -> {
|
||||
assertThat(context.getBeansOfType(AzureOpenAiModelCall.class)).isNotEmpty();
|
||||
assertThat(context.getBeansOfType(AzureOpenAiModelCaller.class)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfiguration;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCall;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiModelCaller;
|
||||
import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
|
||||
import org.springframework.ai.chat.ModelCall;
|
||||
import org.springframework.ai.chat.ChatCaller;
|
||||
import org.springframework.ai.chat.ChatResponse;
|
||||
import org.springframework.ai.chat.messages.UserMessage;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
@@ -57,7 +57,7 @@ class FunctionCallWithFunctionBeanIT {
|
||||
contextRunner.withPropertyValues("spring.ai.azure.openai.chat.options..deployment-name=gpt-4-0125-preview")
|
||||
.run(context -> {
|
||||
|
||||
ModelCall modelCall = context.getBean(AzureOpenAiModelCall.class);
|
||||
ChatCaller modelCall = context.getBean(AzureOpenAiModelCaller.class);
|
||||
|
||||
UserMessage userMessage = new UserMessage(
|
||||
"What's the weather like in San Francisco, Paris and in Tokyo? Use Multi-turn function calling.");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user