Foundry Playground only receives 3 SSE events from custom IChatClient hosted agents — even with hardcoded responses
Bug Description
When deploying a custom hosted agent using Azure.AI.AgentServer.AgentFramework with a custom IChatClient implementation, the Azure AI Foundry playground only receives 3 SSE events before the stream appears to terminate:
response.created
response.in_progress
response.output_item.added — with status: "completed" and content: []
All subsequent events (content_part.added, output_text.delta, content_part.done, output_item.done, response.completed) are never received by the browser, even though server-side logs confirm the agent produces them correctly.
Reproduction
Minimal IChatClient (50 lines, no external dependencies)
using System.Runtime.CompilerServices;
using Microsoft.Extensions.AI;
namespace LibreChatAgent;
public sealed class SimpleChatClient : IChatClient
{
public ChatClientMetadata Metadata => new("SimpleTest");
public object? GetService(Type serviceType, object? serviceKey = null)
{
if (serviceKey is null && serviceType?.IsInstanceOfType(this) == true)
return this;
return null;
}
public Task<ChatResponse> GetResponseAsync(
IEnumerable<ChatMessage> chatMessages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
{
return Task.FromResult(
new ChatResponse([new ChatMessage(ChatRole.Assistant, "Hello from SimpleAgent!")]));
}
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
IEnumerable<ChatMessage> chatMessages,
ChatOptions? options = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var words = new[] { "Hello ", "from ", "Simple", "Agent!" };
foreach (var word in words)
{
yield return new ChatResponseUpdate
{
Role = ChatRole.Assistant,
Contents = [new TextContent(word)]
};
await Task.Delay(50, cancellationToken);
}
}
public void Dispose() { }
}
Program.cs (matches official sample pattern exactly)
using Azure.AI.AgentServer.AgentFramework.Extensions;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
IChatClient chatClient = new LibreChatAgent.SimpleChatClient()
.AsBuilder()
.Build();
var agent = new ChatClientAgent(chatClient, name: "LibreChatAgent")
.AsBuilder()
.Build();
await agent.RunAIAgentAsync(telemetrySourceName: "LibreChatAgent");
agent.yaml
kind: hosted
name: LibreChatAgent
description: Minimal test agent
protocols:
- protocol: responses
version: v1
Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
COPY src/LibreChatAgent/ .
RUN dotnet restore
RUN dotnet build -c Release --no-restore
RUN dotnet publish -c Release --no-build -o /app
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
WORKDIR /app
COPY --from=build /app .
EXPOSE 8088
ENTRYPOINT ["dotnet", "LibreChatAgent.dll"]
.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.AgentServer.AgentFramework" Version="1.0.0-beta.11" />
</ItemGroup>
</Project>
What happens locally
When tested locally via curl http://localhost:8088/responses, the agent produces all 11 SSE events correctly:
event: response.created
event: response.in_progress
event: response.output_item.added
event: content_part.added
event: output_text.delta (x4, one per word)
event: content_part.done
event: output_item.done
event: response.completed
The response completes in ~200ms with the full text "Hello from SimpleAgent!".
What happens in the Foundry playground
The browser's EventSource receives only 3 events, then the stream ends:
// Event 1: response.created
{"id":"...","object":"response","status":"in_progress",...}
// Event 2: response.in_progress
{"id":"...","object":"response","status":"in_progress",...}
// Event 3: response.output_item.added
{"id":"...","object":"response","status":"completed","output":[{"type":"message","status":"completed","content":[]}],...}
Note the suspicious "status": "completed" and "content": [] in the 3rd event. The response is marked as completed with no content before any text deltas arrive.
What we've ruled out
| Hypothesis |
Test |
Result |
| Issue in our backend (LibreChat) |
Replaced with hardcoded SimpleChatClient above |
Same 3 events |
| Framework version mismatch |
Tested both beta.10 (matching official sample) and beta.11 |
Same 3 events |
| Docker base image issue |
Tested both Alpine and standard images |
Same 3 events |
Missing .AsBuilder().Build() |
Added wrapping on both IChatClient and ChatClientAgent |
Same 3 events |
| Streaming timing/delays |
Tested burst mode (no delays), keepalive mode, various delays |
Same 3 events |
ASPNETCORE_URLS or env vars |
Removed all custom env vars |
Same 3 events |
Environment
- Region: Sweden Central
- Framework:
Azure.AI.AgentServer.AgentFramework v1.0.0-beta.11 (also tested beta.10)
- Runtime: .NET 10
- Protocol: Responses v1
- Deployed via:
azd deploy (tested versions 31–37)
- Official sample reference:
scenario-1-intro/src/time-zone-agent
Key Observation
The official time-zone-agent sample uses AzureOpenAIClient as the IChatClient, which delegates to an Azure OpenAI model deployment. This means the framework's SSE-to-Responses translation path for Azure OpenAI models may work, but the path for custom IChatClient implementations that generate their own streaming updates appears broken.
The output_item.added event arriving with status: "completed" suggests the Foundry gateway or the ItemResourceGenerator in the framework is prematurely marking the response as complete before consuming the streaming output from GetStreamingResponseAsync.
Expected Behavior
All SSE events generated by the framework should be forwarded to the playground browser, including text deltas and completion events. The agent should display "Hello from SimpleAgent!" in the playground chat.
Actual Behavior
Only 3 events arrive. The playground shows an empty response or no visible text content.
Foundry Playground only receives 3 SSE events from custom IChatClient hosted agents — even with hardcoded responses
Bug Description
When deploying a custom hosted agent using
Azure.AI.AgentServer.AgentFrameworkwith a customIChatClientimplementation, the Azure AI Foundry playground only receives 3 SSE events before the stream appears to terminate:response.createdresponse.in_progressresponse.output_item.added— withstatus: "completed"andcontent: []All subsequent events (
content_part.added,output_text.delta,content_part.done,output_item.done,response.completed) are never received by the browser, even though server-side logs confirm the agent produces them correctly.Reproduction
Minimal IChatClient (50 lines, no external dependencies)
Program.cs (matches official sample pattern exactly)
agent.yaml
Dockerfile
.csproj
What happens locally
When tested locally via
curl http://localhost:8088/responses, the agent produces all 11 SSE events correctly:The response completes in ~200ms with the full text "Hello from SimpleAgent!".
What happens in the Foundry playground
The browser's EventSource receives only 3 events, then the stream ends:
Note the suspicious
"status": "completed"and"content": []in the 3rd event. The response is marked as completed with no content before any text deltas arrive.What we've ruled out
SimpleChatClientabovebeta.10(matching official sample) andbeta.11.AsBuilder().Build()IChatClientandChatClientAgentASPNETCORE_URLSor env varsEnvironment
Azure.AI.AgentServer.AgentFrameworkv1.0.0-beta.11 (also tested beta.10)azd deploy(tested versions 31–37)scenario-1-intro/src/time-zone-agentKey Observation
The official
time-zone-agentsample usesAzureOpenAIClientas theIChatClient, which delegates to an Azure OpenAI model deployment. This means the framework's SSE-to-Responses translation path for Azure OpenAI models may work, but the path for customIChatClientimplementations that generate their own streaming updates appears broken.The
output_item.addedevent arriving withstatus: "completed"suggests the Foundry gateway or theItemResourceGeneratorin the framework is prematurely marking the response as complete before consuming the streaming output fromGetStreamingResponseAsync.Expected Behavior
All SSE events generated by the framework should be forwarded to the playground browser, including text deltas and completion events. The agent should display "Hello from SimpleAgent!" in the playground chat.
Actual Behavior
Only 3 events arrive. The playground shows an empty response or no visible text content.