From 2b685032cb9773edd29e5f0d0a454c333093da04 Mon Sep 17 00:00:00 2001 From: Thiago Hora Date: Fri, 10 Jan 2025 19:20:43 +0100 Subject: [PATCH] [OPIK-736] Fix deserialization issue --- .../opik/api/AutomationRuleEvaluator.java | 42 +++++++++---------- .../AutomationRuleEvaluatorLlmAsJudge.java | 15 ++++--- .../opik/api/AutomationRuleEvaluatorType.java | 8 +++- .../AutomationRuleEvaluatorsResource.java | 24 ++++++----- .../comet/opik/domain/AutomationRuleDAO.java | 4 +- .../AutomationRuleEvaluatorRowMapper.java | 2 - .../AutomationRuleEvaluatorService.java | 34 ++++++++------- .../opik/domain/AutomationRuleRowMapper.java | 7 ++-- ...lmAsJudgeAutomationRuleEvaluatorModel.java | 6 ++- .../AutomationRuleEvaluatorsResourceTest.java | 2 +- 10 files changed, 76 insertions(+), 68 deletions(-) diff --git a/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluator.java b/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluator.java index c4178bb5a2..e6d08de26a 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluator.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluator.java @@ -1,11 +1,13 @@ package com.comet.opik.api; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonView; import io.swagger.v3.oas.annotations.media.DiscriminatorMapping; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -19,54 +21,50 @@ @SuperBuilder(toBuilder = true) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true) @JsonSubTypes({ - @JsonSubTypes.Type(value = AutomationRuleEvaluatorLlmAsJudge.class, name = "llm_as_judge") + @JsonSubTypes.Type(value = AutomationRuleEvaluatorLlmAsJudge.class, name = AutomationRuleEvaluatorType.Constants.LLM_AS_JUDGE) }) @Schema(name = "AutomationRuleEvaluator", discriminatorProperty = "type", discriminatorMapping = { - @DiscriminatorMapping(value = "llm_as_judge", schema = AutomationRuleEvaluatorLlmAsJudge.class) + @DiscriminatorMapping(value = AutomationRuleEvaluatorType.Constants.LLM_AS_JUDGE, schema = AutomationRuleEvaluatorLlmAsJudge.class) }) @AllArgsConstructor -public abstract sealed class AutomationRuleEvaluator - implements - AutomationRule +public abstract sealed class AutomationRuleEvaluator implements AutomationRule permits AutomationRuleEvaluatorLlmAsJudge { @JsonView({View.Public.class}) @Schema(accessMode = Schema.AccessMode.READ_ONLY) - UUID id; + private UUID id; @JsonView({View.Public.class}) @Schema(accessMode = Schema.AccessMode.READ_ONLY) - UUID projectId; + private UUID projectId; @JsonView({View.Public.class, View.Write.class}) - @Schema(accessMode = Schema.AccessMode.READ_WRITE) @NotBlank - String name; + private String name; @JsonView({View.Public.class, View.Write.class}) - @Schema(accessMode = Schema.AccessMode.READ_WRITE) - Float samplingRate; + private Float samplingRate; @JsonView({View.Public.class}) @Schema(accessMode = Schema.AccessMode.READ_ONLY) - Instant createdAt; + private Instant createdAt; @JsonView({View.Public.class}) @Schema(accessMode = Schema.AccessMode.READ_ONLY) - String createdBy; + private String createdBy; @JsonView({View.Public.class}) @Schema(accessMode = Schema.AccessMode.READ_ONLY) - Instant lastUpdatedAt; + private Instant lastUpdatedAt; @JsonView({View.Public.class}) @Schema(accessMode = Schema.AccessMode.READ_ONLY) - String lastUpdatedBy; + private String lastUpdatedBy; - @JsonView({View.Public.class}) - public abstract AutomationRuleEvaluatorType type(); + @NotNull @JsonView({View.Public.class, View.Write.class}) + public abstract AutomationRuleEvaluatorType getType(); - @JsonView({View.Public.class, View.Write.class}) + @JsonIgnore public abstract T getCode(); @Override @@ -87,12 +85,12 @@ public record AutomationRuleEvaluatorPage( View.Public.class}) int page, @JsonView({View.Public.class}) int size, @JsonView({View.Public.class}) long total, - @JsonView({View.Public.class}) List content) + @JsonView({View.Public.class}) List> content) implements - Page{ + Page>{ - public static AutomationRuleEvaluator.AutomationRuleEvaluatorPage empty(int page) { - return new AutomationRuleEvaluator.AutomationRuleEvaluatorPage(page, 0, 0, List.of()); + public static AutomationRuleEvaluatorPage empty(int page) { + return new AutomationRuleEvaluatorPage(page, 0, 0, List.of()); } } } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorLlmAsJudge.java b/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorLlmAsJudge.java index ee5d87640e..b1c369f5c3 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorLlmAsJudge.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorLlmAsJudge.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonView; import dev.langchain4j.data.message.ChatMessageType; -import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Builder; @@ -18,16 +17,15 @@ import java.util.Map; import java.util.UUID; +import static com.comet.opik.api.AutomationRuleEvaluatorLlmAsJudge.LlmAsJudgeCode; + @EqualsAndHashCode(callSuper = true) @Data @SuperBuilder(toBuilder = true) @ToString(callSuper = true) -public final class AutomationRuleEvaluatorLlmAsJudge - extends - AutomationRuleEvaluator { +public final class AutomationRuleEvaluatorLlmAsJudge extends AutomationRuleEvaluator { @NotNull @JsonView({View.Public.class, View.Write.class}) - @Schema(accessMode = Schema.AccessMode.READ_WRITE) private LlmAsJudgeCode code; @Builder(toBuilder = true) @@ -68,14 +66,15 @@ public record LlmAsJudgeModelParameters( @ConstructorProperties({"id", "projectId", "name", "samplingRate", "code", "createdAt", "createdBy", "lastUpdatedAt", "lastUpdatedBy"}) public AutomationRuleEvaluatorLlmAsJudge(UUID id, UUID projectId, @NotBlank String name, Float samplingRate, - @NotNull LlmAsJudgeCode code, - Instant createdAt, String createdBy, Instant lastUpdatedAt, String lastUpdatedBy) { + @NotNull LlmAsJudgeCode code, Instant createdAt, String createdBy, Instant lastUpdatedAt, + String lastUpdatedBy) { super(id, projectId, name, samplingRate, createdAt, createdBy, lastUpdatedAt, lastUpdatedBy); this.code = code; } @Override - public AutomationRuleEvaluatorType type() { + public AutomationRuleEvaluatorType getType() { return AutomationRuleEvaluatorType.LLM_AS_JUDGE; } + } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorType.java b/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorType.java index 73fe68bc70..998d49f151 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorType.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/api/AutomationRuleEvaluatorType.java @@ -4,6 +4,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.experimental.UtilityClass; import java.util.Arrays; @@ -11,7 +12,7 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public enum AutomationRuleEvaluatorType { - LLM_AS_JUDGE("llm_as_judge"); + LLM_AS_JUDGE(Constants.LLM_AS_JUDGE); @JsonValue private final String type; @@ -21,4 +22,9 @@ public static AutomationRuleEvaluatorType fromString(String type) { .filter(v -> v.type.equals(type)).findFirst() .orElseThrow(() -> new IllegalArgumentException("Unknown evaluator type: " + type)); } + + @UtilityClass + public static class Constants { + public static final String LLM_AS_JUDGE = "llm_as_judge"; + } } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResource.java b/apps/opik-backend/src/main/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResource.java index 4bf8fe4acd..146694326a 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResource.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResource.java @@ -2,7 +2,6 @@ import com.codahale.metrics.annotation.Timed; import com.comet.opik.api.AutomationRuleEvaluator; -import com.comet.opik.api.AutomationRuleEvaluatorLlmAsJudge; import com.comet.opik.api.AutomationRuleEvaluatorUpdate; import com.comet.opik.api.BatchDelete; import com.comet.opik.api.Page; @@ -42,6 +41,9 @@ import java.net.URI; import java.util.UUID; +import static com.comet.opik.api.AutomationRuleEvaluator.AutomationRuleEvaluatorPage; +import static com.comet.opik.api.AutomationRuleEvaluator.View; + @Path("/v1/private/automations/projects/{projectId}/evaluators/") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -56,9 +58,9 @@ public class AutomationRuleEvaluatorsResource { @GET @Operation(operationId = "findEvaluators", summary = "Find project Evaluators", description = "Find project Evaluators", responses = { - @ApiResponse(responseCode = "200", description = "Evaluators resource", content = @Content(schema = @Schema(implementation = AutomationRuleEvaluator.AutomationRuleEvaluatorPage.class))) + @ApiResponse(responseCode = "200", description = "Evaluators resource", content = @Content(schema = @Schema(implementation = AutomationRuleEvaluatorPage.class))) }) - @JsonView(AutomationRuleEvaluator.View.Public.class) + @JsonView(View.Public.class) public Response find(@PathParam("projectId") UUID projectId, @QueryParam("name") String name, @QueryParam("page") @Min(1) @DefaultValue("1") int page, @@ -67,12 +69,12 @@ public Response find(@PathParam("projectId") UUID projectId, String workspaceId = requestContext.get().getWorkspaceId(); log.info("Looking for automated evaluators for project id '{}' on workspaceId '{}' (page {})", projectId, workspaceId, page); - Page definitionPage = service.find(projectId, workspaceId, name, page, size); + Page> evaluatorPage = service.find(projectId, workspaceId, name, page, size); log.info("Found {} automated evaluators for project id '{}' on workspaceId '{}' (page {}, total {})", - definitionPage.size(), projectId, workspaceId, page, definitionPage.total()); + evaluatorPage.size(), projectId, workspaceId, page, evaluatorPage.total()); return Response.ok() - .entity(definitionPage) + .entity(evaluatorPage) .build(); } @@ -81,12 +83,12 @@ public Response find(@PathParam("projectId") UUID projectId, @Operation(operationId = "getEvaluatorById", summary = "Get automation rule evaluator by id", description = "Get automation rule by id", responses = { @ApiResponse(responseCode = "200", description = "Automation Rule resource", content = @Content(schema = @Schema(implementation = AutomationRuleEvaluator.class))) }) - @JsonView(AutomationRuleEvaluator.View.Public.class) + @JsonView(View.Public.class) public Response getEvaluator(@PathParam("projectId") UUID projectId, @PathParam("id") UUID evaluatorId) { String workspaceId = requestContext.get().getWorkspaceId(); log.info("Looking for automated evaluator: id '{}' on project_id '{}'", projectId, workspaceId); - AutomationRuleEvaluator evaluator = service.findById(evaluatorId, projectId, workspaceId); + AutomationRuleEvaluator evaluator = service.findById(evaluatorId, projectId, workspaceId); log.info("Found automated evaluator: id '{}' on project_id '{}'", projectId, workspaceId); return Response.ok().entity(evaluator).build(); @@ -101,16 +103,16 @@ public Response getEvaluator(@PathParam("projectId") UUID projectId, @PathParam( @RateLimited public Response createEvaluator( @PathParam("projectId") UUID projectId, - @RequestBody(content = @Content(schema = @Schema(implementation = AutomationRuleEvaluator.class))) @JsonView(AutomationRuleEvaluator.View.Write.class) @NotNull @Valid AutomationRuleEvaluator evaluator, + @RequestBody(content = @Content(schema = @Schema(implementation = AutomationRuleEvaluator.class))) @JsonView(View.Write.class) @NotNull @Valid AutomationRuleEvaluator evaluator, @Context UriInfo uriInfo) { String workspaceId = requestContext.get().getWorkspaceId(); String userName = requestContext.get().getUserName(); - log.info("Creating {} evaluator for project_id '{}' on workspace_id '{}'", evaluator.type(), + log.info("Creating {} evaluator for project_id '{}' on workspace_id '{}'", evaluator.getType(), evaluator.getProjectId(), workspaceId); AutomationRuleEvaluator savedEvaluator = service.save(evaluator, projectId, workspaceId, userName); - log.info("Created {} evaluator '{}' for project_id '{}' on workspace_id '{}'", evaluator.type(), + log.info("Created {} evaluator '{}' for project_id '{}' on workspace_id '{}'", evaluator.getType(), savedEvaluator.getId(), evaluator.getProjectId(), workspaceId); URI uri = uriInfo.getBaseUriBuilder() diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleDAO.java index aed0ce0a3b..2eabaeaf6b 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleDAO.java @@ -1,7 +1,6 @@ package com.comet.opik.domain; import com.comet.opik.api.AutomationRule; -import com.comet.opik.api.AutomationRuleEvaluator; import com.comet.opik.infrastructure.db.UUIDArgumentFactory; import org.jdbi.v3.sqlobject.config.RegisterArgumentFactory; import org.jdbi.v3.sqlobject.config.RegisterConstructorMapper; @@ -20,7 +19,8 @@ @RegisterArgumentFactory(UUIDArgumentFactory.class) @RegisterRowMapper(AutomationRuleRowMapper.class) -@RegisterConstructorMapper(AutomationRuleEvaluator.class) +@RegisterConstructorMapper(LlmAsJudgeAutomationRuleEvaluatorModel.class) +@RegisterRowMapper(AutomationRuleEvaluatorRowMapper.class) interface AutomationRuleDAO { @SqlUpdate("INSERT INTO automation_rules(id, project_id, workspace_id, `action`, name, sampling_rate) " + diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorRowMapper.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorRowMapper.java index 0a7890ff77..73c4cddf45 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorRowMapper.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorRowMapper.java @@ -11,9 +11,7 @@ public class AutomationRuleEvaluatorRowMapper implements RowMapper map(ResultSet rs, StatementContext ctx) throws SQLException { - var type = AutomationRuleEvaluatorType.fromString(rs.getString("type")); - return switch (type) { case LLM_AS_JUDGE -> ctx.findMapperFor(LlmAsJudgeAutomationRuleEvaluatorModel.class) .orElseThrow(() -> new IllegalStateException( diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorService.java index 7f207bee6e..0ac9cf7610 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleEvaluatorService.java @@ -25,6 +25,7 @@ import java.util.Set; import java.util.UUID; +import static com.comet.opik.api.AutomationRuleEvaluator.AutomationRuleEvaluatorPage; import static com.comet.opik.infrastructure.db.TransactionTemplateAsync.READ_ONLY; import static com.comet.opik.infrastructure.db.TransactionTemplateAsync.WRITE; @@ -42,7 +43,7 @@ > T findById(@NonNull UUID id, @NonNull void delete(@NonNull Set ids, @NonNull UUID projectId, @NonNull String workspaceId); - AutomationRuleEvaluator.AutomationRuleEvaluatorPage find(@NonNull UUID projectId, @NonNull String workspaceId, + AutomationRuleEvaluatorPage find(@NonNull UUID projectId, @NonNull String workspaceId, String name, int page, int size); List findAll(@NonNull UUID projectId, @NonNull String workspaceId, @@ -68,7 +69,7 @@ public > T save(T inputRuleEvaluator, UUID id = idGenerator.generateId(); IdGenerator.validateVersion(id, "AutomationRuleEvaluator"); - return template.inTransaction(WRITE, handle -> { + var savedEvaluator = template.inTransaction(WRITE, handle -> { var evaluatorsDAO = handle.attach(AutomationRuleEvaluatorDAO.class); AutomationRuleEvaluatorModel evaluator = switch (inputRuleEvaluator) { @@ -92,8 +93,7 @@ public > T save(T inputRuleEvaluator, evaluatorsDAO.saveBaseRule(evaluator, workspaceId); evaluatorsDAO.saveEvaluator(evaluator); - return findById(evaluator.id(), evaluator.projectId(), workspaceId); - + return evaluator; } catch (UnableToExecuteStatementException e) { if (e.getCause() instanceof SQLIntegrityConstraintViolationException) { log.info(EVALUATOR_ALREADY_EXISTS, e); @@ -103,6 +103,8 @@ public > T save(T inputRuleEvaluator, } } }); + + return findById(savedEvaluator.id(), savedEvaluator.projectId(), workspaceId); } @Override @@ -147,7 +149,7 @@ public > T findById(@NonNull UUID id, @N log.debug("Finding AutomationRuleEvaluator with id '{}' in projectId '{}' and workspaceId '{}'", id, projectId, workspaceId); - return (T) template.inTransaction(READ_ONLY, handle -> { + return template.inTransaction(READ_ONLY, handle -> { var dao = handle.attach(AutomationRuleEvaluatorDAO.class); var singleIdSet = Collections.singleton(id); var criteria = AutomationRuleEvaluatorCriteria.builder().ids(singleIdSet).build(); @@ -158,6 +160,7 @@ public > T findById(@NonNull UUID id, @N case LlmAsJudgeAutomationRuleEvaluatorModel llmAsJudge -> AutomationModelEvaluatorMapper.INSTANCE.map(llmAsJudge); }) + .map(evaluator -> (T) evaluator) .orElseThrow(this::newNotFoundException); }); } @@ -188,7 +191,7 @@ private NotFoundException newNotFoundException() { } @Override - public AutomationRuleEvaluator.AutomationRuleEvaluatorPage find(@NonNull UUID projectId, + public AutomationRuleEvaluatorPage find(@NonNull UUID projectId, @NonNull String workspaceId, String name, int pageNum, int size) { @@ -202,19 +205,20 @@ public AutomationRuleEvaluator.AutomationRuleEvaluatorPage find(@NonNull UUID pr var offset = (pageNum - 1) * size; var criteria = AutomationRuleEvaluatorCriteria.builder().name(name).build(); - var automationRuleEvaluators = dao.find(workspaceId, projectId, criteria, offset, size) - .stream() - .map(evaluator -> switch (evaluator) { - case LlmAsJudgeAutomationRuleEvaluatorModel llmAsJudge -> - AutomationModelEvaluatorMapper.INSTANCE.map(llmAsJudge); - }) - .toList(); + List> automationRuleEvaluators = List.copyOf( + dao.find(workspaceId, projectId, criteria, offset, size) + .stream() + .map(evaluator -> switch (evaluator) { + case LlmAsJudgeAutomationRuleEvaluatorModel llmAsJudge -> + AutomationModelEvaluatorMapper.INSTANCE.map(llmAsJudge); + }) + .toList()); + log.info("Found {} AutomationRuleEvaluators for projectId '{}'", automationRuleEvaluators.size(), projectId); - return new AutomationRuleEvaluator.AutomationRuleEvaluatorPage(pageNum, automationRuleEvaluators.size(), + return new AutomationRuleEvaluatorPage(pageNum, automationRuleEvaluators.size(), total, automationRuleEvaluators); - }); } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleRowMapper.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleRowMapper.java index 277d4900c4..7e8623d387 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleRowMapper.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/AutomationRuleRowMapper.java @@ -1,22 +1,21 @@ package com.comet.opik.domain; import com.comet.opik.api.AutomationRule; -import com.comet.opik.api.AutomationRuleEvaluator; import org.jdbi.v3.core.mapper.RowMapper; import org.jdbi.v3.core.statement.StatementContext; import java.sql.ResultSet; import java.sql.SQLException; -public class AutomationRuleRowMapper implements RowMapper> { +public class AutomationRuleRowMapper implements RowMapper> { @Override - public AutomationRule map(ResultSet rs, StatementContext ctx) throws SQLException { + public AutomationRuleModel map(ResultSet rs, StatementContext ctx) throws SQLException { var action = AutomationRule.AutomationRuleAction.fromString(rs.getString("action")); return switch (action) { - case EVALUATOR -> ctx.findMapperFor(AutomationRuleEvaluator.class) + case EVALUATOR -> ctx.findMapperFor(AutomationRuleEvaluatorModel.class) .orElseThrow(() -> new IllegalStateException( "No mapper found for Automation Rule Action type: %s".formatted(action))) .map(rs, ctx); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/LlmAsJudgeAutomationRuleEvaluatorModel.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/LlmAsJudgeAutomationRuleEvaluatorModel.java index be1110ee6e..ab135162bc 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/LlmAsJudgeAutomationRuleEvaluatorModel.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/LlmAsJudgeAutomationRuleEvaluatorModel.java @@ -10,19 +10,21 @@ import java.util.Map; import java.util.UUID; +import static com.comet.opik.domain.LlmAsJudgeAutomationRuleEvaluatorModel.LlmAsJudgeCode; + @Builder(toBuilder = true) public record LlmAsJudgeAutomationRuleEvaluatorModel( UUID id, UUID projectId, String name, Float samplingRate, - @Json LlmAsJudgeAutomationRuleEvaluatorModel.LlmAsJudgeCode code, + @Json LlmAsJudgeCode code, Instant createdAt, String createdBy, Instant lastUpdatedAt, String lastUpdatedBy) implements - AutomationRuleEvaluatorModel { + AutomationRuleEvaluatorModel { @Override public AutomationRuleEvaluatorType type() { diff --git a/apps/opik-backend/src/test/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResourceTest.java b/apps/opik-backend/src/test/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResourceTest.java index 9576e0e96b..36a27d118c 100644 --- a/apps/opik-backend/src/test/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResourceTest.java +++ b/apps/opik-backend/src/test/java/com/comet/opik/api/resources/v1/priv/AutomationRuleEvaluatorsResourceTest.java @@ -257,7 +257,7 @@ void find__whenSearchingByName__thenReturnEvaluators() { assertThat(actualEntity.size()).isEqualTo(1); assertThat(actualEntity.total()).isEqualTo(1); - List content = actualEntity.content(); + List> content = actualEntity.content(); assertThat(content.stream().map(AutomationRuleEvaluator::getName).toList()).contains(name); }