Python: Fixed declarative deep research sample#4065
Python: Fixed declarative deep research sample#4065dmytrostruk wants to merge 4 commits intomicrosoft:mainfrom
Conversation
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
This PR fixes and completes the Python declarative “Deep Research” workflow sample and corrects several declarative workflow runtime behaviors to support dynamic agent dispatch and correct control-flow graph wiring.
Changes:
- Adds a missing
workflow.yamlimplementing the Magentic orchestration pattern with dynamic agent selection. - Fixes declarative runtime behavior for (a) expression-based agent name resolution, (b) initializing workflow state when
JoinExecutoris the entry node, and (c) preventing successor wiring for terminator branch exits. - Adds unit tests covering expression-based agent name resolution and terminator branch exit handling.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| python/samples/03-workflows/declarative/deep_research/workflow.yaml | Introduces the declarative Deep Research workflow definition with manager-driven dynamic agent dispatch. |
| python/samples/03-workflows/declarative/deep_research/main.py | Simplifies workflow YAML path resolution to always use the local workflow.yaml. |
| python/packages/declarative/tests/test_graph_coverage.py | Adds tests for dynamic agent-name expression evaluation and terminator branch exit handling. |
| python/packages/declarative/agent_framework_declarative/_workflows/_executors_control_flow.py | Ensures workflow state initialization when JoinExecutor is used as the entry node. |
| python/packages/declarative/agent_framework_declarative/_workflows/_executors_agents.py | Enables expression evaluation for agent names in InvokeAzureAgentExecutor._get_agent_name(). |
| python/packages/declarative/agent_framework_declarative/_workflows/_declarative_builder.py | Skips terminator actions as branch exits to avoid incorrect dual-edge wiring. |
python/packages/declarative/agent_framework_declarative/_workflows/_declarative_builder.py
Show resolved
Hide resolved
| if not workflow_path.exists(): | ||
| # Fall back to local copy if workflow-samples doesn't exist | ||
| workflow_path = Path(__file__).parent / "workflow.yaml" | ||
| workflow_path = Path(__file__).parent / "workflow.yaml" |
There was a problem hiding this comment.
I think the yaml workflow is supposed to be shared between Python and .Net. But let's wait for @moonbox3 's confirmation.
There was a problem hiding this comment.
Yes, we should be using the DeepResearch.yaml sample (the same one that Dotnet uses from MAF's root) as configured previously.
| assert exit_exec is None | ||
|
|
||
| def test_get_branch_exit_returns_none_for_end_workflow_terminator(self): | ||
| """Test that _get_branch_exit returns None when branch ends with EndWorkflow.""" |
There was a problem hiding this comment.
This test looks like it's using the incorrect executor type. The true path is: EndWorkflow creates an EndWorkflowExecutor. This test seems to be working right now because both store _action_def, but we aren't validating the actual "prod path." How about:
from agent_framework_declarative._workflows._executors_control_flow import EndWorkflowExecutor
end_executor = EndWorkflowExecutor({"kind": "EndWorkflow", "id": "end"}, id="end")
end_executor._chain_executors = [end_executor]
exit_exec = graph_builder._get_branch_exit(end_executor)
assert exit_exec is None| last_executor = chain[-1] | ||
|
|
||
| # Skip terminators — they handle their own control flow | ||
| action_def = getattr(last_executor, "_action_def", {}) |
There was a problem hiding this comment.
This works, but could be improved, I think, if we add something like an is_terminator property on the base class. Just cause I see us reaching to the "private" _action_def attribute.
| if not workflow_path.exists(): | ||
| # Fall back to local copy if workflow-samples doesn't exist | ||
| workflow_path = Path(__file__).parent / "workflow.yaml" | ||
| workflow_path = Path(__file__).parent / "workflow.yaml" |
There was a problem hiding this comment.
Yes, we should be using the DeepResearch.yaml sample (the same one that Dotnet uses from MAF's root) as configured previously.
|
Closing in favor of #4159. |
Motivation and Context
declarative/marketingsample.Contribution Checklist