Skip to content

Commit 16b65b0

Browse files
committed
Update OpenTelemetryChatClient to output data on all tools
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 a9b3385 commit 16b65b0

File tree

7 files changed

+53
-8
lines changed

7 files changed

+53
-8
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: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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.Tests/ChatCompletion/OpenTelemetryChatClientTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ async static IAsyncEnumerable<ChatResponseUpdate> CallbackAsync(
134134
[
135135
AIFunctionFactory.Create((string personName) => personName, "GetPersonAge", "Gets the age of a person by name."),
136136
new HostedWebSearchTool(),
137+
new HostedFileSearchTool(),
138+
new HostedCodeInterpreterTool(),
139+
new HostedMcpServerTool("myAwesomeServer", "http://localhost:1234/somewhere"),
137140
AIFunctionFactory.Create((string location) => "", "GetCurrentWeather", "Gets the current weather for a location.").AsDeclarationOnly(),
138141
],
139142
};
@@ -288,6 +291,18 @@ async static IAsyncEnumerable<ChatResponseUpdate> CallbackAsync(
288291
]
289292
}
290293
},
294+
{
295+
"type": "web_search"
296+
},
297+
{
298+
"type": "file_search"
299+
},
300+
{
301+
"type": "code_interpreter"
302+
},
303+
{
304+
"type": "mcp"
305+
},
291306
{
292307
"type": "function",
293308
"name": "GetCurrentWeather",

0 commit comments

Comments
 (0)