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
1862 lines
103 KiB
YAML
1862 lines
103 KiB
YAML
---
|
||
# 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 app’s 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: 1d–30d
|
||
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: 1–10
|
||
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}
|