@@ -196,10 +196,26 @@ private static InterceptedInferenceKnnVectorQueryBuilder rewriteQueryVectorBuild
196196 }
197197
198198 QueryVectorBuilder queryVectorBuilder = originalQuery .queryVectorBuilder ();
199- if (queryVectorBuilder != null && queryVectorBuilder .isValid ()) {
200- SetOnce <float []> newQueryVectorSupplier = new SetOnce <>();
201- QueryVectorBuilderAsyncAction .registerAction (queryRewriteContext , queryVectorBuilder , newQueryVectorSupplier );
202- return new InterceptedInferenceKnnVectorQueryBuilder (queryBuilder , originalQuery , newQueryVectorSupplier );
199+ if (queryVectorBuilder != null ) {
200+ boolean registerAction = false ;
201+ if (queryVectorBuilder instanceof TextEmbeddingQueryVectorBuilder tevb ) {
202+ // TextEmbeddingQueryVectorBuilder is a special case. If a model ID is set, we register an action to generate
203+ // the query vector. If not, the model text will be returned via getQuery() so that InferenceQueryUtils can
204+ // generate the appropriate inference results for the inferred inference ID(s).
205+ if (tevb .getModelId () != null ) {
206+ registerAction = true ;
207+ }
208+ } else {
209+ // We register an action to generate the query vector for all other query vector builders. If they cannot, buildVector()
210+ // should throw an error indicating why.
211+ registerAction = true ;
212+ }
213+
214+ if (registerAction ) {
215+ SetOnce <float []> newQueryVectorSupplier = new SetOnce <>();
216+ QueryVectorBuilderAsyncAction .registerAction (queryRewriteContext , queryVectorBuilder , newQueryVectorSupplier );
217+ return new InterceptedInferenceKnnVectorQueryBuilder (queryBuilder , originalQuery , newQueryVectorSupplier );
218+ }
203219 }
204220
205221 return queryBuilder ;
@@ -224,8 +240,8 @@ protected boolean preInferenceCoordinatorNodeValidate(ResolvedIndices resolvedIn
224240
225241 // We can skip remote cluster inference info gathering if:
226242 // - Inference fields are queried locally, guaranteeing that the query will be intercepted
227- // - A valid query vector builder or query vector is set. In either case, remote cluster inference results are not required.
228- return inferenceFieldsQueried > 0 && (hasValidQueryVectorBuilder () || originalQuery .queryVector () != null );
243+ // - A standalone query vector builder or query vector is set. In either case, remote cluster inference results are not required.
244+ return inferenceFieldsQueried > 0 && (hasStandaloneQueryVectorBuilder () || originalQuery .queryVector () != null );
229245 }
230246
231247 @ Override
@@ -364,30 +380,26 @@ private MlDenseEmbeddingResults getTextEmbeddingResults(FullyQualifiedInferenceI
364380 return (MlDenseEmbeddingResults ) inferenceResults ;
365381 }
366382
367- private void missingInferenceIdOverrideCheck () {
368- QueryVectorBuilder queryVectorBuilder = originalQuery .queryVectorBuilder ();
369- if (queryVectorBuilder instanceof TextEmbeddingQueryVectorBuilder textEmbeddingQueryVectorBuilder
370- && textEmbeddingQueryVectorBuilder .getModelId () == null ) {
371- throw new IllegalArgumentException ("[model_id] must not be null." );
372- }
373- }
374-
375383 private void validateQueryVectorBuilder (boolean requireExplicitInferenceId ) {
376384 QueryVectorBuilder queryVectorBuilder = originalQuery .queryVectorBuilder ();
377- if (queryVectorBuilder instanceof TextEmbeddingQueryVectorBuilder tevb ) {
378- // TextEmbeddingQueryVectorBuilder only needs validation when an explicit inference ID is required. A non-null model text value
385+ if (queryVectorBuilder instanceof TextEmbeddingQueryVectorBuilder tevb && requireExplicitInferenceId ) {
386+ // TextEmbeddingQueryVectorBuilder needs validation when an explicit inference ID is required. A non-null model text value
379387 // is guaranteed by its constructor.
380- if (requireExplicitInferenceId ) {
381- tevb . validate ( );
388+ if (tevb . getModelId () == null ) {
389+ throw new IllegalArgumentException ( "[model_id] must not be null." );
382390 }
383- } else if (queryVectorBuilder != null ) {
384- // Other query vector builder types always require validation
385- queryVectorBuilder .validate ();
386391 }
392+ // For other query vector builders, we don't validate upfront. buildVector() will throw an error if it cannot generate a vector.
387393 }
388394
389- private boolean hasValidQueryVectorBuilder () {
395+ private boolean hasStandaloneQueryVectorBuilder () {
390396 QueryVectorBuilder queryVectorBuilder = originalQuery .queryVectorBuilder ();
391- return queryVectorBuilder != null && queryVectorBuilder .isValid ();
397+ if (queryVectorBuilder instanceof TextEmbeddingQueryVectorBuilder tevb ) {
398+ // TextEmbeddingQueryVectorBuilder is considered to be a standalone query vector builder if the model ID is set
399+ return tevb .getModelId () != null ;
400+ }
401+
402+ // All other query vector builders are assumed to be standalone
403+ return queryVectorBuilder != null ;
392404 }
393405}
0 commit comments