Skip to content

Commit b65636a

Browse files
author
Tracy Boehrer
committed
Handle Teams cancel of StreamingResponse
1 parent bf89b87 commit b65636a

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

src/libraries/Builder/Microsoft.Agents.Builder/StreamingResponse.cs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using Microsoft.Agents.Builder.Errors;
55
using Microsoft.Agents.Core;
6+
using Microsoft.Agents.Core.Errors;
67
using Microsoft.Agents.Core.Models;
78
using System;
89
using System.Collections.Generic;
@@ -40,13 +41,16 @@ internal class StreamingResponse : IStreamingResponse
4041
{
4142
public static readonly int DefaultEndStreamTimeout = (int)TimeSpan.FromMinutes(2).TotalMilliseconds;
4243

44+
private const string TeamsStreamCancelled = "ContentStreamNotAllowed";
45+
4346
private readonly TurnContext _context;
4447
private int _nextSequence = 1;
4548
private bool _ended = false;
4649
private Timer _timer;
4750
private bool _messageUpdated = false;
4851
private bool _informativeSent = false;
4952
private bool _isTeamsChannel;
53+
private bool _cancelled;
5054

5155
// Queue for outgoing activities
5256
private readonly List<Func<IActivity>> _queue = [];
@@ -211,7 +215,7 @@ public async Task QueueInformativeUpdateAsync(string text, CancellationToken can
211215
/// <exception cref="System.InvalidOperationException">Throws if the stream has already ended.</exception>
212216
public void QueueTextChunk(string text)
213217
{
214-
if (string.IsNullOrEmpty(text))
218+
if (string.IsNullOrEmpty(text) || _cancelled)
215219
{
216220
return;
217221
}
@@ -264,7 +268,7 @@ public async Task EndStreamAsync(CancellationToken cancellationToken = default)
264268
}
265269

266270
// Timer isn't running for non-streaming channels. Just send the Message buffer as a message.
267-
if (!string.IsNullOrWhiteSpace(Message) || FinalMessage != null)
271+
if (UpdatesSent() > 0 || FinalMessage != null)
268272
{
269273
await _context.SendActivityAsync(CreateFinalMessage(), cancellationToken).ConfigureAwait(false);
270274
}
@@ -280,7 +284,7 @@ public async Task EndStreamAsync(CancellationToken cancellationToken = default)
280284

281285
_ended = true;
282286

283-
if (UpdatesSent() == 0)
287+
if (UpdatesSent() == 0 || _cancelled)
284288
{
285289
// nothing was queued. nothing to "end".
286290
return;
@@ -312,7 +316,7 @@ private IActivity CreateFinalMessage()
312316
var activity = FinalMessage ?? new Activity();
313317

314318
activity.Type = ActivityTypes.Message;
315-
activity.Text = !string.IsNullOrEmpty(Message) ? Message : "No text was streamed"; // Teams won't allow Activity.Text changes or empty text
319+
activity.Text = Message; // !string.IsNullOrEmpty(Message) ? Message : "No text was streamed"; // Teams won't allow Activity.Text changes or empty text
316320
activity.Entities ??= [];
317321

318322
// make sure the supplied Activity doesn't have a streamInfo already.
@@ -325,7 +329,7 @@ private IActivity CreateFinalMessage()
325329
}
326330
}
327331

328-
activity.Entities.Add(new StreamInfo() { StreamType = StreamTypes.Final });
332+
activity.Entities.Add(new StreamInfo() { StreamType = StreamTypes.Final, StreamResult = (string.IsNullOrEmpty(Message) ? StreamResults.Error : StreamResults.Success) });
329333

330334
// Add in Generated by AI
331335
if (EnableGeneratedByAILabel == true)
@@ -367,6 +371,7 @@ public async Task ResetAsync(CancellationToken cancellationToken = default)
367371
FinalMessage = null;
368372
_nextSequence = 1;
369373
StreamId = null;
374+
_cancelled = false;
370375
}
371376
}
372377

@@ -527,11 +532,29 @@ private async Task SendActivityAsync(IActivity activity, CancellationToken cance
527532
activity.GetStreamingEntity().StreamId = StreamId;
528533
}
529534

530-
var response = await _context.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false);
531-
532-
if (string.IsNullOrEmpty(StreamId))
535+
try
536+
{
537+
var response = await _context.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false);
538+
if (string.IsNullOrEmpty(StreamId))
539+
{
540+
StreamId = response.Id;
541+
}
542+
}
543+
catch (ErrorResponseException ex)
533544
{
534-
StreamId = response.Id;
545+
lock (this)
546+
{
547+
StopStream();
548+
549+
if (TeamsStreamCancelled.Equals(ex.Body.Error.Code, StringComparison.OrdinalIgnoreCase))
550+
{
551+
_cancelled = true;
552+
}
553+
else
554+
{
555+
throw;
556+
}
557+
}
535558
}
536559
}
537560
}

0 commit comments

Comments
 (0)