mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: WorkflowBuilder registry (#2486)
* Add workflow builder factory pattern * Add internal edge groups to registered executors; next samples * Update samples: Part 1 * register -> register_executor * update hil samples * Update other samples * Update agent samples * Update doc string * Add new sample * Fix mypy * Address comments * Fix mypy
This commit is contained in:
committed by
GitHub
Unverified
parent
6809510413
commit
f2ed5b55f6
+14
-15
@@ -10,7 +10,6 @@ from typing import Any, override
|
||||
# `agent_framework.builtin` chat client or mock the writer executor. We keep the
|
||||
# concrete import here so readers can see an end-to-end configuration.
|
||||
from agent_framework import (
|
||||
AgentExecutor,
|
||||
AgentExecutorRequest,
|
||||
AgentExecutorResponse,
|
||||
ChatMessage,
|
||||
@@ -173,25 +172,25 @@ class ReviewGateway(Executor):
|
||||
|
||||
def create_workflow(checkpoint_storage: FileCheckpointStorage) -> Workflow:
|
||||
"""Assemble the workflow graph used by both the initial run and resume."""
|
||||
|
||||
# The Azure client is created once so our agent executor can issue calls to the hosted
|
||||
# model. The agent id is stable across runs which keeps checkpoints deterministic.
|
||||
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
agent = chat_client.create_agent(instructions="Write concise, warm release notes that sound human and helpful.")
|
||||
|
||||
writer = AgentExecutor(agent, id="writer")
|
||||
gateway = ReviewGateway(id="review_gateway", writer_id=writer.id)
|
||||
prepare = BriefPreparer(id="prepare_brief", agent_id=writer.id)
|
||||
|
||||
# Wire the workflow DAG. Edges mirror the numbered steps described in the
|
||||
# module docstring. Because `WorkflowBuilder` is declarative, reading these
|
||||
# edges is often the quickest way to understand execution order.
|
||||
workflow_builder = (
|
||||
WorkflowBuilder(max_iterations=6)
|
||||
.set_start_executor(prepare)
|
||||
.add_edge(prepare, writer)
|
||||
.add_edge(writer, gateway)
|
||||
.add_edge(gateway, writer) # revisions loop
|
||||
.register_agent(
|
||||
lambda: AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent(
|
||||
instructions="Write concise, warm release notes that sound human and helpful.",
|
||||
# The agent name is stable across runs which keeps checkpoints deterministic.
|
||||
name="writer",
|
||||
),
|
||||
name="writer",
|
||||
)
|
||||
.register_executor(lambda: ReviewGateway(id="review_gateway", writer_id="writer"), name="review_gateway")
|
||||
.register_executor(lambda: BriefPreparer(id="prepare_brief", agent_id="writer"), name="prepare_brief")
|
||||
.set_start_executor("prepare_brief")
|
||||
.add_edge("prepare_brief", "writer")
|
||||
.add_edge("writer", "review_gateway")
|
||||
.add_edge("review_gateway", "writer") # revisions loop
|
||||
.with_checkpointing(checkpoint_storage=checkpoint_storage)
|
||||
)
|
||||
|
||||
|
||||
@@ -99,16 +99,14 @@ class WorkerExecutor(Executor):
|
||||
|
||||
|
||||
async def main():
|
||||
# Create workflow executors
|
||||
start_executor = StartExecutor(id="start")
|
||||
worker_executor = WorkerExecutor(id="worker")
|
||||
|
||||
# Build workflow with checkpointing enabled
|
||||
workflow_builder = (
|
||||
WorkflowBuilder()
|
||||
.set_start_executor(start_executor)
|
||||
.add_edge(start_executor, worker_executor)
|
||||
.add_edge(worker_executor, worker_executor) # Self-loop for iterative processing
|
||||
.register_executor(lambda: StartExecutor(id="start"), name="start")
|
||||
.register_executor(lambda: WorkerExecutor(id="worker"), name="worker")
|
||||
.set_start_executor("start")
|
||||
.add_edge("start", "worker")
|
||||
.add_edge("worker", "worker") # Self-loop for iterative processing
|
||||
)
|
||||
checkpoint_storage = InMemoryCheckpointStorage()
|
||||
workflow_builder = workflow_builder.with_checkpointing(checkpoint_storage=checkpoint_storage)
|
||||
|
||||
@@ -292,16 +292,16 @@ class LaunchCoordinator(Executor):
|
||||
|
||||
|
||||
def build_sub_workflow() -> WorkflowExecutor:
|
||||
writer = DraftWriter()
|
||||
router = DraftReviewRouter()
|
||||
finaliser = DraftFinaliser()
|
||||
|
||||
"""Assemble the sub-workflow used by the parent workflow executor."""
|
||||
sub_workflow = (
|
||||
WorkflowBuilder()
|
||||
.set_start_executor(writer)
|
||||
.add_edge(writer, router)
|
||||
.add_edge(router, finaliser)
|
||||
.add_edge(finaliser, writer) # permits revision loops
|
||||
.register_executor(DraftWriter, name="writer")
|
||||
.register_executor(DraftReviewRouter, name="router")
|
||||
.register_executor(DraftFinaliser, name="finaliser")
|
||||
.set_start_executor("writer")
|
||||
.add_edge("writer", "router")
|
||||
.add_edge("router", "finaliser")
|
||||
.add_edge("finaliser", "writer") # permits revision loops
|
||||
.build()
|
||||
)
|
||||
|
||||
@@ -309,14 +309,14 @@ def build_sub_workflow() -> WorkflowExecutor:
|
||||
|
||||
|
||||
def build_parent_workflow(storage: FileCheckpointStorage) -> Workflow:
|
||||
coordinator = LaunchCoordinator()
|
||||
sub_executor = build_sub_workflow()
|
||||
|
||||
"""Assemble the parent workflow that embeds the sub-workflow."""
|
||||
return (
|
||||
WorkflowBuilder()
|
||||
.set_start_executor(coordinator)
|
||||
.add_edge(coordinator, sub_executor)
|
||||
.add_edge(sub_executor, coordinator)
|
||||
.register_executor(LaunchCoordinator, name="coordinator")
|
||||
.register_executor(build_sub_workflow, name="sub_executor")
|
||||
.set_start_executor("coordinator")
|
||||
.add_edge("coordinator", "sub_executor")
|
||||
.add_edge("sub_executor", "coordinator")
|
||||
.with_checkpointing(storage)
|
||||
.build()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user