Skip to content

Python: Foundry hosted agent responses emit failed events#6502

Open
TaoChenOSU wants to merge 1 commit into
mainfrom
feature/python-foundry-hosted-agent-response-emit-failed-events
Open

Python: Foundry hosted agent responses emit failed events#6502
TaoChenOSU wants to merge 1 commit into
mainfrom
feature/python-foundry-hosted-agent-response-emit-failed-events

Conversation

@TaoChenOSU

@TaoChenOSU TaoChenOSU commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Motivation and Context

Previously, if the agent/workflow fails in Foundry Hosted Agent, exceptions will be raised and server error will be returned to users without any detail. Users will have to go to the log stream to figure out what the error is. This is not a great experience.

Description

Instead of the raising exceptions, we now catch the exceptions and emit failed events.

Before:
image

After:
image

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

@TaoChenOSU TaoChenOSU self-assigned this Jun 12, 2026
Copilot AI review requested due to automatic review settings June 12, 2026 22:09
@github-actions github-actions Bot changed the title Foundry hosted agent responses emit failed events Python: Foundry hosted agent responses emit failed events Jun 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/foundry_hosting/agent_framework_foundry_hosting
   _responses.py7838189%186–189, 254, 314–315, 329, 332–333, 381–382, 392, 429, 488, 502, 575, 578, 584, 586, 645, 732–733, 1036, 1049, 1518–1520, 1522, 1569–1570, 1572–1573, 1575–1576, 1578–1579, 1584, 1593, 1596–1598, 1600, 1614, 1627, 1672–1673, 1675, 1680–1684, 1686, 1693–1694, 1696–1697, 1703, 1705–1709, 1716, 1722, 1744, 1750, 1756, 1758, 1760–1763, 1771, 1773, 1824–1826, 1836–1837
TOTAL39733449988% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
7951 34 💤 0 ❌ 0 🔥 2m 8s ⏱️

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Foundry hosted responses handler so that exceptions raised during response creation (both streaming SSE and non-streaming JSON) are surfaced as terminal response.failed events carrying the exception message, rather than bubbling up as generic HTTP 5xx errors.

Changes:

  • Wrap agent/workflow response generation in exception handling that emits response.failed (and drains any active streaming output item first to keep SSE well-formed).
  • Add a shared _emit_failure(...) helper to standardize failure emission behavior.
  • Update and extend tests to assert HTTP 200 with status="failed" and meaningful error.message for failure scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py Emits terminal response.failed on exceptions (streaming + non-streaming), draining any active streaming output item first via a new helper.
python/packages/foundry_hosting/tests/test_responses.py Updates existing assertions away from 5xx and adds new coverage ensuring response.failed emission + error message propagation.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 80% | Result: All clear

Reviewed: Correctness, Test Coverage, Failure Modes, Design Approach


Automated review by TaoChenOSU's agents

@TaoChenOSU TaoChenOSU marked this pull request as ready for review June 12, 2026 23:13

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 3 | Confidence: 81%

✓ Security Reliability

The PR correctly converts raw exceptions into well-formed response.failed protocol events, preserving existing security invariants (path traversal rejection, no filesystem artifacts). The implementation is sound: tracker drainage is defensively wrapped, the stream lifecycle always terminates properly, and exception types are correctly scoped to Exception (not BaseException). The one concern is that str(ex) unconditionally forwards raw exception messages to the client, which could disclose internal infrastructure details (file paths, connection strings) from unexpected library failures, though this is a deliberate design choice with explicit test coverage.

✓ Test Coverage

The PR adds good test coverage for the primary error-surfacing paths (non-streaming, streaming with partial output, workflow agent failures). However, the _emit_failure helper at line 734 has two explicitly coded defensive branches—the empty-message fallback (type(ex).__name__) and the try/except around tracker.close()—that have no corresponding tests. Additionally, the streaming workflow agent failure path in _handle_inner_workflow is exercised only for non-streaming mode in the new test class.

✓ Design Approach

I did not find a design-approach issue that I could support with repo-backed file:line evidence. The new handlers consistently convert agent/workflow exceptions into terminal response.failed events, which matches the new tests in this PR and is also consistent with existing response-failure patterns elsewhere in the repo.

Suggestions

  • Add a test for the empty-message fallback in _emit_failure (e.g., raise a bare RuntimeError() with no message and assert the error message equals the exception type name). This exercises the str(ex) or type(ex).__name__ branch at _responses.py:734.
  • Add a test that verifies when tracker.close() itself raises during failure handling, the original exception's message is still what the client receives (exercises the try/except at _responses.py:730-733).

Automated review by TaoChenOSU's agents

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants