Make responseMessage in AzureOpenAiChatModel.buildGeneration null-safe

Signed-off-by: Berjan Jonker <berjanjonker@users.noreply.github.com>
This commit is contained in:
Berjan Jonker
2025-04-17 22:45:31 +02:00
committed by Mark Pollack
parent 5634d892fa
commit af0303f65a
2 changed files with 36 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 the original author or authors.
* Copyright 2023-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -112,6 +112,7 @@ import org.springframework.util.CollectionUtils;
* @author Jihoon Kim
* @author Ilayaperumal Gopinathan
* @author Alexandros Pappas
* @author Berjan Jonker
* @see ChatModel
* @see com.azure.ai.openai.OpenAIClient
* @since 1.0.0
@@ -462,16 +463,19 @@ public class AzureOpenAiChatModel implements ChatModel {
var responseMessage = Optional.ofNullable(choice.getMessage()).orElse(choice.getDelta());
List<AssistantMessage.ToolCall> toolCalls = responseMessage.getToolCalls() == null ? List.of()
: responseMessage.getToolCalls().stream().map(toolCall -> {
final var tc1 = (ChatCompletionsFunctionToolCall) toolCall;
String id = tc1.getId();
String name = tc1.getFunction().getName();
String arguments = tc1.getFunction().getArguments();
return new AssistantMessage.ToolCall(id, "function", name, arguments);
}).toList();
List<AssistantMessage.ToolCall> toolCalls = List.of();
if (responseMessage != null && responseMessage.getToolCalls() != null) {
toolCalls = responseMessage.getToolCalls().stream().map(toolCall -> {
final var tc1 = (ChatCompletionsFunctionToolCall) toolCall;
String id = tc1.getId();
String name = tc1.getFunction().getName();
String arguments = tc1.getFunction().getArguments();
return new AssistantMessage.ToolCall(id, "function", name, arguments);
}).toList();
}
var assistantMessage = new AssistantMessage(responseMessage.getContent(), metadata, toolCalls);
var content = responseMessage == null ? "" : responseMessage.getContent();
var assistantMessage = new AssistantMessage(content, metadata, toolCalls);
var generationMetadata = generateChoiceMetadata(choice);
return new Generation(assistantMessage, generationMetadata);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2023-2024 the original author or authors.
* Copyright 2023-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import com.azure.ai.openai.OpenAIClientBuilder;
@@ -106,6 +107,26 @@ class AzureOpenAiChatModelIT {
assertThat(response.getResult().getOutput().getText()).containsAnyOf("Blackbeard");
}
@Test
void testStreaming() {
String prompt = """
Provide a list of planets in our solar system
""";
final var counter = new AtomicInteger();
String content = this.chatModel.stream(prompt)
.doOnEach(listSignal -> counter.getAndIncrement())
.collectList()
.block()
.stream()
.collect(Collectors.joining());
logger.info("Response: {}", content);
assertThat(counter.get()).isGreaterThan(8).as("More than 8 chuncks because there are 8 planets");
assertThat(content).contains("Earth", "Mars", "Jupiter");
}
@Test
void listOutputConverter() {
DefaultConversionService conversionService = new DefaultConversionService();