Language

TeamsStreamingWriter Class

Definition

Manages the send loop for Teams streaming messages. Callers append raw deltas; the writer accumulates them and sends the full text so far on each update. Every chunk — informative, intermediate, and final — is sent as a new POST with a shared streamId so Teams renders them as a single progressively-updating bubble.

public sealed class TeamsStreamingWriter
type TeamsStreamingWriter = class
Public NotInheritable Class TeamsStreamingWriter
Inheritance
TeamsStreamingWriter

Remarks

Typical usage:

var writer = TeamsStreamingWriter.CreateFromContext(context);
await writer.SendInformativeUpdateAsync("Thinking…"); //optional placeholder while the bot thinks
await writer.AppendResponseAsync(" Hello");
await writer.AppendResponseAsync(", world");
await writer.FinalizeResponseAsync();            // sends accumulated " Hello, world"

To attach entities, attachments, suggested actions, or feedback to the final message, build a MessageActivityInput using its fluent methods and pass it in. If its Text is null the writer fills in the accumulated streamed text.

MessageActivityInput final = new MessageActivityInput()
    .AddAttachment(card)
    .AddEntity(citation)
    .AddFeedback(FeedbackTypes.Default);
await writer.FinalizeResponseAsync(final);

To stream content in a non-default TextFormat (ex. extended markdown), pass the format on the chunk itself: use AppendResponseAsync(MessageActivityInput, CancellationToken) with a TextFormat set, or SendInformativeUpdateAsync(String, TextFormat, CancellationToken) for an informative update. The most recent streamed chunk's format is also used as the final message's format, unless the caller sets TextFormat explicitly on the activity passed to FinalizeResponseAsync(MessageActivityInput, CancellationToken).

await writer.AppendResponseAsync(
    new MessageActivityInput().WithText("- [x] Rendered as extended markdown", TextFormats.ExtendedMarkdown));
await writer.FinalizeResponseAsync();

The writer is reusable: appending or sending an informative update after FinalizeResponseAsync(MessageActivityInput, CancellationToken) reopens the stream on the same instance and starts a new streamed message. Finalizing is idempotent until the next append/informative update.

Streaming errors are surfaced per the Teams streaming error codes: cancellation and the two-minute timeout are handled gracefully (a timed-out stream finalizes by updating the original message in place), while other streaming errors propagate to the caller.

Properties

Name Description
Cancelled

Whether the stream has been cancelled, for example when the user pressed the Stop button.

TimedOut

Whether streaming exceeded the two-minute limit. When true, the final message is sent by updating the original streamed message in place rather than as a streamed chunk.

Methods

Name Description
AppendResponseAsync(MessageActivityInput, CancellationToken)

Appends chunk's Text to the accumulated text and sends the full accumulated text as an intermediate streaming update, rendered with chunk's TextFormat when set.

AppendResponseAsync(String, CancellationToken)

Appends chunk to the accumulated text and sends the full accumulated text as an intermediate streaming update (streamType = "streaming").

CreateFromContext<TActivity>(Context<TActivity>)

Creates a TeamsStreamingWriter bound to the given context.

FinalizeResponseAsync(MessageActivityInput, CancellationToken)

Sends the final streaming activity and marks the stream complete.

SendInformativeUpdateAsync(String, CancellationToken)

Sends an informative placeholder (streamType = "informative"). Optional — if omitted the first AppendResponseAsync(String, CancellationToken) call begins the stream.

SendInformativeUpdateAsync(String, TextFormat, CancellationToken)

Sends an informative placeholder (streamType = "informative") rendered with the given textFormat (ex. extended markdown).

Applies to