This is an automated email from the ASF dual-hosted git repository.

wenjin272 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/flink-agents.git


The following commit(s) were added to refs/heads/main by this push:
     new 678c5a7c [api][java][python] Reject null and non-positive limit in 
VectorStoreQuery (#1144)
678c5a7c is described below

commit 678c5a7c9c35887f869c24f89b7f2d8ee96057cf
Author: william <[email protected]>
AuthorDate: Tue Sep 22 14:50:44 2026 +0800

    [api][java][python] Reject null and non-positive limit in VectorStoreQuery 
(#1144)
    
    Generated-by: CodeBuddy (Auto model)
---
 .../agents/api/vectorstores/VectorStoreQuery.java  |  10 +-
 .../api/vectorstores/VectorStoreQueryTest.java     | 108 +++++++++++++++++++++
 .../api/tests/test_vector_store_query.py           |  43 ++++++++
 .../flink_agents/api/vector_stores/vector_store.py |   6 +-
 4 files changed, 164 insertions(+), 3 deletions(-)

diff --git 
a/api/src/main/java/org/apache/flink/agents/api/vectorstores/VectorStoreQuery.java
 
b/api/src/main/java/org/apache/flink/agents/api/vectorstores/VectorStoreQuery.java
index c0e1be65..b364db53 100644
--- 
a/api/src/main/java/org/apache/flink/agents/api/vectorstores/VectorStoreQuery.java
+++ 
b/api/src/main/java/org/apache/flink/agents/api/vectorstores/VectorStoreQuery.java
@@ -89,10 +89,11 @@ public class VectorStoreQuery {
      *
      * @param mode the query mode
      * @param queryText the text to search for
-     * @param limit maximum number of results to return
+     * @param limit maximum number of results to return; must be non-null and 
positive
      * @param collection the collection to query to
      * @param filters unified filter DSL (equality shorthand) or {@code null} 
for no filter
      * @param extraArgs store-specific additional parameters
+     * @throws IllegalArgumentException if {@code limit} is {@code null} or 
non-positive
      */
     public VectorStoreQuery(
             VectorStoreQueryMode mode,
@@ -101,6 +102,13 @@ public class VectorStoreQuery {
             @Nullable String collection,
             @Nullable Map<String, Object> filters,
             Map<String, Object> extraArgs) {
+        if (limit == null) {
+            throw new IllegalArgumentException("`limit` must not be null.");
+        }
+        if (limit <= 0) {
+            throw new IllegalArgumentException(
+                    String.format("`limit` must be positive, but was %d.", 
limit));
+        }
         this.mode = mode;
         this.queryText = queryText;
         this.limit = limit;
diff --git 
a/api/src/test/java/org/apache/flink/agents/api/vectorstores/VectorStoreQueryTest.java
 
b/api/src/test/java/org/apache/flink/agents/api/vectorstores/VectorStoreQueryTest.java
new file mode 100644
index 00000000..f051f466
--- /dev/null
+++ 
b/api/src/test/java/org/apache/flink/agents/api/vectorstores/VectorStoreQueryTest.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ *
+ *     http://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.apache.flink.agents.api.vectorstores;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+/** Tests for {@link VectorStoreQuery}. */
+class VectorStoreQueryTest {
+
+    @Test
+    @DisplayName("Null limit is rejected with a message naming the parameter")
+    void testNullLimitRejected() {
+        assertThatThrownBy(() -> new VectorStoreQuery("flink", null))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("limit");
+    }
+
+    @Test
+    @DisplayName("Negative limit is rejected with a message naming the 
parameter and its value")
+    void testNegativeLimitRejected() {
+        assertThatThrownBy(() -> new VectorStoreQuery("flink", -1))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("limit")
+                .hasMessageContaining("-1");
+    }
+
+    @Test
+    @DisplayName("Negative limit is rejected through the fully specified 
constructor")
+    void testNegativeLimitRejectedWithAllArguments() {
+        assertThatThrownBy(
+                        () ->
+                                new VectorStoreQuery(
+                                        VectorStoreQueryMode.SEMANTIC,
+                                        "flink",
+                                        -5,
+                                        "collection",
+                                        null,
+                                        new HashMap<>()))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("limit");
+    }
+
+    @Test
+    @DisplayName("Zero limit is rejected with a message naming the parameter 
and its value")
+    void testZeroLimitRejected() {
+        assertThatThrownBy(() -> new VectorStoreQuery("flink", 0))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("limit")
+                .hasMessageContaining("0");
+    }
+
+    @Test
+    @DisplayName("Zero limit is rejected through the fully specified 
constructor")
+    void testZeroLimitRejectedWithAllArguments() {
+        assertThatThrownBy(
+                        () ->
+                                new VectorStoreQuery(
+                                        VectorStoreQueryMode.SEMANTIC,
+                                        "flink",
+                                        0,
+                                        "collection",
+                                        null,
+                                        new HashMap<>()))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessageContaining("limit")
+                .hasMessageContaining("0");
+    }
+
+    @Test
+    @DisplayName("Positive limits stay legal and are returned unchanged")
+    void testPositiveLimitsAccepted() {
+        assertThat(new VectorStoreQuery("flink", 5).getLimit()).isEqualTo(5);
+
+        assertThat(
+                        new VectorStoreQuery(
+                                        VectorStoreQueryMode.SEMANTIC,
+                                        "flink",
+                                        10,
+                                        "collection",
+                                        null,
+                                        Collections.emptyMap())
+                                .getLimit())
+                .isEqualTo(10);
+    }
+}
diff --git a/python/flink_agents/api/tests/test_vector_store_query.py 
b/python/flink_agents/api/tests/test_vector_store_query.py
new file mode 100644
index 00000000..28d9ec95
--- /dev/null
+++ b/python/flink_agents/api/tests/test_vector_store_query.py
@@ -0,0 +1,43 @@
+################################################################################
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you 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
+#
+#      http://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.
+#################################################################################
+"""Tests for the limit validation of :class:`VectorStoreQuery`."""
+
+from __future__ import annotations
+
+import pytest
+from pydantic import ValidationError
+
+from flink_agents.api.vector_stores.vector_store import VectorStoreQuery
+
+
+def test_negative_limit_rejected() -> None:
+    with pytest.raises(ValidationError, match="limit"):
+        VectorStoreQuery(query_text="flink", limit=-1)
+
+
+def test_zero_limit_rejected() -> None:
+    with pytest.raises(ValidationError, match="limit"):
+        VectorStoreQuery(query_text="flink", limit=0)
+
+
+def test_positive_limits_accepted() -> None:
+    assert VectorStoreQuery(query_text="flink", limit=5).limit == 5
+
+
+def test_default_limit_unchanged() -> None:
+    assert VectorStoreQuery(query_text="flink").limit == 10
diff --git a/python/flink_agents/api/vector_stores/vector_store.py 
b/python/flink_agents/api/vector_stores/vector_store.py
index d16d00c7..f825fd80 100644
--- a/python/flink_agents/api/vector_stores/vector_store.py
+++ b/python/flink_agents/api/vector_stores/vector_store.py
@@ -54,7 +54,7 @@ class VectorStoreQuery(BaseModel):
     query_text : str
         Text query to be converted to embedding for semantic search.
     limit : int
-        Maximum number of results to return (default: 10).
+        Maximum number of results to return; must be positive (default: 10).
     collection_name : str
         The collection to apply the query. Optional.
     extra_args : Dict[str, Any]
@@ -69,7 +69,9 @@ class VectorStoreQuery(BaseModel):
     query_text: str = Field(
         description="Text query to be converted to embedding for semantic 
search."
     )
-    limit: int = Field(default=10, description="Maximum number of results to 
return.")
+    limit: int = Field(
+        default=10, gt=0, description="Maximum number of results to return."
+    )
     collection_name: str | None = Field(
         default=None, description="The collection to apply the query."
     )

Reply via email to