@@ -125,10 +125,10 @@ public async Task SendAsync(
125
125
if ( functionParts . Count > 0 )
126
126
{
127
127
Dictionary < string , object > toolResponse = new ( ) {
128
- { "toolResponse" , new Dictionary < string , object > ( ) {
129
- { "functionResponses" , functionParts . Select ( frPart => ( frPart as ModelContent . Part ) . ToJson ( ) [ "functionResponse" ] ) . ToList ( ) }
130
- } }
131
- } ;
128
+ { "toolResponse" , new Dictionary < string , object > ( ) {
129
+ { "functionResponses" , functionParts . Select ( frPart => ( frPart as ModelContent . Part ) . ToJson ( ) [ "functionResponse" ] ) . ToList ( ) }
130
+ } }
131
+ } ;
132
132
var toolResponseBytes = Encoding . UTF8 . GetBytes ( Json . Serialize ( toolResponse ) ) ;
133
133
134
134
await InternalSendBytesAsync ( new ArraySegment < byte > ( toolResponseBytes ) , cancellationToken ) ;
@@ -147,15 +147,15 @@ public async Task SendAsync(
147
147
148
148
// Prepare the message payload
149
149
Dictionary < string , object > contentDict = new ( ) {
150
- { "turnComplete" , turnComplete }
151
- } ;
150
+ { "turnComplete" , turnComplete }
151
+ } ;
152
152
if ( content . HasValue )
153
153
{
154
154
contentDict [ "turns" ] = new List < object > ( new [ ] { content ? . ToJson ( ) } ) ;
155
155
}
156
156
Dictionary < string , object > jsonDict = new ( ) {
157
- { "clientContent" , contentDict }
158
- } ;
157
+ { "clientContent" , contentDict }
158
+ } ;
159
159
var byteArray = Encoding . UTF8 . GetBytes ( Json . Serialize ( jsonDict ) ) ;
160
160
161
161
await InternalSendBytesAsync ( new ArraySegment < byte > ( byteArray ) , cancellationToken ) ;
@@ -166,23 +166,84 @@ public async Task SendAsync(
166
166
/// </summary>
167
167
/// <param name="mediaChunks">A list of media chunks to send.</param>
168
168
/// <param name="cancellationToken">A token to cancel the send operation.</param>
169
+ /// <remarks>
170
+ /// Use SendAudioRealtimeAsync, SendVideoRealtimeAsync, or SendTextRealtimeAsync instead.
171
+ /// </remarks>
172
+ /// @deprecated Use SendAudioRealtimeAsync, SendVideoRealtimeAsync, or SendTextRealtimeAsync instead.
173
+ [ Obsolete ( "Use SendAudioRealtimeAsync, SendVideoRealtimeAsync, or SendTextRealtimeAsync instead." ) ]
169
174
public async Task SendMediaChunksAsync (
170
175
List < ModelContent . InlineDataPart > mediaChunks ,
171
176
CancellationToken cancellationToken = default )
172
177
{
173
178
if ( mediaChunks == null ) return ;
174
179
180
+ await InternalSendRealtimeInputAsync ( "mediaChunks" ,
181
+ mediaChunks . Select ( mc => ( mc as ModelContent . Part ) . ToJson ( ) [ "inlineData" ] ) . ToList ( ) ,
182
+ cancellationToken ) ;
183
+ }
184
+
185
+ /// <summary>
186
+ /// Sends text data to the server in realtime.
187
+ ///
188
+ /// Check https://ai.google.dev/api/live#bidigeneratecontentrealtimeinput for
189
+ /// details about the realtime input usage.
190
+ /// </summary>
191
+ /// <param name="text">The text data to send.</param>
192
+ /// <param name="cancellationToken">A token to cancel the send operation.</param>
193
+ public async Task SendTextRealtimeAsync (
194
+ string text ,
195
+ CancellationToken cancellationToken = default )
196
+ {
197
+ if ( string . IsNullOrEmpty ( text ) ) return ;
198
+
199
+ await InternalSendRealtimeInputAsync ( "text" , text , cancellationToken ) ;
200
+ }
201
+
202
+ /// <summary>
203
+ /// Sends audio data to the server in realtime.
204
+ ///
205
+ /// Check https://ai.google.dev/api/live#bidigeneratecontentrealtimeinput for
206
+ /// details about the realtime input usage.
207
+ /// </summary>
208
+ /// <param name="audio">The audio data to send.</param>
209
+ /// <param name="cancellationToken">A token to cancel the send operation.</param>
210
+ public async Task SendAudioRealtimeAsync (
211
+ ModelContent . InlineDataPart audio ,
212
+ CancellationToken cancellationToken = default )
213
+ {
214
+ await InternalSendRealtimeInputAsync ( "audio" ,
215
+ ( audio as ModelContent . Part ) . ToJson ( ) [ "inlineData" ] , cancellationToken ) ;
216
+ }
217
+
218
+ /// <summary>
219
+ /// Sends video data to the server in realtime.
220
+ ///
221
+ /// Check https://ai.google.dev/api/live#bidigeneratecontentrealtimeinput for
222
+ /// details about the realtime input usage.
223
+ /// </summary>
224
+ /// <param name="video">The video data to send.</param>
225
+ /// <param name="cancellationToken">A token to cancel the send operation.</param>
226
+ public async Task SendVideoRealtimeAsync (
227
+ ModelContent . InlineDataPart video ,
228
+ CancellationToken cancellationToken = default )
229
+ {
230
+ await InternalSendRealtimeInputAsync ( "video" ,
231
+ ( video as ModelContent . Part ) . ToJson ( ) [ "inlineData" ] , cancellationToken ) ;
232
+ }
233
+
234
+ private async Task InternalSendRealtimeInputAsync (
235
+ string key , object data , CancellationToken cancellationToken )
236
+ {
175
237
// Prepare the message payload.
176
238
Dictionary < string , object > jsonDict = new ( ) {
177
- {
178
- "realtimeInput" , new Dictionary < string , object > ( ) {
179
- {
180
- // InlineDataPart inherits from Part, so this conversion should be safe.
181
- "mediaChunks" , mediaChunks . Select ( mc => ( mc as ModelContent . Part ) . ToJson ( ) [ "inlineData" ] ) . ToList ( )
239
+ {
240
+ "realtimeInput" , new Dictionary < string , object > ( ) {
241
+ {
242
+ key , data
243
+ }
182
244
}
183
245
}
184
- }
185
- } ;
246
+ } ;
186
247
var byteArray = Encoding . UTF8 . GetBytes ( Json . Serialize ( jsonDict ) ) ;
187
248
188
249
await InternalSendBytesAsync ( new ArraySegment < byte > ( byteArray ) , cancellationToken ) ;
@@ -214,7 +275,7 @@ private static byte[] ConvertTo16BitPCM(float[] samples)
214
275
public Task SendAudioAsync ( float [ ] audioData , CancellationToken cancellationToken = default )
215
276
{
216
277
ModelContent . InlineDataPart inlineDataPart = new ( "audio/pcm" , ConvertTo16BitPCM ( audioData ) ) ;
217
- return SendMediaChunksAsync ( new List < ModelContent . InlineDataPart > ( new [ ] { inlineDataPart } ) , cancellationToken ) ;
278
+ return SendAudioRealtimeAsync ( inlineDataPart , cancellationToken ) ;
218
279
}
219
280
220
281
/// <summary>
0 commit comments