Skip to content

Add startTime and endTime parameters to OpenTelemetry scope classes#205

Merged
nikhilNava merged 2 commits intomainfrom
copilot/implement-pr-in-dotnet
Feb 27, 2026
Merged

Add startTime and endTime parameters to OpenTelemetry scope classes#205
nikhilNava merged 2 commits intomainfrom
copilot/implement-pr-in-dotnet

Conversation

Copy link
Contributor

Copilot AI commented Feb 24, 2026

Port of Agent365-python#181. Enables explicit span timestamps for post-hoc span recording (e.g., LangChain tracer using run.start_time/run.end_time).

Changes

  • OpenTelemetryScope: Add endTime constructor param (complements existing startTime)
  • ExecuteToolScope, InferenceScope, InvokeAgentScope, OutputScope: Forward startTime/endTime through Start() factory methods

Usage

// Via constructor params
using var scope = ExecuteToolScope.Start(
    details, agentDetails, tenantDetails,
    startTime: DateTimeOffset.Parse("2023-11-14T22:13:20Z"),
    endTime: DateTimeOffset.Parse("2023-11-14T22:13:25Z"));

// Or via methods (existing API)
scope.SetStartTime(customStart);
scope.SetEndTime(customEnd);

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Port of Python PR #181. Enables explicit span timestamps for operations
recorded after completion (e.g., LangChain tracer using run.start_time/run.end_time).

Changes:
- OpenTelemetryScope: Add endTime constructor param to complement existing startTime
- ExecuteToolScope: Add startTime/endTime params to Start() method
- InferenceScope: Add startTime/endTime params to Start() method
- InvokeAgentScope: Add startTime/endTime params to Start() method
- OutputScope: Add startTime/endTime params to Start() method
- Added unit tests for custom time functionality

Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement features from Python PR in .NET Add startTime and endTime parameters to OpenTelemetry scope classes Feb 24, 2026
@github-actions
Copy link

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@nikhilNava nikhilNava marked this pull request as ready for review February 24, 2026 20:52
@nikhilNava nikhilNava requested a review from a team as a code owner February 24, 2026 20:52
Copilot AI review requested due to automatic review settings February 24, 2026 20:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds optional startTime/endTime parameters to the .NET OpenTelemetry scope APIs to support explicit span timestamps (useful for post-hoc span recording scenarios, e.g., tracing integrations that already have run.start_time/run.end_time).

Changes:

  • Extend OpenTelemetryScope to accept an optional endTime (in addition to existing startTime) and carry it through lifecycle/end-of-scope logic.
  • Update scope factory Start(...) methods (ExecuteToolScope, InferenceScope, InvokeAgentScope, OutputScope) to accept and forward startTime/endTime.
  • Add/extend unit tests to exercise custom start/end time usage paths.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Observability/Runtime/Tracing/Scopes/OpenTelemetryScope.cs Adds endTime parameter/storage and end-of-scope timing handling.
src/Observability/Runtime/Tracing/Scopes/ExecuteToolScope.cs Forwards optional startTime/endTime through Start(...).
src/Observability/Runtime/Tracing/Scopes/InferenceScope.cs Forwards optional startTime/endTime through Start(...).
src/Observability/Runtime/Tracing/Scopes/InvokeAgentScope.cs Forwards optional startTime/endTime through Start(...).
src/Observability/Runtime/Tracing/Scopes/OutputScope.cs Forwards optional startTime/endTime through Start(...).
src/Tests/.../Tracing/Scopes/ExecuteToolScopeTest.cs Adds tests for custom start/end time/override scenarios.
src/Tests/.../Tracing/Scopes/InferenceScopeTest.cs Adds tests for custom start/end time/override scenarios.
src/Tests/.../Tracing/Scopes/InvokeAgentScopeTest.cs Adds tests for custom start/end time/override scenarios.
src/Tests/.../Tracing/Scopes/OutputScopeTest.cs Adds tests for custom start/end time/override scenarios.
Comments suppressed due to low confidence (9)

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/InvokeAgentScopeTest.cs:350

  • This test passes an explicit endTime but only asserts on StartTimeUtc, so it doesn't confirm that the span end timestamp/duration was set from endTime. Add an assertion on activity.Duration (or derived end time) to verify endTime is honored.
        // Assert - Start time should be set to custom time
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/InvokeAgentScopeTest.cs:374

  • This test calls SetEndTime(laterEndTime) but only asserts the start time, so it doesn't validate that the override took effect. Add an assertion that the final duration/end time corresponds to laterEndTime (not initialEndTime).
        // Assert - The start time should be set
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/InferenceScopeTest.cs:363

  • This test sets laterEndTime via SetEndTime but only checks the start time. Add an assertion to verify the recorded end time/duration matches laterEndTime - customStartTime (and not the initially provided end time).
        // Assert - The start time should be set
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/ExecuteToolScopeTest.cs:329

  • This test calls SetEndTime(laterEndTime) but doesn't assert anything about end time/duration. Add an assertion that the final duration/end time corresponds to laterEndTime rather than initialEndTime.
        // Assert - The start time should be set
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

src/Observability/Runtime/Tracing/Scopes/OpenTelemetryScope.cs:55

  • endTime is accepted/stored by the constructor, but the scope currently only applies a custom end timestamp when customStartTime is also set (see the End() logic). If a caller provides only endTime (or calls SetEndTime without setting a custom start time), the end time is effectively ignored and the span will end at wall-clock time, which conflicts with the parameter documentation. Consider either (a) honoring customEndTime regardless of whether customStartTime is set by using the activity's actual StartTimeUtc as the start for duration calculation, or (b) validating/throwing when endTime is provided without startTime and documenting that requirement.
        protected OpenTelemetryScope(ActivityKind kind, AgentDetails agentDetails, TenantDetails tenantDetails, string operationName, string activityName, DateTimeOffset? startTime = null, DateTimeOffset? endTime = null, string? parentId = null, string? conversationId = null, SourceMetadata? sourceMetadata = null, CallerDetails? callerDetails = null)
        {
            customStartTime = startTime;
            customEndTime = endTime;
            activity = ActivitySource.CreateActivity(activityName, kind, default(ActivityContext));

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/OutputScopeTest.cs:142

  • This test passes an explicit endTime but only asserts on StartTimeUtc, so it doesn't actually verify that the end timestamp (or resulting duration) was applied. Add an assertion against activity.Duration (or derived end time) to confirm the endTime parameter is honored.
        // Assert - Start time should be set to custom time
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/OutputScopeTest.cs:170

  • This test is named as if it validates the end time override, but it only asserts the start time. Add an assertion that the final duration/end time reflects laterEndTime rather than initialEndTime (e.g., activity.Duration matches laterEndTime - customStartTime).
        // Assert - The start time should be set
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/InferenceScopeTest.cs:334

  • This test includes an endTime argument but never asserts the end timestamp/duration. Add an assertion on activity.Duration (or compute end time from StartTimeUtc + Duration) to ensure endTime is applied.
        // Assert - Start time should be set to custom time
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

src/Tests/Microsoft.Agents.A365.Observability.Runtime.Tests/Tracing/Scopes/ExecuteToolScopeTest.cs:304

  • This test passes both startTime and endTime but only asserts on StartTimeUtc, so it doesn't validate the new endTime behavior. Add an assertion that activity.Duration (or derived end time) matches customEndTime - customStartTime.
        // Assert - Start time should be set to custom time
        var startTime = new DateTimeOffset(activity.StartTimeUtc);
        startTime.Should().BeCloseTo(customStartTime, TimeSpan.FromMilliseconds(100));
    }

@nikhilNava nikhilNava enabled auto-merge (squash) February 24, 2026 20:57
@nikhilNava nikhilNava merged commit f9dac92 into main Feb 27, 2026
12 checks passed
@nikhilNava nikhilNava deleted the copilot/implement-pr-in-dotnet branch February 27, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants