Skip to content

Conversation

@moonbox3
Copy link
Contributor

@moonbox3 moonbox3 commented Jan 21, 2026

Motivation and Context

This refactor restructures AG-UI orchestration to reduce bespoke state handling and make the flow maintainable. The existing code was growing in complexity and brittleness; this change consolidates orchestration, simplifies state transitions, and removes ad hoc management paths.

Important

The only breaking change here is we're removing the confirmation strategies - no need for this custom behavior. The confirmation_strategy arg is no longer passed into AgentFrameworkAgent.

Description

Testing:

  • All samples from AG-UI dojo were tested with the AzureOpenAIClient, AnthropicClient, and the AzureAIClient
  • Multiple MCP tools were tested
  • Human-in-the-loop approvals with MCP tools were tested
  • Unit test coverage > 85% for current package

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

@markwallace-microsoft
Copy link
Member

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/ag-ui/agent_framework_ag_ui
   _agent.py36197%62
   _client.py1401192%37, 88–92, 238, 268, 423–425
   _endpoint.py46197%92
   _message_adapters.py4428979%65, 75–76, 85–88, 117–118, 121, 125–127, 136–138, 147–158, 160–162, 192, 205–206, 216–217, 254, 257, 259, 262, 265, 281, 298, 320, 351, 356, 367–368, 419, 435–436, 496–499, 501, 507, 515–516, 518, 522–525, 538, 627–630, 632, 697, 732–734, 736–739, 742–743, 745, 751, 754, 756, 759, 761, 767–768, 770
   _run.py43212171%146–153, 296, 315–316, 329–330, 341, 344–345, 347–348, 350–352, 362, 372–375, 379–381, 383, 393, 396–399, 401–402, 405–411, 414–416, 419, 435–437, 444, 450–451, 453–454, 468–474, 485, 498–500, 534–535, 587–589, 601–603, 627, 632–634, 750, 761–762, 769, 816–818, 833, 839, 847, 849, 885–891, 894–897, 899–909, 912–913, 918, 924–926, 939–941
   _types.py33196%12
packages/ag-ui/agent_framework_ag_ui/_orchestration
   _helpers.py1070100% 
   _tooling.py570100% 
packages/anthropic/agent_framework_anthropic
   _chat_client.py34413760%51, 361, 384, 386, 399, 421–424, 476–477, 486, 488–489, 494, 511–512, 554, 569, 573–574, 590, 599, 601, 605–606, 647–649, 651, 664–665, 672–674, 678–680, 684–687, 698, 700, 722, 732, 754–760, 767–768, 776–777, 785–788, 795–796, 802–803, 809–810, 816, 824–826, 830, 837–838, 844–845, 851–852, 858, 866–869, 876–877, 896, 903–904, 923, 945, 947, 956–957, 963, 985–986, 992–993, 1002–1012, 1019–1025, 1032–1038, 1045–1054, 1061–1064
packages/core/agent_framework
   _agents.py2995282%51, 90, 98, 101, 104, 406–408, 454, 636, 805, 808–810, 928–930, 935–937, 1038, 1079, 1081, 1090–1095, 1101, 1103, 1113–1114, 1121, 1123–1124, 1132–1136, 1144–1145, 1147, 1152, 1154, 1188, 1233–1234, 1236, 1238, 1249
   _tools.py7706991%226, 272, 323, 325, 353, 523, 555–556, 658, 660, 680, 698, 712, 724, 729, 731, 738, 771, 827–829, 870, 895–904, 911–912, 914–915, 919, 955, 965, 1206, 1543, 1629–1633, 1769, 1771, 1837, 1929, 1935, 1977–1978, 1991–1992, 2035, 2119, 2157–2158, 2195–2197, 2235–2236, 2246, 2303–2304, 2311–2312
TOTAL16970263784% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3224 214 💤 0 ❌ 0 🔥 1m 2s ⏱️

@moonbox3 moonbox3 added the breaking change Introduces changes that are not backward compatible and may require updates to dependent code. label Jan 21, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR performs a major refactoring of the AG-UI orchestration system to simplify the run logic and fix several bugs. The changes consolidate orchestration into a single linear flow in _run.py, removing the complex orchestrator pattern and confirmation strategies.

Changes:

  • Simplified orchestration by consolidating into a single run_agent_stream() function in _run.py
  • Fixed Anthropic client bug where empty text content was causing API errors
  • Fixed MCP tool approval handling by ensuring approval tools are properly passed to the execution handler
  • Removed confirmation strategies (BREAKING CHANGE)

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
python/packages/core/agent_framework/_tools.py Added debug logging and fixed conversation_id filtering in tool invocation
python/packages/core/agent_framework/_agents.py Added tool deduplication by name when merging options
python/packages/anthropic/agent_framework_anthropic/_chat_client.py Fixed empty text content handling and added conversation_id to ignored options
python/packages/ag-ui/agent_framework_ag_ui/_run.py New 949-line orchestration implementation replacing orchestrators
python/packages/ag-ui/agent_framework_ag_ui/_orchestration/_tooling.py Fixed approval tool detection to ensure tools are passed when needed
python/packages/ag-ui/agent_framework_ag_ui/_agent.py Simplified to use new run_agent_stream() function
python/packages/ag-ui/agent_framework_ag_ui/__init__.py Removed confirmation strategy exports
python/packages/ag-ui/agent_framework_ag_ui_examples/agents/ Removed confirmation_strategy parameters from agent examples
Multiple test files Removed obsolete tests and added new tests for simplified architecture

Comment on lines +1692 to +1695
logger.info(
f"[APPROVAL-DEBUG] _try_execute_function_calls: tool_map keys={list(tool_map.keys())}, "
f"approval_tools={approval_tools}"
)
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug logging statements should be removed before merging to production. The [APPROVAL-DEBUG] prefix and associated logger.info calls appear to be temporary debugging code that should not be committed. Consider using logger.debug() for detailed debugging or removing these statements entirely.

Copilot uses AI. Check for mistakes.
Comment on lines +2162 to +2170
fc_count = len(function_calls) if function_calls else 0
logger.info(
f"[APPROVAL-DEBUG-STREAMING] tools extracted: {tools is not None}, function_calls: {fc_count}"
)
if tools:
for t in tools if isinstance(tools, list) else [tools]:
t_name = getattr(t, "name", "unknown")
t_approval = getattr(t, "approval_mode", None)
logger.info(f"[APPROVAL-DEBUG-STREAMING] - {t_name}: approval_mode={t_approval}")
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug logging statements with [APPROVAL-DEBUG-STREAMING] prefix should be removed before merging. These appear to be temporary debugging code used during development.

Copilot uses AI. Check for mistakes.
Comment on lines +127 to +128
# Note: TestExecutionContext was removed along with _orchestrators.py
# Tests should now use run_agent_stream() directly or the StubAgent class
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment at the end of the file references code that has been removed. The note about TestExecutionContext being removed is useful during transition, but consider removing this comment in a follow-up cleanup or documenting the replacement pattern more clearly in the docstring of the test utilities that remain.

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +68
# chat_client: BaseChatClient[ChatOptions] = AzureOpenAIChatClient()
chat_client: BaseChatClient[ChatOptions] = AnthropicClient()
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded change from AzureOpenAIChatClient to AnthropicClient appears to be temporary for testing purposes. This should be reverted before merging or made configurable through environment variables so developers can choose their chat client.

Copilot uses AI. Check for mistakes.
if "accepted" in result and "steps" in result:
return True
except json.JSONDecodeError:
pass
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
pass
logger.debug(
"Failed to parse confirm_changes tool result as JSON; treating as non-confirmation."
)

Copilot uses AI. Check for mistakes.
flow.current_state[state_key] = state_value
yield StateSnapshotEvent(snapshot=flow.current_state)
except json.JSONDecodeError:
pass
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
pass
# Ignore malformed JSON in tool arguments for predictive state;
# predictive updates are best-effort and should not break the flow.
logger.warning(
"Failed to decode JSON arguments for predictive tool '%s' (tool_call_id=%s).",
tool_name,
tool_call_id,
)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ag-ui breaking change Introduces changes that are not backward compatible and may require updates to dependent code. python

Projects

Status: No status

2 participants