2222import com .fasterxml .jackson .annotation .JsonInclude ;
2323import com .fasterxml .jackson .annotation .JsonInclude .Include ;
2424import com .fasterxml .jackson .annotation .JsonProperty ;
25+ import com .fasterxml .jackson .core .JsonProcessingException ;
26+ import com .fasterxml .jackson .databind .ObjectMapper ;
27+ import com .fasterxml .jackson .databind .annotation .JsonDeserialize ;
28+ import com .fasterxml .jackson .databind .node .ObjectNode ;
2529import java .util .List ;
2630import java .util .Map ;
2731import java .util .concurrent .atomic .AtomicBoolean ;
2832import java .util .function .Consumer ;
2933import java .util .function .Predicate ;
3034import java .util .stream .Collectors ;
31- import com .fasterxml .jackson .databind .annotation .JsonDeserialize ;
3235import org .springframework .ai .model .ApiKey ;
3336import org .springframework .ai .model .ChatModelDescription ;
3437import org .springframework .ai .model .ModelOptionsUtils ;
@@ -185,14 +188,15 @@ public ResponseEntity<ChatCompletion> chatCompletionEntity(ChatCompletionRequest
185188 Assert .isTrue (!chatRequest .stream (), "Request must set the stream property to false." );
186189 Assert .notNull (additionalHttpHeader , "The additional HTTP headers can not be null." );
187190
191+ Object dynamicRequestBody = createDynamicRequestBody (chatRequest );
188192 // @formatter:off
189193 return this .restClient .post ()
190194 .uri (this .completionsPath )
191195 .headers (headers -> {
192196 headers .addAll (additionalHttpHeader );
193197 addDefaultHeadersIfMissing (headers );
194198 })
195- .body (chatRequest )
199+ .body (dynamicRequestBody )
196200 .retrieve ()
197201 .toEntity (ChatCompletion .class );
198202 // @formatter:on
@@ -208,6 +212,29 @@ public Flux<ChatCompletionChunk> chatCompletionStream(ChatCompletionRequest chat
208212 return chatCompletionStream (chatRequest , new LinkedMultiValueMap <>());
209213 }
210214
215+ private Object createDynamicRequestBody (ChatCompletionRequest baseRequest ) {
216+ ObjectMapper mapper = new ObjectMapper ();
217+ ObjectNode requestNode = mapper .valueToTree (baseRequest );
218+ if (null == baseRequest .extraBody ) {
219+ return requestNode ;
220+ }
221+
222+ // 添加额外字段
223+ baseRequest .extraBody ().forEach ((key , value ) -> {
224+ if (value instanceof Map ) {
225+ requestNode .set (key , mapper .valueToTree (value ));
226+ }
227+ else if (value instanceof List ) {
228+ requestNode .set (key , mapper .valueToTree (value ));
229+ }
230+ else {
231+ requestNode .putPOJO (key , value );
232+ }
233+ });
234+
235+ return requestNode ;
236+ }
237+
211238 /**
212239 * Creates a streaming chat response for the given chat conversation.
213240 * @param chatRequest The chat completion request. Must have the stream property set
@@ -224,14 +251,25 @@ public Flux<ChatCompletionChunk> chatCompletionStream(ChatCompletionRequest chat
224251
225252 AtomicBoolean isInsideTool = new AtomicBoolean (false );
226253
227- // @formatter:off
228- return this .webClient .post ()
229- .uri (this .completionsPath )
230- .headers (headers -> {
231- headers .addAll (additionalHttpHeader );
232- addDefaultHeadersIfMissing (headers );
233- }) // @formatter:on
234- .body (Mono .just (chatRequest ), ChatCompletionRequest .class )
254+ ObjectMapper objectMapper = new ObjectMapper ();
255+ try {
256+ var s = objectMapper .writeValueAsString (chatRequest );
257+ System .out .println ("aaaaaaaa:" + s );
258+ }
259+ catch (JsonProcessingException e ) {
260+ throw new RuntimeException (e );
261+ }
262+ Object dynamicBody = createDynamicRequestBody (chatRequest );
263+ // @formatter:off
264+ return this .webClient
265+ .post ()
266+ .uri (this .completionsPath )
267+ .headers (
268+ headers -> {
269+ headers .addAll (additionalHttpHeader );
270+ addDefaultHeadersIfMissing (headers );
271+ }) // @formatter:on
272+ .bodyValue (dynamicBody )
235273 .retrieve ()
236274 .bodyToFlux (String .class )
237275 // cancels the flux stream after the "[DONE]" is received.
0 commit comments