|
16 | 16 |
|
17 | 17 | package org.springframework.ai.ollama; |
18 | 18 |
|
| 19 | +import java.util.concurrent.atomic.AtomicBoolean; |
| 20 | + |
19 | 21 | import io.micrometer.observation.tck.TestObservationRegistry; |
20 | 22 | import org.junit.jupiter.api.BeforeEach; |
21 | 23 | import org.junit.jupiter.api.Test; |
| 24 | +import reactor.core.publisher.Flux; |
22 | 25 |
|
23 | 26 | import org.springframework.ai.chat.metadata.ChatGenerationMetadata; |
24 | 27 | import org.springframework.ai.chat.model.ChatResponse; |
@@ -70,6 +73,60 @@ void ollamaThinkingMetadataCaptured() { |
70 | 73 | }); |
71 | 74 | } |
72 | 75 |
|
| 76 | + @Test |
| 77 | + void ollamaThinkingMedataCapturedWhenStreaming() { |
| 78 | + var options = OllamaChatOptions.builder().model(MODEL).enableThinking().build(); |
| 79 | + var response = new StringBuilder(); |
| 80 | + var thinking = new StringBuilder(); |
| 81 | + var foundThinking = new AtomicBoolean(false); |
| 82 | + |
| 83 | + Prompt prompt = new Prompt("Why is the sky blue?", options); |
| 84 | + |
| 85 | + Flux<ChatResponse> chatResponse = this.chatModel.stream(prompt); |
| 86 | + var captured = chatResponse.collectList().block(); |
| 87 | + |
| 88 | + assertThat(captured).isNotEmpty(); |
| 89 | + |
| 90 | + captured.forEach(chunk -> { |
| 91 | + ChatGenerationMetadata chatGenerationMetadata = chunk.getResult().getMetadata(); |
| 92 | + assertThat(chatGenerationMetadata).isNotNull(); |
| 93 | + |
| 94 | + if (chatGenerationMetadata.containsKey("thinking") && chatGenerationMetadata.get("thinking") != null) { |
| 95 | + foundThinking.set(true); |
| 96 | + thinking.append(chatGenerationMetadata.get("thinking").toString()); |
| 97 | + } |
| 98 | + |
| 99 | + response.append(chunk.getResult().getOutput().getText()); |
| 100 | + }); |
| 101 | + |
| 102 | + assertThat(response.toString()).isNotEmpty(); |
| 103 | + assertThat(thinking.toString()).isNotEmpty(); |
| 104 | + } |
| 105 | + |
| 106 | + @Test |
| 107 | + void ollamaThinkingMedataNotCapturedWhenStreamingWhenSetThinkingToFalse() { |
| 108 | + var options = OllamaChatOptions.builder().model(MODEL).disableThinking().build(); |
| 109 | + var response = new StringBuilder(); |
| 110 | + |
| 111 | + Prompt prompt = new Prompt("Why is the sky blue?", options); |
| 112 | + |
| 113 | + Flux<ChatResponse> chatResponse = this.chatModel.stream(prompt); |
| 114 | + var captured = chatResponse.collectList().block(); |
| 115 | + |
| 116 | + assertThat(captured).isNotEmpty(); |
| 117 | + |
| 118 | + captured.forEach(chunk -> { |
| 119 | + ChatGenerationMetadata chatGenerationMetadata = chunk.getResult().getMetadata(); |
| 120 | + assertThat(chatGenerationMetadata).isNotNull(); |
| 121 | + var thinking = chatGenerationMetadata.get("thinking"); |
| 122 | + assertThat(thinking).isNull(); |
| 123 | + |
| 124 | + response.append(chunk.getResult().getOutput().getText()); |
| 125 | + }); |
| 126 | + |
| 127 | + assertThat(response.toString()).isNotEmpty(); |
| 128 | + } |
| 129 | + |
73 | 130 | @Test |
74 | 131 | void ollamaThinkingMetadataNotCapturedWhenSetThinkFlagToFalse() { |
75 | 132 | // Note: Thinking-capable models (e.g., qwen3:*) auto-enable thinking by default |
|
0 commit comments