11// Licensed to the .NET Foundation under one or more agreements.
22// The .NET Foundation licenses this file to you under the MIT license.
33
4- using System ;
54using System . Collections . Generic ;
65using System . Diagnostics . CodeAnalysis ;
76using System . Threading ;
87using System . Threading . Tasks ;
98using Microsoft . Shared . Diagnostics ;
109
10+ #pragma warning disable S1121 // Assignments should not be made from within sub-expressions
11+
1112namespace Microsoft . Extensions . AI ;
1213
1314/// <summary>
@@ -25,32 +26,13 @@ public static SpeechToTextResponse ToSpeechToTextResponse(
2526 _ = Throw . IfNull ( updates ) ;
2627
2728 SpeechToTextResponse response = new ( ) ;
28- List < AIContent > contents = [ ] ;
29- string ? responseId = null ;
30- string ? modelId = null ;
31- AdditionalPropertiesDictionary ? additionalProperties = null ;
3229
33- TimeSpan ? endTime = null ;
3430 foreach ( var update in updates )
3531 {
36- // Track the first start time provided by the updates
37- response . StartTime ??= update . StartTime ;
38-
39- // Track the last end time provided by the updates
40- if ( update . EndTime is not null )
41- {
42- endTime = update . EndTime ;
43- }
44-
45- ProcessUpdate ( update , contents , ref responseId , ref modelId , ref additionalProperties ) ;
32+ ProcessUpdate ( update , response ) ;
4633 }
4734
48- ChatResponseExtensions . CoalesceTextContent ( contents ) ;
49- response . EndTime = endTime ;
50- response . Contents = contents ;
51- response . ResponseId = responseId ;
52- response . ModelId = modelId ;
53- response . AdditionalProperties = additionalProperties ;
35+ ChatResponseExtensions . CoalesceTextContent ( ( List < AIContent > ) response . Contents ) ;
5436
5537 return response ;
5638 }
@@ -70,74 +52,73 @@ static async Task<SpeechToTextResponse> ToResponseAsync(
7052 IAsyncEnumerable < SpeechToTextResponseUpdate > updates , CancellationToken cancellationToken )
7153 {
7254 SpeechToTextResponse response = new ( ) ;
73- List < AIContent > contents = [ ] ;
74- string ? responseId = null ;
75- string ? modelId = null ;
76- AdditionalPropertiesDictionary ? additionalProperties = null ;
7755
78- TimeSpan ? endTime = null ;
7956 await foreach ( var update in updates . WithCancellation ( cancellationToken ) . ConfigureAwait ( false ) )
8057 {
81- // Track the first start time provided by the updates
82- response . StartTime ??= update . StartTime ;
83-
84- // Track the last end time provided by the updates
85- if ( update . EndTime is not null )
86- {
87- endTime = update . EndTime ;
88- }
89-
90- ProcessUpdate ( update , contents , ref responseId , ref modelId , ref additionalProperties ) ;
58+ ProcessUpdate ( update , response ) ;
9159 }
9260
93- ChatResponseExtensions . CoalesceTextContent ( contents ) ;
94-
95- response . EndTime = endTime ;
96- response . Contents = contents ;
97- response . ResponseId = responseId ;
98- response . ModelId = modelId ;
99- response . AdditionalProperties = additionalProperties ;
61+ ChatResponseExtensions . CoalesceTextContent ( ( List < AIContent > ) response . Contents ) ;
10062
10163 return response ;
10264 }
10365 }
10466
10567 /// <summary>Processes the <see cref="SpeechToTextResponseUpdate"/>, incorporating its contents and properties.</summary>
10668 /// <param name="update">The update to process.</param>
107- /// <param name="contents">The list of content items being accumulated.</param>
108- /// <param name="responseId">The response ID to update if the update has one.</param>
109- /// <param name="modelId">The model ID to update if the update has one.</param>
110- /// <param name="additionalProperties">The additional properties to update if the update has any.</param>
69+ /// <param name="response">The <see cref="SpeechToTextResponse"/> object that should be updated based on <paramref name="update"/>.</param>
11170 private static void ProcessUpdate (
11271 SpeechToTextResponseUpdate update ,
113- List < AIContent > contents ,
114- ref string ? responseId ,
115- ref string ? modelId ,
116- ref AdditionalPropertiesDictionary ? additionalProperties )
72+ SpeechToTextResponse response )
11773 {
11874 if ( update . ResponseId is not null )
11975 {
120- responseId = update . ResponseId ;
76+ response . ResponseId = update . ResponseId ;
12177 }
12278
12379 if ( update . ModelId is not null )
12480 {
125- modelId = update . ModelId ;
81+ response . ModelId = update . ModelId ;
12682 }
12783
128- contents . AddRange ( update . Contents ) ;
84+ if ( response . StartTime is null || ( update . StartTime is not null && update . StartTime < response . StartTime ) )
85+ {
86+ // Track the first start time provided by the updates
87+ response . StartTime = update . StartTime ;
88+ }
89+
90+ if ( response . EndTime is null || ( update . EndTime is not null && update . EndTime > response . EndTime ) )
91+ {
92+ // Track the last end time provided by the updates
93+ response . EndTime = update . EndTime ;
94+ }
95+
96+ foreach ( var content in update . Contents )
97+ {
98+ switch ( content )
99+ {
100+ // Usage content is treated specially and propagated to the response's Usage.
101+ case UsageContent usage :
102+ ( response . Usage ??= new ( ) ) . Add ( usage . Details ) ;
103+ break ;
104+
105+ default :
106+ response . Contents . Add ( content ) ;
107+ break ;
108+ }
109+ }
129110
130111 if ( update . AdditionalProperties is not null )
131112 {
132- if ( additionalProperties is null )
113+ if ( response . AdditionalProperties is null )
133114 {
134- additionalProperties = new ( update . AdditionalProperties ) ;
115+ response . AdditionalProperties = new ( update . AdditionalProperties ) ;
135116 }
136117 else
137118 {
138119 foreach ( var entry in update . AdditionalProperties )
139120 {
140- additionalProperties [ entry . Key ] = entry . Value ;
121+ response . AdditionalProperties [ entry . Key ] = entry . Value ;
141122 }
142123 }
143124 }
0 commit comments