Add server tool call support to OpenTelemetryChatClient per semantic conventions#7240
Merged
stephentoub merged 5 commits intomainfrom Jan 31, 2026
Merged
Conversation
Per OpenTelemetry semantic conventions, add support for: - CodeInterpreterToolCallContent → server_tool_call (type=code_interpreter) - CodeInterpreterToolResultContent → server_tool_call_response (type=code_interpreter) - ImageGenerationToolCallContent → server_tool_call (type=image_generation) - ImageGenerationToolResultContent → server_tool_call_response (type=image_generation) - McpServerToolCallContent → server_tool_call (type=mcp) - McpServerToolResultContent → server_tool_call_response (type=mcp) - McpServerToolApprovalRequestContent → server_tool_call (type=mcp_approval_request) - McpServerToolApprovalResponseContent → server_tool_call_response (type=mcp_approval_response) Add new Otel types: - OtelServerToolCallPart - OtelServerToolCallResponsePart - OtelGenericServerToolCall - OtelGenericServerToolCallResponse Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Change OtelGenericServerToolCall.Arguments from IDictionary to IReadOnlyDictionary to avoid potential null results when the source is a read-only dictionary implementation. Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Update OpenTelemetryChatClient for standard convention changes
Add server tool call support to OpenTelemetryChatClient per semantic conventions
Jan 29, 2026
stephentoub
reviewed
Jan 30, 2026
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Outdated
Show resolved
Hide resolved
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Show resolved
Hide resolved
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Outdated
Show resolved
Hide resolved
…t type Per code review feedback: - Replace generic OtelGenericServerToolCall and OtelGenericServerToolCallResponse with specialized classes for each content type - Create OtelCodeInterpreterToolCall with "code" field (extracts code from DataContent/TextContent) - Create OtelCodeInterpreterToolCallResponse with "output" field - Create OtelImageGenerationToolCall and OtelImageGenerationToolCallResponse - Create OtelMcpToolCall and OtelMcpToolCallResponse with server_name and arguments - Create OtelMcpApprovalRequest and OtelMcpApprovalResponse with approved field - Use generic OtelServerToolCallPart<T> and OtelServerToolCallResponsePart<T> for type safety Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
stephentoub
reviewed
Jan 30, 2026
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Outdated
Show resolved
Hide resolved
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Outdated
Show resolved
Hide resolved
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Outdated
Show resolved
Hide resolved
test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/OpenTelemetryChatClientTests.cs
Outdated
Show resolved
Hide resolved
- Use dc.HasTopLevelMediaType("text") instead of StartsWith
- Remove redundant application/x-python-code condition
- Invert null check to have single return null at end
- Remove unnecessary pragma warnings (MEAI001 already suppressed in test project)
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends OpenTelemetryChatClient to support new OpenTelemetry semantic conventions for server tool calls, covering code interpreter, image generation, and MCP server tooling, and updates tests accordingly. It introduces specialized OTEL serialization types and a helper to extract code interpreter input, ensuring both streaming and non-streaming paths emit the expected OTEL JSON.
Changes:
- Map
CodeInterpreterToolCallContent,CodeInterpreterToolResultContent,ImageGenerationToolCallContent,ImageGenerationToolResultContent,McpServerToolCallContent,McpServerToolResultContent,McpServerToolApprovalRequestContent, andMcpServerToolApprovalResponseContentinto OTELserver_tool_call/server_tool_call_responseparts with dedicated internal DTOs. - Add
ExtractCodeFromInputsto derive thecodefield for code interpreter calls fromAIContentinputs and register the new OTEL DTOs withJsonSerializablefor source-generated serialization. - Add tests to verify the new server tool call and MCP approval content types serialize to the expected OTEL JSON for both single-shot and streaming chat flows.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs |
Adds server tool call / response part types, content-to-OTEL mapping for new server tool content types, the ExtractCodeFromInputs helper, and updates OTEL JSON source-generation registrations. |
test/Libraries/Microsoft.Extensions.AI.Tests/ChatCompletion/OpenTelemetryChatClientTests.cs |
Adds tests to assert correct OTEL JSON for server tool calls/results (code interpreter, image generation, MCP) and MCP approval request/response content, for both streaming and non-streaming scenarios. |
Comments suppressed due to low confidence (1)
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs:493
ExtractCodeFromInputshandles bothDataContent(by decodingdc.Datawhen the media type istext/*orapplication/x-python-code) andTextContent, but the new tests exercise only theTextContentcode path. To reduce the risk of regressions and to validate the primaryDataContent-based scenario used by the OpenAI clients (which populateInputswithDataContentusing a"text/x-python"media type), consider adding a test that creates aCodeInterpreterToolCallContentwith aDataContentinput and verifies that the serializedserver_tool_call.server_tool_call.codefield contains the expected decoded code string.
private static string? ExtractCodeFromInputs(IList<AIContent>? inputs)
{
if (inputs is not null)
{
foreach (var input in inputs)
{
// Check for DataContent with text MIME types
if (input is DataContent dc && dc.HasTopLevelMediaType("text"))
{
// Return the data as a string (decode bytes as UTF8)
return Encoding.UTF8.GetString(dc.Data.ToArray());
}
// Check for TextContent
if (input is TextContent tc && !string.IsNullOrEmpty(tc.Text))
{
return tc.Text;
}
}
}
return null;
}
/// <summary>Creates an activity for a chat request, or returns <see langword="null"/> if not enabled.</summary>
private Activity? CreateAndConfigureActivity(ChatOptions? options)
{
Activity? activity = null;
tarekgh
reviewed
Jan 31, 2026
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Show resolved
Hide resolved
tarekgh
reviewed
Jan 31, 2026
src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs
Show resolved
Hide resolved
ptr727
added a commit
to ptr727/LanguageTags
that referenced
this pull request
Feb 12, 2026
Updated [csharpier](https://github.com/belav/csharpier) from 1.2.5 to 1.2.6. <details> <summary>Release notes</summary> _Sourced from [csharpier's releases](https://github.com/belav/csharpier/releases)._ ## 1.2.6 ## What's Changed ### [Bug]: XML with DOCTYPE results in "invalid xml" warning [#1809](belav/csharpier#1809) CSharpier was not formatting xml that included a doctype and instead reporting that it was invalid xml. ```xml <?xml version="1.0"?> <!DOCTYPE staff SYSTEM "staff.dtd"[ <!ENTITY ent1 "es"> ]> <staff></staff> ``` ### [Bug]: Initializing a span using `stackalloc` leads to different formatting compared to `new` [#1808](belav/csharpier#1808) When initializing a spacn using stackalloc, it was not being formatting consistently with other code ```c# // input & expected output Span<int> metatable = new int[] { 00000000000000000000000001, 00000000000000000000000002, 00000000000000000000000003, }; Span<int> metatable = stackalloc int[] { 00000000000000000000000001, 00000000000000000000000002, 00000000000000000000000003, }; // 1.2.5 Span<int> metatable = new int[] { 00000000000000000000000001, 00000000000000000000000002, 00000000000000000000000003, }; Span<int> metatable = stackalloc int[] { 00000000000000000000000001, 00000000000000000000000002, 00000000000000000000000003, }; ``` ### [Bug]: Comments in otherwise empty object pattern disappear when formatting [#1804](belav/csharpier#1804) CSharpier was removing comments if they were the only content of an object pattern. ```c# // input & expected output var match = obj is { //Property: 123 ... (truncated) Commits viewable in [compare view](belav/csharpier@1.2.5...1.2.6). </details> Updated [Microsoft.Extensions.Http.Resilience](https://github.com/dotnet/extensions) from 10.2.0 to 10.3.0. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Extensions.Http.Resilience's releases](https://github.com/dotnet/extensions/releases)._ ## 10.3.0 ## What's Changed * Bump version to 10.3.0 for next development cycle by @Copilot in dotnet/extensions#7197 * Fix race condition in UnreliableL2Tests.WriteFailureInvisible by @Copilot in dotnet/extensions#7075 * Set Microsoft.McpServer.ProjectTemplates version to align with MCP packages by @jeffhandley in dotnet/extensions#7170 * ToChatResponse: Merge AdditionalProperties into ChatMessage instead of ChatResponse by @Copilot in dotnet/extensions#7194 * Fix NRT resolution for AIFunction parameters. by @eiriktsarpalis in dotnet/extensions#7200 * Bump mdast-util-to-hast from 13.2.0 to 13.2.1 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @dependabot[bot] in dotnet/extensions#7198 * Add .npmrc next to package.json and add lockfile for PublishAIEvaluationReport by @akoeplinger in dotnet/extensions#7108 * Bump qs from 6.14.0 to 6.14.1 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @dependabot[bot] in dotnet/extensions#7189 * Bump js-yaml from 4.1.0 to 4.1.1 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @dependabot[bot] in dotnet/extensions#7054 * Bump validator from 13.15.20 to 13.15.23 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @dependabot[bot] in dotnet/extensions#7103 * Update AI changelogs by @stephentoub in dotnet/extensions#7206 * Merge changes from internal after 10.2 release by @joperezr in dotnet/extensions#7205 * Merge changes from release/10.2 to main by @joperezr in dotnet/extensions#7209 * Categorize MEAI001 experimental APIs by @Copilot in dotnet/extensions#7116 * [main] Update dependencies from dotnet/arcade by @dotnet-maestro[bot] in dotnet/extensions#7212 * Update Package Validation Baseline to 10.2.0 by @Copilot in dotnet/extensions#7208 * Enable package validation for M.E.AmbientMetadata.Build by @evgenyfedorov2 in dotnet/extensions#7213 * [5752] FakeLogCollector waiting capabilities by @Demo30 in dotnet/extensions#6228 * Set network isolation policy for extensions-ci by @wtgodbe in dotnet/extensions#7221 * Fix FunctionInvokingChatClient invoke_agent span detection with exact match or space delimiter by @Copilot in dotnet/extensions#7224 * Add Ordinal into ordering by @cincuranet in dotnet/extensions#7225 * Remove AIFunctionDeclaration tools on last iteration in FunctionInvokingChatClient by @Copilot in dotnet/extensions#7207 * Remove unnecessary description tags by @gewarren in dotnet/extensions#7226 * Fix FunctionInvokingChatClient to respect ChatOptions.Tools modifications by function tools by @Copilot in dotnet/extensions#7218 * Add LoadFromAsync and SaveToAsync helper methods to DataContent by @Copilot in dotnet/extensions#7159 * Bump lodash from 4.17.21 to 4.17.23 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @dependabot[bot] in dotnet/extensions#7227 * Add logging to FunctionInvokingChatClient for approval flow, error handling, and loop control by @Copilot in dotnet/extensions#7228 * [main] Update dependencies from dotnet/arcade by @dotnet-maestro[bot] in dotnet/extensions#7230 * Allow FunctionResultContent pass-through when CallId matches by @Copilot in dotnet/extensions#7229 * Propagate CachedInputTokenCount in OpenTelemetry telemetry by @Copilot in dotnet/extensions#7234 * Add InvocationRequired property to FunctionCallContent by @Copilot in dotnet/extensions#7126 * Escape the JSON data before embedding in Evaluation reports by @peterwald in dotnet/extensions#7238 * Update mcpserver template to ModelContextProtocol 0.7.0-preview.1 by @Copilot in dotnet/extensions#7236 * Update aiagent-webapi template to Agent Framework 1.0.0-preview.260127.1 by @Copilot in dotnet/extensions#7237 * Fix token metric unit to use UCUM format {token} by @stephentoub in dotnet/extensions#7241 * Add server tool call support to OpenTelemetryChatClient per semantic conventions by @Copilot in dotnet/extensions#7240 * Preserve extra JSON schema properties in ToolJson serialization by @Copilot in dotnet/extensions#7250 * Bring new cpu.requests formula from Kubernetes by @amadeuszl in dotnet/extensions#7239 * Update M.E.AI changelogs with recent changes by @stephentoub in dotnet/extensions#7242 * Fix DataUriParser to default to text/plain;charset=US-ASCII per RFC 2397 by @Copilot in dotnet/extensions#7247 * Fix deadlock in ServiceEndpointWatcher when disposing change token registration by @ReubenBond in dotnet/extensions#7255 * Rename FunctionCallContent.InvocationRequired to InformationalOnly with inverted polarity by @Copilot in dotnet/extensions#7262 * Fix approval request/response correlation in FunctionInvokingChatClient by @Copilot in dotnet/extensions#7261 * Add ReasoningOptions to ChatOptions by @Copilot in dotnet/extensions#7252 ## New Contributors * @cincuranet made their first contribution in dotnet/extensions#7225 * @ReubenBond made their first contribution in dotnet/extensions#7255 ... (truncated) Commits viewable in [compare view](dotnet/extensions@v10.2.0...v10.3.0). </details> Updated [Microsoft.Extensions.Logging.Abstractions](https://github.com/dotnet/dotnet) from 10.0.2 to 10.0.3. <details> <summary>Release notes</summary> _Sourced from [Microsoft.Extensions.Logging.Abstractions's releases](https://github.com/dotnet/dotnet/releases)._ ## 10.0.3 [Release](https://github.com/dotnet/core/releases/tag/v10.0.3) Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits/v10.0.3). </details> Updated [Microsoft.SourceLink.GitHub](https://github.com/dotnet/dotnet) from 10.0.102 to 10.0.103. <details> <summary>Release notes</summary> _Sourced from [Microsoft.SourceLink.GitHub's releases](https://github.com/dotnet/dotnet/releases)._ ## 10.0.103 You can build .NET 10.0 from the repository by cloning the release tag `v10.0.103` and following the build instructions in the [main README.md](https://github.com/dotnet/dotnet/blob/v10.0.103/README.md#building). Alternatively, you can build from the sources attached to this release directly. More information on this process can be found in the [dotnet/dotnet repository](https://github.com/dotnet/dotnet/blob/v10.0.103/README.md#building-from-released-sources). Attached is the PGP signature for the GitHub generated tarball. You can find the public key at https://dot.net/release-key-2023 Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits/v10.0.103). </details> Updated [Serilog](https://github.com/serilog/serilog) from 4.3.0 to 4.3.1. <details> <summary>Release notes</summary> _Sourced from [Serilog's releases](https://github.com/serilog/serilog/releases)._ ## 4.3.1 ## What's Changed * Remove SourceLink by @SimonCropp in serilog/serilog#2183 * Handle Exception.ToString failures in text formatter by @krisbiradar in serilog/serilog#2197 * Remove char[] allocation by @karpinsn in serilog/serilog#2198 * Remove backpressure from XMLDoc by @timothycoleman in serilog/serilog#2203 * Don't enable XDOC for tests by @nblumhardt in serilog/serilog#2205 * Target and test on net10 by @SimonCropp in serilog/serilog#2206 * Fix trimming error when Serilog is a transitive dependency by @Numpsy in serilog/serilog#2214 * Inline TraceId and SpanId JSON string formatting by @SimonCropp in serilog/serilog#2215 ## New Contributors * @krisbiradar made their first contribution in serilog/serilog#2197 * @karpinsn made their first contribution in serilog/serilog#2198 * @timothycoleman made their first contribution in serilog/serilog#2203 * @Numpsy made their first contribution in serilog/serilog#2214 **Full Changelog**: serilog/serilog@v4.3.0...v4.3.1 Commits viewable in [compare view](serilog/serilog@v4.3.0...v4.3.1). </details> Updated [System.CommandLine](https://github.com/dotnet/dotnet) from 2.0.2 to 2.0.3. <details> <summary>Release notes</summary> _Sourced from [System.CommandLine's releases](https://github.com/dotnet/dotnet/releases)._ No release notes found for this version range. Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits). </details> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pieter Viljoen <ptr727@users.noreply.github.com>
This was referenced Feb 12, 2026
jozkee
pushed a commit
to jozkee/extensions
that referenced
this pull request
Feb 12, 2026
…conventions (dotnet#7240) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
This was referenced Feb 12, 2026
Update: Bump Microsoft.Extensions.Http.Resilience from 10.0.0 to 10.3.0
sergej-stk/Steinsiek.Odin#15
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.
Microsoft Reviewers: Open in CodeFlow