Files
comet-ml--opik/apps/opik-backend/config.yml
T
wehub-resource-sync 5a558eb09e
TypeScript SDK Compatibility V1.x E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / TypeScript SDK Compatibility V1.x E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
TypeScript SDK E2E Tests / TypeScript SDK E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
Python SDK E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK E2E Tests / Python SDK E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK E2E Tests / build-opik (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Python SDK Compatibility V1.x E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK E2E Tests / build-opik (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer E2E Tests Python ${{matrix.python_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer Integration Smoke Tests (push) Has been cancelled
🐙 Code Quality / detect (push) Has been cancelled
🐙 Code Quality / lint (${{ matrix.leg.name }}) (push) Has been cancelled
🐙 Code Quality / summary (push) Has been cancelled
TypeScript SDK Library Integration Tests / Check Secrets (push) Has been cancelled
TypeScript SDK Library Integration Tests / opik-vercel (Vercel AI SDK / eve) (push) Has been cancelled
SDK Library Integration Tests Runner / Check Secrets (push) Has been cancelled
SDK Library Integration Tests Runner / Missed OpenAI API Key Warning (push) Has been cancelled
SDK Library Integration Tests Runner / Build (push) Has been cancelled
SDK Library Integration Tests Runner / openai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_legacy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / llama_index_tests (push) Has been cancelled
SDK Library Integration Tests Runner / anthropic_tests (push) Has been cancelled
SDK Library Integration Tests Runner / mistral_tests (push) Has been cancelled
SDK Library Integration Tests Runner / groq_tests (push) Has been cancelled
SDK Library Integration Tests Runner / aisuite_tests (push) Has been cancelled
SDK Library Integration Tests Runner / haystack_tests (push) Has been cancelled
SDK Library Integration Tests Runner / dspy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v1_tests (push) Has been cancelled
SDK Library Integration Tests Runner / genai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_legacy_1_3_0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / evaluation_metrics_tests (push) Has been cancelled
SDK Library Integration Tests Runner / bedrock_tests (push) Has been cancelled
SDK Library Integration Tests Runner / litellm_tests (push) Has been cancelled
SDK Library Integration Tests Runner / harbor_tests (push) Has been cancelled
SDK Library Integration Tests Runner / Slack Notification (push) Has been cancelled
Lint Opik Helm Chart / render-equality (push) Has been cancelled
Opik Optimizer - Unit Tests / Opik Optimizer Unit Tests Python ${{matrix.python_version}} (push) Has been cancelled
Python BE E2E Tests / Python BE E2E (push) Has been cancelled
Python Backend Tests / run-python-backend-tests (push) Has been cancelled
Python SDK Unit Tests / Python SDK Unit Tests ${{matrix.python_version}} (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
SDK E2E Libraries Integration Tests / Check Secrets (push) Has been cancelled
SDK E2E Libraries Integration Tests / Missed OpenAI API Key Warning (push) Has been cancelled
SDK E2E Libraries Integration Tests / build-opik (push) Has been cancelled
SDK E2E Libraries Integration Tests / E2E Lib Integration Python ${{matrix.python_version}} (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-gemini) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-langchain) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-openai) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-otel) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-vercel) (push) Has been cancelled
TypeScript SDK Build & Publish / build-and-publish (push) Has been cancelled
TypeScript SDK Unit Tests / Test on Node ${{ matrix.node-version }} (push) Has been cancelled
Backend Tests / discover-tests (push) Has been cancelled
Backend Tests / ${{ matrix.name }} (push) Has been cancelled
Build and Publish SDK / build-and-publish (push) Has been cancelled
Build Opik Docker Images / set-version (push) Has been cancelled
Build Opik Docker Images / build-backend (push) Has been cancelled
Build Opik Docker Images / build-sandbox-executor-python (push) Has been cancelled
Build Opik Docker Images / build-python-backend (push) Has been cancelled
Build Opik Docker Images / build-frontend (push) Has been cancelled
Build Opik Docker Images / create-git-tag (push) Has been cancelled
ClickHouse Migration Cluster Check / validate-clickhouse-migrations (push) Has been cancelled
Docs - Publish / run (push) Has been cancelled
E2E Tests - Post Merge (v2) / 🧪 E2E v2 Tests (${{ github.event.inputs.tier || 't1' }}) (push) Has been cancelled
E2E Tests - Post Merge (v2) / 📢 Slack Notification (push) Has been cancelled
Frontend Unit Tests / Test on Node 20 (push) Has been cancelled
Guardrails E2E Tests / Select Python version matrix (push) Has been cancelled
Guardrails E2E Tests / Guardrails E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Guardrails E2E Tests / 📢 Slack Notification (push) Has been cancelled
Guardrails Backend Unit Tests / Guardrails Backend Unit Tests (push) Has been cancelled
Guardrails Backend Unit Tests / 📢 Slack Notification (push) Has been cancelled
Lint Opik Helm Chart / lint-helm-chart (Helm v3.21.0) (push) Has been cancelled
Lint Opik Helm Chart / lint-helm-chart (Helm v4.2.0) (push) Has been cancelled
Lint Opik Helm Chart / unittest-helm-chart (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:25:44 +08:00

1862 lines
103 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# https://www.dropwizard.io/en/stable/manual/configuration.html#logging
logging:
# Default: INFO
# Description: Logback logging level
level: ${GENERAL_LOG_LEVEL:-INFO}
# Default: com.comet: INFO
# Description: Individual logger configuration
loggers:
com.comet: ${OPIK_LOG_LEVEL:-INFO}
# Default: INFO
# Description: Set to DEBUG to see complete assembled LLM streaming responses (application-level logging)
com.comet.opik.infrastructure.llm: ${LLM_PROXY_REQUEST_LOG_LEVEL:-INFO}
# Description: state database configuration
# https://www.dropwizard.io/en/stable/manual/configuration.html#database
database:
# Default: jdbc:mysql://localhost:3306/opik?createDatabaseIfNotExist=true&rewriteBatchedStatements=true&connectionTimeZone=UTC&forceConnectionTimeZoneToSession=true
# Description: The URL of the server.
url: ${STATE_DB_PROTOCOL:-jdbc:mysql://}${STATE_DB_URL:-localhost:3306/opik?createDatabaseIfNotExist=true&rewriteBatchedStatements=true&connectionTimeZone=UTC&forceConnectionTimeZoneToSession=true}
# Default: opik
# Description: The username used to connect to the server
user: ${STATE_DB_USER:-opik}
# Default: opik
# Description: The password used to connect to the server
password: ${STATE_DB_PASS:-opik}
# Default: com.mysql.cj.jdbc.Driver
# Description: The fully qualified class name of the JDBC driver class.
# Only required if there were no JDBC drivers registered in META-INF/services/java.sql.Driver.
driverClass: ${STATE_DB_DRIVER_CLASS:-com.mysql.cj.jdbc.Driver}
# Default: Empty
# Description: Any additional JDBC driver parameters
properties:
wrapperPlugins: ${STATE_DB_PLUGINS:-''}
useSSL: ${MYSQL_USE_SSL:-''}
requireSSL: ${MYSQL_REQUIRE_SSL:-''}
verifyServerCertificate: ${MYSQL_VERIFY_SSL:-''}
trustCertificateKeyStoreUrl: ${MYSQL_TRUSTSTORE_URL:-''}
trustCertificateKeyStorePassword: ${MYSQL_TRUSTSTORE_PASSWORD:-''}
trustCertificateKeyStoreType: ${MYSQL_TRUSTSTORE_TYPE:-''}
clientCertificateKeyStoreUrl: ${MYSQL_CLIENTSTORE_URL:-''}
clientCertificateKeyStorePassword: ${MYSQL_CLIENTSTORE_PASSWORD:-''}
clientCertificateKeyStoreType: ${MYSQL_CLIENTSTORE_TYPE:-''}
# Description: analytics database configuration for migrations connection
databaseAnalyticsMigrations:
# Default: jdbc:clickhouse://localhost:8123/opik
# Description: The URL of the server
url: ${ANALYTICS_DB_MIGRATIONS_URL:-jdbc:clickhouse://localhost:8123/opik}
# Default: opik
# Description: The username used to connect to the server
user: ${ANALYTICS_DB_MIGRATIONS_USER:-opik}
# Default: opik
# Description: The password used to connect to the server
password: ${ANALYTICS_DB_MIGRATIONS_PASS:-opik}
# Default: ru.yandex.clickhouse.ClickHouseDriver
# Description: The fully qualified class name of the JDBC driver class.
# Community support only. Requires an old driver for migrations to work
driverClass: ru.yandex.clickhouse.ClickHouseDriver
# Description: analytics database configuration for service connection
databaseAnalytics:
# Default: http
# Description: The protocol used to connect to the server
protocol: ${ANALYTICS_DB_PROTOCOL:-HTTP}
# Default: localhost
# Description: The host used to connect to the server
host: ${ANALYTICS_DB_HOST:-localhost}
# Default: 8123
# Description: The port used to connect to the server
port: ${ANALYTICS_DB_PORT:-8123}
# Default: opik
# Description: The username used to connect to the server
username: ${ANALYTICS_DB_USERNAME:-opik}
# Default: opik
# Description: The password used to connect to the server
password: ${ANALYTICS_DB_PASS:-opik}
# Default: opik
# Description: The database name
databaseName: ${ANALYTICS_DB_DATABASE_NAME:-opik}
# Default:
# - health_check_interval=2000
# - compress=1
# - auto_discovery=true
# - failover=3
# - custom_http_params=max_query_size=100000000
# Description: query parameters that will be added to the connection string
queryParameters: ${ANALYTICS_DB_QUERY_PARAMETERS:-health_check_interval=2000&compress=1&auto_discovery=true&failover=3&custom_http_params=max_query_size=100000000,async_insert_busy_timeout_max_ms=250,async_insert_busy_timeout_min_ms=100,async_insert=1,wait_for_async_insert=1,async_insert_use_adaptive_busy_timeout=1,async_insert_deduplicate=1,use_skip_indexes_if_final=1,optimize_skip_unused_shards=1,do_not_merge_across_partitions_select_final=1,distributed_product_mode=local}
# Default: unset (inherits the async_insert_busy_timeout_max_ms=250 carried by queryParameters above)
# Description: Optional override (ms) for async_insert_busy_timeout_max_ms in the custom_http_params chain of
# queryParameters above; only applied when that setting is already present there, otherwise it is not injected.
# Leave unset to keep the queryParameters value untouched. With async_insert_use_adaptive_busy_timeout=1 this is
# a ceiling: the adaptive scheduler widens the buffer only while rows are queued.
asyncInsertBusyTimeoutMaxMs: ${ANALYTICS_DB_ASYNC_INSERT_BUSY_TIMEOUT_MAX_MS:-}
# Default: 1s
# Description: Timeout for the ClickHouse health check query (e.g. 1s, 500ms, 2 minutes)
healthCheckTimeout: ${ANALYTICS_DB_HEALTH_CHECK_TIMEOUT:-1s}
# Description: Cutover toggles migrating the trace analytics columns to non-nullable, sentinel-defaulted form.
databaseAnalyticsDataModel:
# Default: false
# Description: Leave false while the traces table still has Nullable end_time/duration/ttft columns; trace writes
# bind null for absent end_time/ttft. Set true once replaced with sentinel-defaulted
# non-nullable columns so writes bind the sentinels (end_time->epoch, ttft->NaN) instead. Gates reads too, so
# while false a legitimate epoch end time round-trips unchanged instead of reading as null.
# Flip in lockstep with the cutover EXCHANGE.
traceColumnsNonNullable: ${ANALYTICS_DB_DATA_MODEL_TRACE_COLUMNS_NON_NULLABLE:-false}
# Default: false
# Description: Leave false at deploy time. Turn true once the trace backfill starts so trace deletes also
# record the deleted ids in the deletion_events_local bridge; without it those deletes are lost from the table
# copy. Scope capture to the backfill-to-cutover window.
traceDeletionEventsCaptureEnabled: ${ANALYTICS_DB_DATA_MODEL_TRACE_DELETION_EVENTS_CAPTURE_ENABLED:-false}
# Default: 1000
# Description: Rows per INSERT into the deletion_events_local bridge. A single delete batch can carry more ids
# than the ClickHouse driver binds reliably in one statement (5 columns per row), so the insert is split into
# chunks of this size.
deletionEventsInsertBatchSize: ${ANALYTICS_DB_DATA_MODEL_DELETION_EVENTS_INSERT_BATCH_SIZE:-1000}
# Description: UUIDv7 ingestion validation. Rejects writes whose `id` embeds a timestamp outside the
# window, protecting data quality.
uuidValidation:
# Default: false
# Description: Operational kill-switch. When false, ids are not checked against the window (the
# window is still validated to be a sane value).
enabled: ${UUID_VALIDATION_ENABLED:-false}
# Default: 24h
# Description: Validation window (between 12h and 45d). Writes whose `id` is a UUIDv7 with an
# embedded timestamp more than this far in the past or future are rejected.
window: ${UUID_VALIDATION_WINDOW:-24h}
# Description: credentials for the Agent Insights read-only free-form SQL ClickHouse user (restricted user with a
# read-only profile + row policies, provisioned by OPIK-6846). Only the user/password live here; the connection
# params (protocol/host/port/database) are reused from databaseAnalytics above (same ClickHouse instance). Only used
# when the serviceToggles.agentInsightsEnabled toggle is on.
databaseAnalyticsReadOnlyFreeFormSql:
# Default: comet_readonly_freeform_sql_user
# Description: The read-only username used to connect to the server
username: ${ANALYTICS_DB_READ_ONLY_FREEFORM_SQL_USER:-comet_readonly_freeform_sql_user}
# Default: opik
# Description: The read-only user password used to connect to the server
password: ${ANALYTICS_DB_READ_ONLY_FREEFORM_SQL_PASS:-opik}
# Default: 200s
# Description: Socket read timeout for the read-only client (client-v2 default is 0/none). Kept
# above the read-only profile's max_execution_time (180s) so the server-side cap fires first.
socketTimeout: ${ANALYTICS_DB_READ_ONLY_FREEFORM_SQL_SOCKET_TIMEOUT:-200s}
# https://www.dropwizard.io/en/stable/manual/configuration.html#health
health:
# Default: ["/health-check"]
# Description: URLs to expose the apps health check on.
healthCheckUrlPaths: ["/health-check"]
# Options around a particular health check which is registered in an Application
# https://www.dropwizard.io/en/stable/manual/configuration.html#man-configuration-health-checks
healthChecks:
- name: deadlocks
critical: true
type: alive
# Gates liveness (type: alive) so a pod whose shared outbound HTTP pool has been shut down gets restarted and
# recreates the pool. A shut-down pool is unrecoverable without a restart, so removing it from rotation isn't
# enough. Fails only on the local "Connection pool shut down" condition, never on transient upstream errors, so a
# blip in any outbound dependency cannot restart-storm the fleet.
- name: shared_http_client
critical: true
type: alive
- name: db
critical: true
type: ready
- name: redis
critical: true
type: ready
- name: clickhouse
critical: true
type: ready
# Non-critical on purpose: this is an optional, toggle-gated feature (Agent Insights freeform SQL). A
# provisioning issue or transient CH rejection on the read-only user must degrade only that feature, not pull
# the whole backend out of readiness/traffic.
- name: clickhouse-readonly-freeform-sql
critical: false
type: ready
- name: mysql
critical: true
type: ready
# Configuration for distributed locking using redis
distributedLock:
# Default: 500
# Description: Lease time in milliseconds
lockTimeoutMS: ${DISTRIBUTED_LOCK_TIME_OUT:-500}
# Default: 5
# Description: This value has to be considerably higher than the lockTimeoutMS value, as it has to guarantee that the
# last thread to join the queue to acquire the lock will have enough time to execute the action. Then, the lock will
# be deleted from redis after the specified period of time.
# This is needed as Redisson by default doesn't delete the lock from redis after the lease time expires, it just
# releases the lock. The expiration time will be reset every time the lock is acquired.
ttlInSeconds: ${DISTRIBUTED_LOCK_TTL_IN_SEC:-5}
# Redis configuration
redis:
# Default: redis://:opik@localhost:6379/0
# Description: single node redis's URL
singleNodeUrl: ${REDIS_URL:-redis://:opik@localhost:6379/0}
# Default: 1s
# Description: Timeout for the Redis health check ping
healthCheckTimeout: ${REDIS_HEALTH_CHECK_TIMEOUT:-1s}
# AWS IAM authentication configuration (optional)
# When enabled, takes precedence over singleNodeUrl authentication
awsIamAuth:
# Default: false
# Description: Enable AWS IAM authentication for ElasticCache Redis
enabled: ${OPIK_REDIS_AWS_IAM_AUTH_ENABLED:-false}
# Description: AWS User ID for IAM authentication
awsUserId: ${OPIK_REDIS_AWS_USER_ID:-''}
# Default: us-east-1
# Description: AWS region where ElastiCache is deployed
awsRegion: ${AWS_REGION:-us-east-1}
# Default: opik-redis
# Description: ElasticCache resource name (replication group/cluster/serverless name)
awsResourceName: ${OPIK_REDIS_AWS_RESOURCE_NAME:-''}
# Default: 13m
# Description: How often to refresh the AWS authentication token
tokenCacheRefreshAfter: ${OPIK_REDIS_AWS_TOKEN_CACHE_REFRESH_AFTER:-13m}
# Default: 14m
# Description: How long the AWS authentication token will be cached locally
tokenCacheExpireAfter: ${OPIK_REDIS_AWS_TOKEN_CACHE_EXPIRE_AFTER:-14m}
# Default: 15m
# Description: How long the AWS authentication token is valid
tokenExpiryDuration: ${OPIK_REDIS_AWS_TOKEN_EXPIRY_DURATION:-15m}
openTelemetry:
# Default: 3h
# Description: how long it takes to expire non-used keys
ttl: ${OTEL_TTL_INTERVAL:-3h}
# Authentication configuration. This is not enabled by default for open source installations.
authentication:
# Default: false
# Description: Whether or not to enable authentication
enabled: ${AUTH_ENABLED:-false}
# Default: 5
# Description: API key resolution cache TTL (seconds). Setting this value to 0 means no caching.
apiKeyResolutionCacheTTLInSec: ${AUTH_API_KEY_RESOLUTION_CACHE_TTL_IN_SEC:-5}
# Default: http://react-svc:8080
# Description: Configures base url for React service, used for user management and authentication
reactService:
url: ${REACT_SERVICE_URL:-http://react-svc:8080}
# Liveness health check for the shared outbound HTTP client (see shared_http_client under healthChecks)
sharedHttpClientHealthCheck:
# Default: 1s
# Description: Probe timeout (connect + read) for the shared_http_client liveness health check.
timeout: ${SHARED_HTTP_CLIENT_HEALTH_CHECK_TIMEOUT:-1s}
# OAuth 2.1 Authorization Server for hosted/local Opik MCP
mcpOAuth:
# Default: false
# Description: Whether to enable the MCP OAuth Authorization Server endpoints
enabled: ${MCP_OAUTH_ENABLED:-false}
# Default: empty
# Description: Public base URL of this deployment; drives the RFC 8414 issuer and the default RFC 8707 resource audience (baseUrl + /api/v1/mcp)
baseUrl: ${OPIK_BASE_URL:-}
# Default: empty (derived from baseUrl + /api/v1/mcp)
# Description: Canonical MCP resource URI for the OAuth instance. Set to a distinct path (e.g. .../api/v2/mcp) to run the OAuth-based opik-mcp alongside the existing API-key opik-mcp during migration.
mcpResourceUri: ${MCP_OAUTH_RESOURCE_URI:-}
# Default: PT1H
# Description: Access token lifetime
accessTokenTtl: ${MCP_OAUTH_ACCESS_TOKEN_TTL:-PT1H}
# Default: P7D
# Description: Refresh token absolute lifetime (not sliding)
refreshTokenTtl: ${MCP_OAUTH_REFRESH_TOKEN_TTL:-P7D}
# Default: PT60S
# Description: Authorization code lifetime
codeTtl: ${MCP_OAUTH_CODE_TTL:-PT60S}
# Default: PT30S
# Description: Grace window during which a just-rotated refresh token is still accepted
refreshRotationGrace: ${MCP_OAUTH_REFRESH_ROTATION_GRACE:-PT30S}
# Default: PT5M
# Description: TTL of the Redis lock held by the scrub job. The lock is held until expiry (not released after the scrub), so keeping it close to the 5-minute schedule prevents staggered replicas from re-scrubbing within the same cycle.
scrubLockTimeout: ${MCP_OAUTH_SCRUB_LOCK_TIMEOUT:-PT5M}
# Default: PT0.1S
# Description: Maximum time the scrub job waits to acquire the Redis lock before giving up for this cycle
scrubLockWaitTime: ${MCP_OAUTH_SCRUB_LOCK_WAIT_TIME:-PT0.1S}
# https://www.dropwizard.io/en/stable/manual/configuration.html#servers
server:
# Default: false
# Description: Whether to enable virtual threads for Jetty's thread pool.
enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false}
# https://www.dropwizard.io/en/stable/manual/configuration.html#gzip
gzip:
# Default: true
# Description: If true, all requests with gzip in the Accept-Encoding header will have their response entities
# compressed and requests with gzip in the Content-Encoding header will have their request entities decompressed.
enabled: true
# HTTP connector configuration for handling large request headers
# Default: 16KB (16000 bytes) - matches ALB/Nginx request line limit
# Description: Maximum size of request headers to prevent 431 errors from long URLs with many filters
applicationConnectors:
- type: http
# Default: 8080
# Description: The port on which the application HTTP connector listens
port: ${SERVER_APPLICATION_PORT:-8080}
maxRequestHeaderSize: ${SERVER_MAX_REQUEST_HEADER_SIZE:-16KB}
# Default: 1m
# Description: The maximum idle time for a connection, after which it will be closed.
idleTimeout: ${SERVER_IDLE_TIMEOUT:-1m}
adminConnectors:
- type: http
# Default: 8081
# Description: The port on which the admin HTTP connector listens
port: ${SERVER_ADMIN_PORT:-8081}
# Jackson JSON processing configuration
# Controls limits for JSON deserialization to prevent memory exhaustion
jacksonConfig:
# Default: 104857600 (100MB)
# Description: Maximum size for individual string values during JSON deserialization.
# A JSON with 3 fields up to this size will work, but a single larger string will fail.
# This configuration is used by both HTTP layer and internal JSON processing for consistency,
# preventing memory exhaustion from extremely large base64-encoded attachments before they can be stripped
maxStringLength: ${JACKSON_MAX_STRING_LENGTH:-104857600}
# Configuration for batch operations
batchOperations:
datasets:
# Default: 5000
# Description: The maximal number of ids to be used for IN clause. Find requests with a larger number of ids will
# involve the use of temp tables for querying
maxExperimentInClauseSize: ${BATCH_OPERATIONS_MAX_EXPERIMENT_IN_CLAUSE_SIZE:-5000}
# Default: 1000
# Description: The batch size for processing CSV files. Dataset items are saved to the database in batches of this size.
csvBatchSize: ${BATCH_OPERATIONS_CSV_BATCH_SIZE:-1000}
# Configuration for experiment aggregates population
experimentAggregates:
# Default: 1000
# Description: Number of experiment items processed per batch when populating experiment_item_aggregates table. Higher values improve performance but increase memory usage. Recommended range: 100-5000.
batchSize: ${EXPERIMENT_AGGREGATES_BATCH_SIZE:-1000}
# Configuration for experiment denormalization (debounced re-computation of experiment aggregates)
experimentDenormalization:
# Default: true
# Description: Whether the experiment denormalization job and subscriber are enabled
enabled: ${EXPERIMENT_DENORMALIZATION_ENABLED:-true}
# Default: experiment_denormalization_stream
# Description: The name of the Redis Stream used for experiment aggregates recomputation
streamName: ${OPIK_REDIS_EXPERIMENT_DENORM_STREAM_NAME:-'experiment_denormalization_stream'}
# Default: experiment_denormalization
# Description: A consumer group name so multiple instances can share the stream load
consumerGroupName: ${OPIK_REDIS_EXPERIMENT_DENORM_CONSUMER_GROUP_NAME:-'experiment_denormalization'}
# Default: 100
# Description: Maximum number of messages returned within a Redis Stream get
consumerBatchSize: ${OPIK_REDIS_EXPERIMENT_DENORM_CONSUMER_BATCH_SIZE:-100}
# Default: 500ms
# Description: How often the experiment denormalization consumer will check Redis for new messages
poolingInterval: ${OPIK_REDIS_EXPERIMENT_DENORM_POOLING_INTERVAL:-500ms}
# Default: 5s
# Description: Timeout for blocking read operations on Redis streams (long polling duration)
longPollingDuration: ${OPIK_REDIS_EXPERIMENT_DENORM_LONG_POLLING_DURATION:-5s}
# Default: 1m
# Description: Debounce delay before an experiment is published to the denormalization stream. Each new write resets the timer.
debounceDelay: ${OPIK_EXPERIMENT_DENORM_DEBOUNCE_DELAY:-1m}
# Default: 4s
# Description: The time to wait for the denormalization scan job to finish before releasing the lock
jobLockTime: ${OPIK_EXPERIMENT_DENORM_JOB_LOCK_TIME:-4s}
# Default: 300ms
# Description: The time to wait for the denormalization scan job to acquire the lock before giving up
jobLockWaitTime: ${OPIK_EXPERIMENT_DENORM_JOB_LOCK_WAIT_TIME:-300ms}
# Default: 10m
# Description: Maximum duration for the per-experiment aggregation lock held by the stream subscriber
aggregationLockTime: ${OPIK_EXPERIMENT_DENORM_AGGREGATION_LOCK_TIME:-10m}
# Default: 500ms
# Description: Time to wait when trying to acquire the per-experiment aggregation lock before skipping (fail-fast). Must be between 100ms and 5s.
lockAcquireWait: ${OPIK_EXPERIMENT_DENORM_LOCK_ACQUIRE_WAIT:-500ms}
# Default: 3
# Description: Maximum automatic re-trigger attempts per (workspace, experiment) when the aggregation lock TTL is exceeded. Must be between 1 and 10.
maxLockExpiryRetries: ${OPIK_EXPERIMENT_DENORM_MAX_LOCK_EXPIRY_RETRIES:-3}
# Default: 30m
# Description: TTL applied to the per-(workspace, experiment) lock-expiry retry counter in Redis (minimum 1m). Prevents stale counters from accumulating when an experiment stops producing events.
retryCounterTtl: ${OPIK_EXPERIMENT_DENORM_RETRY_COUNTER_TTL:-30m}
# Default: 10
# Description: Claim pending messages every N polling intervals
claimIntervalRatio: ${OPIK_REDIS_EXPERIMENT_DENORM_CLAIM_INTERVAL_RATIO:-10}
# Default: 10m
# Description: Time before a message is considered orphaned and eligible for claiming
pendingMessageDuration: ${OPIK_REDIS_EXPERIMENT_DENORM_PENDING_MESSAGE_DURATION:-10m}
# Default: 3
# Description: Maximum number of retry attempts for failed messages (1-10)
maxRetries: ${OPIK_REDIS_EXPERIMENT_DENORM_MAX_RETRIES:-3}
# Default: 100
# Description: Maximum number of ZSET entries to read per page when flushing pending experiments (10-1000)
jobBatchSize: ${OPIK_EXPERIMENT_DENORM_JOB_BATCH_SIZE:-100}
# Default: 5s
# Description: Interval at which the denormalization job runs to flush pending experiments (min 1s)
jobInterval: ${OPIK_EXPERIMENT_DENORM_JOB_INTERVAL:-5s}
# Default: 10000
# Description: Maximum length of the Redis stream. Older entries are trimmed when this limit is exceeded.
streamMaxLen: ${OPIK_REDIS_EXPERIMENT_DENORM_STREAM_MAX_LEN:-10000}
# Default: 100
# Description: Number of entries to trim in a single operation when streamMaxLen is exceeded.
streamTrimLimit: ${OPIK_REDIS_EXPERIMENT_DENORM_STREAM_TRIM_LIMIT:-100}
# Configuration for buffering projects.last_updated_trace_at updates in Redis and flushing them to MySQL
# periodically, instead of writing MySQL synchronously on every trace-created/updated event. Keeps the
# high-frequency ingestion path off the contended `projects` row (avoids lock contention / connection churn).
projectLastUpdatedFlush:
# Default: false
# Description: When enabled, trace events buffer the per-project last-updated timestamp in Redis and a job
# flushes it to MySQL; when disabled, the timestamp is written to MySQL synchronously per event (legacy).
enabled: ${PROJECT_LAST_UPDATED_FLUSH_ENABLED:-false}
# Default: true
# Description: When enabled (and the feature above is on), schedule the periodic flush job. Set false to buffer in
# Redis without a scheduler (e.g. tests that invoke the job manually).
jobEnabled: ${PROJECT_LAST_UPDATED_FLUSH_JOB_ENABLED:-true}
# Default: 30s
# Description: Interval at which the flush job drains the Redis buffer into MySQL (min 1s)
jobInterval: ${PROJECT_LAST_UPDATED_FLUSH_JOB_INTERVAL:-30s}
# Default: 25s
# Description: Time the flush job holds the distributed lock (kept below jobInterval so it releases each cycle)
jobLockTime: ${PROJECT_LAST_UPDATED_FLUSH_JOB_LOCK_TIME:-25s}
# Default: 500ms
# Description: Time the flush job waits to acquire the lock before giving up (100ms-5s)
jobLockWaitTime: ${PROJECT_LAST_UPDATED_FLUSH_JOB_LOCK_WAIT_TIME:-500ms}
# Default: 500
# Description: Maximum number of ZSET entries to read per page when flushing pending projects (10-5000)
jobBatchSize: ${PROJECT_LAST_UPDATED_FLUSH_JOB_BATCH_SIZE:-500}
# Configuration for rate limit. This is not enabled by default for open source installations.
# If enabled, rate limit is applied to creation and update of various entities including traces, spans, projects,
# prompts, feedback definitions, experiments, datasets and dataset items
rateLimit:
# Default: false
# Description: Whether or not rate limit is enabled
enabled: ${RATE_LIMIT_ENABLED:-false}
# This uses as a fallback rate limit configuration in case an entity specific configuration doesn't exist
generalLimit:
# Default: 10000
# Description: how many events are allowed in the specified time bucket
limit: ${RATE_LIMIT_GENERAL_EVENTS_LIMIT:-10000}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_GENERAL_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: User
# Description: User facing bucket name
userFacingBucketName: general_events
# Description: Rate limit error message
errorMessage: "You have exceeded the general rate limit for this user. Please try again later."
workspaceLimit:
# Default: 5000
# Description: how many events per workspace are allowed in the specified time bucket
limit: ${RATE_LIMIT_WORKSPACE_EVENTS_LIMIT:-5000}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Workspace
# Description: User facing bucket name
userFacingBucketName: workspace_events
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this user in this workspace. Please try again later."
customLimits:
getSpanById:
# Default: 250
# Description: how many events are allowed in the specified time bucket
limit: ${RATE_LIMIT_GET_SPANS_BY_ID_EVENTS_PER_WORKSPACE_LIMIT:-250}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Get-Span-Id
# Description: User facing bucket name
userFacingBucketName: get_span_by_id
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
singleTracingOps:
# Default: 800
# Description: how many events are allowed in the specified time bucket
limit: ${RATE_LIMIT_SINGLE_TRACING_OPS_EVENTS_PER_WORKSPACE_LIMIT:-800}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Single-Tracing-Ops
# Description: User facing bucket name
userFacingBucketName: single_tracing_ops
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for single tracing operations. Please try again later."
ollieStateUpload:
# Default: 4
# Description: how many ollie state uploads are allowed in the specified time bucket (per API key)
limit: ${RATE_LIMIT_OLLIE_STATE_UPLOAD:-4}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_OLLIE_STATE_UPLOAD_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Ollie-State-Upload
# Description: User facing bucket name
userFacingBucketName: ollie_state_upload
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for ollie state uploads. Please try again later."
getSpans:
# Default: 30
# Description: how many getSpansByProject queries are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_GET_SPANS_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Get-Spans
# Description: User facing bucket name
userFacingBucketName: get_spans
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
search_spans:
# Default: 30
# Description: how many searchSpans queries are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_SEARCH_SPANS_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Search-Spans
# Description: User facing bucket name
userFacingBucketName: search_spans
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
getSpanStats:
# Default: 30
# Description: how many getSpanStats queries are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_GET_SPAN_STATS_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Get-Span-Stats
# Description: User facing bucket name
userFacingBucketName: get_span_stats
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
getTraces:
# Default: 30
# Description: how many getTracesByProject queries are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_GET_TRACES_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Get-Traces
# Description: User facing bucket name
userFacingBucketName: get_traces
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
searchTraces:
# Default: 30
# Description: how many searchTraces queries are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_SEARCH_TRACES_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Search-Traces
# Description: User facing bucket name
userFacingBucketName: search_traces
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
getTraceStats:
# Default: 30
# Description: how many getTraceStats queries are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_GET_TRACE_STATS_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Get-Trace-Stats
# Description: User facing bucket name
userFacingBucketName: get_trace_stats
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
tracesExist:
# Default: 30
# Description: how many tracesExist empty-state probes are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_TRACES_EXIST_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Traces-Exist
# Description: User facing bucket name
userFacingBucketName: traces_exist
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
spansExist:
# Default: 30
# Description: how many spansExist empty-state probes are allowed per workspace in the specified time bucket
limit: ${RATE_LIMIT_SPANS_EXIST_EVENTS_PER_WORKSPACE_LIMIT:-30}
# Default: 60
# Description: Time bucket size in seconds
durationInSeconds: ${RATE_LIMIT_WORKSPACE_EVENTS_DURATION_IN_SEC:-60}
# Description: Header name to use for rate limiting
headerName: Spans-Exist
# Description: User facing bucket name
userFacingBucketName: spans_exist
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for this operation. Please try again later."
mcpOAuthRegister:
# Default: 20
# Description: Max dynamic client registrations (RFC 7591) accepted per source IP in the specified time bucket
limit: ${MCP_OAUTH_REGISTRATION_RATE_LIMIT:-20}
# Default: 3600
# Description: Time bucket size in seconds
durationInSeconds: ${MCP_OAUTH_REGISTRATION_RATE_LIMIT_DURATION_IN_SEC:-3600}
# Description: Header name to use for rate limiting
headerName: Mcp-OAuth-Register
# Description: User facing bucket name
userFacingBucketName: mcp_oauth_register
# Description: Rate limit error message
errorMessage: "You have exceeded the rate limit for MCP OAuth client registration. Please try again later."
# Configuration for usage limit. This is not enabled by default for open source installations.
# In order to support that, the remote authentication server must contain a `quotas` object in its authentication
# response.
usageLimit:
# Description: The error to be displayed when submitting entities to a workspace where the usage limit is exceeded
errorMessage: ${USAGE_LIMIT_ERROR_MESSAGE:-You have exceeded the usage limit for this operation.}
# Configuration for product analytics events
analytics:
# Default: false
# Description: Whether or not to send product analytics events
enabled: ${OPIK_ANALYTICS_ENABLED:-false}
# Default: empty
# Description: Environment name included in every analytics event (e.g. "staging", "production")
environment: ${OPIK_ANALYTICS_ENVIRONMENT:-}
# Configuration for anonymous usage reporting
usageReport:
# Default: true
# Description: Whether or not to send anonymous usage reports
enabled: ${OPIK_USAGE_REPORT_ENABLED:-true}
# Default: https://stats.comet.com/notify/event/
# Description: URL to send the anonymous usage reports to
url: ${OPIK_USAGE_REPORT_URL:-https://stats.comet.com/notify/event/}
# Default: 5s
# Description: HTTP connect timeout for usage report
connectTimeout: ${OPIK_USAGE_REPORT_CONNECT_TIMEOUT:-5s}
# Default: 10s
# Description: HTTP read timeout for usage report
readTimeout: ${OPIK_USAGE_REPORT_READ_TIMEOUT:-10s}
# Description: Configuration for anonymous ID used to identify the installation
# Default: empty
anonymousId: ${OPIK_ANONYMOUS_ID:-}
# Configuration for application metadata
metadata:
# Default: latest
# Description: The application version
version: ${OPIK_VERSION:-latest}
# CORS related configuration
cors:
# Default: false
# Description: Whether or not to allow cross site scripting
enabled: ${CORS:-false}
# Encryption related configuration
encryption:
# Default: GiTHubiLoVeYouAA
# Description: Encryption key to use when storing sensitive information
key: ${OPIK_ENCRYPTION_KEY:-'GiTHubiLoVeYouAA'}
# Configuration for Online Scoring
onlineScoring:
# Default: 500 ms
# Description: How often Online Scoring will check Redis for new messages (in milliseconds)
# This is the global default value, can be overridden per stream
poolingInterval: ${REDIS_SCORING_CONSUMER_POOL_INTERVAL:-500ms}
# Default: 5s
# Description: Timeout for blocking read operations on Redis streams (long polling duration)
# This is the global default value, can be overridden per stream
longPollingDuration: ${REDIS_SCORING_LONG_POLLING_DURATION:-5s}
# Default: online_scoring
# Description: A consumer group name so multiple instances can share the stream load
consumerGroupName: ${REDIS_SCORING_CONSUMER_GROUP_NAME:-'online_scoring'}
# Default: 10
# Description: Maximum number of messages returned within a Redis Stream get
# This is the global default value, can be overridden per stream
consumerBatchSize: ${REDIS_SCORING_CONSUMER_BATCH_SIZE:-10}
# Default: 10
# Description: Claim pending messages every N polling intervals (global default)
claimIntervalRatio: ${REDIS_SCORING_CLAIM_INTERVAL_RATIO:-10}
# Default: 10m
# Description: Time before message considered orphaned and eligible for claiming (global default)
pendingMessageDuration: ${REDIS_SCORING_PENDING_MESSAGE_DURATION:-10m}
# Default: 3
# Description: Maximum number of retry attempts for failed messages (1-10, global default)
maxRetries: ${REDIS_SCORING_MAX_RETRIES:-3}
# Default: 10000
# Description: Max number of entries (approx) when publishing to the Redis stream. Oldest are evicted if exceeded
streamMaxLen: ${REDIS_SCORING_STREAM_MAX_LEN:-10000}
# Default: 100
# Description: Max number of entries to evict when publishing to the Redis stream (0 = no limit) if over max length
streamTrimLimit: ${REDIS_SCORING_STREAM_TRIM_LIMIT:-100}
# Default: 50000
# Description: Estimated-tokens threshold above which the LLM-as-judge online scorer routes through the
# agentic-tools path (skeleton initial prompt + read/jq/search tools). Below the threshold the inline
# path is used.
agenticToolsThresholdTokens: ${ONLINE_SCORING_AGENTIC_TOOLS_THRESHOLD_TOKENS:-50000}
# Default: 4
# Description: Characters-per-token ratio used to estimate a trace's token count from its serialized JSON
# length. 4 ≈ natural-language English. Lower for code/JSON-heavy workloads (≈ 2) — yields a more
# pessimistic estimate so the agentic-tools path engages earlier.
agenticToolsCharsPerToken: ${ONLINE_SCORING_AGENTIC_TOOLS_CHARS_PER_TOKEN:-4}
# Default: 52428800 (50 MB)
# Description: Maximum total bytes of attachment data injected as multimodal content per judge invocation.
# Every injected attachment is re-sent on every follow-up tool round, so cost is multiplicative.
# Lower this on memory-constrained deployments.
agenticToolsMaxInjectedBytes: ${ONLINE_SCORING_AGENTIC_TOOLS_MAX_INJECTED_BYTES:-52428800}
# Default: 120
# Description: TTL in seconds for S3 presigned download URLs generated by the get_attachment agentic
# tool. The URL is consumed within a single tool-call round; 120 s is ample for most providers.
# Capped at 3600 s — longer-lived URLs are a security risk if the URL leaks.
agenticToolsS3PresignTtlSeconds: ${ONLINE_SCORING_AGENTIC_TOOLS_S3_PRESIGN_TTL_SECONDS:-120}
# Default: 4000
# Description: Per-variable substitution cap (in characters) for the {{trace}}/{{span}} structure-injection
# and agentic-tools paths. Large enough that small entity input/output renders inline, small enough that a
# huge entity doesn't blow context (the agent fetches the rest via the read tool). 500-100000.
maxPromptFieldChars: ${ONLINE_SCORING_MAX_PROMPT_FIELD_CHARS:-4000}
# Default: 5
# Description: Attachment-upload race tolerance for the {{trace}}/{{span}} structures — how many times the
# attachment lookup is retried when the entity references an attachment that isn't persisted yet. Interim
# guard (0-20; 0 disables retrying) pending the pre-evaluation dispatch delay (OPIK-7224).
attachmentFetchMaxRetries: ${ONLINE_SCORING_ATTACHMENT_FETCH_MAX_RETRIES:-5}
# Default: 300ms
# Description: Delay between attachment-lookup retries (see attachmentFetchMaxRetries). Worst-case added
# latency ≈ attachmentFetchMaxRetries × this, and only for entities that expect an attachment. 50ms-5s.
attachmentFetchRetryDelay: ${ONLINE_SCORING_ATTACHMENT_FETCH_RETRY_DELAY:-300ms}
## scorer: options from AutomationRuleEvaluatorType
## streamName: the name of the stream in redis
## codec: 'json' when there are non-java consumers, 'java' for java consumers only
## poolingInterval: (optional, but highly recommended) per stream pooling interval, overrides global value
## longPollingDuration: (optional, but highly recommended) per stream long polling duration, overrides global value
## consumerBatchSize: (optional, but highly recommended) per stream batch size, overrides global value
## claimIntervalRatio: (optional) per stream claim interval ratio, overrides global value
## pendingMessageDuration: (optional) per stream pending message duration, overrides global value
## maxRetries: (optional) per stream max retries, overrides global value
## streamMaxLen: (optional) per stream max length, overrides global streamMaxLen value
## streamTrimLimit: (optional) per stream trim limit, overrides global streamTrimLimit value
streams:
- scorer: llm_as_judge
streamName: stream_scoring_llm_as_judge
codec: java
# Optional per stream configuration (falls back to global if not specified)
poolingInterval: ${REDIS_SCORING_LLM_AS_JUDGE_CONSUMER_POOL_INTERVAL:-}
longPollingDuration: ${REDIS_SCORING_LLM_AS_JUDGE_LONG_POLLING_DURATION:-}
consumerBatchSize: ${REDIS_SCORING_LLM_AS_JUDGE_CONSUMER_BATCH_SIZE:-}
claimIntervalRatio: ${REDIS_SCORING_LLM_AS_JUDGE_CLAIM_INTERVAL_RATIO:-}
pendingMessageDuration: ${REDIS_SCORING_LLM_AS_JUDGE_PENDING_MESSAGE_DURATION:-}
maxRetries: ${REDIS_SCORING_LLM_AS_JUDGE_MAX_RETRIES:-}
streamMaxLen: ${REDIS_SCORING_LLM_AS_JUDGE_STREAM_MAX_LEN:-}
streamTrimLimit: ${REDIS_SCORING_LLM_AS_JUDGE_STREAM_TRIM_LIMIT:-}
- scorer: user_defined_metric_python
streamName: stream_scoring_user_defined_metric_python
codec: java
# Optional per stream configuration (falls back to global if not specified)
poolingInterval: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_CONSUMER_POOL_INTERVAL:-}
longPollingDuration: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_LONG_POLLING_DURATION:-}
consumerBatchSize: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_CONSUMER_BATCH_SIZE:-}
claimIntervalRatio: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_CLAIM_INTERVAL_RATIO:-}
pendingMessageDuration: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_PENDING_MESSAGE_DURATION:-}
maxRetries: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_MAX_RETRIES:-}
streamMaxLen: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_STREAM_MAX_LEN:-}
streamTrimLimit: ${REDIS_SCORING_USER_DEFINED_METRIC_PYTHON_STREAM_TRIM_LIMIT:-}
- scorer: trace_thread_llm_as_judge
streamName: stream_scoring_trace_thread_llm_as_judge
codec: java
# Optional per stream configuration (falls back to global if not specified)
poolingInterval: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_CONSUMER_POOL_INTERVAL:-}
longPollingDuration: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_LONG_POLLING_DURATION:-}
consumerBatchSize: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_CONSUMER_BATCH_SIZE:-}
claimIntervalRatio: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_CLAIM_INTERVAL_RATIO:-}
pendingMessageDuration: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_PENDING_MESSAGE_DURATION:-}
maxRetries: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_MAX_RETRIES:-}
streamMaxLen: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_STREAM_MAX_LEN:-}
streamTrimLimit: ${REDIS_SCORING_TRACE_THREAD_LLM_AS_JUDGE_STREAM_TRIM_LIMIT:-}
- scorer: trace_thread_user_defined_metric_python
streamName: stream_scoring_trace_thread_user_defined_metric_python
codec: java
# Optional per stream configuration (falls back to global if not specified)
poolingInterval: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_CONSUMER_POOL_INTERVAL:-}
longPollingDuration: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_LONG_POLLING_DURATION:-}
consumerBatchSize: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_CONSUMER_BATCH_SIZE:-}
claimIntervalRatio: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_CLAIM_INTERVAL_RATIO:-}
pendingMessageDuration: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_PENDING_MESSAGE_DURATION:-}
maxRetries: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_MAX_RETRIES:-}
streamMaxLen: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_STREAM_MAX_LEN:-}
streamTrimLimit: ${REDIS_SCORING_TRACE_THREAD_USER_DEFINED_METRIC_PYTHON_STREAM_TRIM_LIMIT:-}
- scorer: span_llm_as_judge
streamName: stream_scoring_span_llm_as_judge
codec: java
# Optional per stream configuration (falls back to global if not specified)
poolingInterval: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_CONSUMER_POOL_INTERVAL:-}
longPollingDuration: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_LONG_POLLING_DURATION:-}
consumerBatchSize: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_CONSUMER_BATCH_SIZE:-}
claimIntervalRatio: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_CLAIM_INTERVAL_RATIO:-}
pendingMessageDuration: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_PENDING_MESSAGE_DURATION:-}
maxRetries: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_MAX_RETRIES:-}
streamMaxLen: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_STREAM_MAX_LEN:-}
streamTrimLimit: ${REDIS_SCORING_SPAN_LLM_AS_JUDGE_STREAM_TRIM_LIMIT:-}
- scorer: span_user_defined_metric_python
streamName: stream_scoring_span_user_defined_metric_python
codec: java
# Optional per stream configuration (falls back to global if not specified)
poolingInterval: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_CONSUMER_POOL_INTERVAL:-}
longPollingDuration: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_LONG_POLLING_DURATION:-}
consumerBatchSize: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_CONSUMER_BATCH_SIZE:-}
claimIntervalRatio: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_CLAIM_INTERVAL_RATIO:-}
pendingMessageDuration: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_PENDING_MESSAGE_DURATION:-}
maxRetries: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_MAX_RETRIES:-}
streamMaxLen: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_STREAM_MAX_LEN:-}
streamTrimLimit: ${REDIS_SCORING_SPAN_USER_DEFINED_METRIC_PYTHON_STREAM_TRIM_LIMIT:-}
# Configuration for Test Suite assertions
testSuite:
# Default: 1
# Description: Number of LLM runs per dataset item during test suite execution
defaultRunsPerItem: ${TEST_SUITE_DEFAULT_RUNS_PER_ITEM:-1}
# Default: 10
# Description: Timeout in seconds for fetching dataset evaluators and item evaluators
fetchTimeoutSeconds: ${TEST_SUITE_FETCH_TIMEOUT_SECONDS:-10}
# Configuration for Experiment Execution (Redis Streams-based processing)
experimentExecution:
# Default: playground
# Description: Default project name when experiments are run from the playground without an explicit project
defaultProjectName: ${EXPERIMENT_EXECUTION_DEFAULT_PROJECT_NAME:-playground}
# Default: true
# Description: Whether the experiment item processing subscriber is enabled
enabled: ${EXPERIMENT_EXECUTION_ENABLED:-true}
# Default: experiment_item_processing_stream
# Description: Redis Stream name for experiment item processing messages
streamName: ${EXPERIMENT_EXECUTION_STREAM_NAME:-'experiment_item_processing_stream'}
# Default: experiment_item_processing
# Description: Consumer group name for experiment item processing
consumerGroupName: ${EXPERIMENT_EXECUTION_CONSUMER_GROUP_NAME:-'experiment_item_processing'}
# Default: 10
# Description: Maximum number of messages returned within a Redis Stream get
consumerBatchSize: ${EXPERIMENT_EXECUTION_CONSUMER_BATCH_SIZE:-10}
# Default: 500ms
# Description: How often the consumer checks Redis for new messages
poolingInterval: ${EXPERIMENT_EXECUTION_POOLING_INTERVAL:-500ms}
# Default: 5s
# Description: Duration for long-polling reads on the Redis Stream
longPollingDuration: ${EXPERIMENT_EXECUTION_LONG_POLLING_DURATION:-5s}
# Default: 10000
# Description: Maximum length of the Redis Stream (trimmed non-strictly)
streamMaxLen: ${EXPERIMENT_EXECUTION_STREAM_MAX_LEN:-10000}
# Default: 100
# Description: Trim limit for the Redis Stream
streamTrimLimit: ${EXPERIMENT_EXECUTION_STREAM_TRIM_LIMIT:-100}
# Default: 10
# Description: Ratio for claim interval calculation
claimIntervalRatio: ${EXPERIMENT_EXECUTION_CLAIM_INTERVAL_RATIO:-10}
# Default: 10m
# Description: Duration after which a pending message is eligible for claiming
pendingMessageDuration: ${EXPERIMENT_EXECUTION_PENDING_MESSAGE_DURATION:-10m}
# Default: 3
# Description: Maximum number of retries for failed messages
maxRetries: ${EXPERIMENT_EXECUTION_MAX_RETRIES:-3}
# Default: 24h
# Description: TTL for the batch completion counter in Redis
batchCounterTtl: ${EXPERIMENT_EXECUTION_BATCH_COUNTER_TTL:-24h}
# Configuration for Dataset Export
datasetExport:
# Default: false
# Description: Whether dataset export feature is enabled
enabled: ${DATASET_EXPORT_ENABLED:-false}
# Default: dataset-export
# Description: Redis stream name for dataset export jobs
streamName: ${DATASET_EXPORT_STREAM_NAME:-'dataset-export'}
# Default: dataset-export-consumers
# Description: Consumer group name for dataset export job processing
consumerGroupName: ${DATASET_EXPORT_CONSUMER_GROUP_NAME:-'dataset-export-consumers'}
# Default: 10
# Description: Maximum number of export jobs to process in a single batch
consumerBatchSize: ${DATASET_EXPORT_CONSUMER_BATCH_SIZE:-10}
# Default: 1s
# Description: How often to poll Redis for new export jobs
poolingInterval: ${DATASET_EXPORT_POOLING_INTERVAL:-1s}
# Default: 5s
# Description: Timeout for blocking read operations on Redis streams (long polling)
longPollingDuration: ${DATASET_EXPORT_LONG_POLLING_DURATION:-5s}
# Default: 3
# Description: Maximum number of retry attempts for failed export jobs (1-10)
maxRetries: ${DATASET_EXPORT_MAX_RETRIES:-3}
# Default: 2
# Description: Claim pending messages every N polling intervals
claimIntervalRatio: ${DATASET_EXPORT_CLAIM_INTERVAL_RATIO:-2}
# Default: 5m
# Description: Time before export job message considered orphaned and eligible for claiming
pendingMessageDuration: ${DATASET_EXPORT_PENDING_MESSAGE_DURATION:-5m}
# Default: 10000
# Description: Max number of entries (approx) when publishing to the Redis stream. Oldest are evicted if exceeded
streamMaxLen: ${DATASET_EXPORT_STREAM_MAX_LEN:-10000}
# Default: 100
# Description: Max number of entries to evict when publishing to the Redis stream (0 = no limit) if over max length
streamTrimLimit: ${DATASET_EXPORT_STREAM_TRIM_LIMIT:-100}
# Default: 24h
# Description: Default time-to-live for exported CSV files before automatic cleanup
defaultTtl: ${DATASET_EXPORT_DEFAULT_TTL:-24h}
# Default: 5MB (5242880 bytes - S3 minimum for non-final parts)
# Description: Minimum part size for S3 multipart upload (in bytes). Must be >= 5242880 bytes.
# Values below 5242880 will be clamped to 5242880 at runtime.
minPartSize: ${DATASET_EXPORT_MIN_PART_SIZE:-5242880}
# Default: 10MB (10 * 1024 * 1024 = 10485760 bytes)
# Description: Maximum part size for S3 multipart upload (in bytes). Must be >= minPartSize.
# Values below minPartSize will be clamped to minPartSize at runtime.
maxPartSize: ${DATASET_EXPORT_MAX_PART_SIZE:-10485760}
# Default: 100
# Description: Number of items to fetch per batch when streaming dataset items
itemBatchSize: ${DATASET_EXPORT_ITEM_BATCH_SIZE:-100}
# Default: 5m
# Description: Timeout for cleanup job execution (how long the cleanup can run)
cleanupTimeout: ${DATASET_EXPORT_CLEANUP_TIMEOUT:-5m}
# Default: 1s
# Description: How long to wait for acquiring the distributed lock for cleanup
cleanupLockWaitTime: ${DATASET_EXPORT_CLEANUP_LOCK_WAIT_TIME:-1s}
# Default: 100
# Description: Batch size for cleanup job operations (number of jobs to process per batch). Must be between 10 and 1000.
cleanupBatchSize: ${DATASET_EXPORT_CLEANUP_BATCH_SIZE:-100}
# Configuration for the Agent Insights report trigger queue (manual /trigger + daily cron enqueue here;
# a bounded Redis consumer group performs the actual report calls)
agentInsightsReport:
# Default: http://react-svc:8080/opik/ollie/generate-agent-insights
# Description: Platform BE endpoint that triggers Agent Insights report generation on the Ollie pod
triggerUrl: ${AGENT_INSIGHTS_REPORT_TRIGGER_URL:-http://react-svc:8080/opik/ollie/generate-agent-insights}
# Default: 0 5 0 * * ? (daily at 00:05 UTC)
# Description: Quartz cron expression (UTC) for the daily Agent Insights report sweep
schedule: ${AGENT_INSIGHTS_REPORT_SCHEDULE:-'0 5 0 * * ?'}
# Default: 5m
# Description: Timeout for the daily Agent Insights report job sweep (distributed lock hold time)
jobTimeout: ${AGENT_INSIGHTS_REPORT_JOB_TIMEOUT:-5m}
# Default: 5s
# Description: How long to wait to acquire the distributed lock before giving up the sweep
lockWaitTime: ${AGENT_INSIGHTS_REPORT_LOCK_WAIT_TIME:-5s}
# Default: agent-insights-reports
# Description: Redis stream name for queued Agent Insights report triggers
streamName: ${AGENT_INSIGHTS_REPORT_STREAM_NAME:-'agent-insights-reports'}
# Default: agent-insights-report-consumers
# Description: Consumer group name for Agent Insights report trigger processing
consumerGroupName: ${AGENT_INSIGHTS_REPORT_CONSUMER_GROUP_NAME:-'agent-insights-report-consumers'}
# Default: 5
# Description: Maximum number of report triggers to process in a single batch (caps concurrent runs)
consumerBatchSize: ${AGENT_INSIGHTS_REPORT_CONSUMER_BATCH_SIZE:-5}
# Default: 1s
# Description: How often to poll Redis for new report triggers
poolingInterval: ${AGENT_INSIGHTS_REPORT_POOLING_INTERVAL:-1s}
# Default: 5s
# Description: Timeout for blocking read operations on Redis streams (long polling)
longPollingDuration: ${AGENT_INSIGHTS_REPORT_LONG_POLLING_DURATION:-5s}
# Default: 3
# Description: Maximum number of retries for a failing report trigger before it is dropped
maxRetries: ${AGENT_INSIGHTS_REPORT_MAX_RETRIES:-3}
# Default: 2
# Description: Claim pending messages every N polling intervals
claimIntervalRatio: ${AGENT_INSIGHTS_REPORT_CLAIM_INTERVAL_RATIO:-2}
# Default: 5m
# Description: How long a message can stay pending before it is auto-claimed by another consumer
pendingMessageDuration: ${AGENT_INSIGHTS_REPORT_PENDING_MESSAGE_DURATION:-5m}
# Default: 10000
# Description: Maximum stream length before old entries are trimmed
streamMaxLen: ${AGENT_INSIGHTS_REPORT_STREAM_MAX_LEN:-10000}
# Default: 100
# Description: Number of entries trimmed at a time when the stream exceeds streamMaxLen
streamTrimLimit: ${AGENT_INSIGHTS_REPORT_STREAM_TRIM_LIMIT:-100}
# Configuration for Optimization Studio logs synchronization
optimizationLogs:
# Default: true
# Description: Whether log synchronization from Redis to S3 is enabled
enabled: ${OPTIMIZATION_LOGS_ENABLED:-true}
# Default: 30s
# Description: Interval between log sync runs
syncInterval: ${OPTIMIZATION_LOGS_SYNC_INTERVAL:-30s}
# Default: 30s
# Description: Lock timeout for per-optimization distributed lock during sync
lockTimeout: ${OPTIMIZATION_LOGS_LOCK_TIMEOUT:-30s}
# Default: 5
# Description: Maximum number of concurrent S3 uploads during sync
syncConcurrency: ${OPTIMIZATION_LOGS_SYNC_CONCURRENCY:-5}
# Environment CRUD configuration
environment:
# Maximum number of environments allowed per workspace.
maxPerWorkspace: ${OPIK_ENVIRONMENT_MAX_PER_WORKSPACE:-100}
# Data retention policy enforcement
# The job splits the workspace UUID space into N=executionsPerDay fractions and processes one fraction per tick.
# Use a value that divides 1440 evenly for consistent interval spacing (e.g., 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 30, 32, 36, 48, 60, 80, 96, 120, 144, 160, 180, 240, 288).
retention:
enabled: ${RETENTION_ENABLED:-false}
executionsPerDay: ${RETENTION_EXECUTIONS_PER_DAY:-48}
workspaceBatchSize: ${RETENTION_WORKSPACE_BATCH_SIZE:-1000}
slidingWindowDays: ${RETENTION_SLIDING_WINDOW_DAYS:-3}
# Progressive catch-up for apply-to-past rules. Deletes historical data older than the sliding window.
# At rule creation, estimates workspace span velocity (spans/week) to triage into tiers:
# small (<smallThreshold/week): batch one-shot delete, up to smallBatchSize workspaces per cycle
# medium (smallThreshold..largeThreshold/week): 10 most outdated, mediumChunkDays per cycle each
# large (>=largeThreshold/week or estimation hit row limit): 1 most outdated, largeChunkDays per cycle
catchUp:
enabled: ${RETENTION_CATCH_UP_ENABLED:-true}
# Velocity thresholds (spans/week). Free tier ~6K/week, so 10K keeps them in the small (fast) path.
smallThreshold: ${RETENTION_CATCH_UP_SMALL_THRESHOLD:-10000}
largeThreshold: ${RETENTION_CATCH_UP_LARGE_THRESHOLD:-100000}
# Max workspaces processed per cycle per tier
smallBatchSize: ${RETENTION_CATCH_UP_SMALL_BATCH_SIZE:-200}
mediumBatchSize: ${RETENTION_CATCH_UP_MEDIUM_BATCH_SIZE:-10}
# Time window (days) deleted per cycle for medium and large workspaces
mediumChunkDays: ${RETENTION_CATCH_UP_MEDIUM_CHUNK_DAYS:-7}
largeChunkDays: ${RETENTION_CATCH_UP_LARGE_CHUNK_DAYS:-1}
# Assumed velocity when the estimation query fails with TOO_MANY_ROWS (>20M rows)
defaultVelocity: ${RETENTION_CATCH_UP_DEFAULT_VELOCITY:-1000000}
# Interval in minutes between catch-up cycles (default: 45)
intervalMinutes: ${RETENTION_CATCH_UP_INTERVAL_MINUTES:-45}
# Interval in minutes between estimation cycles for new rules (default: 5)
estimationIntervalMinutes: ${RETENTION_CATCH_UP_ESTIMATION_INTERVAL_MINUTES:-5}
# Earliest date for catch-up cursor start (service launch date)
serviceStartDate: ${RETENTION_CATCH_UP_SERVICE_START_DATE:-2024-09-01}
# LLM providers client configuration
llmProviderClient:
# Default: 3
# Description: Max amount of attempts to reach the LLM provider before giving up
maxAttempts: ${LLM_PROVIDER_CLIENT_MAX_ATTEMPTS:-3}
# Default: 500
# Description: Number of milliseconds to wait between retry attempts
delayMillis: ${LLM_PROVIDER_CLIENT_DELAY_MILLIS:-500}
# Default: 0.2
# Description: Max amount of jitter to add to the delay. The value is a percentage in the range [0-1]
jitterScale: ${LLM_PROVIDER_CLIENT_JITTER_SCALE:-0.2}
# Default: 1.5
# Description: Backoff exponent to be used in retry attempts
backoffExp: ${LLM_PROVIDER_CLIENT_BACKOFF_EXP:-1.5}
# Default: 60s
# Description: Call timeout for LLM providers
callTimeout: ${LLM_PROVIDER_CLIENT_CALL_TIMEOUT:-60s}
# Default: 60s
# Description: Connect timeout for LLM providers
connectTimeout: ${LLM_PROVIDER_CLIENT_CONNECT_TIMEOUT:-60s}
# Default: 60s
# Description: Read timeout for LLM providers
readTimeout: ${LLM_PROVIDER_CLIENT_READ_TIMEOUT:-60s}
# Default: 60s
# Description: Write timeout for LLM providers
writeTimeout: ${LLM_PROVIDER_CLIENT_WRITE_TIMEOUT:-60s}
# Default: false
# Description: Whether or not to log requests (HTTP-level logging via langchain4j - can be verbose and may contain credentials)
logRequests: ${LLM_PROVIDER_CLIENT_LOG_REQUESTS:-false}
# Default: false
# Description: Whether or not to log responses (HTTP-level logging via langchain4j - can be verbose)
logResponses: ${LLM_PROVIDER_CLIENT_LOG_RESPONSES:-false}
# Configuration for OpenAI client
openAiClient:
# Default:
# Description: OpenAI API URL
url: ${LLM_PROVIDER_OPENAI_URL:-}
# Configuration for Anthropic client
anthropicClient:
# Default: https://api.anthropic.com/v1/
# Description: Anthropic API URL
url: ${LLM_PROVIDER_ANTHROPIC_URL:-https://api.anthropic.com/v1/}
# Default: 2023-06-01
# Description: Anthropic API version https://docs.anthropic.com/en/api/versioning
version: ${LLM_PROVIDER_ANTHROPIC_VERSION:-'2023-06-01'}
# Default: https://openrouter.ai/api/v1
# Description: OpenRouter API URL
openRouterUrl: ${LLM_PROVIDER_OPENROUTER_URL:-https://openrouter.ai/api/v1}
vertexAIClient:
# Default: https://www.googleapis.com/auth/cloud-platform
# Description: Vertex AI SCOPE API URL
scope: ${LLM_PROVIDER_VERTEXAI_SCOPE:-https://www.googleapis.com/auth/cloud-platform}
# Configuration for cache manager
cacheManager:
# Default: true
# Description: Whether or not cache manager is enabled
enabled: ${CACHE_MANAGER_ENABLED:-true}
# Default: PT1S
# Description: Time to live for cache entries in using the formats accepted are based on the ISO-8601: https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-
defaultDuration: ${CACHE_MANAGER_DEFAULT_DURATION:-PT1S}
caches:
# Default: {}
# Description: Dynamically created caches with their respective time to live in seconds
automationRules: ${CACHE_MANAGER_AUTOMATION_RULES_DURATION:-PT1S}
# Default: PT1H
# Description: Cache TTL for the per-project size estimate (ScopeMetadata) gating dynamic sorting.
# The estimate scans all of the project's spans, so cache misses are expensive by design.
# Renamed from the orphaned workspace_metadata entry, which no code referenced.
project_metadata: ${CACHE_MANAGER_PROJECT_METADATA_DURATION:-PT1H}
# Default: PT5M
# Description: Cache TTL for workspace version determination results, applied per workspace
# Scope: Per workspace (cache key includes workspace ID)
# Overrides: Overrides defaultDuration for the workspace_version cache group
# Operational impact: Lower values increase DB query frequency on workspace load; higher values delay version transitions after entity changes
workspace_version: ${CACHE_MANAGER_WORKSPACE_VERSION_DURATION:-PT5M}
experiment_metadata: ${CACHE_MANAGER_EXPERIMENT_METADATA_DURATION:-PT1H}
# Default: PT30M
# Description: Cache TTL for the max(timeout_mark_thread_as_inactive) across all workspaces, used to compute the closing job lookback window
max_timeout_mark_thread_as_inactive: ${CACHE_MANAGER_MAX_TIMEOUT_MARK_THREAD_AS_INACTIVE_DURATION:-PT30M}
# Configuration for clickhouse log appender
clickHouseLogAppender:
# Default: 1000
# Description: Number of log messages to be batched before sending to ClickHouse
batchSize: ${CLICKHOUSE_LOG_APPENDER_BATCH_SIZE:-1000}
# Default: PT0.500S or 500ms
# Description: Time interval after which the log messages are sent to ClickHouse if the batch size is not reached
flushIntervalDuration: ${CLICKHOUSE_LOG_APPENDER_FLUSH_INTERVAL_DURATION:-PT0.500S}
workspaceSettings:
# Default: 50
# Description: Maximum size of a workspace in GB to allow dynamic sorting.
# Set to -1 to disable the limit (allow sorting for all workspace sizes).
# This value is calculated via estimated size based on spans table
maxSizeToAllowSorting: ${WORKSPACE_SETTINGS_MAX_SIZE_IN_GB_TO_ALLOW_SORTING:-50}
# Default: 100
# Description: Maximum size of a project in GB to allow dynamic sorting.
# Set to -1 to disable the limit (allow sorting for all project sizes).
# This value is calculated via estimated size based on spans table.
maxProjectSizeToAllowSorting: ${WORKSPACE_SETTINGS_MAX_PROJECT_SIZE_IN_GB_TO_ALLOW_SORTING:-100}
# Default: 1000000
# Description: Maximum number of experiment items in a workspace to allow dynamic sorting.
# Set to -1 to disable the limit (allow sorting for all experiment item counts).
# This count-based limit is used because experiment_items has fixed-size columns (UUIDs only)
# and query performance scales with row count, not data size.
maxExperimentItemsToAllowSorting: ${WORKSPACE_SETTINGS_MAX_EXPERIMENT_ITEMS_TO_ALLOW_SORTING:-1000000}
# Configuration AWS S3
s3Config:
s3Region: ${S3_REGION:-'us-east-1'}
# Description: AWS S3 bucket for Opik
s3BucketName: ${S3_BUCKET:-'public'}
# Description: AWS S3 presign url timeout
preSignUrlTimeoutSec: ${S3_PRESIGN_URL_TIMEOUT:-3600}
# Description: Url for local MinIO or Aws
s3Url: ${S3_URL:-http://localhost:9001}
# Description: Whether installation uses MinIO or AWS S3
isMinIO: ${IS_MINIO:-true}
# Ollie state persistence configuration
ollieStateConfig:
# Default: 52428800 (50MB)
# Description: Maximum upload size in bytes for ollie state persistence
maxUploadSizeBytes: ${OLLIE_STATE_MAX_UPLOAD_SIZE_BYTES:-52428800}
reportGeneration:
# Default: "" (blank disables report generation)
# Description: URL for triggering Ollie report generation. Blank disables report generation.
# Locally: set REPORT_GENERATION_URL=http://localhost:9080/reports/generate
# Deployed: points to the Comet API (e.g. http://comet-api/opik/ollie/generate-report)
# which resolves workspace credentials and proxies to Ollie.
url: ${REPORT_GENERATION_URL:-""}
# Attachments configuration
attachmentsConfig:
# Description: Minimum size (bytes) for base64 strings to be considered attachments
# Default: 256000 (256KB)
stripMinSize: ${ATTACHMENTS_STRIP_MIN_SIZE:-256000}
# Python evaluator configuration
pythonEvaluator:
# Default: http://localhost:8000
# Description: URL of the Python evaluator service, generally the opik-python-backend service
url: ${PYTHON_EVALUATOR_URL:-http://localhost:8000}
# Default: 4
# Description: Maximum number of retry attempts to reach the Python evaluator before giving up
maxRetryAttempts: ${PYTHON_EVALUATOR_MAX_RETRY_ATTEMPTS:-4}
# Default: 1s
# Description: Max delay between retry attempts, will be increased exponentially based on backoffExp
maxRetryDelay: ${PYTHON_EVALUATOR_MAX_RETRY_DELAY:-1s}
# Default: 500ms
# Description: Min delay between retry attempts
minRetryDelay: ${PYTHON_EVALUATOR_MIN_RETRY_DELAY:-500ms}
# Default: 10s
# Description: Max wait for a Python evaluator response read per call.
readTimeout: ${PYTHON_EVALUATOR_READ_TIMEOUT:-10s}
# Default: 5s
# Description: Max wait for the TCP/TLS connection to the Python evaluator to be established.
connectTimeout: ${PYTHON_EVALUATOR_CONNECT_TIMEOUT:-5s}
# JAX-RS Jersey client configuration. This is the singleton HTTP client shared in the service.
jerseyClient:
# Default: 30s
# Description: Overall response read timeout. Per-call timeouts can override via Jersey ClientProperties.READ_TIMEOUT.
timeout: ${JERSEY_CLIENT_TIMEOUT:-30s}
# Default: 2s
# Description: The maximum time to wait for a connection to open.
connectionTimeout: ${JERSEY_CLIENT_CONNECTION_TIMEOUT:-2s}
# Default: 1s
# Description: The maximum time to wait for a connection to be returned from the connection pool.
connectionRequestTimeout: ${JERSEY_CLIENT_CONNECTION_REQUEST_TIMEOUT:-1s}
# Default: 5m
# Description: Max connection lifetime; recycles connections to drain stale upstream pods after rollouts.
timeToLive: ${JERSEY_CLIENT_TIME_TO_LIVE:-5m}
# Default: 256
# Description: The maximum number of concurrent open connections.
maxConnections: ${JERSEY_CLIENT_MAX_CONNECTIONS:-256}
# Default: 64
# Description: The maximum number of concurrent open connections per route.
maxConnectionsPerRoute: ${JERSEY_CLIENT_MAX_CONNECTIONS_PER_ROUTE:-64}
# Default: 5s
# Description: The maximum time before a persistent connection is checked to remain active. If set to 0, no inactivity check will be performed.
validateAfterInactivityPeriod: ${JERSEY_CLIENT_VALIDATE_AFTER_INACTIVITY:-5s}
# Default: 16
# Description: Minimum idle Jersey async worker threads.
minThreads: ${JERSEY_CLIENT_MIN_THREADS:-16}
# Default: 128
# Description: Maximum Jersey async worker threads.
maxThreads: ${JERSEY_CLIENT_MAX_THREADS:-128}
# Default: 64
# Description: The size of the work queue of the pool used for asynchronous requests. Additional threads will be spawn only if the queue is reached its maximum size.
workQueueSize: ${JERSEY_CLIENT_WORK_QUEUE_SIZE:-64}
# Default: false
# Description: Whether to send gzipped request bodies. Off because not all upstreams handle Content-Encoding: gzip on requests.
gzipEnabledForRequests: ${JERSEY_CLIENT_GZIP_ENABLED_FOR_REQUESTS:-false}
# Default: false
# Description: Whether to enable Transfer-Encoding: chunked on outbound request bodies. Off because sending Content-Length is universally accepted.
chunkedEncodingEnabled: ${JERSEY_CLIENT_CHUNKED_ENCODING_ENABLED:-false}
serviceToggles:
# Default: true
# Description: Whether or not Python evaluator is enabled
pythonEvaluatorEnabled: ${TOGGLE_PYTHON_EVALUATOR_ENABLED:-"true"}
# Default: false
# Description: Whether or not Guardrails feature is enabled
guardrailsEnabled: ${TOGGLE_GUARDRAILS_ENABLED:-"false"}
# Default: false
# Description: Whether or not to enable the trace thread Python evaluator
traceThreadPythonEvaluatorEnabled: ${TOGGLE_TRACE_THREAD_PYTHON_EVALUATOR_ENABLED:-"true"}
# Default: false
# Description: Whether or not to enable the span LLM as Judge evaluator
spanLlmAsJudgeEnabled: ${TOGGLE_SPAN_LLM_AS_JUDGE_ENABLED:-"true"}
# Default: true
# Description: Whether or not to enable the span user-defined metric Python evaluator
spanUserDefinedMetricPythonEnabled: ${TOGGLE_SPAN_USER_DEFINED_METRIC_PYTHON_ENABLED:-"true"}
# Default: false
# Description: Whether or not OpikAI feature is enabled
opikAIEnabled: ${TOGGLE_OPIK_AI_ENABLED:-"false"}
# Default: false
# Description: Whether or not Alert feature is enabled
alertsEnabled: ${TOGGLE_ALERTS_ENABLED:-"true"}
# Default: false
# Description: Whether or not Welcome Wizard is enabled
welcomeWizardEnabled: ${TOGGLE_WELCOME_WIZARD_ENABLED:-"false"}
# Default: true
# Description: Whether or not export/download functionality is enabled
exportEnabled: ${TOGGLE_EXPORT_ENABLED:-"true"}
# Default: false
# Description: Whether or not dataset versioning feature is enabled
datasetVersioningEnabled: ${TOGGLE_DATASET_VERSIONING_ENABLED:-"true"}
# Default: true
# Description: Whether or not dataset export to CSV feature is enabled
datasetExportEnabled: ${DATASET_EXPORT_ENABLED:-"false"}
# Default: true
# Description: Whether the deployment is expected to produce demo project data on signup. When false, the FE skips the onboarding demo-loading screen and lets the user proceed to the empty workspace immediately.
demoDataEnabled: ${TOGGLE_DEMO_DATA_ENABLED:-"true"}
# Default: false
# Description: Whether or not the Cost Intelligence (AI Spend) feature is enabled
costIntelligenceEnabled: ${TOGGLE_COST_INTELLIGENCE_ENABLED:-"false"}
# Default: true
# Description: Whether or not OpenAI provider is enabled
openaiProviderEnabled: ${TOGGLE_OPENAI_PROVIDER_ENABLED:-"true"}
# Default: true
# Description: Whether or not Anthropic provider is enabled
anthropicProviderEnabled: ${TOGGLE_ANTHROPIC_PROVIDER_ENABLED:-"true"}
# Default: true
# Description: Whether or not Gemini provider is enabled
geminiProviderEnabled: ${TOGGLE_GEMINI_PROVIDER_ENABLED:-"true"}
# Default: true
# Description: Whether or not OpenRouter provider is enabled
openrouterProviderEnabled: ${TOGGLE_OPENROUTER_PROVIDER_ENABLED:-"true"}
# Default: true
# Description: Whether or not Vertex AI provider is enabled
vertexaiProviderEnabled: ${TOGGLE_VERTEXAI_PROVIDER_ENABLED:-"true"}
# Default: true
# Description: Whether or not Bedrock provider is enabled
bedrockProviderEnabled: ${TOGGLE_BEDROCK_PROVIDER_ENABLED:-"true"}
# Default: true
# Description: Whether or not Custom LLM provider is enabled
customllmProviderEnabled: ${TOGGLE_CUSTOMLLM_PROVIDER_ENABLED:-"true"}
# Default: true
# Description: Whether or not Ollama provider is enabled
ollamaProviderEnabled: ${TOGGLE_OLLAMA_PROVIDER_ENABLED:-"true"}
# Default: false
# Description: Whether or not the Ollie AI assistant integration is enabled.
ollieEnabled: ${TOGGLE_OLLIE_ENABLED:-"false"}
# Default: false
# Description: Whether the project homepage is enabled. When false, the Ollie page is the default project page.
projectHomepageEnabled: ${TOGGLE_PROJECT_HOMEPAGE_ENABLED:-"false"}
# Default: false
# Description: Master switch for the agentic-tools path on LLM-as-judge online scoring. When false, the
# inline path is used regardless of context size. Threshold lives under onlineScoring.agenticToolsThresholdTokens.
agenticToolsEnabled: ${TOGGLE_AGENTIC_TOOLS_ENABLED:-"false"}
# Default: false
# Description: Whether or not the Agent Insights freeform SQL path is enabled. Gates the read-only ClickHouse client
# and the clickhouse-readonly-freeform-sql health check usage. When off, the read-only client is never queried.
agentInsightsEnabled: ${TOGGLE_AGENT_INSIGHTS_ENABLED:-"false"}
# Default: true
# Description: Whether the online-scoring (LLM-as-judge) evaluation loop is persisted as monitoring traces/spans.
# When on, each evaluation produces one trace (source=evaluator) with one llm span per LLM round, so cost and
# behavior are auditable inside Opik. When off, evaluations run exactly as before with no extra writes.
onlineScoringTracingEnabled: ${TOGGLE_ONLINE_SCORING_TRACING_ENABLED:-"true"}
# Default: "" (empty, no allowlisted workspaces)
# Description: Comma-separated list of workspace IDs that should always receive V2 navigation.
# Valid values: comma-separated workspace IDs (e.g. "ws-id-1,ws-id-2"), or "" (empty, disabled).
# Scope: Per-workspace — only listed workspace IDs are affected, all others follow normal determination.
# Priority: Highest — overrides forceWorkspaceVersion and all other determination logic for listed workspaces.
# Use case: gradual V2 rollout — allowlist specific workspace IDs for V2 while the rest use entity-based determination.
# Operational impact: empty/missing means no allowlisting. Non-allowlisted workspaces are unaffected.
v2WorkspaceAllowlist: ${TOGGLE_V2_WORKSPACE_ALLOWLIST:-""}
# Default: "" (empty, no allowlisted workspaces)
# Description: Comma-separated list of workspace IDs that should always receive V1 navigation.
# Valid values: comma-separated workspace IDs (e.g. "ws-id-1,ws-id-2"), or "" (empty, disabled).
# Scope: Per-workspace — only listed workspace IDs are affected, all others follow normal determination.
# Priority: Second — overridden by v2WorkspaceAllowlist; overrides forceWorkspaceVersion and all subsequent determination logic.
# Use case: customer-driven V1 stickiness — pin specific workspaces to legacy navigation without affecting the rest of the deployment.
# Operational impact: empty/missing means no allowlisting. Non-allowlisted workspaces are unaffected.
v1WorkspaceAllowlist: ${TOGGLE_V1_WORKSPACE_ALLOWLIST:-""}
# Default: version_2
# Description: Forces ALL workspaces to a specific navigation version.
# Valid values: "disabled" (use version 1 entity check), "version_1" (force legacy), "version_2" (force project-first).
# Scope: Global — applies to all workspaces regardless of their entity state.
# Priority: Third — overridden by v2WorkspaceAllowlist and v1WorkspaceAllowlist for listed workspaces.
# Overrides: When not "disabled", overrides the version entity check and auth gate entirely.
# Operational impact: Default is "version_2". Override to "disabled" (entity-based determination) or "version_1" if global enforcement is needed.
forceWorkspaceVersion: ${TOGGLE_FORCE_WORKSPACE_VERSION:-"version_2"}
# Default: 100
# Description: Deployment-level default rows-per-page for UI tables (experiments v1/v2).
# Lower this value to reduce initial render cost for high-volume workspaces.
defaultPageSize: ${UI_DEFAULT_PAGE_SIZE:-100}
# Local Runner configuration
localRunner:
# Default: 30m
# Description: Maximum time a job can run before being considered timed out
jobTimeout: ${OPIK_RUNNER_JOB_TIMEOUT:-30m}
# Default: 100
# Description: Maximum number of pending jobs allowed in a runner's queue
maxPendingJobsPerRunner: ${OPIK_RUNNER_MAX_PENDING:-100}
# Default: 15s
# Description: Time-to-live for runner heartbeats; runners not heartbeating within this window are considered dead
heartbeatTtl: ${OPIK_RUNNER_HEARTBEAT_TTL:-15s}
# Default: 10s
# Description: How long the nextJob long-poll blocks waiting for a new job before returning empty
nextJobPollTimeout: ${OPIK_RUNNER_NEXT_JOB_POLL_TIMEOUT:-10s}
# Default: 24h
# Description: How long after a runner dies before its data is purged from Redis
deadRunnerPurgeTime: ${OPIK_RUNNER_DEAD_PURGE_HOURS:-24h}
# Default: 7d
# Description: How long completed job metadata is retained in Redis
completedJobTtl: ${OPIK_RUNNER_COMPLETED_JOB_TTL:-7d}
# Default: 60s
# Description: Interval between reaper job executions that clean up dead runners
reaperJobInterval: ${OPIK_RUNNER_REAPER_JOB_INTERVAL:-60s}
# Default: 55s
# Description: How long the reaper holds its distributed lock while processing
reaperLockDuration: ${OPIK_RUNNER_REAPER_LOCK_DURATION:-55s}
# Default: 5s
# Description: How long the reaper waits to acquire the distributed lock before giving up
reaperLockWait: ${OPIK_RUNNER_REAPER_LOCK_WAIT:-5s}
# Default: 5s
# Description: Extra buffer added to the async response timeout beyond nextJobPollTimeout
nextJobAsyncTimeoutBuffer: ${OPIK_RUNNER_ASYNC_TIMEOUT_BUFFER:-5s}
# Default: 100
# Description: Maximum number of runners the reaper processes per cycle across all workspaces
reaperMaxRunnersPerCycle: ${OPIK_RUNNER_REAPER_MAX_RUNNERS_PER_CYCLE:-100}
# Default: 50
# Description: Maximum number of agents allowed per runner
maxAgentsPerRunner: ${OPIK_RUNNER_MAX_AGENTS_PER_RUNNER:-50}
# Default: 1000
# Description: Maximum number of log entries a runner can send in a single batch
maxLogEntriesPerBatch: ${OPIK_RUNNER_MAX_LOG_ENTRIES_PER_BATCH:-1000}
# Default: 50
# Description: Maximum number of pending bridge commands allowed per runner
bridgeMaxPendingPerRunner: ${OPIK_RUNNER_BRIDGE_MAX_PENDING:-50}
# Default: 600
# Description: Maximum bridge commands per minute per runner
bridgeMaxCommandsPerMinute: ${OPIK_RUNNER_BRIDGE_MAX_COMMANDS_PER_MIN:-600}
# Default: 120
# Description: Maximum bridge write commands per minute per runner
bridgeMaxWriteCommandsPerMinute: ${OPIK_RUNNER_BRIDGE_MAX_WRITE_COMMANDS_PER_MIN:-120}
# Default: 30s
# Description: How long the bridge nextCommands long-poll blocks before returning empty
bridgePollTimeout: ${OPIK_RUNNER_BRIDGE_POLL_TIMEOUT:-30s}
# Default: 30s
# Description: Default timeout for bridge commands when not specified by caller
bridgeDefaultCommandTimeout: ${OPIK_RUNNER_BRIDGE_DEFAULT_CMD_TIMEOUT:-30s}
# Default: 120s
# Description: Maximum allowed timeout for bridge commands
bridgeMaxCommandTimeout: ${OPIK_RUNNER_BRIDGE_MAX_CMD_TIMEOUT:-120s}
# Default: 1h
# Description: How long completed bridge command metadata is retained in Redis
bridgeCompletedCommandTtl: ${OPIK_RUNNER_BRIDGE_COMPLETED_CMD_TTL:-1h}
# Default: 5s
# Description: Extra buffer added to async response timeout beyond bridge poll/command timeout
bridgeAsyncTimeoutBuffer: ${OPIK_RUNNER_BRIDGE_ASYNC_TIMEOUT_BUFFER:-5s}
# Default: 1048576 (1MB)
# Description: Maximum payload size in bytes for bridge command args and results
bridgeMaxPayloadBytes: ${OPIK_RUNNER_BRIDGE_MAX_PAYLOAD_BYTES:-1048576}
# Orphaned Redis stream-consumer reaper (OPIK-6982). Non-graceful pod exits (OOMKill/SIGKILL/crash) leak
# stream consumers that Redis never removes; this job deletes consumers idle beyond the threshold with no
# pending entries. One instance runs per cycle (distributed lock with hold-until-expiry).
streamConsumerReaper:
# Default: true
# Description: Whether the orphaned stream-consumer reaper job is enabled
enabled: ${OPIK_STREAM_CONSUMER_REAPER_ENABLED:-true}
# Default: 1h
# Description: Interval between reaper job executions
jobInterval: ${OPIK_STREAM_CONSUMER_REAPER_JOB_INTERVAL:-1h}
# Default: 5m
# Description: Delay before the first reaper run after startup, to avoid reaping during warm-up
startupDelay: ${OPIK_STREAM_CONSUMER_REAPER_STARTUP_DELAY:-5m}
# Default: 3d
# Description: Consumers idle beyond this (and with no pending entries) are removed
idleThreshold: ${OPIK_STREAM_CONSUMER_REAPER_IDLE_THRESHOLD:-3d}
# Default: 10m
# Description: How long the reaper holds its distributed lock (until expiry) to prevent concurrent fleet-wide runs
lockDuration: ${OPIK_STREAM_CONSUMER_REAPER_LOCK_DURATION:-10m}
# Trace Thread configuration
traceThreadConfig:
# Default: true
# Description: Whether the trace thread closing job is enabled
enabled: ${OPIK_TRACE_THREAD_CLOSING_JOB_ENABLED:-true}
# Default: 15min
# Description: Inactive thread timeout. If a thread is inactive for this amount of time, it will be marked as inactive
timeoutToMarkThreadAsInactive: ${OPIK_TRACE_THREAD_TIMEOUT_TO_MARK_AS_INACTIVE:-15m}
# Default: trace_thread_closing
# Description: A consumer group name so multiple instances can share the stream load
consumerGroupName: ${OPIK_REDIS_TRACE_THREAD_CONSUMER_GROUP_NAME:-'trace_thread_closing'}
# Default: 100
# Description: Maximum number of messages returned within a Redis Stream get
consumerBatchSize: ${OPIK_REDIS_TRACE_THREAD_CONSUMER_BATCH_SIZE:-100}
# Default: 500ms
# Description: How often the trace thread consumer will check Redis for new messages (in milliseconds)
poolingInterval: ${OPIK_REDIS_TRACE_THREAD_POOLING_INTERVAL:-500ms}
# Default: 5s
# Description: Timeout for blocking read operations on Redis streams (long polling duration)
longPollingDuration: ${OPIK_REDIS_TRACE_THREAD_LONG_POLLING_DURATION:-5s}
# Default: trace_thread_closing_stream
# Description: The name of the Redis Stream used for trace thread closing
streamName: ${OPIK_REDIS_TRACE_THREAD_STREAM_NAME:-'trace_thread_closing_stream'}
# Default: 15s
# Description: The interval at which the close trace thread job will run to inactive threads
closeTraceThreadJobInterval: ${OPIK_CLOSE_TRACE_THREAD_JOB_INTERVAL:-15s}
# Default: 300ms
# Description: The time to wait for the close trace threads job to acquire the lock before giving up
closeTraceThreadJobLockWaitTime: ${OPIK_CLOSE_TRACE_THREAD_JOB_LOCK_WAIT_TIME:-300ms}
# Default: 2000
# Description: The maximum number of item to process in a single close trace thread run
closeTraceThreadMaxItemPerRun: ${OPIK_CLOSE_TRACE_THREAD_MAX_ITEM_PER_RUN:-2000}
# Default: 7d
# Type: Duration (e.g. 1d, 12h, 7d)
# Scope: Global — applies to the trace-thread closing job on every instance
# Description: On first run after startup (or after an outage), look back this far to catch threads
# that became stale during downtime. The minmax skip index keeps cost proportional to matching
# granules, so wider windows are cheap. Subsequent runs use the normal computed lookback.
# Impact: Larger values scan more granules on first run but reduce risk of missing stale threads
# after prolonged outages. Smaller values reduce first-run cost but may miss old threads.
# Safe range: 1d30d
coldStartLookback: ${OPIK_CLOSE_TRACE_THREAD_COLD_START_LOOKBACK:-7d}
# Default: 5
# Type: Integer (exponent, not the backoff duration itself)
# Scope: Global — applies to the trace-thread closing job on every instance
# Description: Max exponent for exponential backoff on consecutive failures.
# Backoff duration = closeTraceThreadJobInterval * 2^exponent (e.g. 15s * 2^5 = 480s = 8min).
# Impact: Higher values allow longer backoff on persistent failures, reducing load on ClickHouse.
# Lower values resume faster after transient errors but risk hammering a struggling server.
# Safe range: 110
maxBackoffExponent: ${OPIK_CLOSE_TRACE_THREAD_MAX_BACKOFF_EXPONENT:-5}
# Default: 10
# Description: Claim pending messages every N polling intervals
claimIntervalRatio: ${OPIK_REDIS_TRACE_THREAD_CLAIM_INTERVAL_RATIO:-10}
# Default: 10m
# Description: Time before message considered orphaned and eligible for claiming
pendingMessageDuration: ${OPIK_REDIS_TRACE_THREAD_PENDING_MESSAGE_DURATION:-10m}
# Default: 3
# Description: Maximum number of retry attempts for failed messages (1-10)
maxRetries: ${OPIK_REDIS_TRACE_THREAD_MAX_RETRIES:-3}
# Default: 100000
# Description: Max number of entries (approx) when publishing to the Redis stream. Oldest are evicted if exceeded
streamMaxLen: ${OPIK_REDIS_TRACE_THREAD_STREAM_MAX_LEN:-100000}
# Default: 100
# Description: Max number of entries to evict when publishing to the Redis stream (0 = no limit) if over max length
streamTrimLimit: ${OPIK_REDIS_TRACE_THREAD_STREAM_TRIM_LIMIT:-100}
# Job timeout configuration
jobTimeout:
# Default: 30s
# Description: Timeout for the daily usage report job execution
dailyUsageReportJobTimeout: ${OPIK_DAILY_USAGE_REPORT_JOB_TIMEOUT:-30}
# Default: 30s
# Description: Timeout for the trace threads closing job execution
traceThreadsClosingJobTimeout: ${OPIK_TRACE_THREADS_CLOSING_JOB_TIMEOUT:-30}
# Response formatting configuration
responseFormatting:
# Default: 10001
# Description: Maximum size of input/output/metadata fields in responses (FE limit + 1)
truncationSize: ${OPIK_RESPONSE_TRUNCATION_CHAR_LIMIT:-10001}
# Queue configuration for Python RQ workers
queues:
# Default: true
# Description: Whether queue functionality is enabled
enabled: ${OPIK_QUEUES_ENABLED:-true}
# Default: 14 days
# Description: Default TTL for jobs in queues (how long job data is kept in Redis)
defaultJobTtl: ${OPIK_QUEUES_DEFAULT_JOB_TTL:-14 days}
# Per-queue specific configurations
queues:
# Optimizer cloud queue configuration
opik:optimizer-cloud:
# Job TTL for optimizer jobs
jobTTl: ${OPIK_OPTIMIZER_QUEUE_JOB_TTL:-1 day}
# Webhook configuration
webhook:
# Default: false
# Description: Whether or not webhook functionality is enabled
enabled: ${WEBHOOK_ENABLED:-true}
# Default: webhook-events
# Description: Redis stream name for webhook events
streamName: ${WEBHOOK_STREAM_NAME:-webhook-events}
# Default: webhook-consumers
# Description: Consumer group name for webhook event processing
consumerGroupName: ${WEBHOOK_CONSUMER_GROUP_NAME:-webhook-consumers}
# Default: 10
# Description: Maximum number of messages to consume in a single batch (1-100)
consumerBatchSize: ${WEBHOOK_CONSUMER_BATCH_SIZE:-10}
# Default: 1s
# Description: How often webhook consumer will check Redis for new messages
poolingInterval: ${WEBHOOK_POOLING_INTERVAL:-1s}
# Default: 5s
# Description: Timeout for blocking read operations on Redis streams (long polling duration)
longPollingDuration: ${WEBHOOK_LONG_POLLING_DURATION:-5s}
# Default: 3
# Description: Maximum number of retry attempts for failed webhooks (1-10)
maxRetries: ${WEBHOOK_MAX_RETRIES:-3}
# Default: 500ms
# Description: Initial delay between retry attempts
initialRetryDelay: ${WEBHOOK_INITIAL_RETRY_DELAY:-500ms}
# Default: 30s
# Description: Maximum delay between retry attempts
maxRetryDelay: ${WEBHOOK_MAX_RETRY_DELAY:-30s}
# Default: 10s
# Description: HTTP request timeout for webhook calls
requestTimeout: ${WEBHOOK_REQUEST_TIMEOUT:-10s}
# Default: 5s
# Description: HTTP connection timeout for webhook calls
connectionTimeout: ${WEBHOOK_CONNECTION_TIMEOUT:-5s}
# Default: 10
# Description: Claim pending messages every N polling intervals
claimIntervalRatio: ${WEBHOOK_CLAIM_INTERVAL_RATIO:-10}
# Default: 10m
# Description: Time before message considered orphaned and eligible for claiming
pendingMessageDuration: ${WEBHOOK_PENDING_MESSAGE_DURATION:-10m}
# Default: 10000
# Description: Max number of entries (approx) when publishing to the Redis stream. Oldest are evicted if exceeded
streamMaxLen: ${WEBHOOK_STREAM_MAX_LEN:-10000}
# Default: 100
# Description: Max number of entries to evict when publishing to the Redis stream (0 = no limit) if over max length
streamTrimLimit: ${WEBHOOK_STREAM_TRIM_LIMIT:-100}
debouncing:
# Default: true
# Description: Whether or not webhook event debouncing is enabled
enabled: ${WEBHOOK_DEBOUNCING_ENABLED:-true}
# Default: 60s
# Description: Period for events aggregation before sending to webhook endpoint
windowSize: ${WEBHOOK_DEBOUNCING_WINDOW_SIZE:-60s}
# Default: 3m
# Description: Time-to-live for debouncing buckets in Redis
bucketTtl: ${WEBHOOK_DEBOUNCING_BUCKET_TTL:-3m}
# Default: 4s
# Description: Timeout for alert job execution
alertJobTimeout: ${WEBHOOK_DEBOUNCING_ALERT_JOB_TIMEOUT:-4s}
# Default: 100ms
# Description: Maximum time to wait for acquiring alert job lock
alertJobLockWaitTimeout: ${WEBHOOK_DEBOUNCING_ALERT_JOB_LOCK_WAIT_TIMEOUT:-100ms}
metrics:
# Default: 300s
# Description: Initial delay before the first metrics alert job execution
initialDelay: ${WEBHOOK_METRICS_INITIAL_DELAY:-300s}
# Default: 300s
# Description: Fixed delay between metrics alert job executions (waits this duration after completion)
fixedDelay: ${WEBHOOK_METRICS_FIXED_DELAY:-300s}
# Default: 60s
# Description: Timeout for metrics alert job execution
metricsAlertJobTimeout: ${WEBHOOK_METRICS_ALERT_JOB_TIMEOUT:-60s}
# Default: 1s
# Description: Maximum time to wait for acquiring metrics alert job lock
metricsAlertJobLockWaitTimeout: ${WEBHOOK_METRICS_ALERT_JOB_LOCK_WAIT_TIMEOUT:-1s}
# Free Model configuration (admin-configured server-side LLM provider)
# Note: The model name "opik-free-model" is hardcoded and cannot be changed.
# This ensures backward compatibility with automation rules that store the model name.
freeModel:
# Description: Whether to enable the free model provider
# Default: false
enabled: ${OPIK_FREE_MODEL_ENABLED:-false}
# Description: Actual model name sent to the AI server (the underlying LLM)
# Default: empty
actualModel: ${OPIK_FREE_MODEL_ACTUAL_MODEL:-}
# Description: Provider name stored in spans for cost tracking (e.g., "openai")
# Default: empty
spanProvider: ${OPIK_FREE_MODEL_SPAN_PROVIDER:-}
# Description: Base URL for OpenAI-compatible endpoint (e.g., "https://api.openai.com/v1")
# Default: empty
baseUrl: ${OPIK_FREE_MODEL_BASE_URL:-}
# Description: API key for the endpoint (optional for auth-less endpoints)
# Default: empty
apiKey: ${OPIK_FREE_MODEL_API_KEY:-}
# Dataset Versioning Migration configuration
# Includes both lazy migration (on-demand) and items_total migration (startup)
datasetVersioningMigration:
# Default: false
# Description: Whether to enable lazy migration (migrate datasets on first access)
lazyEnabled: ${DATASET_VERSIONING_MIGRATION_LAZY_ENABLED:-"false"}
# Default: true
# Description: Whether to run the items_total migration on startup
# Set to true to enable the migration, false to disable after completion
# This migration calculates and updates the items_total field for dataset versions
# that were created by the Liquibase migration (where dataset_id = dataset_version_id)
itemsTotalEnabled: ${DATASET_VERSION_ITEMS_TOTAL_MIGRATION_ENABLED:-"true"}
# Default: 100
# Description: Number of dataset versions to process in each batch for items_total migration
# Smaller batches reduce memory usage but increase total migration time
itemsTotalDatasetsBatchSize: ${DATASET_VERSION_ITEMS_TOTAL_MIGRATION_BATCH_SIZE:-100}
# Default: 3600 (1 hour)
# Description: Lock timeout in seconds for the items_total migration process
# Should be long enough to complete the migration
itemsTotalLockTimeoutSeconds: ${DATASET_VERSION_ITEMS_TOTAL_MIGRATION_LOCK_TIMEOUT_SECONDS:-3600}
# Default: 30 seconds
# Description: Delay in seconds before starting the items_total migration job after application startup
# This allows the service to stabilize before running the migration
itemsTotalStartupDelaySeconds: ${DATASET_VERSION_ITEMS_TOTAL_MIGRATION_STARTUP_DELAY_SECONDS:-30}
# Default: 3600s (1 hour)
# Description: Job execution timeout in seconds for the items_total migration
# Should be long enough to complete the entire migration process
itemsTotalJobTimeoutSeconds: ${DATASET_VERSION_ITEMS_TOTAL_MIGRATION_JOB_TIMEOUT_SECONDS:-3600}
# Dataset Versioning runtime configuration (OPIK-6674).
# Tunes the application-side retry guard around the INSERT...SELECT operations that
# materialise new dataset versions in ClickHouse (COPY_VERSION_ITEMS / EDIT_ITEM_VIA_SELECT_INSERT).
# If the SELECT lands on a stale replica it can return 0 rows; without this guard the
# new version row would be silently committed with truncated items_total.
datasetVersioning:
zeroRowsRetry:
# Default: 3
# Description: Number of retry attempts when an INSERT...SELECT writes 0 rows
# while the input set was non-empty. Total call count = maxAttempts + 1 (initial + retries).
# Set to 0 to disable retries (the guard still surfaces the failure as an exception).
maxAttempts: ${DATASET_VERSIONING_ZERO_ROWS_RETRY_MAX_ATTEMPTS:-3}
# Default: 100ms
# Description: Minimum backoff between retries. Actual delay grows exponentially
# from this value up to maxBackoff.
minBackoff: ${DATASET_VERSIONING_ZERO_ROWS_RETRY_MIN_BACKOFF:-100ms}
# Default: 1s
# Description: Maximum backoff between retries. Caps the exponential growth of
# the per-attempt delay.
maxBackoff: ${DATASET_VERSIONING_ZERO_ROWS_RETRY_MAX_BACKOFF:-1s}
# Experiment Project Migration configuration
# Assigns project_id to orphan experiments (V1 → V2 workspace migration).
# Runs as a recurring job, processing workspaces in batches.
experimentProjectMigration:
# Master switch — disabled by default, enable for staged rollout
enabled: ${EXPERIMENT_PROJECT_MIGRATION_ENABLED:-false}
# Number of workspaces to process per job run (smallest first)
workspacesPerRun: ${EXPERIMENT_PROJECT_MIGRATION_WORKSPACES_PER_RUN:-20}
# Number of experiments to update per ClickHouse INSERT batch
experimentBatchSize: ${EXPERIMENT_PROJECT_MIGRATION_BATCH_SIZE:-1000}
# Interval between recurring job runs
interval: ${EXPERIMENT_PROJECT_MIGRATION_INTERVAL:-30s}
# Delay before first run after app startup
startupDelay: ${EXPERIMENT_PROJECT_MIGRATION_STARTUP_DELAY:-30s}
# Distributed lock timeout — prevents overlap across replicas.
# Intentionally shorter than jobTimeout: the lock covers typical cycle duration (minutes) and
# prevents redundant scheduling across replicas. Cycles that exceed lockTimeout tolerate replica
# overlap because the migration is idempotent (WHERE project_id = '' skips already-migrated rows).
lockTimeout: ${EXPERIMENT_PROJECT_MIGRATION_LOCK_TIMEOUT:-5m}
# Max time to wait for the distributed lock when another replica holds it. Kept brief so a held
# lock doesn't block this fire — the next scheduled tick will try again.
lockWaitTime: ${EXPERIMENT_PROJECT_MIGRATION_LOCK_WAIT_TIME:-100ms}
# Per-cycle timeout — safety net for stuck cycles, not normal completion
jobTimeout: ${EXPERIMENT_PROJECT_MIGRATION_JOB_TIMEOUT:-1h}
# Dedicated reactor scheduler isolating this job from the shared boundedElastic.
# Max threads in the pool — the job runs sequentially per replica; a small cap suffices.
schedulerThreadCap: ${EXPERIMENT_PROJECT_MIGRATION_SCHEDULER_THREAD_CAP:-4}
# Max tasks queued when all threads are busy — backpressure buffer for the sequential flow.
schedulerQueuedTaskCap: ${EXPERIMENT_PROJECT_MIGRATION_SCHEDULER_QUEUED_TASK_CAP:-100}
# Idle-thread TTL — should typically exceed `interval` so threads survive the between-cycle
# idle window and don't churn on every tick.
schedulerThreadTtl: ${EXPERIMENT_PROJECT_MIGRATION_SCHEDULER_THREAD_TTL:-60s}
datasetProjectMigration:
# Master switch — disabled by default, enable for staged rollout
enabled: ${DATASET_PROJECT_MIGRATION_ENABLED:-false}
# Number of workspaces to process per job run (smallest first)
workspacesPerRun: ${DATASET_PROJECT_MIGRATION_WORKSPACES_PER_RUN:-20}
# Number of datasets to update per MySQL batch
datasetBatchSize: ${DATASET_PROJECT_MIGRATION_BATCH_SIZE:-1000}
# Interval between recurring job runs
interval: ${DATASET_PROJECT_MIGRATION_INTERVAL:-30s}
# Delay before first run after app startup
startupDelay: ${DATASET_PROJECT_MIGRATION_STARTUP_DELAY:-30s}
# Distributed lock timeout — prevents overlap across replicas.
lockTimeout: ${DATASET_PROJECT_MIGRATION_LOCK_TIMEOUT:-5m}
# Max time to wait for the distributed lock when another replica holds it.
lockWaitTime: ${DATASET_PROJECT_MIGRATION_LOCK_WAIT_TIME:-100ms}
# Per-cycle timeout — safety net for stuck cycles, not normal completion
jobTimeout: ${DATASET_PROJECT_MIGRATION_JOB_TIMEOUT:-1h}
# Dedicated reactor scheduler isolating this job from the shared boundedElastic.
schedulerThreadCap: ${DATASET_PROJECT_MIGRATION_SCHEDULER_THREAD_CAP:-4}
schedulerQueuedTaskCap: ${DATASET_PROJECT_MIGRATION_SCHEDULER_QUEUED_TASK_CAP:-100}
schedulerThreadTtl: ${DATASET_PROJECT_MIGRATION_SCHEDULER_THREAD_TTL:-60s}
# Optimization Project Migration configuration (D3)
# Assigns project_id to orphan optimizations in ClickHouse. Inference is experiments-primary (Path
# A) with a dataset fallback (Path B), so this job depends on D1 (experiments) and D2 (datasets)
# being complete in production. The dependency ordering is enforced by the deployment runbook,
# not by code.
optimizationProjectMigration:
# Master switch — disabled by default, enable for staged rollout
enabled: ${OPTIMIZATION_PROJECT_MIGRATION_ENABLED:-false}
# Number of workspaces to process per job run (smallest first)
workspacesPerRun: ${OPTIMIZATION_PROJECT_MIGRATION_WORKSPACES_PER_RUN:-20}
# Number of optimizations to update per ClickHouse INSERT batch
optimizationBatchSize: ${OPTIMIZATION_PROJECT_MIGRATION_BATCH_SIZE:-1000}
# Interval between recurring job runs
interval: ${OPTIMIZATION_PROJECT_MIGRATION_INTERVAL:-30s}
# Delay before first run after app startup
startupDelay: ${OPTIMIZATION_PROJECT_MIGRATION_STARTUP_DELAY:-30s}
# Distributed lock timeout — prevents overlap across replicas.
lockTimeout: ${OPTIMIZATION_PROJECT_MIGRATION_LOCK_TIMEOUT:-5m}
# Max time to wait for the distributed lock when another replica holds it.
lockWaitTime: ${OPTIMIZATION_PROJECT_MIGRATION_LOCK_WAIT_TIME:-100ms}
# Per-cycle timeout — safety net for stuck cycles, not normal completion
jobTimeout: ${OPTIMIZATION_PROJECT_MIGRATION_JOB_TIMEOUT:-1h}
# Dedicated reactor scheduler isolating this job from the shared boundedElastic.
schedulerThreadCap: ${OPTIMIZATION_PROJECT_MIGRATION_SCHEDULER_THREAD_CAP:-4}
schedulerQueuedTaskCap: ${OPTIMIZATION_PROJECT_MIGRATION_SCHEDULER_QUEUED_TASK_CAP:-100}
schedulerThreadTtl: ${OPTIMIZATION_PROJECT_MIGRATION_SCHEDULER_THREAD_TTL:-60s}
# Prompt Project Migration configuration (D4)
# Assigns project_id to orphan prompts (V1 → V2 workspace migration). Mirrors
# experimentProjectMigration. Operational prerequisite (enforced via the rollout runbook, not in
# code): D1 (OPIK-6184) and OPIK-6579 must be fully shipped to this environment first because the
# only inference signal is experiment.project_id.
promptProjectMigration:
# Master switch — disabled by default, enable for staged rollout
enabled: ${PROMPT_PROJECT_MIGRATION_ENABLED:-false}
# Number of workspaces to process per job run (smallest first)
workspacesPerRun: ${PROMPT_PROJECT_MIGRATION_WORKSPACES_PER_RUN:-20}
# Number of prompts to update per MySQL UPDATE batch
promptBatchSize: ${PROMPT_PROJECT_MIGRATION_BATCH_SIZE:-1000}
# Interval between recurring job runs
interval: ${PROMPT_PROJECT_MIGRATION_INTERVAL:-30s}
# Delay before first run after app startup
startupDelay: ${PROMPT_PROJECT_MIGRATION_STARTUP_DELAY:-30s}
# Distributed lock timeout — prevents overlap across replicas. Intentionally shorter than
# jobTimeout: the WHERE project_id IS NULL predicate makes the cycle idempotent so replica
# overlap after lock expiry is safe.
lockTimeout: ${PROMPT_PROJECT_MIGRATION_LOCK_TIMEOUT:-5m}
# Max time to wait for the distributed lock when another replica holds it
lockWaitTime: ${PROMPT_PROJECT_MIGRATION_LOCK_WAIT_TIME:-100ms}
# Per-cycle timeout — safety net for stuck cycles, not normal completion
jobTimeout: ${PROMPT_PROJECT_MIGRATION_JOB_TIMEOUT:-1h}
# Dedicated reactor scheduler isolating this job from the shared boundedElastic.
schedulerThreadCap: ${PROMPT_PROJECT_MIGRATION_SCHEDULER_THREAD_CAP:-4}
schedulerQueuedTaskCap: ${PROMPT_PROJECT_MIGRATION_SCHEDULER_QUEUED_TASK_CAP:-100}
# Idle-thread TTL — should typically exceed `interval` so threads survive the idle window.
schedulerThreadTtl: ${PROMPT_PROJECT_MIGRATION_SCHEDULER_THREAD_TTL:-60s}
automationRuleProjectMigration:
# Master switch — set to true to activate the recurring Quartz job.
enabled: ${AUTOMATION_RULE_PROJECT_MIGRATION_ENABLED:-false}
# Max workspaces processed per cycle (global, across all replicas via distributed lock).
workspacesPerRun: ${AUTOMATION_RULE_PROJECT_MIGRATION_WORKSPACES_PER_RUN:-20}
# Max multi-project rules split per workspace per cycle — caps work to avoid long transactions.
maxRulesPerCycle: ${AUTOMATION_RULE_PROJECT_MIGRATION_MAX_RULES_PER_CYCLE:-100}
# How often the Quartz job fires.
interval: ${AUTOMATION_RULE_PROJECT_MIGRATION_INTERVAL:-30s}
# Delay after application start before the first cycle runs.
startupDelay: ${AUTOMATION_RULE_PROJECT_MIGRATION_STARTUP_DELAY:-30s}
# Redis distributed lock held by the winning replica — must be shorter than jobTimeout.
lockTimeout: ${AUTOMATION_RULE_PROJECT_MIGRATION_LOCK_TIMEOUT:-5m}
# How long to wait trying to acquire the lock before giving up (non-blocking skip).
lockWaitTime: ${AUTOMATION_RULE_PROJECT_MIGRATION_LOCK_WAIT_TIME:-100ms}
# Hard timeout for the entire cycle — safety net if processing stalls.
jobTimeout: ${AUTOMATION_RULE_PROJECT_MIGRATION_JOB_TIMEOUT:-1h}
# Dedicated bounded-elastic scheduler — isolates migration from the shared reactive chain.
schedulerThreadCap: ${AUTOMATION_RULE_PROJECT_MIGRATION_SCHEDULER_THREAD_CAP:-2}
schedulerQueuedTaskCap: ${AUTOMATION_RULE_PROJECT_MIGRATION_SCHEDULER_QUEUED_TASK_CAP:-100}
schedulerThreadTtl: ${AUTOMATION_RULE_PROJECT_MIGRATION_SCHEDULER_THREAD_TTL:-60s}
# Assigns project_id to orphan alerts and splits multi-project alerts (V1 → V2 workspace migration).
# Runs as a recurring job, processing workspaces in batches.
alertProjectMigration:
# Master switch — disabled by default, enable for staged rollout
enabled: ${ALERT_PROJECT_MIGRATION_ENABLED:-false}
# Number of workspaces to process per job run (smallest first)
workspacesPerRun: ${ALERT_PROJECT_MIGRATION_WORKSPACES_PER_RUN:-100}
# Number of orphan alerts to process per workspace per cycle
alertBatchSize: ${ALERT_PROJECT_MIGRATION_ALERT_BATCH_SIZE:-100}
# Interval between recurring job runs
interval: ${ALERT_PROJECT_MIGRATION_INTERVAL:-30s}
# Delay before first run after app startup
startupDelay: ${ALERT_PROJECT_MIGRATION_STARTUP_DELAY:-30s}
# Distributed lock timeout — prevents overlap across replicas.
lockTimeout: ${ALERT_PROJECT_MIGRATION_LOCK_TIMEOUT:-5m}
# Max time to wait for the distributed lock when another replica holds it.
lockWaitTime: ${ALERT_PROJECT_MIGRATION_LOCK_WAIT_TIME:-100ms}
# Per-cycle timeout — safety net for stuck cycles, not normal completion
jobTimeout: ${ALERT_PROJECT_MIGRATION_JOB_TIMEOUT:-1h}
# Dedicated reactor scheduler isolating this job from the shared boundedElastic.
schedulerThreadCap: ${ALERT_PROJECT_MIGRATION_SCHEDULER_THREAD_CAP:-4}
schedulerQueuedTaskCap: ${ALERT_PROJECT_MIGRATION_SCHEDULER_QUEUED_TASK_CAP:-100}
schedulerThreadTtl: ${ALERT_PROJECT_MIGRATION_SCHEDULER_THREAD_TTL:-60s}
# Shared configuration for V1 → V2 entity project migration jobs
# Centralised so all migration jobs (experiments, datasets, etc.) share the same exclusion list
migration:
# Comma-separated workspace IDs to exclude (e.g. internal Comet workspaces)
excludedWorkspaceIds: ${MIGRATION_EXCLUDED_WORKSPACE_IDS:-}
llmModelRegistry:
defaultResource: ${LLM_MODEL_REGISTRY_DEFAULT_RESOURCE:-llm-models-default.yaml}
localOverridePath: ${LLM_MODEL_REGISTRY_LOCAL_OVERRIDE_PATH:-}
# Remote CDN fetch is opt-in. Self-hosted / OSS deployments stay on the
# classpath YAML shipped with the release by default, so no outbound
# traffic unless the operator explicitly enables it. Comet SaaS sets
# LLM_MODEL_REGISTRY_REMOTE_ENABLED=true + LLM_MODEL_REGISTRY_REMOTE_URL
# via its own Helm overrides.
remoteEnabled: ${LLM_MODEL_REGISTRY_REMOTE_ENABLED:-false}
remoteUrl: ${LLM_MODEL_REGISTRY_REMOTE_URL:-}
refreshIntervalSeconds: ${LLM_MODEL_REGISTRY_REFRESH_INTERVAL_SECONDS:-300}
# Agent Config configuration
agentConfig:
# Default: 5000ms
# Description: Duration of the distributed lock held during blueprint create/update operations
blueprintLockDuration: ${OPIK_AGENT_CONFIG_BLUEPRINT_LOCK_DURATION:-5000ms}