diff --git a/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py b/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py index 022bebbe2b..786754f3da 100644 --- a/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py +++ b/python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py @@ -32,7 +32,6 @@ from azure.ai.agentserver.responses import ( ResponseProviderProtocol, ResponsesServerOptions, ) -from azure.ai.agentserver.responses._id_generator import IdGenerator from azure.ai.agentserver.responses.hosting import ResponsesAgentServerHost from azure.ai.agentserver.responses.models import ( ApplyPatchToolCallItemParam, @@ -432,14 +431,22 @@ class ResponsesHostServer(ResponsesAgentServerHost): except Exception as ex: if consent_url := is_consent_error(ex): logger.warning("OAuth consent required for Foundry MCP gateway.") - oauth_item = OAuthConsentRequestOutputItem( - id=IdGenerator.new_id("oacr", ""), - consent_link=consent_url, - server_label="Foundry Toolbox", - ) - builder = response_event_stream.add_output_item(oauth_item.id) - yield builder.emit_added(oauth_item) - yield builder.emit_done(oauth_item) + # oauth_item = OAuthConsentRequestOutputItem( + # id=IdGenerator.new_id("oacr"), + # consent_link=consent_url, + # server_label="Foundry Toolbox", + # ) + # builder = response_event_stream.add_output_item(oauth_item.id) + # yield builder.emit_added(oauth_item) + # yield builder.emit_done(oauth_item) + message_item = response_event_stream.add_output_item_message() + yield message_item.emit_added() + for event in message_item.text_content( + f"OAuth consent is required before this agent's tools can be used. " + f"Please open the following URL in a browser to authorize access: {consent_url}" + ): + yield event + yield message_item.emit_done() yield response_event_stream.emit_completed() return else: @@ -462,6 +469,7 @@ class ResponsesHostServer(ResponsesAgentServerHost): approval_storage=self._approval_storage, ): yield item + yield response_event_stream.emit_completed() else: if tracker is None: # pragma: no cover - defensive, set above raise RuntimeError("Streaming tracker was not initialized.") @@ -482,6 +490,7 @@ class ResponsesHostServer(ResponsesAgentServerHost): # Close any remaining active builder for event in tracker.close(): yield event + yield response_event_stream.emit_completed() except Exception: # Drain any in-progress streaming builder before emitting consent # so the resulting stream stays well-formed.