Fixes #219 - Remove dependency cycles

This commit is contained in:
Mark Pollack
2024-02-19 12:24:16 -05:00
parent 60f9446562
commit a107e313fc
52 changed files with 77 additions and 114 deletions

View File

@@ -18,7 +18,6 @@ package org.springframework.ai.azure.openai;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import com.azure.ai.openai.OpenAIClient;
import com.azure.ai.openai.models.ChatChoice;
@@ -36,7 +35,7 @@ import reactor.core.publisher.Flux;
import org.springframework.ai.azure.openai.metadata.AzureOpenAiChatResponseMetadata;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.StreamingChatClient;

View File

@@ -24,7 +24,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
/**
* The configuration information for a chat completions request. Completions support a

View File

@@ -29,11 +29,7 @@ import org.springframework.ai.azure.openai.MockAzureOpenAiTestConfiguration;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
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.chat.metadata.*;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
@@ -111,12 +107,12 @@ class AzureOpenAiChatClientMetadataTests {
ChatResponseMetadata chatResponseMetadata = response.getMetadata();
assertThat(chatResponseMetadata).isNotNull();
assertThat(chatResponseMetadata.getRateLimit()).isEqualTo(RateLimit.NULL);
assertThat(chatResponseMetadata.getRateLimit().getRequestsLimit())
.isEqualTo(new EmptyRateLimit().getRequestsLimit());
Usage usage = chatResponseMetadata.getUsage();
assertThat(usage).isNotNull();
assertThat(usage).isNotEqualTo(Usage.NULL);
assertThat(usage.getPromptTokens()).isEqualTo(58);
assertThat(usage.getGenerationTokens()).isEqualTo(68);
assertThat(usage.getTotalTokens()).isEqualTo(126);

View File

@@ -21,7 +21,7 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@@ -19,7 +19,7 @@ package org.springframework.ai.bedrock.anthropic;
import java.util.List;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import reactor.core.publisher.Flux;

View File

@@ -26,7 +26,7 @@ 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.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.StreamingChatClient;

View File

@@ -25,7 +25,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi.CohereChatRequest.LogitBias;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi.CohereChatRequest.ReturnLikelihoods;
import org.springframework.ai.bedrock.cohere.api.CohereChatBedrockApi.CohereChatRequest.Truncate;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
/**
* @author Christian Tzolov

View File

@@ -25,7 +25,7 @@ import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi;
import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatRequest;
import org.springframework.ai.bedrock.llama2.api.Llama2ChatBedrockApi.Llama2ChatResponse;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.StreamingChatClient;

View File

@@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
/**
* @author Christian Tzolov

View File

@@ -26,7 +26,7 @@ import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatReq
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatResponse;
import org.springframework.ai.bedrock.titan.api.TitanChatBedrockApi.TitanChatResponseChunk;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.StreamingChatClient;

View File

@@ -21,7 +21,7 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import com.fasterxml.jackson.annotation.JsonProperty;

View File

@@ -21,7 +21,7 @@ import java.util.List;
import reactor.core.publisher.Flux;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.StreamingChatClient;

View File

@@ -27,7 +27,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.embedding.EmbeddingOptions;
/**

View File

@@ -26,7 +26,7 @@ import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.ChatOptionsBuilder;
import org.springframework.ai.chat.prompt.ChatOptionsBuilder;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;

View File

@@ -18,8 +18,8 @@ package org.springframework.ai.ollama;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.ChatOptionsBuilder;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptionsBuilder;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.ollama.api.OllamaApi;
import org.springframework.ai.ollama.api.OllamaOptions;

View File

@@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.StreamingChatClient;

View File

@@ -27,7 +27,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.model.function.FunctionCallback;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ResponseFormat;
import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionRequest.ToolChoice;

View File

@@ -16,9 +16,7 @@
package org.springframework.ai.openai.metadata;
import org.springframework.ai.chat.metadata.ChatResponseMetadata;
import org.springframework.ai.chat.metadata.RateLimit;
import org.springframework.ai.chat.metadata.Usage;
import org.springframework.ai.chat.metadata.*;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -68,13 +66,13 @@ public class OpenAiChatResponseMetadata implements ChatResponseMetadata {
@Nullable
public RateLimit getRateLimit() {
RateLimit rateLimit = this.rateLimit;
return rateLimit != null ? rateLimit : RateLimit.NULL;
return rateLimit != null ? rateLimit : new EmptyRateLimit();
}
@Override
public Usage getUsage() {
Usage usage = this.usage;
return usage != null ? usage : Usage.NULL;
return usage != null ? usage : new EmptyUsage();
}
public OpenAiChatResponseMetadata withRateLimit(RateLimit rateLimit) {

View File

@@ -20,7 +20,7 @@ import java.util.List;
import java.util.stream.Collectors;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.Generation;
import org.springframework.ai.chat.prompt.Prompt;

View File

@@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptions;
/**
* @author Christian Tzolov

View File

@@ -18,8 +18,8 @@ package org.springframework.ai.vertex;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.ChatOptionsBuilder;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.ChatOptionsBuilder;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.vertex.api.VertexAiApi;

View File

@@ -36,7 +36,7 @@ public interface ChatResponseMetadata extends ResponseMetadata {
* @see RateLimit
*/
default RateLimit getRateLimit() {
return RateLimit.NULL;
return new EmptyRateLimit();
}
/**
@@ -45,7 +45,7 @@ public interface ChatResponseMetadata extends ResponseMetadata {
* @see Usage
*/
default Usage getUsage() {
return Usage.NULL;
return new EmptyUsage();
}
default PromptMetadata getPromptMetadata() {

View File

@@ -19,12 +19,12 @@ package org.springframework.ai.chat.metadata;
import java.time.Duration;
/**
* Abstract base class used as a foundation for implementing {@link RateLimit}.
* A RateLimit implementation that returns zero for all property getters
*
* @author John Blum
* @since 0.7.0
*/
public abstract class AbstractRateLimit implements RateLimit {
public class EmptyRateLimit implements RateLimit {
@Override
public Long getRequestsLimit() {

View File

@@ -17,12 +17,12 @@
package org.springframework.ai.chat.metadata;
/**
* Abstract base class used as a foundation for implementing {@link Usage}.
* A EmpytUsage implementation that returns zero for all property getters
*
* @author John Blum
* @since 0.7.0
*/
public abstract class AbstractUsage implements Usage {
public class EmptyUsage implements Usage {
@Override
public Long getPromptTokens() {

View File

@@ -27,9 +27,6 @@ import java.time.Duration;
*/
public interface RateLimit {
RateLimit NULL = new AbstractRateLimit() {
};
/**
* Returns the maximum number of requests that are permitted before exhausting the
* rate limit.

View File

@@ -25,9 +25,6 @@ package org.springframework.ai.chat.metadata;
*/
public interface Usage {
Usage NULL = new AbstractUsage() {
};
/**
* Returns the number of tokens used in the {@literal prompt} of the AI request.
* @return an {@link Long} with the number of tokens used in the {@literal prompt} of

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.ai.chat;
package org.springframework.ai.chat.prompt;
import org.springframework.ai.model.ModelOptions;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.ai.chat;
package org.springframework.ai.chat.prompt;
public class ChatOptionsBuilder {

View File

@@ -18,7 +18,6 @@ package org.springframework.ai.chat.prompt;
import org.springframework.ai.model.ModelOptions;
import org.springframework.ai.model.ModelRequest;
import org.springframework.ai.chat.ChatOptions;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;

View File

@@ -113,18 +113,6 @@ abstract class AbstractFunctionCallback<I, O> implements Function<I, O>, Functio
this.objectMapper = objectMapper;
}
public static <I, O> AbstractFunctionCallback<I, O> of(String name, String description, Function<I, O> function) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(description, "Description must not be null");
Assert.notNull(function, "Function must not be null");
@SuppressWarnings("unchecked")
final Class<I> inputClassType = (Class<I>) TypeResolverHelper
.getFunctionInputClass((Class<Function<I, O>>) function.getClass());
return new FunctionCallbackWrapper<I, O>(name, description, inputClassType, function);
}
@Override
public String getName() {
return this.name;

View File

@@ -226,7 +226,8 @@ public class SearchRequest {
* @return this.builder
*/
public SearchRequest withFilterExpression(String textExpression) {
this.filterExpression = (textExpression != null) ? Filter.parser().parse(textExpression) : null;
this.filterExpression = (textExpression != null) ? new FilterExpressionTextParser().parse(textExpression)
: null;
return this;
}

View File

@@ -58,28 +58,13 @@ package org.springframework.ai.vectorstore.filter;
*
*
* Usually you will not create expression manually but use either the
* {@link Filter#builder()} DSL or the {@link Filter#parser()} for parsing generic text
* expressions. Follow the {@link FilterExpressionBuilder} and
* {@link FilterExpressionTextParser} documentation for how to use them.
* {@link FilterExpressionBuilder} DSL or the {@link FilterExpressionTextParser} for
* parsing generic text expressions.
*
* @author Christian Tzolov
*/
public class Filter {
/**
* DSL builder for creating {@link Filter.Expression} programmatically.
*/
public static FilterExpressionBuilder builder() {
return new FilterExpressionBuilder();
}
/**
* Parses a portable filter expression text language into {@link Filter.Expression}.
*/
public static FilterExpressionTextParser parser() {
return new FilterExpressionTextParser();
}
/**
* Mark interface representing the supported expression types: {@link Key},
* {@link Value}, {@link Expression} and {@link Group}.

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.ai.vectorstore.filter.converter;
package org.springframework.ai.vectorstore.filter;
import org.springframework.ai.vectorstore.filter.Filter;

View File

@@ -23,7 +23,6 @@ import java.util.Map;
import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.ExpressionType;
import org.springframework.ai.vectorstore.filter.Filter.Operand;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.util.Assert;
/**

View File

@@ -19,6 +19,7 @@ package org.springframework.ai.vectorstore.filter.converter;
import java.util.List;
import org.springframework.ai.vectorstore.filter.Filter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterHelper;
import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.ExpressionType;

View File

@@ -35,19 +35,19 @@ public class FilterHelperTests {
@Test
public void negateEQ() {
assertThat(Filter.parser().parse("NOT key == 'UK' ")).isEqualTo(new Filter.Expression(ExpressionType.NOT,
new Filter.Expression(ExpressionType.EQ, new Key("key"), new Value("UK")), null));
assertThat(new FilterExpressionTextParser().parse("NOT key == 'UK' ")).isEqualTo(new Filter.Expression(
ExpressionType.NOT, new Filter.Expression(ExpressionType.EQ, new Key("key"), new Value("UK")), null));
assertThat(FilterHelper.negate(Filter.parser().parse("NOT key == 'UK' ")))
assertThat(FilterHelper.negate(new FilterExpressionTextParser().parse("NOT key == 'UK' ")))
.isEqualTo(new Filter.Expression(ExpressionType.NE, new Key("key"), new Value("UK")));
assertThat(FilterHelper.negate(Filter.parser().parse("NOT (key == 'UK') ")))
assertThat(FilterHelper.negate(new FilterExpressionTextParser().parse("NOT (key == 'UK') ")))
.isEqualTo(new Filter.Group(new Filter.Expression(ExpressionType.NE, new Key("key"), new Value("UK"))));
}
@Test
public void negateNE() {
var exp = Filter.parser().parse("NOT key != 'UK' ");
var exp = new FilterExpressionTextParser().parse("NOT key != 'UK' ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.EQ, new Key("key"), new Value("UK")));
@@ -55,7 +55,7 @@ public class FilterHelperTests {
@Test
public void negateGT() {
var exp = Filter.parser().parse("NOT key > 13 ");
var exp = new FilterExpressionTextParser().parse("NOT key > 13 ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.LTE, new Key("key"), new Value(13)));
@@ -63,49 +63,49 @@ public class FilterHelperTests {
@Test
public void negateGTE() {
var exp = Filter.parser().parse("NOT key >= 13 ");
var exp = new FilterExpressionTextParser().parse("NOT key >= 13 ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.LT, new Key("key"), new Value(13)));
}
@Test
public void negateLT() {
var exp = Filter.parser().parse("NOT key < 13 ");
var exp = new FilterExpressionTextParser().parse("NOT key < 13 ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.GTE, new Key("key"), new Value(13)));
}
@Test
public void negateLTE() {
var exp = Filter.parser().parse("NOT key <= 13 ");
var exp = new FilterExpressionTextParser().parse("NOT key <= 13 ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.GT, new Key("key"), new Value(13)));
}
@Test
public void negateIN() {
var exp = Filter.parser().parse("NOT key IN [11, 12, 13] ");
var exp = new FilterExpressionTextParser().parse("NOT key IN [11, 12, 13] ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.NIN, new Key("key"), new Value(List.of(11, 12, 13))));
}
@Test
public void negateNIN() {
var exp = Filter.parser().parse("NOT key NIN [11, 12, 13] ");
var exp = new FilterExpressionTextParser().parse("NOT key NIN [11, 12, 13] ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.IN, new Key("key"), new Value(List.of(11, 12, 13))));
}
@Test
public void negateNIN2() {
var exp = Filter.parser().parse("NOT key NOT IN [11, 12, 13] ");
var exp = new FilterExpressionTextParser().parse("NOT key NOT IN [11, 12, 13] ");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Expression(ExpressionType.IN, new Key("key"), new Value(List.of(11, 12, 13))));
}
@Test
public void negateAND() {
var exp = Filter.parser().parse("NOT(key >= 11 AND key < 13)");
var exp = new FilterExpressionTextParser().parse("NOT(key >= 11 AND key < 13)");
assertThat(FilterHelper.negate(exp)).isEqualTo(new Filter.Group(new Filter.Expression(ExpressionType.OR,
new Filter.Expression(ExpressionType.LT, new Key("key"), new Value(11)),
new Filter.Expression(ExpressionType.GTE, new Key("key"), new Value(13)))));
@@ -113,7 +113,7 @@ public class FilterHelperTests {
@Test
public void negateOR() {
var exp = Filter.parser().parse("NOT(key >= 11 OR key < 13)");
var exp = new FilterExpressionTextParser().parse("NOT(key >= 11 OR key < 13)");
assertThat(FilterHelper.negate(exp)).isEqualTo(new Filter.Group(new Filter.Expression(ExpressionType.AND,
new Filter.Expression(ExpressionType.LT, new Key("key"), new Value(11)),
new Filter.Expression(ExpressionType.GTE, new Key("key"), new Value(13)))));
@@ -121,14 +121,14 @@ public class FilterHelperTests {
@Test
public void negateNot() {
var exp = Filter.parser().parse("NOT NOT(key >= 11)");
var exp = new FilterExpressionTextParser().parse("NOT NOT(key >= 11)");
assertThat(FilterHelper.negate(exp))
.isEqualTo(new Filter.Group(new Filter.Expression(ExpressionType.LT, new Key("key"), new Value(11))));
}
@Test
public void negateNestedNot() {
var exp = Filter.parser().parse("NOT(NOT(key >= 11))");
var exp = new FilterExpressionTextParser().parse("NOT(NOT(key >= 11))");
assertThat(exp).isEqualTo(
new Filter.Expression(ExpressionType.NOT, new Filter.Group(new Filter.Expression(ExpressionType.NOT,
new Filter.Group(new Filter.Expression(ExpressionType.GTE, new Key("key"), new Value(11)))))));
@@ -139,14 +139,14 @@ public class FilterHelperTests {
@Test
public void expandIN() {
var exp = Filter.parser().parse("key IN [11, 12, 13] ");
var exp = new FilterExpressionTextParser().parse("key IN [11, 12, 13] ");
assertThat(new InNinTestConverter().convertExpression(exp)).isEqualTo("key EQ 11 OR key EQ 12 OR key EQ 13");
}
@Test
public void expandNIN() {
var exp1 = Filter.parser().parse("key NIN [11, 12, 13] ");
var exp2 = Filter.parser().parse("key NOT IN [11, 12, 13] ");
var exp1 = new FilterExpressionTextParser().parse("key NIN [11, 12, 13] ");
var exp2 = new FilterExpressionTextParser().parse("key NOT IN [11, 12, 13] ");
assertThat(exp1).isEqualTo(exp2);
assertThat(new InNinTestConverter().convertExpression(exp1)).isEqualTo("key NE 11 AND key NE 12 AND key NE 13");
}

View File

@@ -116,7 +116,7 @@ public class SearchRequestTests {
new Filter.Expression(Filter.ExpressionType.EQ, new Filter.Key("active"), new Filter.Value(true)));
assertThat(request.hasFilterExpression()).isTrue();
request.withFilterExpression(Filter.builder().eq("country", "NL").build());
request.withFilterExpression(new FilterExpressionBuilder().eq("country", "NL").build());
assertThat(request.getFilterExpression()).isEqualTo(
new Filter.Expression(Filter.ExpressionType.EQ, new Filter.Key("country"), new Filter.Value("NL")));
assertThat(request.hasFilterExpression()).isTrue();

View File

@@ -24,6 +24,7 @@ import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.Group;
import org.springframework.ai.vectorstore.filter.Filter.Key;
import org.springframework.ai.vectorstore.filter.Filter.Value;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;

View File

@@ -24,6 +24,7 @@ import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.Group;
import org.springframework.ai.vectorstore.filter.Filter.Key;
import org.springframework.ai.vectorstore.filter.Filter.Value;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;

View File

@@ -24,6 +24,7 @@ import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.Group;
import org.springframework.ai.vectorstore.filter.Filter.Key;
import org.springframework.ai.vectorstore.filter.Filter.Value;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;

View File

@@ -170,7 +170,7 @@ or programmatically using the expression DSL:
[source,java]
----
FilterExpressionBuilder b = Filter.builder();
FilterExpressionBuilder b = new FilterExpressionBuilder();
vectorStore.similaritySearch(
SearchRequest

View File

@@ -159,7 +159,7 @@ or programmatically using the expression DSL:
[source,java]
----
FilterExpressionBuilder b = Filter.builder();
FilterExpressionBuilder b = new FilterExpressionBuilder();
vectorStore.similaritySearch(
SearchRequest

View File

@@ -148,7 +148,7 @@ or programmatically using the expression DSL:
[source,java]
----
FilterExpressionBuilder b = Filter.builder();
FilterExpressionBuilder b = new FilterExpressionBuilder();
vectorStore.similaritySearch(
SearchRequest

View File

@@ -49,7 +49,7 @@ import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

View File

@@ -26,7 +26,7 @@ import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.Group;
import org.springframework.ai.vectorstore.filter.Filter.Key;
import org.springframework.ai.vectorstore.filter.Filter.Value;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

View File

@@ -27,7 +27,7 @@ import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.filter.converter.ChromaFilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.ai.chroma.ChromaApi;
import org.springframework.ai.chroma.ChromaApi.AddEmbeddingsRequest;

View File

@@ -54,7 +54,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.converter.MilvusFilterExpressionConverter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

View File

@@ -24,7 +24,6 @@ import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.Group;
import org.springframework.ai.vectorstore.filter.Filter.Key;
import org.springframework.ai.vectorstore.filter.Filter.Value;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;
@@ -130,7 +129,8 @@ public class Neo4jVectorFilterExpressionConverterTests {
@Test
public void testComplexIdentifiers2() {
Filter.Expression expr = Filter.parser().parse("author in ['john', 'jill'] && 'article_type' == 'blog'");
Filter.Expression expr = new FilterExpressionTextParser()
.parse("author in ['john', 'jill'] && 'article_type' == 'blog'");
String vectorExpr = converter.convertExpression(expr);
assertThat(vectorExpr)
.isEqualTo("node.`metadata.author` IN [\"john\",\"jill\"] AND node.`metadata.'article_type'` = \"blog\"");

View File

@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.converter.PgVectorFilterExpressionConverter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;

View File

@@ -36,7 +36,7 @@ import io.pinecone.proto.Vector;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.converter.PineconeFilterExpressionConverter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

View File

@@ -31,7 +31,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingClient;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

View File

@@ -24,7 +24,7 @@ import org.springframework.ai.vectorstore.filter.Filter.Expression;
import org.springframework.ai.vectorstore.filter.Filter.Group;
import org.springframework.ai.vectorstore.filter.Filter.Key;
import org.springframework.ai.vectorstore.filter.Filter.Value;
import org.springframework.ai.vectorstore.filter.converter.FilterExpressionConverter;
import org.springframework.ai.vectorstore.filter.FilterExpressionConverter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;