Skip to content

Comments

Python: Add CreateConversationExecutor, fix input routing, remove unused handler layer#4159

Merged
moonbox3 merged 9 commits intomicrosoft:mainfrom
moonbox3:4129-fix
Feb 24, 2026
Merged

Python: Add CreateConversationExecutor, fix input routing, remove unused handler layer#4159
moonbox3 merged 9 commits intomicrosoft:mainfrom
moonbox3:4129-fix

Conversation

@moonbox3
Copy link
Contributor

@moonbox3 moonbox3 commented Feb 23, 2026

Motivation and Context

  • Adds CreateConversationExecutor to the graph-based executor system, fixing Python: [Bug]: Declarative: Missing CreateConversation implementation #4129
  • Fixes System.LastMessage.Text not being populated from workflow string input, so YAML expressions like =System.LastMessage.Text see the user's message
  • Fixes runner convergence for looping workflows by threading max_iterations through WorkflowFactory / DeclarativeWorkflowBuilder and supporting a maxTurns YAML field
  • Fixes DeepResearch.yaml: adds maxTurns: 500, sets autoSend: false on ManagerAgent to suppress raw JSON output
  • Fixes deep_research/main.py: restores shared YAML path, adds newlines between output events
  • Removes the entire dead action handler layer (6 source files, 3 test files) confirmed unused in Python: remove unnecessary declarative workflows Action Handlers #3904
  • System.ConversationId was hardcoded to "default" in Python declarative workflows, so YAML expressions like conversationId: =System.ConversationId routed messages to System.conversations.default.messages instead of a properly scoped conversation. Now initialize() generates a UUID and seeds a matching System.conversations entry, matching the .NET behavior.

Supersedes #4065

This branch builds on sample-fixes-8 (#4065) and keeps all of its executor fixes. It supersedes #4065 because that PR worked around missing executors by using a simplified local workflow.yaml; this PR fixes the root causes instead.

Description

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.

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 enhances the Python declarative (graph-based) workflow execution path by adding missing executors (notably CreateConversation), improving input/state routing for PowerFx expressions, and removing an unused legacy “action handler” execution layer.

Changes:

  • Add CreateConversationExecutor, improve dynamic agent name expression evaluation, and adjust branch-exit/terminator handling to prevent incorrect edge wiring.
  • Thread runner iteration limits via WorkflowFactory/DeclarativeWorkflowBuilder, supporting a YAML maxTurns field; update DeepResearch sample accordingly.
  • Remove the unused legacy handler layer and associated tests; update samples/tests to use the executor-based system.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
workflow-samples/DeepResearch.yaml Adds maxTurns: 500 and sets autoSend: false to improve looping convergence and suppress raw JSON output.
python/samples/03-workflows/declarative/human_in_loop/main.py Updates streaming output handling to align with executor-based output payloads.
python/samples/03-workflows/declarative/deep_research/main.py Adjusts streaming print formatting (adds newlines between output events).
python/samples/02-agents/context_providers/redis/redis_conversation.py Removes an unused import.
python/samples/01-get-started/06_host_your_agent.py Adds whitespace (formatting-only).
python/packages/declarative/tests/test_workflow_samples_integration.py Switches coverage check from handlers to ALL_ACTION_EXECUTORS.
python/packages/declarative/tests/test_workflow_handlers.py Removes tests for the deleted handler layer.
python/packages/declarative/tests/test_workflow_factory.py Removes tests tied to the deleted handler-layer ActionContext.
python/packages/declarative/tests/test_graph_coverage.py Adds tests for expression-based agent name resolution, terminator branch exit handling, and CreateConversationExecutor.
python/packages/declarative/tests/test_external_input.py Removes tests for the deleted handler-based HITL implementation.
python/packages/declarative/tests/test_additional_handlers.py Removes tests for the deleted handler layer (conversation/variables/etc.).
python/packages/declarative/agent_framework_declarative/_workflows/_human_input.py Removes the handler-based HITL implementation module.
python/packages/declarative/agent_framework_declarative/_workflows/_handlers.py Removes the handler registry/types module.
python/packages/declarative/agent_framework_declarative/_workflows/_factory.py Adds max_iterations plumbing into graph builder creation.
python/packages/declarative/agent_framework_declarative/_workflows/_executors_control_flow.py Ensures JoinExecutor initializes state before passing through.
python/packages/declarative/agent_framework_declarative/_workflows/_executors_basic.py Adds CreateConversationExecutor and registers it in BASIC_ACTION_EXECUTORS.
python/packages/declarative/agent_framework_declarative/_workflows/_executors_agents.py Supports = PowerFx expressions for agent name fields across schema variants.
python/packages/declarative/agent_framework_declarative/_workflows/_declarative_builder.py Adds more terminators, threads max_iterations into WorkflowBuilder, and improves _get_branch_exit terminator handling.
python/packages/declarative/agent_framework_declarative/_workflows/_declarative_base.py Populates System.LastMessage.Text from string (and non-dict) workflow inputs.
python/packages/declarative/agent_framework_declarative/_workflows/_actions_error.py Removes handler-based error actions module.
python/packages/declarative/agent_framework_declarative/_workflows/_actions_control_flow.py Removes handler-based control-flow actions module.
python/packages/declarative/agent_framework_declarative/_workflows/_actions_basic.py Removes handler-based basic actions module.
python/packages/declarative/agent_framework_declarative/_workflows/_actions_agents.py Removes handler-based agent invocation actions module.
python/packages/declarative/agent_framework_declarative/_workflows/init.py Updates exports to reflect the executor-only workflow implementation.

@corradopignato
Copy link

corradopignato commented Feb 23, 2026

Hi @moonbox3, could you also check System.ConversationId?
It seems that its value always remains _default when we call InvokeAzureAgent.
Is this the intended behavior?

@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Feb 23, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/declarative/agent_framework_declarative/_workflows
   _declarative_base.py3854089%44, 47, 130–131, 134, 212, 226, 240, 251, 268, 403, 431, 514–516, 518–520, 522, 525, 532, 558, 582–586, 588–596, 617–618, 620–621
   _declarative_builder.py3522692%148, 180, 187, 244, 335, 357, 367, 418, 420, 428, 443, 479, 482, 508–509, 528–529, 605, 610, 654–656, 680–681, 903, 976
   _executors_agents.py4768681%95–96, 113–115, 156–157, 164, 192, 195–196, 204–205, 215, 226–231, 497, 535–537, 540, 556, 572–576, 600, 605, 695, 701–706, 713, 737–738, 747–749, 798–799, 807, 826, 933–936, 943–944, 953–954, 966–971, 975–976, 978, 983, 985, 989–992, 995, 997–998, 1001, 1009–1011, 1013, 1016–1017, 1019, 1046–1047
   _executors_basic.py2943687%343, 418, 420, 425–427, 440–446, 469, 474–477, 544, 549, 556–558, 562, 565, 569, 571, 576–578, 582, 584, 589–591, 594
   _executors_control_flow.py170696%81, 89, 152, 342–343, 347
   _factory.py1396056%186, 263–264, 328–330, 338, 340, 343–349, 378, 390–391, 400, 435, 448, 473–476, 495–499, 502–503, 506, 509, 514, 623–624, 626–627, 629–631, 634, 648, 651–656, 659–660, 662, 665, 675–676, 678, 682–683, 685
   _state.py31117244%23, 26, 146, 170, 184, 197, 206–207, 209, 225, 233, 241, 245, 247, 249, 259, 367, 373, 375, 377–381, 385, 403, 405, 408–411, 414–417, 420–422, 424–430, 433–437, 440–444, 447–463, 466–469, 471–474, 476–479, 481–484, 486–493, 496–499, 501–508, 511–514, 516–522, 524–528, 531–532, 535–540, 543–546, 549, 552–557, 560, 571–575, 577–594, 596, 598–599, 601, 617
TOTAL21208308585% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
4221 240 💤 0 ❌ 0 🔥 1m 11s ⏱️

@moonbox3 moonbox3 moved this to In Review in Agent Framework Feb 23, 2026
@moonbox3
Copy link
Contributor Author

Hi @moonbox3, could you also check System.ConversationId? It seems that its value always remains _default when we call InvokeAzureAgent. Is this the intended behavior?

Fixed in 19c71d2.

@moonbox3 moonbox3 enabled auto-merge February 23, 2026 23:27
@moonbox3 moonbox3 added this pull request to the merge queue Feb 24, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 24, 2026
@moonbox3 moonbox3 added this pull request to the merge queue Feb 24, 2026
Merged via the queue into microsoft:main with commit de612c4 Feb 24, 2026
25 checks passed
@github-project-automation github-project-automation bot moved this from In Review to Done in Agent Framework Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Declarative: Missing CreateConversation implementation Python: remove unnecessary declarative workflows Action Handlers

7 participants