mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Fix: Parse oauth_consent_request events in Azure AI client (#4197)
* Fix: Parse oauth_consent_request events in Azure AI client (#3950) When Azure AI Agent Service returns an oauth_consent_request output item for OAuth-protected MCP tools, the base OpenAI responses parser drops it (hits case _ default branch). This causes agent runs to complete silently with zero content. Changes: - Add oauth_consent_request ContentType and Content.from_oauth_consent_request() factory with consent_link field and user_input_request=True - Override _parse_response_from_openai and _parse_chunk_from_openai in RawAzureAIClient to intercept Azure-specific oauth_consent_request items - Add _emit_oauth_consent helper in AG-UI to emit CustomEvent for frontends - Add tests proving base parser drops the event and Azure AI override catches it Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * addressed comment * addressed comments * addressed comments --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -372,6 +372,15 @@ def _emit_usage(content: Content) -> list[BaseEvent]:
|
||||
return [CustomEvent(name="usage", value=usage_details)]
|
||||
|
||||
|
||||
def _emit_oauth_consent(content: Content) -> list[BaseEvent]:
|
||||
"""Emit an OAuth consent request as a custom event so frontends can render a consent link."""
|
||||
return (
|
||||
[CustomEvent(name="oauth_consent_request", value={"consent_link": content.consent_link})]
|
||||
if content.consent_link
|
||||
else []
|
||||
)
|
||||
|
||||
|
||||
def _emit_content(
|
||||
content: Any,
|
||||
flow: FlowState,
|
||||
@@ -391,5 +400,7 @@ def _emit_content(
|
||||
return _emit_approval_request(content, flow, predictive_handler, require_confirmation)
|
||||
if content_type == "usage":
|
||||
return _emit_usage(content)
|
||||
if content_type == "oauth_consent_request":
|
||||
return _emit_oauth_consent(content)
|
||||
logger.debug("Skipping unsupported content type in AG-UI emitter: %s", content_type)
|
||||
return []
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import pytest
|
||||
from ag_ui.core import (
|
||||
CustomEvent,
|
||||
TextMessageEndEvent,
|
||||
TextMessageStartEvent,
|
||||
ToolCallArgsEvent,
|
||||
@@ -871,3 +872,26 @@ class TestTextMessageEventBalancing:
|
||||
|
||||
assert len(start_events) == 2
|
||||
assert len(end_events) == 2
|
||||
|
||||
|
||||
def test_emit_oauth_consent_request():
|
||||
"""Test that oauth_consent_request content emits a CustomEvent."""
|
||||
content = Content.from_oauth_consent_request(
|
||||
consent_link="https://login.microsoftonline.com/consent",
|
||||
)
|
||||
flow = FlowState()
|
||||
events = _emit_content(content, flow)
|
||||
|
||||
assert len(events) == 1
|
||||
assert isinstance(events[0], CustomEvent)
|
||||
assert events[0].name == "oauth_consent_request"
|
||||
assert events[0].value == {"consent_link": "https://login.microsoftonline.com/consent"}
|
||||
|
||||
|
||||
def test_emit_oauth_consent_request_no_link():
|
||||
"""Test that oauth_consent_request without a consent_link emits no events."""
|
||||
content = Content("oauth_consent_request")
|
||||
flow = FlowState()
|
||||
events = _emit_content(content, flow)
|
||||
|
||||
assert len(events) == 0
|
||||
|
||||
Reference in New Issue
Block a user