Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -521,10 +521,21 @@ private ChatClientResponse doGetObservableChatClientResponse(ChatClientRequest c

@Nullable
private static String getContentFromChatResponse(@Nullable ChatResponse chatResponse) {
return Optional.ofNullable(chatResponse)
.map(ChatResponse::getResult)
if (chatResponse == null || CollectionUtils.isEmpty(chatResponse.getResults())) {
return null;
}
// Iterate through all generations to find the first one with non-null content
// This handles cases where models return multiple generations (e.g., Bedrock
// Converse API
// with openai.gpt-oss models may return reasoning output first with null
// content,
// followed by the actual response)
return chatResponse.getResults()
.stream()
.map(Generation::getOutput)
.map(AbstractMessage::getText)
.filter(text -> text != null)
.findFirst()
.orElse(null);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,37 @@ void whenChatResponseContentIsNull() {
assertThat(content).isNull();
}

@Test
void whenMultipleGenerationsWithFirstContentNull() {
// Test case for Bedrock Converse API with openai.gpt-oss models
// which return multiple generations where the first one has null content
// (reasoning output)
// and the second one contains the actual response
ChatModel chatModel = mock(ChatModel.class);
ArgumentCaptor<Prompt> promptCaptor = ArgumentCaptor.forClass(Prompt.class);
given(chatModel.call(promptCaptor.capture()))
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage(null)), // First
// generation
// with
// null
// content
new Generation(new AssistantMessage("Hello! How can I help you today?")) // Second
// generation
// with
// actual
// content
)));

ChatClient chatClient = new DefaultChatClientBuilder(chatModel).build();
DefaultChatClient.DefaultChatClientRequestSpec chatClientRequestSpec = (DefaultChatClient.DefaultChatClientRequestSpec) chatClient
.prompt("Hello");
DefaultChatClient.DefaultCallResponseSpec spec = (DefaultChatClient.DefaultCallResponseSpec) chatClientRequestSpec
.call();

String content = spec.content();
assertThat(content).isEqualTo("Hello! How can I help you today?");
}

@Test
void whenResponseEntityWithParameterizedTypeIsNull() {
ChatClient chatClient = new DefaultChatClientBuilder(mock(ChatModel.class)).build();
Expand Down