Skip to content

Commit ffee6c7

Browse files
authored
Update OpenTelemetryChatClient to output data on all tools (#6906)
We're currently filtering down to only AITools that are AIFunctionDeclaration. With this, we'll handle AIFunctionDeclaration wrappers the same as well, and for all other tools emit their name as the type. This can be further extended as otel adds more details about how non-function tools should be represented.
1 parent 4c8b35f commit ffee6c7

File tree

11 files changed

+65
-19
lines changed

11 files changed

+65
-19
lines changed

src/Libraries/Microsoft.Extensions.AI.Abstractions/Microsoft.Extensions.AI.Abstractions.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,10 @@
19521952
{
19531953
"Member": "System.Collections.Generic.IList<Microsoft.Extensions.AI.AIContent>? Microsoft.Extensions.AI.HostedCodeInterpreterTool.Inputs { get; set; }",
19541954
"Stage": "Stable"
1955+
},
1956+
{
1957+
"Member": "override string Microsoft.Extensions.AI.HostedCodeInterpreterTool.Name { get; }",
1958+
"Stage": "Stable"
19551959
}
19561960
]
19571961
},
@@ -1972,6 +1976,10 @@
19721976
{
19731977
"Member": "int? Microsoft.Extensions.AI.HostedFileSearchTool.MaximumResultCount { get; set; }",
19741978
"Stage": "Stable"
1979+
},
1980+
{
1981+
"Member": "override string Microsoft.Extensions.AI.HostedFileSearchTool.Name { get; }",
1982+
"Stage": "Stable"
19751983
}
19761984
]
19771985
},
@@ -1983,6 +1991,12 @@
19831991
"Member": "Microsoft.Extensions.AI.HostedWebSearchTool.HostedWebSearchTool();",
19841992
"Stage": "Stable"
19851993
}
1994+
],
1995+
"Properties": [
1996+
{
1997+
"Member": "override string Microsoft.Extensions.AI.HostedWebSearchTool.Name { get; }",
1998+
"Stage": "Stable"
1999+
}
19862000
]
19872001
},
19882002
{

src/Libraries/Microsoft.Extensions.AI.Abstractions/Tools/HostedCodeInterpreterTool.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public HostedCodeInterpreterTool()
1717
{
1818
}
1919

20+
/// <inheritdoc />
21+
public override string Name => "code_interpreter";
22+
2023
/// <summary>Gets or sets a collection of <see cref="AIContent"/> to be used as input to the code interpreter tool.</summary>
2124
/// <remarks>
2225
/// Services support different varied kinds of inputs. Most support the IDs of files that are hosted by the service,

src/Libraries/Microsoft.Extensions.AI.Abstractions/Tools/HostedFileSearchTool.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public HostedFileSearchTool()
1717
{
1818
}
1919

20+
/// <inheritdoc />
21+
public override string Name => "file_search";
22+
2023
/// <summary>Gets or sets a collection of <see cref="AIContent"/> to be used as input to the file search tool.</summary>
2124
/// <remarks>
2225
/// If no explicit inputs are provided, the service determines what inputs should be searched. Different services

src/Libraries/Microsoft.Extensions.AI.Abstractions/Tools/HostedMcpServerTool.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public HostedMcpServerTool(string serverName, Uri url)
3939
Url = Throw.IfNull(url);
4040
}
4141

42+
/// <inheritdoc />
43+
public override string Name => "mcp";
44+
4245
/// <summary>
4346
/// Gets the name of the remote MCP server that is used to identify it.
4447
/// </summary>

src/Libraries/Microsoft.Extensions.AI.Abstractions/Tools/HostedWebSearchTool.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ public class HostedWebSearchTool : AITool
1414
public HostedWebSearchTool()
1515
{
1616
}
17+
18+
/// <inheritdoc />
19+
public override string Name => "web_search";
1720
}

src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ internal static string SerializeChatMessages(IEnumerable<ChatMessage> messages,
249249
m.Parts.Add(new OtelGenericPart { Content = tc.Text });
250250
break;
251251

252+
case TextReasoningContent trc when !string.IsNullOrWhiteSpace(trc.Text):
253+
m.Parts.Add(new OtelGenericPart { Type = "reasoning", Content = trc.Text });
254+
break;
255+
252256
case FunctionCallContent fcc:
253257
m.Parts.Add(new OtelToolCallRequestPart
254258
{
@@ -268,10 +272,6 @@ internal static string SerializeChatMessages(IEnumerable<ChatMessage> messages,
268272

269273
// These are non-standard and are using the "generic" non-text part that provides an extensibility mechanism:
270274

271-
case TextReasoningContent trc when !string.IsNullOrWhiteSpace(trc.Text):
272-
m.Parts.Add(new OtelGenericPart { Type = "reasoning", Content = trc.Text });
273-
break;
274-
275275
case UriContent uc:
276276
m.Parts.Add(new OtelGenericPart { Type = "image", Content = uc.Uri.ToString() });
277277
break;
@@ -396,16 +396,20 @@ internal static string SerializeChatMessages(IEnumerable<ChatMessage> messages,
396396

397397
if (EnableSensitiveData)
398398
{
399-
if (options.Tools?.Any(t => t is AIFunctionDeclaration) is true)
399+
if (options.Tools is { Count: > 0 })
400400
{
401401
_ = activity.AddTag(
402-
OpenTelemetryConsts.GenAI.Tool.Definitions,
403-
JsonSerializer.Serialize(options.Tools.OfType<AIFunctionDeclaration>().Select(t => new OtelFunction
402+
OpenTelemetryConsts.GenAI.Tool.Definitions,
403+
JsonSerializer.Serialize(options.Tools.Select(t => t switch
404+
{
405+
_ when t.GetService<AIFunctionDeclaration>() is { } af => new OtelFunction
404406
{
405-
Name = t.Name,
406-
Description = t.Description,
407-
Parameters = t.JsonSchema,
408-
}), OtelContext.Default.IEnumerableOtelFunction));
407+
Name = af.Name,
408+
Description = af.Description,
409+
Parameters = af.JsonSchema,
410+
},
411+
_ => new OtelFunction { Type = t.Name },
412+
}), OtelContext.Default.IEnumerableOtelFunction));
409413
}
410414

411415
// Log all additional request options as raw values on the span.
@@ -601,7 +605,7 @@ private sealed class OtelFunction
601605
public string Type { get; set; } = "function";
602606
public string? Name { get; set; }
603607
public string? Description { get; set; }
604-
public JsonElement Parameters { get; set; }
608+
public JsonElement? Parameters { get; set; }
605609
}
606610

607611
private static readonly JsonSerializerOptions _defaultOptions = CreateDefaultOptions();

test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Tools/HostedCodeInterpreterToolTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ public class HostedCodeInterpreterToolTests
1111
public void Constructor_Roundtrips()
1212
{
1313
var tool = new HostedCodeInterpreterTool();
14-
Assert.Equal(nameof(HostedCodeInterpreterTool), tool.Name);
14+
Assert.Equal("code_interpreter", tool.Name);
1515
Assert.Empty(tool.Description);
1616
Assert.Empty(tool.AdditionalProperties);
1717
Assert.Null(tool.Inputs);
18-
Assert.Equal(nameof(HostedCodeInterpreterTool), tool.ToString());
18+
Assert.Equal(tool.Name, tool.ToString());
1919
}
2020

2121
[Fact]

test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Tools/HostedFileSearchToolTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ public class HostedFileSearchToolTests
1111
public void Constructor_Roundtrips()
1212
{
1313
var tool = new HostedFileSearchTool();
14-
Assert.Equal(nameof(HostedFileSearchTool), tool.Name);
14+
Assert.Equal("file_search", tool.Name);
1515
Assert.Empty(tool.Description);
1616
Assert.Empty(tool.AdditionalProperties);
1717
Assert.Null(tool.Inputs);
1818
Assert.Null(tool.MaximumResultCount);
19-
Assert.Equal(nameof(HostedFileSearchTool), tool.ToString());
19+
Assert.Equal(tool.Name, tool.ToString());
2020
}
2121

2222
[Fact]

test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Tools/HostedMcpServerToolTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public void Constructor_Roundtrips()
3131

3232
Assert.Empty(tool.AdditionalProperties);
3333
Assert.Empty(tool.Description);
34-
Assert.Equal(nameof(HostedMcpServerTool), tool.Name);
34+
Assert.Equal("mcp", tool.Name);
35+
Assert.Equal(tool.Name, tool.ToString());
3536

3637
Assert.Equal("serverName", tool.ServerName);
3738
Assert.Equal("https://localhost/", tool.Url.ToString());

test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/Tools/HostedWebSearchToolTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ public class HostedWebSearchToolTests
1111
public void Constructor_Roundtrips()
1212
{
1313
var tool = new HostedWebSearchTool();
14-
Assert.Equal(nameof(HostedWebSearchTool), tool.Name);
14+
Assert.Equal("web_search", tool.Name);
1515
Assert.Empty(tool.Description);
1616
Assert.Empty(tool.AdditionalProperties);
17-
Assert.Equal(nameof(HostedWebSearchTool), tool.ToString());
17+
Assert.Equal(tool.Name, tool.ToString());
1818
}
1919
}

0 commit comments

Comments
 (0)