diff --git a/dotnet/nuget/nuget-package.props b/dotnet/nuget/nuget-package.props index 6d1c657fa8..2cbd1356bc 100644 --- a/dotnet/nuget/nuget-package.props +++ b/dotnet/nuget/nuget-package.props @@ -8,7 +8,7 @@ $(VersionPrefix)-preview.260402.1 $(VersionPrefix) - 0.9.0-hosted.260403.1 + 0.9.0-hosted.260403.2 1.0.0 Debug;Release;Publish diff --git a/dotnet/samples/04-hosting/FoundryResponsesHosting/FoundryResponsesHosting.csproj b/dotnet/samples/04-hosting/FoundryResponsesHosting/FoundryResponsesHosting.csproj index 3dfab4ad48..269754203d 100644 --- a/dotnet/samples/04-hosting/FoundryResponsesHosting/FoundryResponsesHosting.csproj +++ b/dotnet/samples/04-hosting/FoundryResponsesHosting/FoundryResponsesHosting.csproj @@ -6,7 +6,7 @@ enable enable false - $(NoWarn);NU1903;NU1605 + $(NoWarn);NU1903;NU1605;MAAIW001 diff --git a/dotnet/src/Microsoft.Agents.AI.Foundry/Hosting/AgentFrameworkResponseHandler.cs b/dotnet/src/Microsoft.Agents.AI.Foundry/Hosting/AgentFrameworkResponseHandler.cs index 3423a0b4a3..eaacbc67a3 100644 --- a/dotnet/src/Microsoft.Agents.AI.Foundry/Hosting/AgentFrameworkResponseHandler.cs +++ b/dotnet/src/Microsoft.Agents.AI.Foundry/Hosting/AgentFrameworkResponseHandler.cs @@ -95,6 +95,7 @@ public class AgentFrameworkResponseHandler : ResponseHandler while (true) { bool shutdownDetected = false; + ResponseStreamEvent? failedEvent = null; ResponseStreamEvent? evt = null; try { @@ -109,6 +110,26 @@ public class AgentFrameworkResponseHandler : ResponseHandler { shutdownDetected = true; } + catch (Exception ex) when (ex is not OperationCanceledException && !emittedTerminal) + { + // Catch agent execution errors and emit a proper failed event + // with the real error message instead of letting the SDK emit + // a generic "An internal server error occurred." + if (this._logger.IsEnabled(LogLevel.Error)) + { + this._logger.LogError(ex, "Agent execution failed for response {ResponseId}.", context.ResponseId); + } + + failedEvent = stream.EmitFailed( + ResponseErrorCode.ServerError, + ex.Message); + } + + if (failedEvent is not null) + { + yield return failedEvent; + yield break; + } if (shutdownDetected) { diff --git a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/AgentFrameworkResponseHandlerTests.cs b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/AgentFrameworkResponseHandlerTests.cs index dc38c42739..b1bdd31916 100644 --- a/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/AgentFrameworkResponseHandlerTests.cs +++ b/dotnet/tests/Microsoft.Agents.AI.Foundry.UnitTests/Hosting/AgentFrameworkResponseHandlerTests.cs @@ -538,7 +538,7 @@ public class AgentFrameworkResponseHandlerTests } [Fact] - public async Task CreateAsync_AgentThrows_ExceptionPropagates() + public async Task CreateAsync_AgentThrows_EmitsFailedEventWithErrorMessage() { // Arrange var agent = new ThrowingAgent(new InvalidOperationException("Agent crashed")); @@ -561,13 +561,18 @@ public class AgentFrameworkResponseHandlerTests mockContext.Setup(x => x.GetInputItemsAsync(It.IsAny())) .ReturnsAsync(Array.Empty()); - // Act & Assert - await Assert.ThrowsAsync(async () => + // Act — collect all events + var events = new List(); + await foreach (var evt in handler.CreateAsync(request, mockContext.Object, CancellationToken.None)) { - await foreach (var _ in handler.CreateAsync(request, mockContext.Object, CancellationToken.None)) - { - } - }); + events.Add(evt); + } + + // Assert — should contain created, in_progress, and failed (with real error message) + Assert.Contains(events, e => e is ResponseCreatedEvent); + Assert.Contains(events, e => e is ResponseInProgressEvent); + var failedEvent = Assert.Single(events.OfType()); + Assert.Contains("Agent crashed", failedEvent.Response.Error.Message); } [Fact]