Remove deprecated code from 1.0 M2 and before

- Remove deprecated types,methods and references
 - Remove usage of "Generation(String text)" and replace with
  "Generation(AssistantMessage)"
 - Remove MiniMaxApi,MootShotApi,OpenAiApi,ZhiPuAiApi
   ChatCompletionFinishReason's FUNCTION_CALL
 - Remove OllamaApi's deprecated types
 - Remove deprecated constructors from PostgresMlEmbeddingModel
 - Remove deprecated constructor from Media
 - Remove tokenNames usage from antlr4 FiltersLexer and FiltersParser
 - Remove deprecated methods from CassandraVectorStoreProperties
 - Remove deprecated constructor and static config class from QdrantVectorStore
 - Minor cleanups on removing deprecated models and versions
 - Remove old name for mixtral models

Resolves #1599
This commit is contained in:
Ilayaperumal Gopinathan
2024-11-14 12:28:13 +00:00
committed by Mark Pollack
parent ea1871041c
commit 72c84fe8b8
29 changed files with 73 additions and 607 deletions

View File

@@ -24,6 +24,7 @@ import org.springframework.ai.bedrock.MessageToPromptConverter;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi.AnthropicChatRequest;
import org.springframework.ai.bedrock.anthropic.api.AnthropicChatBedrockApi.AnthropicChatResponse;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
@@ -68,7 +69,7 @@ public class BedrockAnthropicChatModel implements ChatModel, StreamingChatModel
AnthropicChatResponse response = this.anthropicChatApi.chatCompletion(request);
return new ChatResponse(List.of(new Generation(response.completion())));
return new ChatResponse(List.of(new Generation(new AssistantMessage(response.completion()))));
}
@Override
@@ -80,12 +81,13 @@ public class BedrockAnthropicChatModel implements ChatModel, StreamingChatModel
return fluxResponse.map(response -> {
String stopReason = response.stopReason() != null ? response.stopReason() : null;
var generation = new Generation(response.completion());
ChatGenerationMetadata chatGenerationMetadata = null;
if (response.amazonBedrockInvocationMetrics() != null) {
generation = generation.withGenerationMetadata(
ChatGenerationMetadata.from(stopReason, response.amazonBedrockInvocationMetrics()));
chatGenerationMetadata = ChatGenerationMetadata.from(stopReason,
response.amazonBedrockInvocationMetrics());
}
return new ChatResponse(List.of(generation));
return new ChatResponse(
List.of(new Generation(new AssistantMessage(response.completion()), chatGenerationMetadata)));
});
}

View File

@@ -114,16 +114,13 @@ public class BedrockAnthropic3ChatModel implements ChatModel, StreamingChatModel
inputTokens.set(response.message().usage().inputTokens());
}
String content = response.type() == StreamingType.CONTENT_BLOCK_DELTA ? response.delta().text() : "";
var generation = new Generation(content);
ChatGenerationMetadata chatGenerationMetadata = null;
if (response.type() == StreamingType.MESSAGE_DELTA) {
generation = generation.withGenerationMetadata(ChatGenerationMetadata
.from(response.delta().stopReason(), new Anthropic3ChatBedrockApi.AnthropicUsage(inputTokens.get(),
response.usage().outputTokens())));
chatGenerationMetadata = ChatGenerationMetadata.from(response.delta().stopReason(),
new Anthropic3ChatBedrockApi.AnthropicUsage(inputTokens.get(),
response.usage().outputTokens()));
}
return new ChatResponse(List.of(generation));
return new ChatResponse(List.of(new Generation(new AssistantMessage(content), chatGenerationMetadata)));
});
}

View File

@@ -25,6 +25,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.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.metadata.Usage;
import org.springframework.ai.chat.model.ChatModel;
@@ -61,7 +62,10 @@ public class BedrockCohereChatModel implements ChatModel, StreamingChatModel {
@Override
public ChatResponse call(Prompt prompt) {
CohereChatResponse response = this.chatApi.chatCompletion(this.createRequest(prompt, false));
List<Generation> generations = response.generations().stream().map(g -> new Generation(g.text())).toList();
List<Generation> generations = response.generations()
.stream()
.map(g -> new Generation(new AssistantMessage(g.text())))
.toList();
return new ChatResponse(generations);
}
@@ -73,9 +77,9 @@ public class BedrockCohereChatModel implements ChatModel, StreamingChatModel {
String finishReason = g.finishReason().name();
Usage usage = BedrockUsage.from(g.amazonBedrockInvocationMetrics());
return new ChatResponse(List
.of(new Generation("").withGenerationMetadata(ChatGenerationMetadata.from(finishReason, usage))));
.of(new Generation(new AssistantMessage(""), ChatGenerationMetadata.from(finishReason, usage))));
}
return new ChatResponse(List.of(new Generation(g.text())));
return new ChatResponse(List.of(new Generation(new AssistantMessage(g.text()))));
});
}

View File

@@ -19,6 +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.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
@@ -68,8 +69,8 @@ public class BedrockAi21Jurassic2ChatModel implements ChatModel {
return new ChatResponse(response.completions()
.stream()
.map(completion -> new Generation(completion.data().text())
.withGenerationMetadata(ChatGenerationMetadata.from(completion.finishReason().reason(), null)))
.map(completion -> new Generation(new AssistantMessage(completion.data().text()),
ChatGenerationMetadata.from(completion.finishReason().reason(), null)))
.toList());
}

View File

@@ -24,6 +24,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.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.metadata.Usage;
import org.springframework.ai.chat.model.ChatModel;
@@ -68,7 +69,7 @@ public class BedrockLlamaChatModel implements ChatModel, StreamingChatModel {
LlamaChatResponse response = this.chatApi.chatCompletion(request);
return new ChatResponse(List.of(new Generation(response.generation()).withGenerationMetadata(
return new ChatResponse(List.of(new Generation(new AssistantMessage(response.generation()),
ChatGenerationMetadata.from(response.stopReason().name(), extractUsage(response)))));
}
@@ -81,8 +82,8 @@ public class BedrockLlamaChatModel implements ChatModel, StreamingChatModel {
return fluxResponse.map(response -> {
String stopReason = response.stopReason() != null ? response.stopReason().name() : null;
return new ChatResponse(List.of(new Generation(response.generation())
.withGenerationMetadata(ChatGenerationMetadata.from(stopReason, extractUsage(response)))));
return new ChatResponse(List.of(new Generation(new AssistantMessage(response.generation()),
ChatGenerationMetadata.from(stopReason, extractUsage(response)))));
});
}

View File

@@ -25,6 +25,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.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.metadata.Usage;
import org.springframework.ai.chat.model.ChatModel;
@@ -62,7 +63,7 @@ public class BedrockTitanChatModel implements ChatModel, StreamingChatModel {
TitanChatResponse response = this.chatApi.chatCompletion(this.createRequest(prompt));
List<Generation> generations = response.results()
.stream()
.map(result -> new Generation(result.outputText()))
.map(result -> new Generation(new AssistantMessage(result.outputText())))
.toList();
return new ChatResponse(generations);
@@ -71,21 +72,18 @@ public class BedrockTitanChatModel implements ChatModel, StreamingChatModel {
@Override
public Flux<ChatResponse> stream(Prompt prompt) {
return this.chatApi.chatCompletionStream(this.createRequest(prompt)).map(chunk -> {
Generation generation = new Generation(chunk.outputText());
ChatGenerationMetadata chatGenerationMetadata = null;
if (chunk.amazonBedrockInvocationMetrics() != null) {
String completionReason = chunk.completionReason().name();
generation = generation.withGenerationMetadata(
ChatGenerationMetadata.from(completionReason, chunk.amazonBedrockInvocationMetrics()));
chatGenerationMetadata = ChatGenerationMetadata.from(completionReason,
chunk.amazonBedrockInvocationMetrics());
}
else if (chunk.inputTextTokenCount() != null && chunk.totalOutputTextTokenCount() != null) {
String completionReason = chunk.completionReason().name();
generation = generation
.withGenerationMetadata(ChatGenerationMetadata.from(completionReason, extractUsage(chunk)));
chatGenerationMetadata = ChatGenerationMetadata.from(completionReason, extractUsage(chunk));
}
return new ChatResponse(List.of(generation));
return new ChatResponse(
List.of(new Generation(new AssistantMessage(chunk.outputText()), chatGenerationMetadata)));
});
}

View File

@@ -92,8 +92,11 @@ class BedrockLlamaChatModelIT {
@Test
void roleTest() {
UserMessage userMessage = new UserMessage(
"Tell me about 3 famous pirates from the Golden Age of Piracy and why they did.");
String message = """
Describe 3 of the most feared and legendary pirates from the Golden Age of Piracy, particularly
those known for their intimidating tactics and whose stories influenced popular culture.
""";
UserMessage userMessage = new UserMessage(message);
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(this.systemResource);
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
@@ -111,7 +114,7 @@ class BedrockLlamaChatModelIT {
String format = outputConverter.getFormat();
String template = """
List five {subject}
List exactly five {subject}, no more and no less.
{format}
""";
PromptTemplate promptTemplate = new PromptTemplate(template,

View File

@@ -23,6 +23,8 @@ import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.model.Generation;
@@ -105,7 +107,7 @@ public class HuggingfaceChatModel implements ChatModel {
new TypeReference<Map<String, Object>>() {
});
Generation generation = new Generation(generatedText, detailsMap);
Generation generation = new Generation(new AssistantMessage(generatedText, detailsMap));
generations.add(generation);
}
return new ChatResponse(generations);

View File

@@ -224,10 +224,7 @@ public class MiniMaxApi {
ABAB_6_5_T_Chat("abab6.5t-chat"),
ABAB_6_5_G_Chat("abab6.5g-chat"),
ABAB_5_5_Chat("abab5.5-chat"),
ABAB_5_5_S_Chat("abab5.5s-chat"),
@Deprecated(since = "1.0.0-M2", forRemoval = true) // Replaced by ABAB_6_5_S_Chat
ABAB_6_Chat("abab6-chat");
ABAB_5_5_S_Chat("abab5.5s-chat");
public final String value;
@@ -269,11 +266,6 @@ public class MiniMaxApi {
*/
@JsonProperty("tool_calls")
TOOL_CALLS,
/**
* (deprecated) The model called a function.
*/
@JsonProperty("function_call")
FUNCTION_CALL,
/**
* Only for compatibility with Mistral AI API.
*/

View File

@@ -264,15 +264,11 @@ public class MistralAiApi {
public enum ChatModel implements ChatModelDescription {
// @formatter:off
@Deprecated(since = "1.0.0-M1", forRemoval = true) // Replaced by OPEN_MISTRAL_7B
TINY("open-mistral-7b"),
@Deprecated(since = "1.0.0-M1", forRemoval = true) // Replaced by OPEN_MIXTRAL_7B
MIXTRAL("open-mixtral-8x7b"),
OPEN_MISTRAL_7B("open-mistral-7b"),
OPEN_MIXTRAL_7B("open-mixtral-8x7b"),
OPEN_MIXTRAL_22B("open-mixtral-8x22b"),
SMALL("mistral-small-latest"),
@Deprecated(since = "1.0.0-M1", forRemoval = true) // Mistral is removing this model
@Deprecated(since = "1.0.0-M1", forRemoval = true) // Mistral will be removing this model - see https://docs.mistral.ai/getting-started/models/models_overview/
MEDIUM("mistral-medium-latest"),
LARGE("mistral-large-latest");
// @formatter:on

View File

@@ -195,11 +195,6 @@ public class MoonshotApi {
*/
@JsonProperty("tool_calls")
TOOL_CALLS,
/**
* (deprecated) The model called a function.
*/
@JsonProperty("function_call")
FUNCTION_CALL,
/**
* Only for compatibility with Mistral AI API.
*/

View File

@@ -104,54 +104,6 @@ public class OllamaApi {
this.webClient = webClientBuilder.baseUrl(baseUrl).defaultHeaders(defaultHeaders).build();
}
/**
* Generate a completion for the given prompt.
* @param completionRequest Completion request.
* @return Completion response.
* @deprecated Use {@link #chat(ChatRequest)} instead.
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true)
public GenerateResponse generate(GenerateRequest completionRequest) {
Assert.notNull(completionRequest, REQUEST_BODY_NULL_ERROR);
Assert.isTrue(!completionRequest.stream(), "Stream mode must be disabled.");
return this.restClient.post()
.uri("/api/generate")
.body(completionRequest)
.retrieve()
.onStatus(this.responseErrorHandler)
.body(GenerateResponse.class);
}
// --------------------------------------------------------------------------
// Generate & Streaming Generate
// --------------------------------------------------------------------------
/**
* Generate a streaming completion for the given prompt.
* @param completionRequest Completion request. The request must set the stream
* property to true.
* @return Completion response as a {@link Flux} stream.
* @deprecated Use {@link #streamingChat(ChatRequest)} instead.
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true)
public Flux<GenerateResponse> generateStreaming(GenerateRequest completionRequest) {
Assert.notNull(completionRequest, REQUEST_BODY_NULL_ERROR);
Assert.isTrue(completionRequest.stream(), "Request must set the stream property to true.");
return this.webClient.post()
.uri("/api/generate")
.body(Mono.just(completionRequest), GenerateRequest.class)
.retrieve()
.bodyToFlux(GenerateResponse.class)
.handle((data, sink) -> {
if (logger.isTraceEnabled()) {
logger.trace(data);
}
sink.next(data);
});
}
/**
* Generate the next message in a chat with a provided model.
* This is a streaming endpoint (controlled by the 'stream' request property), so
@@ -183,7 +135,7 @@ public class OllamaApi {
return this.webClient.post()
.uri("/api/chat")
.body(Mono.just(chatRequest), GenerateRequest.class)
.body(Mono.just(chatRequest), ChatRequest.class)
.retrieve()
.bodyToFlux(ChatResponse.class)
.handle((data, sink) -> {
@@ -210,28 +162,6 @@ public class OllamaApi {
.body(EmbeddingsResponse.class);
}
// --------------------------------------------------------------------------
// Chat & Streaming Chat
// --------------------------------------------------------------------------
/**
* Generate embeddings from a model.
* @param embeddingRequest Embedding request.
* @return Embedding response.
* @deprecated Use {@link #embed(EmbeddingsRequest)} instead.
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true)
public EmbeddingResponse embeddings(EmbeddingRequest embeddingRequest) {
Assert.notNull(embeddingRequest, REQUEST_BODY_NULL_ERROR);
return this.restClient.post()
.uri("/api/embeddings")
.body(embeddingRequest)
.retrieve()
.onStatus(this.responseErrorHandler)
.body(EmbeddingResponse.class);
}
/**
* List models that are available locally on the machine where Ollama is running.
*/
@@ -321,192 +251,6 @@ public class OllamaApi {
}
/**
* The request object sent to the /generate endpoint.
*
* @param model (required) The model to use for completion.
* @param prompt (required) The prompt(s) to generate completions for.
* @param format (optional) The format to return the response in. Currently, the only
* accepted value is "json".
* @param options (optional) additional model parameters listed in the documentation
* for the Model file such as temperature.
* @param system (optional) system prompt to (overrides what is defined in the Model file).
* @param template (optional) the full prompt or prompt template (overrides what is
* defined in the Model file).
* @param context the context parameter returned from a previous request to /generate,
* this can be used to keep a short conversational memory.
* @param stream (optional) if false the response will be returned as a single
* response object, rather than a stream of objects.
* @param raw (optional) if true no formatting will be applied to the prompt and no
* context will be returned. You may choose to use the raw parameter if you are
* specifying a full templated prompt in your request to the API, and are managing
* history yourself.
* @param images (optional) a list of base64-encoded images (for multimodal models such as llava).
* @param keepAlive (optional) controls how long the model will stay loaded into memory following the request (default: 5m).
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true)
@JsonInclude(Include.NON_NULL)
public record GenerateRequest(
@JsonProperty("model") String model,
@JsonProperty("prompt") String prompt,
@JsonProperty("format") String format,
@JsonProperty("options") Map<String, Object> options,
@JsonProperty("system") String system,
@JsonProperty("template") String template,
@JsonProperty("context") List<Integer> context,
@JsonProperty("stream") Boolean stream,
@JsonProperty("raw") Boolean raw,
@JsonProperty("images") List<String> images,
@JsonProperty("keep_alive") String keepAlive) {
/**
* Shortcut constructor to create a CompletionRequest without options.
* @param model The model used for completion.
* @param prompt The prompt(s) to generate completions for.
* @param stream Whether to stream the response.
*/
public GenerateRequest(String model, String prompt, Boolean stream) {
this(model, prompt, null, null, null, null, null, stream, null, null, null);
}
/**
* Shortcut constructor to create a CompletionRequest without options.
* @param model The model used for completion.
* @param prompt The prompt(s) to generate completions for.
* @param enableJsonFormat Whether to return the response in json format.
* @param stream Whether to stream the response.
*/
public GenerateRequest(String model, String prompt, boolean enableJsonFormat, Boolean stream) {
this(model, prompt, (enableJsonFormat) ? "json" : null, null, null, null, null, stream, null, null, null);
}
/**
* Create a CompletionRequest builder.
* @param prompt The prompt(s) to generate completions for.
*/
public static Builder builder(String prompt) {
return new Builder(prompt);
}
public static class Builder {
private final String prompt;
private String model;
private String format;
private Map<String, Object> options;
private String system;
private String template;
private List<Integer> context;
private Boolean stream;
private Boolean raw;
private List<String> images;
private String keepAlive;
public Builder(String prompt) {
this.prompt = prompt;
}
public Builder withModel(String model) {
this.model = model;
return this;
}
public Builder withFormat(String format) {
this.format = format;
return this;
}
public Builder withOptions(Map<String, Object> options) {
this.options = options;
return this;
}
public Builder withOptions(OllamaOptions options) {
this.options = options.toMap();
return this;
}
public Builder withSystem(String system) {
this.system = system;
return this;
}
public Builder withTemplate(String template) {
this.template = template;
return this;
}
public Builder withContext(List<Integer> context) {
this.context = context;
return this;
}
public Builder withStream(Boolean stream) {
this.stream = stream;
return this;
}
public Builder withRaw(Boolean raw) {
this.raw = raw;
return this;
}
public Builder withImages(List<String> images) {
this.images = images;
return this;
}
public Builder withKeepAlive(String keepAlive) {
this.keepAlive = keepAlive;
return this;
}
public GenerateRequest build() {
return new GenerateRequest(this.model, this.prompt, this.format, this.options, this.system, this.template, this.context, this.stream, this.raw, this.images, this.keepAlive);
}
}
}
/**
* The response object returned from the /generate endpoint. To calculate how fast the
* response is generated in tokens per second (token/s), divide eval_count /
* eval_duration.
*
* @param model The model used for completion.
* @param createdAt When the request was made.
* @param response The completion response. Empty if the response was streamed, if not
* streamed, this will contain the full response
* @param done Whether this is the final response. If true, this response may be
* followed by another response with the following, additional fields: context,
* prompt_eval_count, prompt_eval_duration, eval_count, eval_duration.
* @param context Encoding of the conversation used in this response, this can be sent
* in the next request to keep a conversational memory.
* @param totalDuration Time spent generating the response.
* @param loadDuration Time spent loading the model.
* @param promptEvalCount Number of times the prompt was evaluated.
* @param promptEvalDuration Time spent evaluating the prompt.
* @param evalCount Number of tokens in the response.
* @param evalDuration Time spent generating the response.
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true)
@JsonInclude(Include.NON_NULL)
public record GenerateResponse(
@JsonProperty("model") String model,
@JsonProperty("created_at") Instant createdAt,
@JsonProperty("response") String response,
@JsonProperty("done") Boolean done,
@JsonProperty("context") List<Integer> context,
@JsonProperty("total_duration") Duration totalDuration,
@JsonProperty("load_duration") Duration loadDuration,
@JsonProperty("prompt_eval_count") Integer promptEvalCount,
@JsonProperty("prompt_eval_duration") Duration promptEvalDuration,
@JsonProperty("eval_count") Integer evalCount,
@JsonProperty("eval_duration") Duration evalDuration) {
}
/**
* Chat message object.
*
@@ -830,45 +574,6 @@ public class OllamaApi {
}
}
/**
* Generate embeddings from a model.
*
* @param model The name of model to generate embeddings from.
* @param prompt The text generate embeddings for
* @param keepAlive Controls how long the model will stay loaded into memory following the request (default: 5m).
* @param options Additional model parameters listed in the documentation for the
* @deprecated Use {@link EmbeddingsRequest} instead.
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true)
@JsonInclude(Include.NON_NULL)
public record EmbeddingRequest(
@JsonProperty("model") String model,
@JsonProperty("prompt") String prompt,
@JsonProperty("keep_alive") Duration keepAlive,
@JsonProperty("options") Map<String, Object> options) {
/**
* Shortcut constructor to create a EmbeddingRequest without options.
* @param model The name of model to generate embeddings from.
* @param prompt The text to generate embeddings for.
*/
public EmbeddingRequest(String model, String prompt) {
this(model, prompt, null, null);
}
}
/**
* The response object returned from the /embedding endpoint.
*
* @param embedding The embedding generated from the model.
* @deprecated Use {@link EmbeddingsResponse} instead.
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true)
@JsonInclude(Include.NON_NULL)
public record EmbeddingResponse(
@JsonProperty("embedding") List<Float> embedding) {
}
/**
* The response object returned from the /embedding endpoint.
* @param model The model used for generating the embeddings.

View File

@@ -24,13 +24,12 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.ollama.BaseOllamaIT;
import org.springframework.ai.ollama.api.OllamaApi.ChatRequest;
import org.springframework.ai.ollama.api.OllamaApi.ChatResponse;
import org.springframework.ai.ollama.api.OllamaApi.EmbeddingsRequest;
import org.springframework.ai.ollama.api.OllamaApi.EmbeddingsResponse;
import org.springframework.ai.ollama.api.OllamaApi.GenerateRequest;
import org.springframework.ai.ollama.api.OllamaApi.GenerateResponse;
import org.springframework.ai.ollama.api.OllamaApi.Message;
import org.springframework.ai.ollama.api.OllamaApi.Message.Role;
@@ -49,23 +48,6 @@ public class OllamaApiIT extends BaseOllamaIT {
initializeOllama(MODEL);
}
@Test
public void generation() {
var request = GenerateRequest
.builder("What is the capital of Bulgaria and what is the size? What it the national anthem?")
.withModel(MODEL)
.withStream(false)
.build();
GenerateResponse response = getOllamaApi().generate(request);
System.out.println(response);
assertThat(response).isNotNull();
assertThat(response.model()).contains(MODEL);
assertThat(response.response()).contains("Sofia");
}
@Test
public void chat() {
var request = ChatRequest.builder(MODEL)

View File

@@ -397,27 +397,12 @@ public class OpenAiApi {
*/
GPT_4_TURBO_PREVIEW("gpt-4-turbo-preview"),
/**
* GPT-4 with the ability to understand images, in addition to all other GPT-4
* Turbo capabilities. Currently points to gpt-4-1106-vision-preview. Returns a
* maximum of 4,096 output tokens Context window: 128k tokens
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true) // Replaced by GPT_4_O
GPT_4_VISION_PREVIEW("gpt-4-vision-preview"),
/**
* Currently points to gpt-4-0613. Snapshot of gpt-4 from June 13th 2023 with
* improved function calling support. Context window: 8k tokens
*/
GPT_4("gpt-4"),
/**
* Currently points to gpt-4-32k-0613. Snapshot of gpt-4-32k from June 13th 2023
* with improved function calling support. Context window: 32k tokens
*/
@Deprecated(since = "1.0.0-M2", forRemoval = true) // Replaced by GPT_4_O
GPT_4_32K("gpt-4-32k"),
/**
* Currently points to gpt-3.5-turbo-0125. model with higher accuracy at
* responding in requested formats and a fix for a bug which caused a text
@@ -483,11 +468,6 @@ public class OpenAiApi {
*/
@JsonProperty("tool_calls")
TOOL_CALLS,
/**
* (deprecated) The model called a function.
*/
@JsonProperty("function_call")
FUNCTION_CALL,
/**
* Only for compatibility with Mistral AI API.
*/

View File

@@ -88,56 +88,6 @@ public class PostgresMlEmbeddingModel extends AbstractEmbeddingModel implements
this.createExtension = createExtension;
}
/**
* a constructor
* @param jdbcTemplate JdbcTemplate
* @param transformer huggingface sentence-transformer name
*/
@Deprecated(since = "0.8.0", forRemoval = true)
public PostgresMlEmbeddingModel(JdbcTemplate jdbcTemplate, String transformer) {
this(jdbcTemplate, transformer, VectorType.PG_ARRAY);
}
/**
* a constructor
* @deprecated Use the constructor with {@link PostgresMlEmbeddingOptions} instead.
* @param jdbcTemplate JdbcTemplate
* @param transformer huggingface sentence-transformer name
* @param vectorType vector type in PostgreSQL
*/
@Deprecated(since = "0.8.0", forRemoval = true)
public PostgresMlEmbeddingModel(JdbcTemplate jdbcTemplate, String transformer, VectorType vectorType) {
this(jdbcTemplate, transformer, vectorType, Map.of(), MetadataMode.EMBED, false);
}
/**
* a constructor * @deprecated Use the constructor with
* {@link PostgresMlEmbeddingOptions} instead.
* @param jdbcTemplate JdbcTemplate
* @param transformer huggingface sentence-transformer name
* @param vectorType vector type in PostgreSQL
* @param kwargs optional arguments
*/
@Deprecated(since = "0.8.0", forRemoval = true)
public PostgresMlEmbeddingModel(JdbcTemplate jdbcTemplate, String transformer, VectorType vectorType,
Map<String, Object> kwargs, MetadataMode metadataMode, boolean createExtension) {
Assert.notNull(jdbcTemplate, "jdbc template must not be null.");
Assert.notNull(transformer, "transformer must not be null.");
Assert.notNull(vectorType, "vectorType must not be null.");
Assert.notNull(kwargs, "kwargs must not be null.");
Assert.notNull(metadataMode, "metadataMode must not be null.");
this.jdbcTemplate = jdbcTemplate;
this.defaultOptions = PostgresMlEmbeddingOptions.builder()
.withTransformer(transformer)
.withVectorType(vectorType)
.withMetadataMode(metadataMode)
.withKwargs(ModelOptionsUtils.toJsonString(kwargs))
.build();
this.createExtension = createExtension;
}
@SuppressWarnings("null")
@Override
public float[] embed(String text) {

View File

@@ -16,6 +16,10 @@
package org.springframework.ai.vertexai.embedding.multimodal;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@@ -104,10 +108,12 @@ class VertexAiMultimodalEmbeddingModelIT {
}
@Test
void textMediaEmbedding() {
void textMediaEmbedding() throws MalformedURLException {
assertThat(this.multiModelEmbeddingModel).isNotNull();
var document = Document.builder().withMedia(new Media(MimeTypeUtils.TEXT_PLAIN, "Hello World")).build();
var document = Document.builder()
.withMedia(new Media(MimeTypeUtils.TEXT_PLAIN, URI.create("http://example.com/image.png").toURL()))
.build();
DocumentEmbeddingRequest embeddingRequest = new DocumentEmbeddingRequest(document);

View File

@@ -26,6 +26,7 @@ import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.model.ChatResponse;
@@ -172,9 +173,9 @@ public class WatsonxAiChatModelTest {
given(mockChatApi.generate(any(WatsonxAiChatRequest.class)))
.willReturn(ResponseEntity.of(Optional.of(fakeResponse)));
Generation expectedGenerator = new Generation("LLM response")
.withGenerationMetadata(ChatGenerationMetadata.from("max_tokens",
Map.of("warnings", List.of(Map.of("message", "the message", "id", "disclaimer_warning")))));
Generation expectedGenerator = new Generation(new AssistantMessage("LLM response"),
ChatGenerationMetadata.from("max_tokens",
Map.of("warnings", List.of(Map.of("message", "the message", "id", "disclaimer_warning")))));
ChatResponse expectedResponse = new ChatResponse(List.of(expectedGenerator));
ChatResponse response = chatModel.call(prompt);
@@ -205,10 +206,9 @@ public class WatsonxAiChatModelTest {
Flux<WatsonxAiChatResponse> fakeResponse = Flux.just(fakeResponseFirst, fakeResponseSecond);
given(mockChatApi.generateStreaming(any(WatsonxAiChatRequest.class))).willReturn(fakeResponse);
Generation firstGen = new Generation("LLM resp")
.withGenerationMetadata(ChatGenerationMetadata.from("max_tokens",
Map.of("warnings", List.of(Map.of("message", "the message", "id", "disclaimer_warning")))));
Generation secondGen = new Generation("onse");
Generation firstGen = new Generation(new AssistantMessage("LLM resp"), ChatGenerationMetadata.from("max_tokens",
Map.of("warnings", List.of(Map.of("message", "the message", "id", "disclaimer_warning")))));
Generation secondGen = new Generation(new AssistantMessage("onse"));
Flux<ChatResponse> response = chatModel.stream(prompt);

View File

@@ -279,11 +279,6 @@ public class ZhiPuAiApi {
*/
@JsonProperty("tool_calls")
TOOL_CALLS,
/**
* (deprecated) The model called a function.
*/
@JsonProperty("function_call")
FUNCTION_CALL,
/**
* Only for compatibility with Mistral AI API.
*/

View File

@@ -16,13 +16,11 @@
package org.springframework.ai.chat.model;
import java.util.Map;
import java.util.Objects;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.model.ModelResult;
import org.springframework.lang.Nullable;
/**
* Represents a response returned by the AI.
@@ -33,22 +31,6 @@ public class Generation implements ModelResult<AssistantMessage> {
private ChatGenerationMetadata chatGenerationMetadata;
/**
* @deprecated Use {@link #Generation(AssistantMessage)} constructor instead.
*/
@Deprecated
public Generation(String text) {
this(text, Map.of());
}
/**
* @deprecated Use {@link #Generation(AssistantMessage)} constructor instead.
*/
@Deprecated
public Generation(String text, Map<String, Object> properties) {
this(new AssistantMessage(text, properties));
}
public Generation(AssistantMessage assistantMessage) {
this(assistantMessage, ChatGenerationMetadata.NULL);
}
@@ -69,18 +51,6 @@ public class Generation implements ModelResult<AssistantMessage> {
return chatGenerationMetadata != null ? chatGenerationMetadata : ChatGenerationMetadata.NULL;
}
/**
* @deprecated Use {@link #Generation(AssistantMessage, ChatGenerationMetadata)}
* constructor instead.
* @param chatGenerationMetadata
* @return
*/
@Deprecated
public Generation withGenerationMetadata(@Nullable ChatGenerationMetadata chatGenerationMetadata) {
this.chatGenerationMetadata = chatGenerationMetadata;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) {

View File

@@ -17,7 +17,6 @@
package org.springframework.ai.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.NonNull;
/**
* Converts the (raw) LLM output into a structured responses of type. The
@@ -30,11 +29,4 @@ import org.springframework.lang.NonNull;
*/
public interface StructuredOutputConverter<T> extends Converter<String, T>, FormatProvider {
/**
* @deprecated Use the {@link #convert(Object)} instead.
*/
default T parse(@NonNull String source) {
return this.convert(source);
}
}

View File

@@ -38,21 +38,6 @@ public class Media {
private final Object data;
/**
* The Media class represents the data and metadata of a media attachment in a
* message. It consists of a MIME type and the raw data.
*
* This class is used as a parameter in the constructor of the UserMessage class.
* @deprecated This constructor is deprecated since version 1.0.0 M1 and will be
* removed in a future release.
*/
@Deprecated(since = "1.0.0 M1", forRemoval = true)
public Media(MimeType mimeType, Object data) {
Assert.notNull(mimeType, "MimeType must not be null");
this.mimeType = mimeType;
this.data = data;
}
public Media(MimeType mimeType, URL url) {
Assert.notNull(mimeType, "MimeType must not be null");
this.mimeType = mimeType;

View File

@@ -167,6 +167,7 @@ public class MethodFunctionCallback implements FunctionCallback {
return ModelOptionsUtils.toJsonString(response);
}
return "" + response;
}
catch (Exception e) {

View File

@@ -26,6 +26,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
@@ -56,9 +57,9 @@ public class ChatClientResponseEntityTests {
ChatResponseMetadata metadata = ChatResponseMetadata.builder().withKeyValue("key1", "value1").build();
var chatResponse = new ChatResponse(List.of(new Generation("""
var chatResponse = new ChatResponse(List.of(new Generation(new AssistantMessage("""
{"name":"John", "age":30}
""")), metadata);
"""))), metadata);
given(this.chatModel.call(this.promptCaptor.capture())).willReturn(chatResponse);
@@ -82,12 +83,12 @@ public class ChatClientResponseEntityTests {
@Test
public void parametrizedResponseEntityTest() {
var chatResponse = new ChatResponse(List.of(new Generation("""
var chatResponse = new ChatResponse(List.of(new Generation(new AssistantMessage("""
[
{"name":"Max", "age":10},
{"name":"Adi", "age":13}
]
""")));
"""))));
given(this.chatModel.call(this.promptCaptor.capture())).willReturn(chatResponse);
@@ -112,9 +113,9 @@ public class ChatClientResponseEntityTests {
@Test
public void customSoCResponseEntityTest() {
var chatResponse = new ChatResponse(List.of(new Generation("""
var chatResponse = new ChatResponse(List.of(new Generation(new AssistantMessage("""
{"name":"Max", "age":10},
""")));
"""))));
given(this.chatModel.call(this.promptCaptor.capture())).willReturn(chatResponse);

View File

@@ -89,18 +89,6 @@ public class CassandraVectorStoreProperties extends CommonVectorStoreProperties
this.embeddingColumnName = embeddingColumnName;
}
@Deprecated
public boolean getDisallowSchemaCreation() {
logger.warn("getDisallowSchemaCreation() is deprecated, use isInitializeSchema()");
return !super.isInitializeSchema();
}
@Deprecated
public void setDisallowSchemaCreation(boolean disallowSchemaCreation) {
logger.warn("setDisallowSchemaCreation(boolean) is deprecated, use setInitializeSchema(boolean)");
super.setInitializeSchema(!disallowSchemaCreation);
}
public boolean getReturnEmbeddings() {
return this.returnEmbeddings;
}

View File

@@ -36,7 +36,6 @@ class CassandraVectorStorePropertiesTests {
assertThat(props.getContentColumnName()).isEqualTo(CassandraVectorStoreConfig.DEFAULT_CONTENT_COLUMN_NAME);
assertThat(props.getEmbeddingColumnName()).isEqualTo(CassandraVectorStoreConfig.DEFAULT_EMBEDDING_COLUMN_NAME);
assertThat(props.getIndexName()).isNull();
assertThat(props.getDisallowSchemaCreation()).isTrue();
assertThat(props.getFixedThreadPoolExecutorSize())
.isEqualTo(CassandraVectorStoreConfig.DEFAULT_ADD_CONCURRENCY);
}
@@ -49,7 +48,6 @@ class CassandraVectorStorePropertiesTests {
props.setContentColumnName("my_content");
props.setEmbeddingColumnName("my_vector");
props.setIndexName("my_sai");
props.setDisallowSchemaCreation(true);
props.setFixedThreadPoolExecutorSize(10);
assertThat(props.getKeyspace()).isEqualTo("my_keyspace");
@@ -57,7 +55,6 @@ class CassandraVectorStorePropertiesTests {
assertThat(props.getContentColumnName()).isEqualTo("my_content");
assertThat(props.getEmbeddingColumnName()).isEqualTo("my_vector");
assertThat(props.getIndexName()).isEqualTo("my_sai");
assertThat(props.getDisallowSchemaCreation()).isTrue();
assertThat(props.getFixedThreadPoolExecutorSize()).isEqualTo(10);
}

View File

@@ -52,8 +52,6 @@ import static org.springframework.ai.autoconfigure.vectorstore.observation.Obser
@Testcontainers
public class Neo4jVectorStoreAutoConfigurationIT {
// Needs to be Neo4j 5.15+, because Neo4j 5.15 deprecated the used embedding storing
// function.
@Container
static Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.18"))
.withRandomPassword();

View File

@@ -23,8 +23,6 @@ import org.testcontainers.utility.DockerImageName;
*/
public final class Neo4jImage {
// Needs to be Neo4j 5.15+ because Neo4j 5.15 deprecated the old vector index creation
// function.
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("neo4j:5.24");
private Neo4jImage() {

View File

@@ -79,18 +79,6 @@ public class QdrantVectorStore extends AbstractObservationVectorStore implements
private final BatchingStrategy batchingStrategy;
/**
* Constructs a new QdrantVectorStore.
* @param config The configuration for the store.
* @param embeddingModel The client for embedding operations.
* @deprecated since 1.0.0 in favor of {@link QdrantVectorStore}.
*/
@Deprecated(since = "1.0.0", forRemoval = true)
public QdrantVectorStore(QdrantClient qdrantClient, QdrantVectorStoreConfig config, EmbeddingModel embeddingModel,
boolean initializeSchema) {
this(qdrantClient, config.collectionName, embeddingModel, initializeSchema);
}
/**
* Constructs a new QdrantVectorStore.
* @param qdrantClient A {@link QdrantClient} instance for interfacing with Qdrant.
@@ -283,66 +271,4 @@ public class QdrantVectorStore extends AbstractObservationVectorStore implements
}
/**
* Configuration class for the QdrantVectorStore.
*
* @deprecated since 1.0.0 in favor of {@link QdrantVectorStore}.
*/
@Deprecated(since = "1.0.0", forRemoval = true)
public static final class QdrantVectorStoreConfig {
private final String collectionName;
/*
* Constructor using the builder.
*
* @param builder The configuration builder.
*/
private QdrantVectorStoreConfig(Builder builder) {
this.collectionName = builder.collectionName;
}
/**
* Start building a new configuration.
* @return The entry point for creating a new configuration.
*/
public static Builder builder() {
return new Builder();
}
/**
* {@return the default config}
*/
public static QdrantVectorStoreConfig defaultConfig() {
return builder().build();
}
public final static class Builder {
private String collectionName;
private Builder() {
}
/**
* @param collectionName REQUIRED. The name of the collection.
*/
public Builder withCollectionName(String collectionName) {
this.collectionName = collectionName;
return this;
}
/**
* {@return the immutable configuration}
*/
public QdrantVectorStoreConfig build() {
Assert.notNull(this.collectionName, "collectionName cannot be null");
return new QdrantVectorStoreConfig(this);
}
}
}
}

View File

@@ -29,6 +29,7 @@ import io.qdrant.client.grpc.Collections.VectorParams;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariables;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.qdrant.QdrantContainer;
@@ -53,8 +54,8 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 0.8.1
*/
@Testcontainers
@EnabledIfEnvironmentVariable(named = "MISTRAL_AI_API_KEY", matches = ".+")
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
@EnabledIfEnvironmentVariables({ @EnabledIfEnvironmentVariable(named = "MISTRAL_AI_API_KEY", matches = ".+"),
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+") })
public class QdrantVectorStoreIT {
private static final String COLLECTION_NAME = "test_collection";