Repository navigation
Open
Labels
.NETUsage: [Issues, PRs], Target: .NetUsage: [Issues, PRs], Target: .NetagentsUsage: [Issues, PRs], Target: Single agentUsage: [Issues, PRs], Target: Single agentreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
Description
Observed Behavior
When a GitHubCopilotAgent is wrapped with UseOpenTelemetry, the invoke_agent span is incomplete:
gen_ai.response.finish_reasons,gen_ai.request.model,gen_ai.response.modelandgen_ai.usage.reasoning.output_tokensare never set.- With sensitive data enabled,
gen_ai.output.messagesis filled with empty parts such as{"type": "Microsoft.Extensions.AI.AIContent", "content": {}}. One streaming turn with three model calls and two tool calls produced 53 empty parts and onetool_callpart.
From GitHubCopilotAgent.cs on main (dotnet-1.26.0):
- No
AgentResponseUpdatesetsFinishReason, and the model is never exposed (OpenTelemetryAgentreadsModelIdfrom aChatResponseUpdateRawRepresentation, which the adapter does not produce), althoughAssistantUsageEvent.Datacarries bothFinishReasonandModel. ConvertToAgentResponseUpdate(AssistantUsageEvent)maps input, output and cached tokens but notAssistantUsageData.ReasoningTokenstoUsageDetails.ReasoningTokenCount.- The default branch of the event switch wraps every other
SessionEvent(reasoning and streaming deltas, turn start/end, model call start/finished, and so on) as an emptyAIContent, and in streaming mode anAssistantMessageEventalso becomes an emptyAIContent. These reach the response and are serialized as empty output parts.
Expected Behavior
- The final update carries
FinishReason(fromAssistantUsageData.FinishReason) and the model (fromAssistantUsageData.Model), soinvoke_agentgetsgen_ai.response.finish_reasonsandgen_ai.response.model. UsageDetails.ReasoningTokenCountis populated fromAssistantUsageData.ReasoningTokens.- Events with no content representation do not appear as empty parts in
gen_ai.output.messages.
Steps to Reproduce
- Create a
CopilotClientand an agent withAsAIAgent, with at least one custom tool. - Wrap it:
agent.AsBuilder().UseOpenTelemetry("test", o => o.EnableSensitiveData = true).Build(). - Add an
ActivityListenerfor source"test". - Run a streaming turn whose prompt makes the model call the tool.
- Inspect the
invoke_agentactivity's tags.
Minimal Reproduction
using var listener = new ActivityListener
{
ShouldListenTo = s => s.Name == "test",
Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllDataAndRecorded,
ActivityStopped = a =>
{
Console.WriteLine(a.DisplayName);
foreach (var tag in a.TagObjects) Console.WriteLine($" {tag.Key} = {tag.Value}");
},
};
ActivitySource.AddActivityListener(listener);
await using var client = new CopilotClient();
await client.StartAsync();
AIAgent agent = client.AsAIAgent(new SessionConfig
{
Tools = [AIFunctionFactory.Create(() => "42", "get_answer", "Returns the answer.")],
});
agent = agent.AsBuilder().UseOpenTelemetry("test", o => o.EnableSensitiveData = true).Build();
await foreach (var _ in agent.RunStreamingAsync("Call get_answer and tell me the result.")) { }
// invoke_agent: no gen_ai.response.finish_reasons, gen_ai.response.model or
// gen_ai.usage.reasoning.output_tokens; gen_ai.output.messages contains empty AIContent parts.Error Messages and Stack Traces
Package Versions
Microsoft.Agents.AI.GitHub.Copilot 1.23.0, GitHub.Copilot.SDK 1.0.14 (same code on main at dotnet-1.26.0)
.NET Version
.NET 10.0
Operating System
Linux
Regression
Unknown
Additional Context
We currently set the missing invoke_agent attributes ourselves from Copilot session events as a workaround.
Acknowledgements
- I searched existing issues and did not find a duplicate.
- I personally verified this behavior and the reproduction details are authentic.
- I will wait for explicit maintainer agreement before starting implementation of a non-trivial change.
Metadata
Metadata
Assignees
Labels
.NETUsage: [Issues, PRs], Target: .NetUsage: [Issues, PRs], Target: .NetagentsUsage: [Issues, PRs], Target: Single agentUsage: [Issues, PRs], Target: Single agentreproducedUsage: [Issues], Target: all issues that can be reproduced by the triage workflowUsage: [Issues], Target: all issues that can be reproduced by the triage workflow
Type
Projects
- StatusShow more project fieldsNo status
Activity
github-actions commentedon Oct 25, 2026
🤖 Automated triage reproduction notes (agent-authored — trust but verify)
Agent analysis
GitHubCopilotAgent.cs::ConvertToAgentResponseUpdatedrops finish reason, model, and reasoning tokens fromAssistantUsageEventand emits bareAIContentfor streaming assistant and fallback session events. The failures occur when usage data contains those fields or streaming receives metadata-only events. Minimal repro: construct those SDK events, invoke the conversion methods, and assert populated telemetry metadata and no empty content parts.dotnet/tests/Microsoft.Agents.AI.GitHub.Copilot.UnitTests/GitHubCopilotAgentTests.cs1.23.01.26.0