22
33import com .comet .opik .api .DatasetVersion ;
44import com .comet .opik .api .EvaluatorItem ;
5+ import com .comet .opik .api .LlmProvider ;
56import com .comet .opik .api .PromptType ;
7+ import com .comet .opik .api .ProviderApiKey ;
68import com .comet .opik .api .Trace ;
79import com .comet .opik .api .evaluators .AutomationRuleEvaluatorType ;
810import com .comet .opik .api .events .TraceToScoreLlmAsJudge ;
1113import com .comet .opik .domain .DatasetItemService ;
1214import com .comet .opik .domain .DatasetVersionService ;
1315import com .comet .opik .domain .IdGenerator ;
16+ import com .comet .opik .domain .LlmProviderApiKeyService ;
1417import com .comet .opik .domain .evaluators .OnlineScorePublisher ;
1518import com .comet .opik .infrastructure .EvalSuiteConfig ;
1619import com .comet .opik .infrastructure .auth .RequestContext ;
2124import lombok .extern .slf4j .Slf4j ;
2225import reactor .core .publisher .Mono ;
2326import reactor .core .scheduler .Schedulers ;
27+ import reactor .util .context .Context ;
2428import ru .vyarus .dropwizard .guice .module .installer .feature .eager .EagerSingleton ;
2529import ru .vyarus .dropwizard .guice .module .yaml .bind .Config ;
2630
3034import java .util .List ;
3135import java .util .Map ;
3236import java .util .Optional ;
37+ import java .util .Set ;
3338import java .util .UUID ;
39+ import java .util .stream .Collectors ;
3440import java .util .stream .Stream ;
3541
3642/**
@@ -56,6 +62,7 @@ public class EvalSuiteAssertionSampler {
5662 private final IdGenerator idGenerator ;
5763 private final EvalSuiteConfig evalSuiteConfig ;
5864 private final EvalSuiteEvaluatorMapper evaluatorMapper ;
65+ private final LlmProviderApiKeyService llmProviderApiKeyService ;
5966
6067 @ Inject
6168 public EvalSuiteAssertionSampler (
@@ -64,13 +71,15 @@ public EvalSuiteAssertionSampler(
6471 @ NonNull OnlineScorePublisher onlineScorePublisher ,
6572 @ NonNull IdGenerator idGenerator ,
6673 @ NonNull @ Config ("evalSuite" ) EvalSuiteConfig evalSuiteConfig ,
67- @ NonNull EvalSuiteEvaluatorMapper evaluatorMapper ) {
74+ @ NonNull EvalSuiteEvaluatorMapper evaluatorMapper ,
75+ @ NonNull LlmProviderApiKeyService llmProviderApiKeyService ) {
6876 this .datasetItemService = datasetItemService ;
6977 this .datasetVersionService = datasetVersionService ;
7078 this .onlineScorePublisher = onlineScorePublisher ;
7179 this .idGenerator = idGenerator ;
7280 this .evalSuiteConfig = evalSuiteConfig ;
7381 this .evaluatorMapper = evaluatorMapper ;
82+ this .llmProviderApiKeyService = llmProviderApiKeyService ;
7483 }
7584
7685 @ Subscribe
@@ -83,13 +92,26 @@ public void onTracesCreated(TracesCreated tracesBatch) {
8392 return ;
8493 }
8594
86- var reactiveContext = reactor . util . context . Context .of (
95+ var reactiveContext = Context .of (
8796 RequestContext .WORKSPACE_ID , tracesBatch .workspaceId (),
8897 RequestContext .USER_NAME , tracesBatch .userName (),
8998 RequestContext .VISIBILITY , com .comet .opik .api .Visibility .PRIVATE );
9099
91100 Duration fetchTimeout = Duration .ofSeconds (evalSuiteConfig .getFetchTimeoutSeconds ());
92101
102+ // Resolve model once per batch: prefer connected provider, fall back to first trace's model
103+ var connectedProviders = getConnectedProviders (tracesBatch .workspaceId ());
104+ String modelName = SupportedJudgeProvider .resolveModel (connectedProviders )
105+ .or (() -> getMetadataString (completeTraces .getFirst (), "eval_suite_model" ))
106+ .orElse (null );
107+
108+ if (modelName == null ) {
109+ log .warn ("No LLM model resolved for eval suite batch in workspace '{}' — "
110+ + "no supported provider connected and no eval_suite_model in trace metadata" ,
111+ tracesBatch .workspaceId ());
112+ return ;
113+ }
114+
93115 // Cache dataset evaluators by (datasetId:versionHash) to avoid redundant fetches
94116 Map <String , List <PreparedEvaluator >> datasetEvaluatorsCache = new HashMap <>();
95117
@@ -120,7 +142,7 @@ public void onTracesCreated(TracesCreated tracesBatch) {
120142 .contextWrite (reactiveContext )
121143 .timeout (fetchTimeout )
122144 .block ();
123- return evaluatorMapper .prepareEvaluators (result .evaluators ());
145+ return evaluatorMapper .prepareEvaluators (result .evaluators (), modelName );
124146 });
125147
126148 var datasetItemId = getMetadataString (trace , "eval_suite_dataset_item_id" );
@@ -134,7 +156,8 @@ public void onTracesCreated(TracesCreated tracesBatch) {
134156 .flatMap (itemId -> {
135157 List <PreparedEvaluator > allEvaluators = new ArrayList <>(
136158 preparedDatasetEvaluators );
137- allEvaluators .addAll (fetchItemEvaluators (itemId , reactiveContext ));
159+ allEvaluators .addAll (fetchItemEvaluators (itemId , reactiveContext ,
160+ modelName ));
138161
139162 if (allEvaluators .isEmpty ()) {
140163 log .debug ("No evaluators found for trace '{}', dataset item '{}'" ,
@@ -191,7 +214,8 @@ private Mono<DatasetEvaluatorsResult> fetchDatasetEvaluators(UUID datasetId, Str
191214 }
192215
193216 private List <PreparedEvaluator > fetchItemEvaluators (
194- UUID itemId , reactor .util .context .Context reactiveContext ) {
217+ UUID itemId , Context reactiveContext ,
218+ String modelName ) {
195219 try {
196220 var item = datasetItemService .get (itemId )
197221 .contextWrite (reactiveContext )
@@ -202,7 +226,7 @@ private List<PreparedEvaluator> fetchItemEvaluators(
202226 return List .of ();
203227 }
204228
205- return evaluatorMapper .prepareEvaluators (item .evaluators ());
229+ return evaluatorMapper .prepareEvaluators (item .evaluators (), modelName );
206230 } catch (Exception e ) {
207231 log .error ("Failed to fetch evaluators for item '{}'" , itemId , e );
208232 return List .of ();
@@ -230,4 +254,16 @@ private Optional<UUID> parseUUID(String id, UUID traceId) {
230254 }
231255 }
232256
257+ private Set <LlmProvider > getConnectedProviders (String workspaceId ) {
258+ try {
259+ return llmProviderApiKeyService .find (workspaceId )
260+ .content ().stream ()
261+ .map (ProviderApiKey ::provider )
262+ .collect (Collectors .toSet ());
263+ } catch (Exception e ) {
264+ log .error ("Failed to fetch connected providers for workspace '{}'" , workspaceId , e );
265+ return Set .of ();
266+ }
267+ }
268+
233269}
0 commit comments