| | | 1 | | namespace NexusLabs.Needlr.AgentFramework.Diagnostics; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Strongly-typed bag of optional tags attached to a <see cref="IGenAiTokenMetrics.RecordTokenUsage"/> |
| | | 5 | | /// measurement. Mirrors the tag schema written by MEAI's |
| | | 6 | | /// <see cref="Microsoft.Extensions.AI.OpenTelemetryChatClient"/> on the same |
| | | 7 | | /// <c>gen_ai.client.token.usage</c> histogram so the resulting series share a label set |
| | | 8 | | /// and aggregate cleanly under a single OpenTelemetry <c>MetricStreamIdentity</c>. |
| | | 9 | | /// </summary> |
| | | 10 | | /// <remarks> |
| | | 11 | | /// <para> |
| | | 12 | | /// Any property whose value is <see langword="null"/> is omitted from the recorded measurement. |
| | | 13 | | /// This matches MEAI's behaviour, where MEAI also omits tags whose source data is unavailable. |
| | | 14 | | /// </para> |
| | | 15 | | /// <para> |
| | | 16 | | /// <see cref="ServerPort"/> SHOULD be supplied whenever <see cref="ServerAddress"/> is |
| | | 17 | | /// supplied, matching MEAI's behaviour of always emitting <c>server.port</c> alongside |
| | | 18 | | /// <c>server.address</c> with no scheme-default special-casing. |
| | | 19 | | /// </para> |
| | | 20 | | /// </remarks> |
| | | 21 | | /// <param name="OperationName"> |
| | | 22 | | /// Value for the <c>gen_ai.operation.name</c> tag, or <see langword="null"/> to use the |
| | | 23 | | /// default <c>"chat"</c>. Note: <c>new GenAiTokenUsageTags()</c> (parameterless |
| | | 24 | | /// invocation) yields <see langword="null"/> here even though the primary constructor |
| | | 25 | | /// declares a default — that is the standard C# record-struct behaviour for the |
| | | 26 | | /// implicit parameterless constructor. The implementation substitutes <c>"chat"</c> in |
| | | 27 | | /// either case so callers can use <c>default</c>/<c>new GenAiTokenUsageTags()</c> |
| | | 28 | | /// without surprise. |
| | | 29 | | /// </param> |
| | | 30 | | /// <param name="RequestModel">Value for the <c>gen_ai.request.model</c> tag, or <see langword="null"/> to omit.</param> |
| | | 31 | | /// <param name="ResponseModel">Value for the <c>gen_ai.response.model</c> tag, or <see langword="null"/> to omit.</para |
| | | 32 | | /// <param name="ProviderName">Value for the <c>gen_ai.provider.name</c> tag, or <see langword="null"/> to omit.</param> |
| | | 33 | | /// <param name="ServerAddress">Value for the <c>server.address</c> tag, or <see langword="null"/> to omit.</param> |
| | | 34 | | /// <param name="ServerPort">Value for the <c>server.port</c> tag, or <see langword="null"/> to omit.</param> |
| | | 35 | | public readonly record struct GenAiTokenUsageTags( |
| | 56 | 36 | | string? OperationName = null, |
| | 38 | 37 | | string? RequestModel = null, |
| | 53 | 38 | | string? ResponseModel = null, |
| | 34 | 39 | | string? ProviderName = null, |
| | 40 | 40 | | string? ServerAddress = null, |
| | 6 | 41 | | int? ServerPort = null); |