Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions apps/opik-backend/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1013,39 +1013,6 @@ optimizationLogs:
# Description: Maximum number of concurrent S3 uploads during sync
syncConcurrency: ${OPTIMIZATION_LOGS_SYNC_CONCURRENCY:-5}

# Safety net for Optimization Studio runs that never reach a terminal status (OPIK-7159).
# A run's status is only advanced by the Python optimizer worker calling back; if the worker never
# runs or dies before reporting, the run stays INITIALIZED/RUNNING forever. This reaper transitions
# such runs to ERROR with a reason so they can never stay stuck indefinitely.
optimizationStalledReaper:
# Default: true
# Description: Whether the stalled-run reaper job is enabled
enabled: ${OPTIMIZATION_STALLED_REAPER_ENABLED:-true}
# Default: 5m
# Description: Delay before the first reaper run after startup, to avoid false positives during warm-up
startupDelay: ${OPTIMIZATION_STALLED_REAPER_STARTUP_DELAY:-5m}
# Default: 5m
# Description: Interval between reaper job executions
jobInterval: ${OPTIMIZATION_STALLED_REAPER_JOB_INTERVAL:-5m}
# Default: 5m
# Description: A run stuck in INITIALIZED longer than this is marked ERROR (the worker should call
# mark_running within seconds; kept above normal queue latency to tolerate a backlog)
initializedTimeout: ${OPTIMIZATION_STALLED_REAPER_INITIALIZED_TIMEOUT:-5m}
# Default: 8h
# Description: A run stuck in RUNNING longer than this is marked ERROR. MUST exceed the worker's max
# execution timeout (OPTSTUDIO_EXECUTION_TIMEOUT, default 6h = 21600s) plus a buffer, since the row
# has no per-progress heartbeat and last_updated_at only advances on a status change. If you raise
# the worker timeout, raise this too or healthy long runs will be reaped.
runningTimeout: ${OPTIMIZATION_STALLED_REAPER_RUNNING_TIMEOUT:-8h}
# Default: 4m
# Description: How long the reaper holds its distributed lock (until expiry) to prevent concurrent
# fleet-wide runs. MUST stay below jobInterval — the lock is held until expiry, so a value >=
# jobInterval would make every other scheduled tick a no-op and halve the effective cadence.
lockDuration: ${OPTIMIZATION_STALLED_REAPER_LOCK_DURATION:-4m}
# Default: 100
# Description: Maximum number of stalled runs reconciled per cycle (a large backlog drains over several cycles)
batchSize: ${OPTIMIZATION_STALLED_REAPER_BATCH_SIZE:-100}

# Environment CRUD configuration
environment:
# Maximum number of environments allowed per workspace.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.comet.opik.api;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
Expand All @@ -21,7 +20,6 @@
* Required for cloud deployments, as it'll be used to automate SDK in behalf of the user.
*/
@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record OptimizationStudioConfig(
@NotBlank String datasetName,
Expand All @@ -32,45 +30,39 @@ public record OptimizationStudioConfig(
@JsonIgnore String opikApiKey) {

@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record StudioPrompt(
@NotEmpty @Valid List<StudioMessage> messages) {
}

@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record StudioMessage(
@NotBlank String role,
@NotBlank String content) {
}

@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record StudioLlmModel(
@NotBlank String model,
JsonNode parameters) {
}

@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record StudioEvaluation(
@NotEmpty @Valid List<StudioMetric> metrics) {
}

@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record StudioMetric(
@NotBlank String type,
JsonNode parameters) {
}

@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record StudioOptimizer(
@NotBlank String type,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
package com.comet.opik.api;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;

@Builder(toBuilder = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record OptimizationUpdate(
String name,
OptimizationStatus status,
@Schema(implementation = JsonListString.class, description = "Optional metadata to merge into the optimization's existing metadata. Provided keys are added or overwritten; existing keys not present here are preserved.") JsonNode metadata) {
public record OptimizationUpdate(String name, OptimizationStatus status) {
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,16 @@ public Response updateOptimizationsById(@PathParam("id") UUID id,

// ==================== Studio Endpoints ====================

@GET
@Path("/studio/{id}/cancel")
@Operation(operationId = "cancelStudioOptimizations", summary = "Cancel Studio optimizations", description = "Cancel Studio optimizations by id", responses = {
@ApiResponse(responseCode = "501", description = "Not Implemented")})
@RequiredPermissions(WorkspaceUserPermission.OPTIMIZATION_STUDIO_USE)
public Response cancelStudioOptimization(@PathParam("id") UUID id) {
log.info("Cancel Studio optimization endpoint called for id '{}' - not yet implemented", id);
return Response.status(Response.Status.NOT_IMPLEMENTED).build();
}

@GET
@Path("/studio/{id}/logs")
@Operation(operationId = "getStudioOptimizationLogs", summary = "Get Studio optimization logs", description = "Get presigned S3 URL for downloading optimization logs", responses = {
Expand Down
Loading
Loading