[BREAKING] Python: Remove workflow register factory methods. Update tests and samples (#3781)

* Remove workflow register factory methods. Update tests and samples

* Address Copilot feedback
This commit is contained in:
Evan Mattson
2026-02-11 07:16:17 +09:00
committed by GitHub
Unverified
parent f407f726a7
commit a4c9e43afb
46 changed files with 650 additions and 3660 deletions
@@ -72,14 +72,15 @@ class Aggregator(Executor):
async def main() -> None:
# 1) Build a simple fan out and fan in workflow
dispatcher = Dispatcher(id="dispatcher")
average = Average(id="average")
summation = Sum(id="summation")
aggregator = Aggregator(id="aggregator")
workflow = (
WorkflowBuilder(start_executor="dispatcher")
.register_executor(lambda: Dispatcher(id="dispatcher"), name="dispatcher")
.register_executor(lambda: Average(id="average"), name="average")
.register_executor(lambda: Sum(id="summation"), name="summation")
.register_executor(lambda: Aggregator(id="aggregator"), name="aggregator")
.add_fan_out_edges("dispatcher", ["average", "summation"])
.add_fan_in_edges(["average", "summation"], "aggregator")
WorkflowBuilder(start_executor=dispatcher)
.add_fan_out_edges(dispatcher, [average, summation])
.add_fan_in_edges([average, summation], aggregator)
.build()
)
@@ -4,9 +4,9 @@ import asyncio
from dataclasses import dataclass
from agent_framework import (
AgentExecutor, # Wraps a ChatAgent as an Executor for use in workflows
AgentExecutorRequest, # The message bundle sent to an AgentExecutor
AgentExecutorResponse, # The structured result returned by an AgentExecutor
ChatAgent, # Tracing event for agent execution steps
ChatMessage, # Chat message structure
Executor, # Base class for custom Python executors
WorkflowBuilder, # Fluent builder for wiring the workflow graph
@@ -87,50 +87,44 @@ class AggregateInsights(Executor):
await ctx.yield_output(consolidated)
def create_researcher_agent() -> ChatAgent:
"""Creates a research domain expert agent."""
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions=(
"You're an expert market and product researcher. Given a prompt, provide concise, factual insights,"
" opportunities, and risks."
),
name="researcher",
)
def create_marketer_agent() -> ChatAgent:
"""Creates a marketing domain expert agent."""
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions=(
"You're a creative marketing strategist. Craft compelling value propositions and target messaging"
" aligned to the prompt."
),
name="marketer",
)
def create_legal_agent() -> ChatAgent:
"""Creates a legal/compliance domain expert agent."""
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions=(
"You're a cautious legal/compliance reviewer. Highlight constraints, disclaimers, and policy concerns"
" based on the prompt."
),
name="legal",
)
async def main() -> None:
# 1) Build a simple fan out and fan in workflow
# 1) Create executor and agent instances
dispatcher = DispatchToExperts(id="dispatcher")
aggregator = AggregateInsights(id="aggregator")
researcher = AgentExecutor(
AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions=(
"You're an expert market and product researcher. Given a prompt, provide concise, factual insights,"
" opportunities, and risks."
),
name="researcher",
)
)
marketer = AgentExecutor(
AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions=(
"You're a creative marketing strategist. Craft compelling value propositions and target messaging"
" aligned to the prompt."
),
name="marketer",
)
)
legal = AgentExecutor(
AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions=(
"You're a cautious legal/compliance reviewer. Highlight constraints, disclaimers, and policy concerns"
" based on the prompt."
),
name="legal",
)
)
# 2) Build a simple fan out and fan in workflow
workflow = (
WorkflowBuilder(start_executor="dispatcher")
.register_agent(create_researcher_agent, name="researcher")
.register_agent(create_marketer_agent, name="marketer")
.register_agent(create_legal_agent, name="legal")
.register_executor(lambda: DispatchToExperts(id="dispatcher"), name="dispatcher")
.register_executor(lambda: AggregateInsights(id="aggregator"), name="aggregator")
.add_fan_out_edges("dispatcher", ["researcher", "marketer", "legal"]) # Parallel branches
.add_fan_in_edges(["researcher", "marketer", "legal"], "aggregator") # Join at the aggregator
WorkflowBuilder(start_executor=dispatcher)
.add_fan_out_edges(dispatcher, [researcher, marketer, legal]) # Parallel branches
.add_fan_in_edges([researcher, marketer, legal], aggregator) # Join at the aggregator
.build()
)
@@ -257,49 +257,31 @@ class CompletionExecutor(Executor):
async def main():
"""Construct the map reduce workflow, visualize it, then run it over a sample file."""
# Step 1: Create the workflow builder and register executors.
workflow_builder = (
WorkflowBuilder(start_executor="split_data_executor")
.register_executor(lambda: Map(id="map_executor_0"), name="map_executor_0")
.register_executor(lambda: Map(id="map_executor_1"), name="map_executor_1")
.register_executor(lambda: Map(id="map_executor_2"), name="map_executor_2")
.register_executor(
lambda: Split(["map_executor_0", "map_executor_1", "map_executor_2"], id="split_data_executor"),
name="split_data_executor",
)
.register_executor(lambda: Reduce(id="reduce_executor_0"), name="reduce_executor_0")
.register_executor(lambda: Reduce(id="reduce_executor_1"), name="reduce_executor_1")
.register_executor(lambda: Reduce(id="reduce_executor_2"), name="reduce_executor_2")
.register_executor(lambda: Reduce(id="reduce_executor_3"), name="reduce_executor_3")
.register_executor(
lambda: Shuffle(
["reduce_executor_0", "reduce_executor_1", "reduce_executor_2", "reduce_executor_3"],
id="shuffle_executor",
),
name="shuffle_executor",
)
.register_executor(lambda: CompletionExecutor(id="completion_executor"), name="completion_executor")
# Step 1: Create executor instances.
map_executor_0 = Map(id="map_executor_0")
map_executor_1 = Map(id="map_executor_1")
map_executor_2 = Map(id="map_executor_2")
split_data_executor = Split(["map_executor_0", "map_executor_1", "map_executor_2"], id="split_data_executor")
reduce_executor_0 = Reduce(id="reduce_executor_0")
reduce_executor_1 = Reduce(id="reduce_executor_1")
reduce_executor_2 = Reduce(id="reduce_executor_2")
reduce_executor_3 = Reduce(id="reduce_executor_3")
shuffle_executor = Shuffle(
["reduce_executor_0", "reduce_executor_1", "reduce_executor_2", "reduce_executor_3"],
id="shuffle_executor",
)
completion_executor = CompletionExecutor(id="completion_executor")
mappers = [map_executor_0, map_executor_1, map_executor_2]
reducers = [reduce_executor_0, reduce_executor_1, reduce_executor_2, reduce_executor_3]
# Step 2: Build the workflow graph using fan out and fan in edges.
workflow = (
workflow_builder
.add_fan_out_edges(
"split_data_executor",
["map_executor_0", "map_executor_1", "map_executor_2"],
) # Split -> many mappers
.add_fan_in_edges(
["map_executor_0", "map_executor_1", "map_executor_2"],
"shuffle_executor",
) # All mappers -> shuffle
.add_fan_out_edges(
"shuffle_executor",
["reduce_executor_0", "reduce_executor_1", "reduce_executor_2", "reduce_executor_3"],
) # Shuffle -> many reducers
.add_fan_in_edges(
["reduce_executor_0", "reduce_executor_1", "reduce_executor_2", "reduce_executor_3"],
"completion_executor",
) # All reducers -> completion
WorkflowBuilder(start_executor=split_data_executor)
.add_fan_out_edges(split_data_executor, mappers) # Split -> many mappers
.add_fan_in_edges(mappers, shuffle_executor) # All mappers -> shuffle
.add_fan_out_edges(shuffle_executor, reducers) # Shuffle -> many reducers
.add_fan_in_edges(reducers, completion_executor) # All reducers -> completion
.build()
)