diff --git a/python/packages/core/agent_framework/_agents.py b/python/packages/core/agent_framework/_agents.py index 3aaf9f1419..3276698d09 100644 --- a/python/packages/core/agent_framework/_agents.py +++ b/python/packages/core/agent_framework/_agents.py @@ -51,7 +51,7 @@ map_chat_to_agent_update, normalize_messages, ) -from .exceptions import AgentInvalidResponseException +from .exceptions import AgentInvalidResponseException, OAuthConsentRequiredException from .observability import AgentTelemetryLayer if sys.version_info >= (3, 13): @@ -532,11 +532,25 @@ async def agent_wrapper(**kwargs: Any) -> str: if stream_callback is None: # Use non-streaming mode - return (await self.run(input_text, stream=False, session=parent_session, **forwarded_kwargs)).text + response = await self.run(input_text, stream=False, session=parent_session, **forwarded_kwargs) + # Check for OAuth consent request in response + for content in response.contents: + if content.type == 'oauth_consent_request': + consent_url = content.get('consent_link') or content.get('url') or '' + from .exceptions import OAuthConsentRequiredException + raise OAuthConsentRequiredException(consent_url) + return response.text # Use streaming mode - accumulate updates and create final response response_updates: list[AgentResponseUpdate] = [] async for update in self.run(input_text, stream=True, session=parent_session, **forwarded_kwargs): + # Check for OAuth consent request in update + for content in update.contents: + if content.type == 'oauth_consent_request': + consent_url = content.get('consent_link') or content.get('url') or '' + from .exceptions import OAuthConsentRequiredException + raise OAuthConsentRequiredException(consent_url) + response_updates.append(update) if is_async_callback: await stream_callback(update) # type: ignore[misc] diff --git a/python/packages/core/agent_framework/exceptions.py b/python/packages/core/agent_framework/exceptions.py index f38aa38590..7560da3ca5 100644 --- a/python/packages/core/agent_framework/exceptions.py +++ b/python/packages/core/agent_framework/exceptions.py @@ -204,6 +204,46 @@ class SettingNotFoundError(AgentFrameworkException): # endregion + + +class OAuthConsentRequiredException(AgentException): + """Raised when a sub-agent tool requires OAuth consent. + + This exception is raised by as_tool() when a wrapped agent returns + an oauth_consent_request event. The parent agent should catch this + exception and forward the consent request to the user. + + Attributes: + consent_url: The OAuth consent URL that the user must visit. + """ + + def __init__(self, consent_url: str): + self.consent_url = consent_url + super().__init__( + f'OAuth consent required. Please visit: {consent_url}', + log_level=logging.INFO, + ) + + + +class OAuthConsentRequiredException(AgentException): + """Raised when a sub-agent tool requires OAuth consent. + + This exception is raised by as_tool() when a wrapped agent returns + an oauth_consent_request event. The parent agent should catch this + exception and forward the consent request to the user. + + Attributes: + consent_url: The OAuth consent URL that the user must visit. + """ + + def __init__(self, consent_url: str): + self.consent_url = consent_url + super().__init__( + f'OAuth consent required. Please visit: {consent_url}', + log_level=logging.INFO, + ) + # region Workflow Exceptions