feat!: extend AiMetrics, MetricSummary, and TrackMetricsOf#300
Merged
Conversation
…alls, duration override, and resumption token
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b2c7bc2. Configure here.
tanderson-ld
approved these changes
Jul 6, 2026
Contributor
|
Jason should be able to review before you merge. |
…rthy/AIC-2727/extend-metrics-ai-metrics
jsonbailey
requested changes
Jul 7, 2026
jsonbailey
left a comment
Contributor
There was a problem hiding this comment.
Take a look at the tool call list comment, other than that this seems okay.
<!-- CURSOR_SUMMARY --> > [!NOTE] > **Medium Risk** > Public interface signature change on ILdAiConfigTracker is a binary-breaking change for external implementers, though call sites passing float literals still compile via implicit widening. > > **Overview** > **`ILdAiConfigTracker.TrackDuration`** and **`LdAiConfigTracker.TrackDuration`** now take **`double durationMs`** instead of **`float`**, matching how durations are already stored internally and how **`Stopwatch.Elapsed.TotalMilliseconds`** / **`AiMetrics.DurationMs`** are produced. > > Internal call sites in **`TrackDurationOf`** and **`TrackMetricsOf`** no longer cast millisecond values to **`float`** before recording. Unit tests were updated to pass **`double`** literals where they exercise **`TrackDuration`** directly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f6cb49d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
jsonbailey
reviewed
Jul 7, 2026
jsonbailey
approved these changes
Jul 7, 2026
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.

BEGIN_COMMIT_OVERRIDE
feat!: ILdAiConfigTracker.TrackDuration now takes a double instead of a float — custom ILdAiConfigTracker implementations must update their TrackDuration override signature
feat: Extend AiMetrics with optional ToolCalls and DurationMs (duration override)
feat: Extend MetricSummary with accumulated ToolCalls and ResumptionToken
feat: TrackMetricsOf auto-tracks tool calls, honors DurationMs override, and aligns operation-vs-extractor failure semantics with the other SDKs
END_COMMIT_OVERRIDE
Summary
Extends
AiMetrics,MetricSummary, andTrackMetricsOfto bring the .NET AI SDK to parity with the JS, Python, and Java SDKs for metric tracking.AiMetrics— new optional fieldsToolCallscarries tool keys invoked during the operation.DurationMsprovides an explicit duration override — when set,TrackMetricsOfuses it instead of the stopwatch measurement.MetricSummary— new optional fieldsToolCallsaccumulates keys fromTrackToolCallinvocations.ResumptionTokensurfaces the tracker's resumption token on the summary.TrackMetricsOf— tool call auto-tracking & duration overrideTrackMetricsOfnow extractsToolCallsfromAiMetricsand callsTrackToolCallsautomatically. It also honorsDurationMswhen present, falling back to the stopwatch value when null.The error-handling semantics now match the other SDKs: if the operation throws, duration + error are tracked and the exception propagates. If the metrics extractor throws, duration is tracked but error is NOT — the AI operation itself succeeded.
TrackToolCall— accumulates keys on summaryTrackToolCallnow appends to an internal list (lock-guarded) so thatSummary.ToolCallsreflects all tool invocations. The existing per-call$ld:ai:tool_callevent emission is unchanged.Breaking change
ILdAiConfigTracker.TrackDurationnow takes adoubleinstead of afloat:ILdAiConfigTrackeris a public interface. Callers that invokeTrackDuration(...)are unaffected — afloatwidens implicitly todouble. Anyone who implementsILdAiConfigTracker(custom or test trackers) must update their override signature. This aligns the tracker duration type withMetricSummary.DurationMs/TimeToFirstTokenMs(alreadydouble?) and avoids the precision loss of the previous(float)sw.Elapsed.TotalMillisecondscast.Migration
Update any custom
ILdAiConfigTrackerimplementation'sTrackDurationsignature:Before:
After:
No changes are required for code that only calls
TrackDuration,TrackMetricsOf, or uses the SDK-provided tracker.How to test
dotnet test pkgs/sdk/server-ai/test/LaunchDarkly.ServerSdk.Ai.Tests.csproj --framework net8.09 new test cases covering backward compat, new field population, auto tool call tracking, duration override vs. stopwatch fallback, extractor failure semantics, and summary accumulation.
Known limitations
The only breaking change is the
ILdAiConfigTracker.TrackDurationsignature (float→double), which affects custom implementations of the interface — see Migration above. All other changes are additive: existing constructors and call sites compile and behave identically.Note
Medium Risk
Public API break on
ILdAiConfigTracker.TrackDurationaffects custom implementations;TrackMetricsOferror/duration semantics changed in ways that alter emitted metrics for extractor failures.Overview
Brings the .NET server AI SDK’s metric tracking in line with the JS, Python, and Java SDKs.
Breaking:
ILdAiConfigTracker.TrackDurationnow takesdoubleinstead offloat(call sites widen implicitly; custom interface implementations must update). Duration is recorded without casting stopwatch results tofloat.Additive:
AiMetricsgains optionalToolCallsandDurationMs.MetricSummaryadds accumulatedToolCalls(fromTrackToolCall) andResumptionToken.TrackMetricsOfauto-emits tool-call events fromAiMetrics.ToolCalls, usesDurationMswhen set, stops the timer before the extractor so slow extractors don’t inflate duration, and treats operation failures (duration + error) separately from extractor failures (duration only, no generation error).TrackToolCallappends keys under a lock for summary snapshots.Reviewed by Cursor Bugbot for commit 0a17bde. Bugbot is set up for automated code reviews on this repo. Configure here.