@@ -2226,4 +2226,68 @@ public async Task ItSendsBinaryContentCorrectlyAsync(bool useUriData)
22262226 /// Sample PDF data URI for testing.
22272227 /// </summary>
22282228 private const string PdfBase64Data = "JVBERi0xLjQKMSAwIG9iago8PC9UeXBlIC9DYXRhbG9nCi9QYWdlcyAyIDAgUgo+PgplbmRvYmoKMiAwIG9iago8PC9UeXBlIC9QYWdlcwovS2lkcyBbMyAwIFJdCi9Db3VudCAxCj4+CmVuZG9iagozIDAgb2JqCjw8L1R5cGUgL1BhZ2UKL1BhcmVudCAyIDAgUgovTWVkaWFCb3ggWzAgMCA1OTUgODQyXQovQ29udGVudHMgNSAwIFIKL1Jlc291cmNlcyA8PC9Qcm9jU2V0IFsvUERGIC9UZXh0XQovRm9udCA8PC9GMSA0IDAgUj4+Cj4+Cj4+CmVuZG9iago0IDAgb2JqCjw8L1R5cGUgL0ZvbnQKL1N1YnR5cGUgL1R5cGUxCi9OYW1lIC9GMQovQmFzZUZvbnQgL0hlbHZldGljYQovRW5jb2RpbmcgL01hY1JvbWFuRW5jb2RpbmcKPj4KZW5kb2JqCjUgMCBvYmoKPDwvTGVuZ3RoIDUzCj4+CnN0cmVhbQpCVAovRjEgMjAgVGYKMjIwIDQwMCBUZAooRHVtbXkgUERGKSBUagpFVAplbmRzdHJlYW0KZW5kb2JqCnhyZWYKMCA2CjAwMDAwMDAwMDAgNjU1MzUgZgowMDAwMDAwMDA5IDAwMDAwIG4KMDAwMDAwMDA2MyAwMDAwMCBuCjAwMDAwMDAxMjQgMDAwMDAgbgowMDAwMDAwMjc3IDAwMDAwIG4KMDAwMDAwMDM5MiAwMDAwMCBuCnRyYWlsZXIKPDwvU2l6ZSA2Ci9Sb290IDEgMCBSCj4+CnN0YXJ0eHJlZgo0OTUKJSVFT0YK" ;
2229+
2230+ [ Fact ( Skip = "Diagnostics tests require environment variables set before process start" ) ]
2231+ public async Task ToolResultMessageDiagnosticsIncludesToolCallIdAsync ( )
2232+ {
2233+ // This test verifies that tool result messages include tool_call_id for correlation.
2234+ // To run manually:
2235+ // 1. Set SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS=true
2236+ // 2. Set SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE=true
2237+ // 3. Run the test
2238+
2239+ // Arrange
2240+ var callId = "call_abc123" ;
2241+ var functionName = "GetWeather" ;
2242+
2243+ var chatHistory = new ChatHistory
2244+ {
2245+ new ChatMessageContent ( AuthorRole . User , "What's the weather?" ) ,
2246+ new ChatMessageContent ( AuthorRole . Assistant , [
2247+ new FunctionCallContent ( functionName , "WeatherPlugin" , callId )
2248+ ] ) ,
2249+ new ChatMessageContent ( AuthorRole . Tool , [
2250+ new FunctionResultContent ( functionName , "WeatherPlugin" , callId , "Sunny, 25°C" )
2251+ ] )
2252+ } ;
2253+
2254+ List < string > capturedEventContent = [ ] ;
2255+
2256+ using var listener = new ActivityListener
2257+ {
2258+ ShouldListenTo = _ => true ,
2259+ Sample = ( ref ActivityCreationOptions < ActivityContext > _ ) => ActivitySamplingResult . AllData ,
2260+ ActivityStopped = activity =>
2261+ {
2262+ foreach ( var evt in activity . Events )
2263+ {
2264+ foreach ( var tag in evt . Tags )
2265+ {
2266+ if ( tag . Key == "gen_ai.event.content" && tag . Value is string content )
2267+ {
2268+ capturedEventContent . Add ( content ) ;
2269+ }
2270+ }
2271+ }
2272+ }
2273+ } ;
2274+
2275+ ActivitySource . AddActivityListener ( listener ) ;
2276+
2277+ this . _messageHandlerStub . ResponseToReturn = new HttpResponseMessage ( HttpStatusCode . OK )
2278+ {
2279+ Content = new StringContent ( File . ReadAllText ( "TestData/chat_completion_test_response.json" ) )
2280+ } ;
2281+
2282+ var sut = new OpenAIChatCompletionService ( "gpt-4" , "api-key" , httpClient : this . _httpClient ) ;
2283+
2284+ // Act
2285+ await sut . GetChatMessageContentsAsync ( chatHistory ) ;
2286+
2287+ // Assert - verify tool result message contains tool_call_id
2288+ var toolMessageContent = capturedEventContent . FirstOrDefault ( c => c . Contains ( "\" role\" :\" Tool\" " ) ) ;
2289+ Assert . NotNull ( toolMessageContent ) ;
2290+ Assert . Contains ( $ "\" tool_call_id\" :\" { callId } \" ", toolMessageContent ) ;
2291+ Assert . Contains ( $ "\" name\" :\" { functionName } \" ", toolMessageContent ) ;
2292+ }
22292293}
0 commit comments