2020import org .junit .jupiter .api .Test ;
2121import org .junit .jupiter .api .extension .ExtendWith ;
2222
23+ import org .springframework .ai .chat .client .observation .ChatClientCompletionObservationHandler ;
2324import org .springframework .ai .chat .client .observation .ChatClientObservationContext ;
2425import org .springframework .ai .chat .client .observation .ChatClientPromptContentObservationHandler ;
2526import org .springframework .ai .observation .TracingAwareLoggingObservationHandler ;
@@ -48,16 +49,18 @@ class ChatClientObservationAutoConfigurationTests {
4849 .withConfiguration (AutoConfigurations .of (ChatClientAutoConfiguration .class ));
4950
5051 @ Test
51- void promptContentHandlerNoTracer () {
52+ void handlersNoTracer () {
5253 this .contextRunner .withClassLoader (new FilteredClassLoader (Tracer .class ))
5354 .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
55+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
5456 .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
5557 }
5658
5759 @ Test
58- void promptContentHandlerWithTracer () {
60+ void handlersWithTracer () {
5961 this .contextRunner .withUserConfiguration (TracerConfiguration .class )
6062 .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
63+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
6164 .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
6265 }
6366
@@ -66,6 +69,7 @@ void promptContentHandlerEnabledNoTracer(CapturedOutput output) {
6669 this .contextRunner .withClassLoader (new FilteredClassLoader (Tracer .class ))
6770 .withPropertyValues ("spring.ai.chat.client.observations.log-prompt=true" )
6871 .run (context -> assertThat (context ).hasSingleBean (ChatClientPromptContentObservationHandler .class )
72+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
6973 .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
7074 assertThat (output ).contains (
7175 "You have enabled logging out the ChatClient prompt content with the risk of exposing sensitive or private information. Please, be careful!" );
@@ -76,6 +80,7 @@ void promptContentHandlerEnabledWithTracer(CapturedOutput output) {
7680 this .contextRunner .withUserConfiguration (TracerConfiguration .class )
7781 .withPropertyValues ("spring.ai.chat.client.observations.log-prompt=true" )
7882 .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
83+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
7984 .hasSingleBean (TracingAwareLoggingObservationHandler .class ));
8085 assertThat (output ).contains (
8186 "You have enabled logging out the ChatClient prompt content with the risk of exposing sensitive or private information. Please, be careful!" );
@@ -86,6 +91,7 @@ void promptContentHandlerDisabledNoTracer() {
8691 this .contextRunner .withClassLoader (new FilteredClassLoader (Tracer .class ))
8792 .withPropertyValues ("spring.ai.chat.client.observations.log-prompt=false" )
8893 .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
94+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
8995 .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
9096 }
9197
@@ -94,6 +100,47 @@ void promptContentHandlerDisabledWithTracer() {
94100 this .contextRunner .withUserConfiguration (TracerConfiguration .class )
95101 .withPropertyValues ("spring.ai.chat.client.observations.log-prompt=false" )
96102 .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
103+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
104+ .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
105+ }
106+
107+ @ Test
108+ void completionHandlerEnabledNoTracer (CapturedOutput output ) {
109+ this .contextRunner .withClassLoader (new FilteredClassLoader (Tracer .class ))
110+ .withPropertyValues ("spring.ai.chat.client.observations.log-completion=true" )
111+ .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
112+ .hasSingleBean (ChatClientCompletionObservationHandler .class )
113+ .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
114+ assertThat (output ).contains (
115+ "You have enabled logging out the ChatClient completion content with the risk of exposing sensitive or private information. Please, be careful!" );
116+ }
117+
118+ @ Test
119+ void completionHandlerEnabledWithTracer (CapturedOutput output ) {
120+ this .contextRunner .withUserConfiguration (TracerConfiguration .class )
121+ .withPropertyValues ("spring.ai.chat.client.observations.log-completion=true" )
122+ .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
123+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
124+ .hasSingleBean (TracingAwareLoggingObservationHandler .class ));
125+ assertThat (output ).contains (
126+ "You have enabled logging out the ChatClient completion content with the risk of exposing sensitive or private information. Please, be careful!" );
127+ }
128+
129+ @ Test
130+ void completionHandlerDisabledNoTracer () {
131+ this .contextRunner .withClassLoader (new FilteredClassLoader (Tracer .class ))
132+ .withPropertyValues ("spring.ai.chat.client.observations.log-completion=false" )
133+ .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
134+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
135+ .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
136+ }
137+
138+ @ Test
139+ void completionDisabledWithTracer () {
140+ this .contextRunner .withUserConfiguration (TracerConfiguration .class )
141+ .withPropertyValues ("spring.ai.chat.client.observations.log-completion=false" )
142+ .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
143+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
97144 .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
98145 }
99146
@@ -104,6 +151,7 @@ void customChatClientPromptContentObservationHandlerNoTracer() {
104151 .withPropertyValues ("spring.ai.chat.client.observations.log-prompt=true" )
105152 .run (context -> assertThat (context ).hasSingleBean (ChatClientPromptContentObservationHandler .class )
106153 .hasBean ("customChatClientPromptContentObservationHandler" )
154+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
107155 .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
108156 }
109157
@@ -114,20 +162,61 @@ void customChatClientPromptContentObservationHandlerWithTracer() {
114162 .withPropertyValues ("spring.ai.chat.client.observations.log-prompt=true" )
115163 .run (context -> assertThat (context ).hasSingleBean (ChatClientPromptContentObservationHandler .class )
116164 .hasBean ("customChatClientPromptContentObservationHandler" )
165+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class )
117166 .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
118167 }
119168
120169 @ Test
121- void customTracingAwareLoggingObservationHandler () {
170+ void customTracingAwareLoggingObservationHandlerForChatClientPromptContent () {
122171 this .contextRunner .withUserConfiguration (TracerConfiguration .class )
123- .withUserConfiguration (CustomTracingAwareLoggingObservationHandlerConfiguration .class )
172+ .withUserConfiguration (
173+ CustomTracingAwareLoggingObservationHandlerForChatClientPromptContentConfiguration .class )
124174 .withPropertyValues ("spring.ai.chat.client.observations.log-prompt=true" )
125175 .run (context -> {
126176 assertThat (context ).hasSingleBean (TracingAwareLoggingObservationHandler .class )
127177 .hasBean ("chatClientPromptContentObservationHandler" )
128- .doesNotHaveBean (ChatClientPromptContentObservationHandler .class );
129- assertThat (context .getBean (TracingAwareLoggingObservationHandler .class ))
130- .isSameAs (CustomTracingAwareLoggingObservationHandlerConfiguration .handlerInstance );
178+ .doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
179+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class );
180+ assertThat (context .getBean (TracingAwareLoggingObservationHandler .class )).isSameAs (
181+ CustomTracingAwareLoggingObservationHandlerForChatClientPromptContentConfiguration .handlerInstance );
182+ });
183+ }
184+
185+ @ Test
186+ void customChatClientCompletionObservationHandlerNoTracer () {
187+ this .contextRunner .withClassLoader (new FilteredClassLoader (Tracer .class ))
188+ .withUserConfiguration (CustomChatClientCompletionObservationHandlerConfiguration .class )
189+ .withPropertyValues ("spring.ai.chat.client.observations.log-completion=true" )
190+ .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
191+ .hasSingleBean (ChatClientCompletionObservationHandler .class )
192+ .hasBean ("customChatClientCompletionObservationHandler" )
193+ .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
194+ }
195+
196+ @ Test
197+ void customChatClientCompletionObservationHandlerWithTracer () {
198+ this .contextRunner .withUserConfiguration (TracerConfiguration .class )
199+ .withUserConfiguration (CustomChatClientCompletionObservationHandlerConfiguration .class )
200+ .withPropertyValues ("spring.ai.chat.client.observations.log-completion=true" )
201+ .run (context -> assertThat (context ).doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
202+ .hasSingleBean (ChatClientCompletionObservationHandler .class )
203+ .hasBean ("customChatClientCompletionObservationHandler" )
204+ .doesNotHaveBean (TracingAwareLoggingObservationHandler .class ));
205+ }
206+
207+ @ Test
208+ void customTracingAwareLoggingObservationHandlerForChatClientCompletion () {
209+ this .contextRunner .withUserConfiguration (TracerConfiguration .class )
210+ .withUserConfiguration (
211+ CustomTracingAwareLoggingObservationHandlerForChatClientChatClientCompletionConfiguration .class )
212+ .withPropertyValues ("spring.ai.chat.client.observations.log-completion=true" )
213+ .run (context -> {
214+ assertThat (context ).hasSingleBean (TracingAwareLoggingObservationHandler .class )
215+ .hasBean ("chatClientCompletionObservationHandler" )
216+ .doesNotHaveBean (ChatClientPromptContentObservationHandler .class )
217+ .doesNotHaveBean (ChatClientCompletionObservationHandler .class );
218+ assertThat (context .getBean (TracingAwareLoggingObservationHandler .class )).isSameAs (
219+ CustomTracingAwareLoggingObservationHandlerForChatClientChatClientCompletionConfiguration .handlerInstance );
131220 });
132221 }
133222
@@ -152,7 +241,7 @@ ChatClientPromptContentObservationHandler customChatClientPromptContentObservati
152241 }
153242
154243 @ Configuration (proxyBeanMethods = false )
155- static class CustomTracingAwareLoggingObservationHandlerConfiguration {
244+ static class CustomTracingAwareLoggingObservationHandlerForChatClientPromptContentConfiguration {
156245
157246 static TracingAwareLoggingObservationHandler <ChatClientObservationContext > handlerInstance = new TracingAwareLoggingObservationHandler <>(
158247 new ChatClientPromptContentObservationHandler (), null );
@@ -164,4 +253,27 @@ TracingAwareLoggingObservationHandler<ChatClientObservationContext> chatClientPr
164253
165254 }
166255
256+ @ Configuration (proxyBeanMethods = false )
257+ static class CustomChatClientCompletionObservationHandlerConfiguration {
258+
259+ @ Bean
260+ ChatClientCompletionObservationHandler customChatClientCompletionObservationHandler () {
261+ return new ChatClientCompletionObservationHandler ();
262+ }
263+
264+ }
265+
266+ @ Configuration (proxyBeanMethods = false )
267+ static class CustomTracingAwareLoggingObservationHandlerForChatClientChatClientCompletionConfiguration {
268+
269+ static TracingAwareLoggingObservationHandler <ChatClientObservationContext > handlerInstance = new TracingAwareLoggingObservationHandler <>(
270+ new ChatClientCompletionObservationHandler (), null );
271+
272+ @ Bean
273+ TracingAwareLoggingObservationHandler <ChatClientObservationContext > chatClientCompletionObservationHandler () {
274+ return handlerInstance ;
275+ }
276+
277+ }
278+
167279}
0 commit comments