diff --git a/java/connectors/semantickernel-connectors-memory-redis/pom.xml b/java/connectors/semantickernel-connectors-memory-redis/pom.xml index a8280a0cc8..eb419a16ce 100644 --- a/java/connectors/semantickernel-connectors-memory-redis/pom.xml +++ b/java/connectors/semantickernel-connectors-memory-redis/pom.xml @@ -13,6 +13,15 @@ Semantic Kernel Redis Memory Connector Defines connector for Redis to be used with the Semantic Kernel + + UTF-8 + UTF-8 + 17 + 17 + 17 + 17 + + com.fasterxml.jackson.core @@ -48,16 +57,18 @@ compile - - - - - - - - - - - - + + + + org.apache.maven.plugins + maven-compiler-plugin + + + 17 + 17 + 17 + + + + \ No newline at end of file diff --git a/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/JsonMemoryRecord.java b/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/JsonMemoryRecord.java index 2684092ea4..6a2bf1a63c 100644 --- a/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/JsonMemoryRecord.java +++ b/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/JsonMemoryRecord.java @@ -21,6 +21,7 @@ public class JsonMemoryRecord { static final String EMBEDDING = "Embedding"; static final String EXTERNAL_SOURCE_NAME = "ExternalSourceName"; static final String IS_REFERENCE = "Reference"; + static final String TIME = "Timestamp"; private final String id; private final String text; diff --git a/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryRecord.java b/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryRecord.java index 5411c9f722..d0f20a7ef8 100644 --- a/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryRecord.java +++ b/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryRecord.java @@ -48,9 +48,9 @@ public class RedisMemoryRecord extends JsonMemoryRecord { ZonedDateTime time = null; ObjectMapper mapper = new ObjectMapper(); try { -// if (map.get(TIME) != null) { -// time = mapper.readValue(map.get(TIME), ZonedDateTime.class); -// } + if (map.get(TIME) != null) { + time = mapper.readValue(map.getOrDefault(TIME, ZonedDateTime.now().toString()), ZonedDateTime.class); + } if (withEmbedding) { List embeddings = mapper.readValue(map.get(EMBEDDING), List.class); embedding = new Embedding(embeddings); diff --git a/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryStore.java b/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryStore.java index abc6aeb35e..368e0b9e45 100644 --- a/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryStore.java +++ b/java/connectors/semantickernel-connectors-memory-redis/src/main/java/com/microsoft/semantickernel/connectors/memory/redis/RedisMemoryStore.java @@ -35,24 +35,30 @@ public class RedisMemoryStore implements MemoryStore { private static final VectorAlgorithm DefaultIndexAlgorithm = VectorAlgorithm.HNSW; // FLAT or HNSW private static final String DefaultVectorType = RedisVectorType.FLOAT32; // prefer better accuracy private static final String DefaultDistanceMetric = RedisVectorDistanceMetric.L2; - private static final int DefaultQueryDialect = 2; // this has to be >= 2 for vector functionality + private static final Integer DefaultQueryDialect = 2; // this has to be >= 2 for vector functionality private static final Integer DefaultVectorSize = 1536; // framework model dependent - ada-002 private static final String SUFFIX = "sk"; private static final String INDEX = "idx"; private static final String OK = "OK"; private final JedisPooled client; - private int vectorSize = DefaultVectorSize; + private Integer vectorSize = DefaultVectorSize; private VectorAlgorithm vectorIndexAlgorithm = DefaultIndexAlgorithm; private String vectorDistanceMetric = DefaultDistanceMetric; private String vectorType = DefaultVectorType; - private int queryDialect; + private Integer queryDialect; + + public static void isXinRange(Integer x, Integer lower, Integer upper, String message) { + if (lower > x || x > upper) { + throw new IllegalArgumentException(MessageFormat.format(message, x)); + } + } /** * Create a new instance of semantic memory using Redis. * * @param client A Redis Database client connection. - * @param vectorSize Embedding vector size, defaults to 1536. + * @param vectorSize Embedding vector size, defaults to 1536 - framework model dependent - ada-002. * @param vectorIndexAlgorithm Indexing algorithm for vectors, defaults to "HNSW" * @param vectorDistanceMetric Metric for measuring vector distances, defaults to "COSINE" * @param queryDialect Query dialect, must be 2 or greater for vector similarity searching, defaults to 2 @@ -62,15 +68,13 @@ public class RedisMemoryStore implements MemoryStore { Integer vectorSize, VectorAlgorithm vectorIndexAlgorithm, String vectorDistanceMetric, - int queryDialect + Integer queryDialect ) { - if (vectorSize <= 0) { - throw new InvalidParameterException( - MessageFormat.format( - "Invalid vector size: {vectorSize}. Vector size must be a positive integer.", - vectorSize.toString())); - } + isXinRange(vectorSize, 0, 8192, + "Invalid vector size: {x}. Vector size must be in the range 0-8192."); + isXinRange(queryDialect, 2, 4, + "Invalid query dialect: {x}. Query dialect must be in the range 2-4."); this.client = client; @@ -91,17 +95,16 @@ public class RedisMemoryStore implements MemoryStore { */ public RedisMemoryStore( String connectionString, - int vectorSize, + Integer vectorSize, VectorAlgorithm vectorIndexAlgorithm, String vectorDistanceMetric, - int queryDialect) { + Integer queryDialect) { + + isXinRange(vectorSize, 0, 8192, + "Invalid vector size: {x}. Vector size must be in the range 0-8192."); + isXinRange(queryDialect, 2, 4, + "Invalid query dialect: {x}. Query dialect must be in the range 2-4."); - if (vectorSize <= 0) { - throw new InvalidParameterException( - MessageFormat.format( - "Invalid vector size: {vectorSize}. Vector size must be a positive integer.", - vectorSize)); - } this.client = new JedisPooled(connectionString); this.vectorSize = vectorSize; @@ -171,7 +174,7 @@ public class RedisMemoryStore implements MemoryStore { @Override public Mono createCollectionAsync(@Nonnull String collectionName) { - // Indexes are created when sending a record. The creation requires the size of the + // Indexes are created when sending a record; creation requires the size of the embedding vector return Mono.empty(); } @@ -373,12 +376,11 @@ public class RedisMemoryStore implements MemoryStore { RedisException.ErrorCodes.INVALID_EMBEDDING_SIZE, "the value must be greater than zero"); } - Map attributes = new HashMap() { - { - put(RedisIndexSchemaParams.TYPE, vectorType); - put(RedisIndexSchemaParams.DIM, embeddingSize); - put(RedisIndexSchemaParams.DIST, vectorDistanceMetric); } - }; + Map attributes = Map.ofEntries( + new AbstractMap.SimpleEntry(RedisIndexSchemaParams.TYPE, vectorType), + new AbstractMap.SimpleEntry(RedisIndexSchemaParams.DIM, embeddingSize), + new AbstractMap.SimpleEntry(RedisIndexSchemaParams.DIST, vectorDistanceMetric)); + Schema schema = new Schema() .addVectorField("Embedding", Schema.VectorField.VectorAlgo.FLAT, attributes).as("Embedding") .addTextField("Id", 1.0).as("Id") @@ -547,7 +549,7 @@ public class RedisMemoryStore implements MemoryStore { vectorSize, vectorIndexAlgorithm, vectorDistanceMetric, - (queryDialect >= 2 ? queryDialect : 2) + queryDialect ); }