Description
ResponsesHostServer drops oauth_consent_request content that an agent produces mid-run (after the agent has already been entered), so the consent link never reaches the client.
This is distinct from #3950, which fixed the chat client hop (agent_framework_foundry._oauth_helpers.try_parse_oauth_consent_event now turns an upstream response.oauth_consent_requested event into Content.from_oauth_consent_request(...)). Users who upgraded per #3950 and run behind agent-framework-foundry-hosting still see the failure, because the content is dropped one layer later.
It is also distinct from #7227, which is about the parsing of connect-time gateway errors (type: a2a_preview vs mcp). Here the consent content is parsed correctly and still never surfaces.
Steps to reproduce
- Host an agent with
ResponsesHostServer whose toolbox includes an on-behalf-of (OBO) MCP server that requires a per-user token.
- Invoke the agent as a user who has not yet completed delegated OAuth authorization. The server connects fine, so consent is raised at tool-invocation time rather than at connect time.
Actual behavior
The host logs:
WARNING:agent_framework_foundry_hosting._responses:Content type 'oauth_consent_request' is not supported yet. This is usually safe to ignore.
The response ends as completed with no oauth_consent_request output item, so the client (e.g. Teams) renders an empty assistant turn and no consent card.
Expected behavior
The host should emit a client-visible output item:
{
"type": "oauth_consent_request",
"server_label": "<tool/server label>",
"consent_link": "https://<consent-url>"
}
and end the response as incomplete (the turn cannot finish until the user consents), matching what the host already does for connect-time consent failures.
Root cause
In agent_framework_foundry_hosting/_responses.py, _to_outputs has branches for text, reasoning, function call/result, image generation, MCP call/result, shell call/result, and function_approval_request — but none for oauth_consent_request. The content therefore falls into the catch-all else and is logged and discarded.
Two supporting observations that this is an oversight rather than a design decision:
- The inbound direction is already implemented:
_output_item_to_message converts an oauth_consent_request output item back into Content.from_oauth_consent_request(...). The outbound half has no counterpart.
- The host already knows how to emit the item, but only in
_handle_inner_agent's connect-time path, when _ensure_agent_ready() raises and consent_url_from_error finds a consent URL. An OBO server that needs a token per tool call never goes through that path.
- Other hosts handle this content type:
agent_framework_ag_ui/_run_common.py emits a custom oauth_consent_request event for it.
Package versions
Reported against:
agent-framework-core==1.13.0
agent-framework-foundry==1.10.4
agent-framework-foundry-hosting==1.0.0b260730
Related issues
Description
ResponsesHostServerdropsoauth_consent_requestcontent that an agent produces mid-run (after the agent has already been entered), so the consent link never reaches the client.This is distinct from #3950, which fixed the chat client hop (
agent_framework_foundry._oauth_helpers.try_parse_oauth_consent_eventnow turns an upstreamresponse.oauth_consent_requestedevent intoContent.from_oauth_consent_request(...)). Users who upgraded per #3950 and run behindagent-framework-foundry-hostingstill see the failure, because the content is dropped one layer later.It is also distinct from #7227, which is about the parsing of connect-time gateway errors (
type: a2a_previewvsmcp). Here the consent content is parsed correctly and still never surfaces.Steps to reproduce
ResponsesHostServerwhose toolbox includes an on-behalf-of (OBO) MCP server that requires a per-user token.Actual behavior
The host logs:
The response ends as
completedwith nooauth_consent_requestoutput item, so the client (e.g. Teams) renders an empty assistant turn and no consent card.Expected behavior
The host should emit a client-visible output item:
{ "type": "oauth_consent_request", "server_label": "<tool/server label>", "consent_link": "https://<consent-url>" }and end the response as
incomplete(the turn cannot finish until the user consents), matching what the host already does for connect-time consent failures.Root cause
In
agent_framework_foundry_hosting/_responses.py,_to_outputshas branches for text, reasoning, function call/result, image generation, MCP call/result, shell call/result, andfunction_approval_request— but none foroauth_consent_request. The content therefore falls into the catch-allelseand is logged and discarded.Two supporting observations that this is an oversight rather than a design decision:
_output_item_to_messageconverts anoauth_consent_requestoutput item back intoContent.from_oauth_consent_request(...). The outbound half has no counterpart._handle_inner_agent's connect-time path, when_ensure_agent_ready()raises andconsent_url_from_errorfinds a consent URL. An OBO server that needs a token per tool call never goes through that path.agent_framework_ag_ui/_run_common.pyemits a customoauth_consent_requestevent for it.Package versions
Reported against:
agent-framework-core==1.13.0agent-framework-foundry==1.10.4agent-framework-foundry-hosting==1.0.0b260730Related issues
a2a_previewsources