From 0cea1470747c668a6886f26e1814a9005626b947 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Mon, 1 Jun 2026 22:45:00 -0700 Subject: [PATCH] Address Copilot comments --- .../_workflows/_agent_executor.py | 28 +++++++++++++++++-- .../tests/workflow/test_workflow_agent.py | 8 ++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/python/packages/core/agent_framework/_workflows/_agent_executor.py b/python/packages/core/agent_framework/_workflows/_agent_executor.py index 9309ce3864..1b5eca6eaa 100644 --- a/python/packages/core/agent_framework/_workflows/_agent_executor.py +++ b/python/packages/core/agent_framework/_workflows/_agent_executor.py @@ -432,13 +432,25 @@ class AgentExecutor(Executor): # Handle any user input requests if response.user_input_requests: + user_input_request_count = len(response.user_input_requests) + total_message_content_count = sum(len(msg.contents) for msg in response.messages) + if user_input_request_count != total_message_content_count: + logger.warning( + "Response %d contains %d user input requests but total message contents are %d. " + "This indicates the response contains both user input requests and message contents. " + "Double check if this is the intended behavior, as non user input request contents in " + "this response will not be emitted.", + response.response_id, + user_input_request_count, + total_message_content_count, + ) for user_input_request in response.user_input_requests: self._pending_agent_requests[user_input_request.id] = user_input_request # type: ignore[index] await ctx.request_info(user_input_request, Content, request_id=user_input_request.id) return None # Only yield output if the response is complete and not waiting for user input. - # This is to avoid emmiting two events of different types ('output' and 'request_info') + # This is to avoid emitting two events of different types ('output' and 'request_info') # that carry the same payload. await ctx.yield_output(response) return response @@ -476,10 +488,22 @@ class AgentExecutor(Executor): async for update in stream: updates.append(update) if update.user_input_requests: + user_input_request_count = len(update.user_input_requests) + total_message_content_count = len(update.contents) + if user_input_request_count != total_message_content_count: + logger.warning( + "Response update %d contains %d user input requests but total message contents are %d. " + "This indicates the response update contains both user input requests and message contents. " + "Double check if this is the intended behavior, as non user input request contents will " + "not be emitted.", + update.response_id, + user_input_request_count, + total_message_content_count, + ) streamed_user_input_requests.extend(update.user_input_requests) else: # Only yield output events for updates that do not contain user input requests. - # This is to avoid emmiting two events of different types ('output' and 'request_info') + # This is to avoid emitting two events of different types ('output' and 'request_info') # that carry the same payload. await ctx.yield_output(update) diff --git a/python/packages/core/tests/workflow/test_workflow_agent.py b/python/packages/core/tests/workflow/test_workflow_agent.py index 4fd74fc75f..5113fb02b8 100644 --- a/python/packages/core/tests/workflow/test_workflow_agent.py +++ b/python/packages/core/tests/workflow/test_workflow_agent.py @@ -1,6 +1,5 @@ # Copyright (c) Microsoft. All rights reserved. -import json import uuid from collections.abc import Awaitable, Sequence from dataclasses import dataclass @@ -313,14 +312,13 @@ class TestWorkflowAgent: response_type=str, ) - function_call, approval_request = agent._process_request_info_event(event) # pyright: ignore[reportPrivateUsage] + approval_request = agent._process_request_info_event(event) # pyright: ignore[reportPrivateUsage] - assert function_call.arguments == { + assert approval_request.function_call is not None + assert approval_request.function_call.arguments == { "request_id": "request_123", "data": {"target_agent": "helper", "reason": "overflow"}, } - assert approval_request.function_call is function_call - assert json.loads(json.dumps(function_call.arguments)) == function_call.arguments def test_workflow_as_agent_method(self) -> None: """Test that Workflow.as_agent() creates a properly configured WorkflowAgent."""