>() {});
}
+
+ /**
+ * Get aggregated test result statistics with all sections.
+ *
+ * @return typed TestResultStats with all sections populated
+ */
+ public TestResultStats stats() {
+ return stats(TestResultStatsMode.ALL, null);
+ }
+
+ /**
+ * Get aggregated test result statistics with the given mode.
+ *
+ * @param mode controls which sections the backend populates
+ * @return typed TestResultStats
+ */
+ public TestResultStats stats(TestResultStatsMode mode) {
+ return stats(mode, null);
+ }
+
+ /**
+ * Get aggregated test result statistics with full control over mode and filters.
+ *
+ * Supported filter keys:
+ *
+ *
+ * - {@code months} โ number of months of historical data (default 6)
+ *
- {@code test_run_id} โ filter by a single test run ID
+ *
- {@code test_run_ids} โ filter by multiple test run IDs (List)
+ *
- {@code test_set_ids} โ filter by test set IDs (List)
+ *
- {@code behavior_ids} โ filter by behavior IDs (List)
+ *
- {@code category_ids} โ filter by category IDs (List)
+ *
- {@code topic_ids} โ filter by topic IDs (List)
+ *
- {@code status_ids} โ filter by test status IDs (List)
+ *
- {@code test_ids} โ filter by specific test IDs (List)
+ *
- {@code test_type_ids} โ filter by test type IDs (List)
+ *
- {@code user_ids} โ filter by test creator user IDs (List)
+ *
- {@code assignee_ids} โ filter by assignee user IDs (List)
+ *
- {@code owner_ids} โ filter by test owner user IDs (List)
+ *
- {@code prompt_ids} โ filter by prompt IDs (List)
+ *
- {@code priority_min} โ minimum priority (inclusive)
+ *
- {@code priority_max} โ maximum priority (inclusive)
+ *
- {@code tags} โ filter by tags (List)
+ *
- {@code start_date} โ start date (ISO format), overrides months
+ *
- {@code end_date} โ end date (ISO format), overrides months
+ *
+ *
+ * @param mode controls which sections the backend populates
+ * @param params optional filter parameters (may be null)
+ * @return typed TestResultStats
+ */
+ public TestResultStats stats(TestResultStatsMode mode, Map params) {
+ StringBuilder path = new StringBuilder("/test_results/stats?mode=");
+ path.append(encode(mode.getValue()));
+
+ if (params != null) {
+ for (Map.Entry entry : params.entrySet()) {
+ Object value = entry.getValue();
+ if (value instanceof List> listVal) {
+ for (Object item : listVal) {
+ path.append("&")
+ .append(encode(entry.getKey()))
+ .append("=")
+ .append(encode(item.toString()));
+ }
+ } else {
+ path.append("&")
+ .append(encode(entry.getKey()))
+ .append("=")
+ .append(encode(value.toString()));
+ }
+ }
+ }
+
+ return httpClient.get(path.toString(), TestResultStats.class);
+ }
+
+ private static String encode(String value) {
+ return java.net.URLEncoder.encode(value, java.nio.charset.StandardCharsets.UTF_8);
+ }
}
diff --git a/src/main/java/ai/rhesis/sdk/clients/TestRunClient.java b/src/main/java/ai/rhesis/sdk/clients/TestRunClient.java
index 9528983..c231ad4 100644
--- a/src/main/java/ai/rhesis/sdk/clients/TestRunClient.java
+++ b/src/main/java/ai/rhesis/sdk/clients/TestRunClient.java
@@ -2,9 +2,13 @@
import ai.rhesis.sdk.entities.TestResult;
import ai.rhesis.sdk.entities.TestRun;
+import ai.rhesis.sdk.entities.stats.TestRunStats;
+import ai.rhesis.sdk.enums.TestRunStatsMode;
import ai.rhesis.sdk.http.InternalHttpClient;
import com.fasterxml.jackson.core.type.TypeReference;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
public class TestRunClient {
private final InternalHttpClient httpClient;
@@ -28,4 +32,76 @@ public List getTestResults(String testRunId) {
String filter = "?$filter=test_run_id%20eq%20'" + testRunId + "'";
return httpClient.get("/test_results/" + filter, new TypeReference>() {});
}
+
+ /**
+ * Get aggregated test run statistics with all sections.
+ *
+ * @return typed TestRunStats with all sections populated
+ */
+ public TestRunStats stats() {
+ return stats(TestRunStatsMode.ALL, null);
+ }
+
+ /**
+ * Get aggregated test run statistics with the given mode.
+ *
+ * @param mode controls which sections the backend populates
+ * @return typed TestRunStats
+ */
+ public TestRunStats stats(TestRunStatsMode mode) {
+ return stats(mode, null);
+ }
+
+ /**
+ * Get statistics scoped to specific test run IDs.
+ *
+ * @param testRunIds list of test run IDs to filter by
+ * @return typed TestRunStats
+ */
+ public TestRunStats stats(List testRunIds) {
+ Map params = new LinkedHashMap<>();
+ if (testRunIds != null && !testRunIds.isEmpty()) {
+ params.put("test_run_ids", testRunIds);
+ }
+ return stats(TestRunStatsMode.ALL, params);
+ }
+
+ /**
+ * Get aggregated test run statistics with full control over mode and filters.
+ *
+ * @param mode controls which sections the backend populates
+ * @param params optional filter parameters. Supported keys: "months", "top", "test_run_ids"
+ * (List), "user_ids" (List), "endpoint_ids" (List), "test_set_ids" (List), "status_list"
+ * (List), "start_date", "end_date"
+ * @return typed TestRunStats
+ */
+ public TestRunStats stats(TestRunStatsMode mode, Map params) {
+ StringBuilder path = new StringBuilder("/test_runs/stats?mode=");
+ path.append(encode(mode.getValue()));
+
+ if (params != null) {
+ for (Map.Entry entry : params.entrySet()) {
+ Object value = entry.getValue();
+ if (value instanceof List> listVal) {
+ for (Object item : listVal) {
+ path.append("&")
+ .append(encode(entry.getKey()))
+ .append("=")
+ .append(encode(item.toString()));
+ }
+ } else {
+ path.append("&")
+ .append(encode(entry.getKey()))
+ .append("=")
+ .append(encode(value.toString()));
+ }
+ }
+ }
+
+ return httpClient.get(path.toString(), TestRunStats.class);
+ }
+
+ private static String encode(String value) {
+ return java.net.URLEncoder.encode(value, java.nio.charset.StandardCharsets.UTF_8);
+ }
}
diff --git a/src/main/java/ai/rhesis/sdk/clients/TestSetClient.java b/src/main/java/ai/rhesis/sdk/clients/TestSetClient.java
index e600f96..f64f941 100644
--- a/src/main/java/ai/rhesis/sdk/clients/TestSetClient.java
+++ b/src/main/java/ai/rhesis/sdk/clients/TestSetClient.java
@@ -1,9 +1,13 @@
package ai.rhesis.sdk.clients;
+import ai.rhesis.sdk.entities.ExecutionRequest;
+import ai.rhesis.sdk.entities.TestRun;
import ai.rhesis.sdk.entities.TestSet;
+import ai.rhesis.sdk.enums.ExecutionMode;
import ai.rhesis.sdk.http.InternalHttpClient;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.List;
+import java.util.Map;
public class TestSetClient {
private final InternalHttpClient httpClient;
@@ -37,4 +41,188 @@ public List getTests(String id, int skip, int limit
public void delete(String id) {
httpClient.delete("/test_sets/" + id);
}
+
+ /**
+ * Execute a test set against the given endpoint.
+ *
+ * @param testSetId the test set ID
+ * @param endpointId the endpoint ID to execute tests against
+ * @return the execution submission response
+ */
+ public Map execute(String testSetId, String endpointId) {
+ return execute(testSetId, endpointId, ExecutionMode.PARALLEL, null);
+ }
+
+ /**
+ * Execute a test set against the given endpoint.
+ *
+ * @param testSetId the test set ID
+ * @param endpointId the endpoint ID to execute tests against
+ * @param mode execution mode (PARALLEL or SEQUENTIAL)
+ * @param metrics optional list of metrics for this execution; each map should contain at least an
+ * "id" key and optionally "name" and "scope"
+ * @return the execution submission response
+ */
+ public Map execute(
+ String testSetId, String endpointId, ExecutionMode mode, List