Skip to content

Commit 50db344

Browse files
ilayaperumalgsobychacko
authored andcommitted
fix (AzureOpenAI): ChatModel streaming response
- Include `model` and `ServiceTier` information when merging the chat completion response - Add test to validate the model value Resolves #4715 Auto-cherry-pick to 1.0.x Signed-off-by: Ilayaperumal Gopinathan <ilayaperumal.gopinathan@broadcom.com>
1 parent d2492a6 commit 50db344

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/MergeUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ public static ChatCompletions mergeChatCompletions(ChatCompletions left, ChatCom
168168

169169
setField(instance, "usage", usage);
170170

171+
setField(instance, "model", right.getModel() == null ? left.getModel() : right.getModel());
172+
173+
setField(instance, "serviceTier",
174+
right.getServiceTier() == null ? left.getServiceTier() : right.getServiceTier());
175+
171176
return instance;
172177
}
173178

models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatModelIT.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.junit.jupiter.api.Test;
3333
import org.slf4j.Logger;
3434
import org.slf4j.LoggerFactory;
35+
import reactor.core.publisher.Flux;
3536

3637
import org.springframework.ai.chat.client.ChatClient;
3738
import org.springframework.ai.chat.messages.AssistantMessage;
@@ -409,6 +410,47 @@ void testMaxTokensForNonReasoningModels() {
409410
}
410411
}
411412

413+
@Test
414+
void testModelInStreamingResponse() {
415+
String prompt = "List three colors of the rainbow.";
416+
417+
// @formatter:off
418+
Flux<ChatResponse> responseFlux = ChatClient.create(this.chatModel).prompt()
419+
.options(AzureOpenAiChatOptions.builder()
420+
.deploymentName("gpt-4o")
421+
.build())
422+
.user(prompt)
423+
.stream()
424+
.chatResponse();
425+
// @formatter:on
426+
427+
List<ChatResponse> responses = responseFlux.collectList().block();
428+
429+
assertThat(responses).isNotEmpty();
430+
431+
ChatResponse lastResponse = responses.get(responses.size() - 1);
432+
433+
// Verify that the final merged response has model metadata
434+
assertThat(lastResponse.getMetadata()).as("Last response should have metadata").isNotNull();
435+
assertThat(lastResponse.getMetadata().getModel()).as("Last response metadata should contain model").isNotNull();
436+
437+
String model = lastResponse.getMetadata().getModel();
438+
logger.info("Final merged response model: {}", model);
439+
assertThat(model).isNotEmpty();
440+
// Azure OpenAI models typically contain "gpt" in their name
441+
assertThat(model).containsIgnoringCase("gpt");
442+
443+
String content = responses.stream()
444+
.flatMap(r -> r.getResults().stream())
445+
.map(Generation::getOutput)
446+
.map(AssistantMessage::getText)
447+
.filter(Objects::nonNull)
448+
.collect(Collectors.joining());
449+
450+
assertThat(content).isNotEmpty();
451+
logger.info("Generated content: {}", content);
452+
}
453+
412454
record ActorsFilms(String actor, List<String> movies) {
413455

414456
}

0 commit comments

Comments
 (0)