11/*
2- * Copyright 2023-2024 the original author or authors.
2+ * Copyright 2023-2025 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2828import org .springframework .ai .embedding .AbstractEmbeddingModel ;
2929import org .springframework .ai .embedding .Embedding ;
3030import org .springframework .ai .embedding .EmbeddingOptions ;
31- import org .springframework .ai .embedding .EmbeddingOptionsBuilder ;
3231import org .springframework .ai .embedding .EmbeddingRequest ;
3332import org .springframework .ai .embedding .EmbeddingResponse ;
3433import org .springframework .ai .embedding .EmbeddingResponseMetadata ;
@@ -110,12 +109,16 @@ public MistralAiEmbeddingModel(MistralAiApi mistralAiApi, MetadataMode metadataM
110109
111110 @ Override
112111 public EmbeddingResponse call (EmbeddingRequest request ) {
113- var apiRequest = createRequest (request );
112+ // Before moving any further, build the final request Prompt,
113+ // merging runtime and default options.
114+ EmbeddingRequest embeddingRequest = buildEmbeddingRequest (request );
115+
116+ var apiRequest = createRequest (embeddingRequest );
114117
115118 var observationContext = EmbeddingModelObservationContext .builder ()
116119 .embeddingRequest (request )
117120 .provider (MistralAiApi .PROVIDER_NAME )
118- .requestOptions (buildRequestOptions ( apiRequest ))
121+ .requestOptions (embeddingRequest . getOptions ( ))
119122 .build ();
120123
121124 return EmbeddingModelObservationDocumentation .EMBEDDING_MODEL_OPERATION
@@ -146,20 +149,29 @@ public EmbeddingResponse call(EmbeddingRequest request) {
146149 });
147150 }
148151
152+ private EmbeddingRequest buildEmbeddingRequest (EmbeddingRequest embeddingRequest ) {
153+ // Process runtime options
154+ MistralAiEmbeddingOptions runtimeOptions = null ;
155+ if (embeddingRequest .getOptions () != null ) {
156+ runtimeOptions = ModelOptionsUtils .copyToTarget (embeddingRequest .getOptions (), EmbeddingOptions .class ,
157+ MistralAiEmbeddingOptions .class );
158+ }
159+
160+ // Define request options by merging runtime options and default options
161+ MistralAiEmbeddingOptions requestOptions = ModelOptionsUtils .merge (runtimeOptions , this .defaultOptions ,
162+ MistralAiEmbeddingOptions .class );
163+
164+ return new EmbeddingRequest (embeddingRequest .getInstructions (), requestOptions );
165+ }
166+
149167 private DefaultUsage getDefaultUsage (MistralAiApi .Usage usage ) {
150168 return new DefaultUsage (usage .promptTokens (), usage .completionTokens (), usage .totalTokens (), usage );
151169 }
152170
153- @ SuppressWarnings ("unchecked" )
154171 private MistralAiApi .EmbeddingRequest <List <String >> createRequest (EmbeddingRequest request ) {
155- var embeddingRequest = new MistralAiApi .EmbeddingRequest <>(request .getInstructions (),
156- this .defaultOptions .getModel (), this .defaultOptions .getEncodingFormat ());
157-
158- if (request .getOptions () != null ) {
159- embeddingRequest = ModelOptionsUtils .merge (request .getOptions (), embeddingRequest ,
160- MistralAiApi .EmbeddingRequest .class );
161- }
162- return embeddingRequest ;
172+ MistralAiEmbeddingOptions requestOptions = (MistralAiEmbeddingOptions ) request .getOptions ();
173+ return new MistralAiApi .EmbeddingRequest <>(request .getInstructions (), requestOptions .getModel (),
174+ requestOptions .getEncodingFormat ());
163175 }
164176
165177 @ Override
@@ -168,10 +180,6 @@ public float[] embed(Document document) {
168180 return this .embed (document .getFormattedContent (this .metadataMode ));
169181 }
170182
171- private EmbeddingOptions buildRequestOptions (MistralAiApi .EmbeddingRequest <List <String >> request ) {
172- return EmbeddingOptionsBuilder .builder ().withModel (request .model ()).build ();
173- }
174-
175183 /**
176184 * Use the provided convention for reporting observation data
177185 * @param observationConvention The provided convention
0 commit comments