microsoft / microsoft/agent-framework

.NET: [Bug]: CopilotStudioAgent drops message activities during streaming

Open
#7,736 0 comments 0 reactions 1 assignee View on GitHub

@javiercn is already working on this.

Since Aug 19, 2026.

.NET
Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
2d 45m
Merged PRs (30d)
358

Description

Description

Microsoft.Agents.AI.CopilotStudio.ActivityProcessor currently exposes activity text only when:

activity.Type == "message" && !streaming
activity.Type == "typing" && streaming

Copilot Studio can return a final message activity while CopilotStudioAgent.RunStreamingAsync is active. That valid activity is discarded before an AgentResponseUpdate is created, so callers cannot observe its text, suggested actions, metadata, or raw provider representation.

This is a provider-adapter issue independent of any protocol integration. Once an activity is dropped inside CopilotStudioAgent, an application, delegating agent, or protocol mapper cannot recover it.

Expected behavior:

  1. Every Copilot Studio IActivity is exposed through AgentResponseUpdate.RawRepresentation, even when there is no default MEAI content mapping.
  2. Existing default text behavior remains available for recognized activity types.
  3. Applications can provide an optional mapping delegate for provider-specific activity semantics.
  4. Suggested actions, cards, progress, and custom activities can be mapped without changes to CopilotStudioAgent internals.
  5. The mapping contract lets applications control deduplication between streaming typing activities and a final message activity.
  6. Activity identity, author, timestamp, additional properties, and raw representation are preserved.

A possible extension point is:

public sealed class CopilotStudioAgentOptions
{
    public Func<IActivity, IEnumerable<AIContent>?>? ActivityMapper
    {
        get;
        init;
    }
}

The adapter should always preserve the original activity:

IEnumerable<AIContent> contents =
    options.ActivityMapper?.Invoke(activity)
    ?? DefaultMapActivity(activity);

yield return new AgentResponseUpdate(
    ChatRole.Assistant,
    contents.ToList())
{
    AuthorName = activity.From?.Name,
    CreatedAt = activity.Timestamp,
    MessageId = activity.Id,
    RawRepresentation = activity,
};

An application can then use AIAgent.AsBuilder() or a DelegatingAIAgent to replace raw activity updates with application-specific text, activity, interaction, or protocol events without duplicating the original update.

Code Sample
await foreach (AgentResponseUpdate update in
    innerAgent.RunStreamingAsync(messages, session, options, cancellationToken))
{
    if (update.RawRepresentation is not IActivity activity)
    {
        yield return update;
        continue;
    }

    foreach (AgentResponseUpdate mapped in MapActivity(activity))
    {
        yield return mapped;
    }
}
Error Messages / Stack Traces

No exception is produced. The streaming message activity is logged as an unknown activity type and omitted from the returned update stream.

Package Versions

Current main versions of Microsoft.Agents.AI.CopilotStudio and Microsoft.Agents.CopilotStudio.Client.

.NET Version

.NET 8, 9, and 10

Additional Context

The existing AG-UI issue exposed the symptom because an empty provider update stream produced only run lifecycle events. The underlying defect is the Copilot Studio activity-to-Agent Framework mapping, not AG-UI.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.