chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:59:43 +08:00
commit c79da9cdf9
9350 changed files with 1725465 additions and 0 deletions
@@ -0,0 +1,348 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "3a045dd3",
"metadata": {},
"source": [
"# 🔄 Basic Agent Workflows with Microsoft Foundry (Python)\n",
"\n",
"## 📋 Workflow Orchestration Tutorial\n",
"\n",
"This notebook introduces the powerful **Workflow Builder** capabilities of the Microsoft Agent Framework. Learn how to create sophisticated, multi-step agent workflows that can handle complex business processes and coordinate multiple AI operations seamlessly.\n",
"\n",
"> **Migration note:** This sample previously referenced GitHub Models. GitHub Models is deprecated (retiring July 2026), so it now uses **Microsoft Foundry** through the `FoundryChatClient`, which targets the Azure OpenAI **Responses API**.\n",
"\n",
"## 🎯 Learning Objectives\n",
"\n",
"### 🏗️ **Workflow Architecture**\n",
"- **Workflow Builder**: Design and orchestrate complex multi-step processes\n",
"- **Event-Driven Execution**: Handle workflow events and state transitions\n",
"- **Visual Workflow Design**: Create and visualize workflow structures\n",
"- **Microsoft Foundry Integration**: Leverage AI models within workflow contexts\n",
"\n",
"### 🔄 **Process Orchestration**\n",
"- **Sequential Operations**: Chain multiple agent tasks in logical order\n",
"- **Conditional Logic**: Implement decision points and branching workflows\n",
"- **Error Handling**: Robust error recovery and workflow resilience\n",
"- **State Management**: Track and manage workflow execution state\n",
"\n",
"### 📊 **Enterprise Workflow Patterns**\n",
"- **Business Process Automation**: Automate complex organizational workflows\n",
"- **Multi-Agent Coordination**: Coordinate multiple specialized agents\n",
"- **Scalable Execution**: Design workflows for enterprise-scale operations\n",
"- **Monitoring & Observability**: Track workflow performance and outcomes\n",
"\n",
"## ⚙️ Prerequisites & Setup\n",
"\n",
"### 📦 **Required Dependencies**\n",
"\n",
"Install the Agent Framework with workflow capabilities:\n",
"\n",
"```bash\n",
"pip install agent-framework -U\n",
"```\n",
"\n",
"### 🔑 **Microsoft Foundry Configuration**\n",
"\n",
"Sign in with the Azure CLI (`az login`) so `AzureCliCredential` can authenticate, then set your Microsoft Foundry project details.\n",
"\n",
"**Environment Setup (.env file):**\n",
"```env\n",
"AZURE_AI_PROJECT_ENDPOINT=https://<your-project>.services.ai.azure.com\n",
"AZURE_AI_MODEL_DEPLOYMENT_NAME=gpt-4o-mini\n",
"```\n",
"\n",
"### 🏢 **Enterprise Use Cases**\n",
"\n",
"**Business Process Examples:**\n",
"- **Customer Onboarding**: Multi-step verification and setup workflows\n",
"- **Content Pipeline**: Automated content creation, review, and publishing\n",
"- **Data Processing**: ETL workflows with AI-powered transformation\n",
"- **Quality Assurance**: Automated testing and validation processes\n",
"\n",
"**Workflow Benefits:**\n",
"- 🎯 **Reliability**: Deterministic execution with error recovery\n",
"- 📈 **Scalability**: Handle high-volume process automation\n",
"- 🔍 **Observability**: Complete audit trails and monitoring\n",
"- 🔧 **Maintainability**: Visual design and modular components\n",
"\n",
"## 🎨 Workflow Design Patterns\n",
"\n",
"### Basic Workflow Structure\n",
"```mermaid\n",
"graph TD\n",
" A[Start] --> B[Agent Task 1]\n",
" B --> C{Decision Point}\n",
" C -->|Success| D[Agent Task 2]\n",
" C -->|Failure| E[Error Handler]\n",
" D --> F[End]\n",
" E --> F\n",
"```\n",
"\n",
"**Key Components:**\n",
"- **WorkflowBuilder**: Main orchestration engine\n",
"- **WorkflowEvent**: Event handling and communication\n",
"- **WorkflowViz**: Visual workflow representation and debugging\n",
"\n",
"Let's build your first intelligent workflow! 🚀\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c0863be7",
"metadata": {},
"outputs": [],
"source": [
"# Already covered by repo-level requirements.txt; left for reference.\n",
"# !pip install agent-framework -U"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "580e76d9",
"metadata": {},
"outputs": [],
"source": [
"# Core components for building sophisticated agent workflows\n",
"from agent_framework import WorkflowBuilder, WorkflowEvent, WorkflowViz\n",
"from agent_framework.foundry import FoundryChatClient\n",
"from azure.identity import AzureCliCredential\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5fe71939",
"metadata": {},
"outputs": [],
"source": [
"# 📦 Import Environment and System Utilities\n",
"# Essential libraries for configuration and environment management\n",
"\n",
"import os # 🔧 Environment variable access\n",
"from dotenv import load_dotenv # 📁 Secure configuration loading"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cf183974",
"metadata": {},
"outputs": [],
"source": [
"# 🔧 Initialize Environment Configuration\n",
"# Load Microsoft Foundry project settings from .env file\n",
"load_dotenv()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7a679634",
"metadata": {},
"outputs": [],
"source": [
"# Configure the Microsoft Foundry client with keyless authentication.\n",
"# FoundryChatClient targets the Azure OpenAI Responses API.\n",
"provider = FoundryChatClient(\n",
" project_endpoint=os.environ[\"AZURE_AI_PROJECT_ENDPOINT\"],\n",
" model=os.environ[\"AZURE_AI_MODEL_DEPLOYMENT_NAME\"],\n",
" credential=AzureCliCredential(),\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ba45c08b",
"metadata": {},
"outputs": [],
"source": [
"REVIEWER_NAME = \"Concierge\"\n",
"REVIEWER_INSTRUCTIONS = \"\"\"\n",
" You are an are hotel concierge who has opinions about providing the most local and authentic experiences for travelers.\n",
" The goal is to determine if the front desk travel agent has recommended the best non-touristy experience for a traveler.\n",
" If so, state that it is approved.\n",
" If not, provide insight on how to refine the recommendation without using a specific example. \n",
" \"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d9f520ff",
"metadata": {},
"outputs": [],
"source": [
"FRONTDESK_NAME = \"FrontDesk\"\n",
"FRONTDESK_INSTRUCTIONS = \"\"\"\n",
" You are a Front Desk Travel Agent with ten years of experience and are known for brevity as you deal with many customers.\n",
" The goal is to provide the best activities and locations for a traveler to visit.\n",
" Only provide a single recommendation per response.\n",
" You're laser focused on the goal at hand.\n",
" Don't waste time with chit chat.\n",
" Consider suggestions when refining an idea.\n",
" \"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad4819e0",
"metadata": {},
"outputs": [],
"source": [
"reviewer_agent = provider.as_agent(\n",
" name=REVIEWER_NAME,\n",
" instructions=REVIEWER_INSTRUCTIONS,\n",
")\n",
"\n",
"front_desk_agent = provider.as_agent(\n",
" name=FRONTDESK_NAME,\n",
" instructions=FRONTDESK_INSTRUCTIONS,\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "150bb29b",
"metadata": {},
"outputs": [],
"source": [
"workflow = (\n",
" WorkflowBuilder(start_executor=front_desk_agent)\n",
" .add_edge(front_desk_agent, reviewer_agent)\n",
" .build()\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e913c773",
"metadata": {},
"outputs": [],
"source": [
"print(\"Generating workflow visualization...\")\n",
"viz = WorkflowViz(workflow)\n",
"# Print out the mermaid string.\n",
"print(\"Mermaid string: \\n=======\")\n",
"print(viz.to_mermaid())\n",
"print(\"=======\")\n",
"# Print out the DiGraph string.\n",
"print(\"DiGraph string: \\n=======\")\n",
"print(viz.to_digraph())\n",
"print(\"=======\")\n",
"# SVG export needs the optional graphviz extra plus the graphviz system binary;\n",
"# fall back gracefully if it is not available.\n",
"try:\n",
" svg_file = viz.export(format=\"svg\")\n",
" print(f\"SVG file saved to: {svg_file}\")\n",
"except ImportError as e:\n",
" svg_file = None\n",
" print(f\"SVG export skipped (install graphviz to enable): {e}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5fe90eb5",
"metadata": {},
"outputs": [],
"source": [
"class DatabaseEvent(WorkflowEvent): ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e802947c",
"metadata": {},
"outputs": [],
"source": [
"# Display the exported workflow SVG inline in the notebook\n",
"\n",
"from IPython.display import SVG, display, HTML\n",
"import os\n",
"\n",
"print(f\"Attempting to display SVG file at: {svg_file}\")\n",
"\n",
"if svg_file and os.path.exists(svg_file):\n",
" try:\n",
" # Preferred: direct SVG rendering\n",
" display(SVG(filename=svg_file))\n",
" except Exception as e:\n",
" print(f\"⚠️ Direct SVG render failed: {e}. Falling back to raw HTML.\")\n",
" try:\n",
" with open(svg_file, \"r\", encoding=\"utf-8\") as f:\n",
" svg_text = f.read()\n",
" display(HTML(svg_text))\n",
" except Exception as inner:\n",
" print(f\"❌ Fallback HTML render also failed: {inner}\")\n",
"else:\n",
" print(\"❌ SVG file not found. Ensure viz.export(format='svg') ran successfully.\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a0651dfc",
"metadata": {},
"outputs": [],
"source": [
"# Workflow.run_stream is no longer part of the public API; the current Workflow\n",
"# returns a results object whose `get_outputs()` produces the AgentResponse from\n",
"# each output executor. The reviewer (last stage) is the only output here.\n",
"events = await workflow.run(\"I would like to go to Paris.\")\n",
"outputs = events.get_outputs()\n",
"result = outputs[0].text if outputs else \"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad9e0c48",
"metadata": {},
"outputs": [],
"source": [
"result.replace(\"None\", \"\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv (3.12.11)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.11"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,388 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "0f298ce0",
"metadata": {},
"source": [
"# ⏩ Sequential Agent Workflows with Microsoft Foundry (Python)\n",
"\n",
"## 📋 Advanced Sequential Processing Tutorial\n",
"\n",
"This notebook demonstrates **sequential workflow patterns** using the Microsoft Agent Framework. You'll learn how to build sophisticated multi-step processing pipelines where agents execute in a specific order, passing data and context between stages.\n",
"\n",
"> **Migration note:** This sample previously referenced GitHub Models. GitHub Models is deprecated (retiring July 2026), so it now uses **Microsoft Foundry** through the `FoundryChatClient`, which targets the Azure OpenAI **Responses API**.\n",
"\n",
"## 🎯 Learning Objectives\n",
"\n",
"### 🔄 **Sequential Processing Patterns**\n",
"- **Linear Workflow Design**: Create step-by-step processing pipelines\n",
"- **Data Flow Management**: Pass information between sequential agents\n",
"- **Stage-Gate Processing**: Implement checkpoints and validation stages\n",
"- **Progress Tracking**: Monitor workflow execution and intermediate results\n",
"\n",
"### 🏗️ **Enterprise Pipeline Architecture**\n",
"- **Business Process Modeling**: Map real business processes to agent workflows\n",
"- **Quality Assurance**: Multi-stage validation and review processes\n",
"- **Document Processing**: Sequential document analysis and transformation\n",
"- **Content Production**: Editorial workflows with review and approval stages\n",
"\n",
"### 📊 **Advanced Workflow Features**\n",
"- **Context Preservation**: Maintain state across workflow stages\n",
"- **Error Propagation**: Handle failures in sequential processing\n",
"- **Performance Optimization**: Efficient sequential execution patterns\n",
"- **Audit Trails**: Complete tracking of sequential operations\n",
"\n",
"## ⚙️ Prerequisites & Setup\n",
"\n",
"### 📦 **Dependencies**\n",
"```bash\n",
"pip install agent-framework -U\n",
"```\n",
"\n",
"### 🔑 **Configuration**\n",
"\n",
"Sign in with the Azure CLI (`az login`) so `AzureCliCredential` can authenticate, then set your Microsoft Foundry project details.\n",
"\n",
"```env\n",
"AZURE_AI_PROJECT_ENDPOINT=https://<your-project>.services.ai.azure.com\n",
"AZURE_AI_MODEL_DEPLOYMENT_NAME=gpt-4o-mini\n",
"```\n",
"\n",
"## 🏢 **Enterprise Sequential Workflow Use Cases**\n",
"\n",
"### 📝 **Document Processing Pipeline**\n",
"```\n",
"Raw Document → Content Extraction → Analysis → Validation → Final Output\n",
"```\n",
"\n",
"### 🔍 **Quality Assurance Workflow** \n",
"```\n",
"Initial Review → Technical Validation → Compliance Check → Final Approval\n",
"```\n",
"\n",
"### 📰 **Content Production Pipeline**\n",
"```\n",
"Research → Writing → Editing → Review → Publishing\n",
"```\n",
"\n",
"### 💼 **Business Process Automation**\n",
"```\n",
"Data Collection → Processing → Analysis → Report Generation → Distribution\n",
"```\n",
"\n",
"## 🎨 **Sequential Workflow Design Principles**\n",
"\n",
"- **🔗 Linear Progression**: Each stage depends on the previous stage's output\n",
"- **📋 State Management**: Preserve context and data across all stages\n",
"- **🛡️ Error Handling**: Graceful failure management in any stage\n",
"- **📊 Progress Monitoring**: Track completion and performance at each stage\n",
"- **🔄 Stage Reusability**: Design reusable workflow components\n",
"\n",
"Let's build sophisticated sequential processing workflows! 🚀\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a3dc4927",
"metadata": {},
"outputs": [],
"source": [
"# Already covered by repo-level requirements.txt; left for reference.\n",
"# !pip install agent-framework -U"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fec2cf19",
"metadata": {},
"outputs": [],
"source": [
"from agent_framework import (\n",
" Message,\n",
" WorkflowBuilder,\n",
" WorkflowEvent,\n",
" WorkflowViz,\n",
")\n",
"from agent_framework.foundry import FoundryChatClient\n",
"from azure.identity import AzureCliCredential\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5d1a0590",
"metadata": {},
"outputs": [],
"source": [
"\n",
"import os\n",
"import base64\n",
"from dotenv import load_dotenv"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cbbeaf06",
"metadata": {},
"outputs": [],
"source": [
"load_dotenv()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b1ff1a7b",
"metadata": {},
"outputs": [],
"source": [
"# Configure the Microsoft Foundry client with keyless authentication.\n",
"# FoundryChatClient targets the Azure OpenAI Responses API.\n",
"provider = FoundryChatClient(\n",
" project_endpoint=os.environ[\"AZURE_AI_PROJECT_ENDPOINT\"],\n",
" model=os.environ[\"AZURE_AI_MODEL_DEPLOYMENT_NAME\"],\n",
" credential=AzureCliCredential(),\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0d64a0a0",
"metadata": {},
"outputs": [],
"source": [
"SalesAgentName = \"Sales-Agent\"\n",
"SalesAgentInstructions = \"You are my furniture sales consultant, you can find different furniture elements from the pictures and give me a purchase suggestion\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "26b38cbf",
"metadata": {},
"outputs": [],
"source": [
"PriceAgentName = \"Price-Agent\"\n",
"PriceAgentInstructions = \"\"\"You are a furniture pricing specialist and budget consultant. Your responsibilities include:\n",
" 1. Analyze furniture items and provide realistic price ranges based on quality, brand, and market standards\n",
" 2. Break down pricing by individual furniture pieces\n",
" 3. Provide budget-friendly alternatives and premium options\n",
" 4. Consider different price tiers (budget, mid-range, premium)\n",
" 5. Include estimated total costs for room setups\n",
" 6. Suggest where to find the best deals and shopping recommendations\n",
" 7. Factor in additional costs like delivery, assembly, and accessories\n",
" 8. Provide seasonal pricing insights and best times to buy\n",
" Always format your response with clear price breakdowns and explanations for the pricing rationale.\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8dad49b7",
"metadata": {},
"outputs": [],
"source": [
"QuoteAgentName = \"Quote-Agent\"\n",
"QuoteAgentInstructions = \"\"\"You are a assistant that create a quote for furniture purchase.\n",
" 1. Create a well-structured quote document that includes:\n",
" 2. A title page with the document title, date, and client name\n",
" 3. An introduction summarizing the purpose of the document\n",
" 4. A summary section with total estimated costs and recommendations\n",
" 5. Use clear headings, bullet points, and tables for easy readability\n",
" 6. All quotes are presented in markdown form\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c9a55d69",
"metadata": {},
"outputs": [],
"source": [
"sales_agent = provider.as_agent(\n",
" name=SalesAgentName,\n",
" instructions=SalesAgentInstructions,\n",
")\n",
"\n",
"price_agent = provider.as_agent(\n",
" name=PriceAgentName,\n",
" instructions=PriceAgentInstructions,\n",
")\n",
"\n",
"quote_agent = provider.as_agent(\n",
" name=QuoteAgentName,\n",
" instructions=QuoteAgentInstructions,\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b3ac64f0",
"metadata": {},
"outputs": [],
"source": [
"workflow = (\n",
" WorkflowBuilder(start_executor=sales_agent)\n",
" .add_edge(sales_agent, price_agent)\n",
" .add_edge(price_agent, quote_agent)\n",
" .build()\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "12eb6379",
"metadata": {},
"outputs": [],
"source": [
"print(\"Generating workflow visualization...\")\n",
"viz = WorkflowViz(workflow)\n",
"# Print out the mermaid string.\n",
"print(\"Mermaid string: \\n=======\")\n",
"print(viz.to_mermaid())\n",
"print(\"=======\")\n",
"# Print out the DiGraph string.\n",
"print(\"DiGraph string: \\n=======\")\n",
"print(viz.to_digraph())\n",
"print(\"=======\")\n",
"# SVG export needs the optional graphviz extra (`pip install graphviz`) plus the\n",
"# graphviz system binary; if it's not available, fall back to the text strings above.\n",
"try:\n",
" svg_file = viz.export(format=\"svg\")\n",
" print(f\"SVG file saved to: {svg_file}\")\n",
"except ImportError as e:\n",
" svg_file = None\n",
" print(f\"SVG export skipped (install graphviz to enable): {e}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "57b86a4e",
"metadata": {},
"outputs": [],
"source": [
"class DatabaseEvent(WorkflowEvent): ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "466f110e",
"metadata": {},
"outputs": [],
"source": [
"# Display the exported workflow SVG inline in the notebook\n",
"\n",
"from IPython.display import SVG, display, HTML\n",
"import os\n",
"\n",
"print(f\"Attempting to display SVG file at: {svg_file}\")\n",
"\n",
"if svg_file and os.path.exists(svg_file):\n",
" try:\n",
" # Preferred: direct SVG rendering\n",
" display(SVG(filename=svg_file))\n",
" except Exception as e:\n",
" print(f\"⚠️ Direct SVG render failed: {e}. Falling back to raw HTML.\")\n",
" try:\n",
" with open(svg_file, \"r\", encoding=\"utf-8\") as f:\n",
" svg_text = f.read()\n",
" display(HTML(svg_text))\n",
" except Exception as inner:\n",
" print(f\"❌ Fallback HTML render also failed: {inner}\")\n",
"else:\n",
" print(\"❌ SVG file not found. Ensure viz.export(format='svg') ran successfully.\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e0c32e98",
"metadata": {},
"outputs": [],
"source": [
"image_path = \"../imgs/home.png\"\n",
"with open(image_path, \"rb\") as image_file:\n",
" image_b64 = base64.b64encode(image_file.read()).decode()\n",
"image_uri = f\"data:image/png;base64,{image_b64}\"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "417e237d",
"metadata": {},
"outputs": [],
"source": [
"# Note: the original notebook used a multimodal ChatMessage with an image of a\n",
"# living room. The current Message class no longer ships TextContent/DataContent\n",
"# helpers, so this migration uses a textual description of the same scene to\n",
"# keep the lesson focused on sequential workflow mechanics.\n",
"message = Message(\n",
" role=\"user\",\n",
" text=(\n",
" \"I am furnishing a modern living room and want pieces that fit a warm, \"\n",
" \"inviting style: a comfortable three-seat sofa, two accent armchairs, a \"\n",
" \"wooden coffee table, a TV stand, a floor lamp, and a soft area rug. \"\n",
" \"Please find appropriate furniture and give the corresponding price for \"\n",
" \"each piece, then produce a final purchase quote.\"\n",
" ),\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bb76bba5",
"metadata": {},
"outputs": [],
"source": [
"# Workflow.run_stream is no longer part of the public API; the current Workflow\n",
"# returns a results object whose `get_outputs()` produces the AgentResponse from\n",
"# each output executor. The final stage (quote_agent) is the only output here.\n",
"events = await workflow.run(message)\n",
"outputs = events.get_outputs()\n",
"result = outputs[0].text if outputs else \"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a8db5dbb",
"metadata": {},
"outputs": [],
"source": [
"result.replace(\"None\", \"\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "agentenv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,354 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "795c70a9",
"metadata": {},
"source": [
"# ⚡ Concurrent Agent Workflows with Microsoft Foundry (Python)\n",
"\n",
"## 📋 Advanced Parallel Processing Tutorial\n",
"\n",
"This notebook demonstrates **concurrent workflow patterns** using the Microsoft Agent Framework. You'll learn how to build high-performance, parallel processing workflows where multiple AI agents execute simultaneously, dramatically improving throughput and enabling sophisticated multi-threaded business processes.\n",
"\n",
"> **Migration note:** This sample previously referenced GitHub Models. GitHub Models is deprecated (retiring July 2026), so it now uses **Microsoft Foundry** through the `FoundryChatClient`, which targets the Azure OpenAI **Responses API**.\n",
"\n",
"## 🎯 Learning Objectives\n",
"\n",
"### 🚀 **Concurrent Processing Fundamentals**\n",
"- **Parallel Agent Execution**: Run multiple agents simultaneously for maximum efficiency\n",
"- **Workflow Orchestration**: Coordinate concurrent operations while maintaining data consistency\n",
"- **Performance Optimization**: Achieve significant speedup through parallel processing\n",
"- **Resource Management**: Efficiently utilize AI model resources across concurrent operations\n",
"\n",
"### 🏗️ **Advanced Concurrency Patterns**\n",
"- **Fork-Join Processing**: Split work across multiple agents and merge results\n",
"- **Pipeline Parallelism**: Overlapping execution stages for continuous throughput\n",
"- **Load Balancing**: Distribute work evenly across available agent resources\n",
"- **Synchronization Points**: Coordinate concurrent agents at critical workflow stages\n",
"\n",
"### 🏢 **Enterprise Concurrent Applications**\n",
"- **High-Volume Document Processing**: Process multiple documents simultaneously\n",
"- **Real-Time Content Analysis**: Concurrent analysis of incoming data streams\n",
"- **Batch Processing Optimization**: Maximize throughput for large-scale operations\n",
"- **Multi-Modal Analysis**: Parallel processing of different content types (text, images, data)\n",
"\n",
"## ⚙️ Prerequisites & Setup\n",
"\n",
"### 📦 **Required Dependencies**\n",
"\n",
"Install Agent Framework with concurrent workflow capabilities:\n",
"\n",
"```bash\n",
"pip install agent-framework -U\n",
"```\n",
"\n",
"### 🔑 **Microsoft Foundry Configuration**\n",
"\n",
"Sign in with the Azure CLI (`az login`) so `AzureCliCredential` can authenticate, then set your Microsoft Foundry project details.\n",
"\n",
"**Environment Setup (.env file):**\n",
"```env\n",
"AZURE_AI_PROJECT_ENDPOINT=https://<your-project>.services.ai.azure.com\n",
"AZURE_AI_MODEL_DEPLOYMENT_NAME=gpt-4o-mini\n",
"```\n",
"\n",
"**Concurrent Processing Considerations:**\n",
"- **Rate Limits**: Monitor Azure OpenAI rate limits for concurrent requests\n",
"- **Resource Usage**: Consider memory and CPU usage with multiple concurrent agents\n",
"- **Error Handling**: Implement robust error recovery for parallel operations\n",
"\n",
"### 🏗️ **Concurrent Workflow Architecture**\n",
"\n",
"```mermaid\n",
"graph TD\n",
" A[Workflow Start] --> B[Concurrent Execution]\n",
" B --> C[Agent Pool 1]\n",
" B --> D[Agent Pool 2]\n",
" B --> E[Agent Pool 3]\n",
" C --> F[Result Aggregation]\n",
" D --> F\n",
" E --> F\n",
" F --> G[Final Output]\n",
" \n",
" H[Microsoft Foundry] --> C\n",
" H --> D\n",
" H --> E\n",
"```\n",
"\n",
"**Key Benefits:**\n",
"- **⚡ Performance**: Significant speedup through parallel execution\n",
"- **📈 Scalability**: Handle increased workloads without proportional time increase\n",
"- **🔄 Efficiency**: Better utilization of available computational resources\n",
"- **🎯 Throughput**: Process more work in the same amount of time\n",
"\n",
"## 🎨 **Concurrent Workflow Design Patterns**\n",
"\n",
"### 🔍 **Research & Analysis Pipeline**\n",
"```\n",
"Research Task → Parallel Research Agents → Content Synthesis → Quality Review\n",
"```\n",
"\n",
"### 📊 **Data Processing Workflow**\n",
"```\n",
"Input Data → Concurrent Processing Agents → Result Aggregation → Final Report\n",
"```\n",
"\n",
"### 🎭 **Content Creation Pipeline**\n",
"```\n",
"Content Brief → Parallel Content Generators → Review & Merge → Final Content\n",
"```\n",
"\n",
"### 🔄 **Multi-Stage Processing**\n",
"```\n",
"Input → Stage 1 (Concurrent) → Stage 2 (Concurrent) → Stage 3 (Sequential) → Output\n",
"```\n",
"\n",
"## 🏢 **Enterprise Performance Benefits**\n",
"\n",
"### ⚡ **Throughput Optimization**\n",
"- **Parallel Execution**: Multiple agents working simultaneously\n",
"- **Resource Utilization**: Maximum efficiency of available AI model capacity\n",
"- **Time Reduction**: Significant decrease in total processing time\n",
"- **Scalable Architecture**: Easily add more concurrent agents as needed\n",
"\n",
"### 🛡️ **Reliability & Resilience**\n",
"- **Fault Tolerance**: Individual agent failures don't stop the entire workflow\n",
"- **Error Isolation**: Problems in one concurrent branch don't affect others\n",
"- **Graceful Degradation**: System continues operating even with reduced agent capacity\n",
"- **Recovery Mechanisms**: Automatic retry and error handling for failed operations\n",
"\n",
"### 📊 **Monitoring & Observability**\n",
"- **Concurrent Execution Tracking**: Monitor progress of all parallel operations\n",
"- **Performance Metrics**: Measure speedup and efficiency gains\n",
"- **Resource Usage Analytics**: Optimize concurrent agent allocation\n",
"- **Bottleneck Identification**: Find and resolve performance constraints\n",
"\n",
"Let's build high-performance concurrent AI workflows! 🚀\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "81f035d2",
"metadata": {},
"outputs": [],
"source": [
"# Already covered by repo-level requirements.txt; left for reference.\n",
"# !pip install agent-framework -U"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c171c539",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from typing import Any\n",
"\n",
"from agent_framework import (\n",
" Executor,\n",
" Message,\n",
" WorkflowBuilder,\n",
" WorkflowContext,\n",
" WorkflowViz,\n",
" handler,\n",
")\n",
"from agent_framework.foundry import FoundryChatClient\n",
"from azure.identity import AzureCliCredential\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6ce4663e",
"metadata": {},
"outputs": [],
"source": [
"# Configure the Microsoft Foundry client with keyless authentication.\n",
"# FoundryChatClient targets the Azure OpenAI Responses API.\n",
"provider = FoundryChatClient(\n",
" project_endpoint=os.environ[\"AZURE_AI_PROJECT_ENDPOINT\"],\n",
" model=os.environ[\"AZURE_AI_MODEL_DEPLOYMENT_NAME\"],\n",
" credential=AzureCliCredential(),\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ae0b1744",
"metadata": {},
"outputs": [],
"source": [
"ResearcherAgentName = \"Researcher-Agent\"\n",
"ResearcherAgentInstructions = \"You are my travel researcher, working with me to analyze the destination, list relevant attractions, and make detailed plans for each attraction.\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "339ca225",
"metadata": {},
"outputs": [],
"source": [
"PlanAgentName = \"Plan-Agent\"\n",
"PlanAgentInstructions = \"You are my travel planner, working with me to create a detailed travel plan based on the researcher's findings.\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "36381824",
"metadata": {},
"outputs": [],
"source": [
"research_agent = provider.as_agent(\n",
" name=ResearcherAgentName,\n",
" instructions=ResearcherAgentInstructions,\n",
")\n",
"\n",
"plan_agent = provider.as_agent(\n",
" name=PlanAgentName,\n",
" instructions=PlanAgentInstructions,\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cc9f8593",
"metadata": {},
"outputs": [],
"source": [
"# A passthrough executor that broadcasts the user input to every agent in parallel.\n",
"class InputDispatcher(Executor):\n",
" \"\"\"Forward the user input unchanged to all participating agents.\"\"\"\n",
"\n",
" @handler\n",
" async def forward(self, text: str, ctx: WorkflowContext[str]) -> None:\n",
" await ctx.send_message(text)\n",
"\n",
"\n",
"dispatcher = InputDispatcher(id=\"dispatcher\")\n",
"agents = [research_agent, plan_agent]\n",
"\n",
"workflow = (\n",
" WorkflowBuilder(\n",
" start_executor=dispatcher,\n",
" output_executors=agents,\n",
" )\n",
" .add_fan_out_edges(dispatcher, agents)\n",
" .build()\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5c7ede3e",
"metadata": {},
"outputs": [],
"source": [
"print(\"Generating workflow visualization...\")\n",
"viz = WorkflowViz(workflow)\n",
"# Print out the mermaid string.\n",
"print(\"Mermaid string: \\n=======\")\n",
"print(viz.to_mermaid())\n",
"print(\"=======\")\n",
"# Print out the DiGraph string.\n",
"print(\"DiGraph string: \\n=======\")\n",
"print(viz.to_digraph())\n",
"print(\"=======\")\n",
"# SVG export needs the optional graphviz extra plus the graphviz system binary;\n",
"# fall back gracefully if it is not available.\n",
"try:\n",
" svg_file = viz.export(format=\"svg\")\n",
" print(f\"SVG file saved to: {svg_file}\")\n",
"except ImportError as e:\n",
" svg_file = None\n",
" print(f\"SVG export skipped (install graphviz to enable): {e}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c329766a",
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import SVG, display, HTML\n",
"import os\n",
"\n",
"print(f\"Attempting to display SVG file at: {svg_file}\")\n",
"\n",
"if svg_file and os.path.exists(svg_file):\n",
" try:\n",
" # Preferred: direct SVG rendering\n",
" display(SVG(filename=svg_file))\n",
" except Exception as e:\n",
" print(f\"⚠️ Direct SVG render failed: {e}. Falling back to raw HTML.\")\n",
" try:\n",
" with open(svg_file, \"r\", encoding=\"utf-8\") as f:\n",
" svg_text = f.read()\n",
" display(HTML(svg_text))\n",
" except Exception as inner:\n",
" print(f\"❌ Fallback HTML render also failed: {inner}\")\n",
"else:\n",
" print(\"❌ SVG file not found. Ensure viz.export(format='svg') ran successfully.\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ccf93181",
"metadata": {},
"outputs": [],
"source": [
"events = await workflow.run(\"Plan a trip to Seattle in December\")\n",
"outputs = events.get_outputs()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3b71d9c7",
"metadata": {},
"outputs": [],
"source": [
"if outputs:\n",
" print(\"===== Final Aggregated Responses =====\")\n",
" # outputs is a list of AgentResponse objects, one per output executor\n",
" # (research_agent then plan_agent), in the order given to output_executors.\n",
" for i, response in enumerate(outputs, start=1):\n",
" print(f\"{'-' * 60}\\n\\n{i:02d}:\\n{response.text}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "agentenv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,518 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "73c153de",
"metadata": {},
"source": [
"# 🔀 Conditional Agent Workflows with Microsoft Foundry (Python)\n",
"\n",
"## 📋 Advanced Decision-Based Workflow Tutorial\n",
"\n",
"This notebook demonstrates **conditional workflow patterns** using Microsoft Foundry and the Microsoft Agent Framework. You'll learn how to build intelligent, decision-driven workflows that dynamically route processing based on content analysis, business rules, and AI-powered decision making.\n",
"\n",
"## 🎯 Learning Objectives\n",
"\n",
"### 🧠 **Intelligent Decision Making**\n",
"- **Conditional Logic**: Implement dynamic branching based on AI analysis and business rules\n",
"- **Content-Aware Routing**: Route workflow paths based on content analysis and classification\n",
"- **Adaptive Processing**: Adjust workflow behavior based on real-time conditions and data\n",
"- **Azure AI Integration**: Leverage Microsoft Foundry's advanced capabilities for decision making\n",
"\n",
"### 🔀 **Advanced Workflow Patterns**\n",
"- **Decision Trees**: Build complex decision structures with multiple branching points\n",
"- **Rule-Based Processing**: Implement business logic and compliance requirements\n",
"- **Dynamic Workflow Modification**: Adapt workflows based on runtime conditions\n",
"- **Context-Aware Operations**: Make decisions based on accumulated workflow context\n",
"\n",
"### 🏢 **Enterprise Conditional Applications**\n",
"- **Document Classification**: Route documents to appropriate processing workflows\n",
"- **Customer Service Triage**: Automatically route inquiries to specialized handling workflows\n",
"- **Compliance Processing**: Apply different validation rules based on content type and regulations\n",
"- **Quality Assurance**: Route content through different review processes based on quality metrics\n",
"\n",
"## ⚙️ Prerequisites & Setup\n",
"\n",
"### 📦 **Installation & Dependencies**\n",
"\n",
"This workflow requires specific installation steps for Microsoft Foundry integration:\n",
"\n",
"```bash\n",
"\n",
"pip install agent-framework-azure-ai -U \n",
"```\n",
"\n",
"### 🔑 **Microsoft Foundry Configuration**\n",
"\n",
"**Required Azure Resources:**\n",
"- Microsoft Foundry workspace with appropriate models deployed\n",
"- Azure subscription with necessary permissions\n",
"- Azure CLI authentication configured\n",
"\n",
"\n",
"**Authentication Setup:**\n",
"```bash\n",
"# Azure CLI authentication\n",
"az login\n",
"az account set --subscription \"your-subscription-id\"\n",
"azd auth login\n",
"```\n",
"\n",
"### 🏗️ **Conditional Workflow Architecture**\n",
"\n",
"```mermaid\n",
"graph TD\n",
" A[Input Document/Request] --> B[Initial Analysis Agent]\n",
" B --> C{Decision Point}\n",
" C -->|Condition 1| D[Workflow Path A]\n",
" C -->|Condition 2| E[Workflow Path B]\n",
" C -->|Condition 3| F[Workflow Path C]\n",
" D --> G[Specialized Processing A]\n",
" E --> H[Specialized Processing B]\n",
" F --> I[Specialized Processing C]\n",
" G --> J[Result Integration]\n",
" H --> J\n",
" I --> J\n",
" J --> K[Final Output]\n",
"```\n",
"\n",
"**Key Components:**\n",
"- **Analysis Agents**: AI agents that evaluate content and make routing decisions\n",
"- **Decision Points**: Conditional logic that determines workflow paths\n",
"- **Specialized Processors**: Different agents optimized for specific content types or scenarios\n",
"- **Integration Layer**: Combines results from different workflow paths\n",
"\n",
"## 🎨 **Conditional Workflow Design Patterns**\n",
"\n",
"### 📋 **Document Processing Triage**\n",
"```\n",
"Document Input → Content Analysis → Classification → Specialized Processing Workflow\n",
"```\n",
"\n",
"### 🎯 **Customer Service Routing**\n",
"```\n",
"Customer Inquiry → Intent Analysis → Urgency Assessment → Route to Specialist Team\n",
"```\n",
"\n",
"### 🔍 **Quality Assurance Workflow**\n",
"```\n",
"Content Input → Quality Metrics → Risk Assessment → Appropriate Review Process\n",
"```\n",
"\n",
"### 📊 **Business Intelligence Pipeline**\n",
"```\n",
"Data Input → Source Analysis → Processing Rules → Specialized Analytics Workflow\n",
"```\n",
"\n",
"## 🏢 **Enterprise Benefits**\n",
"\n",
"### 🎯 **Intelligent Automation**\n",
"- **Smart Routing**: Automatically direct work to the most appropriate processing path\n",
"- **Adaptive Behavior**: Workflows that learn and adapt based on patterns and outcomes\n",
"- **Business Rule Integration**: Incorporate complex business logic and compliance requirements\n",
"- **Context-Aware Processing**: Make decisions based on full workflow context and history\n",
"\n",
"### 📈 **Operational Efficiency**\n",
"- **Reduced Manual Intervention**: Automated decision making reduces need for human routing\n",
"- **Specialized Processing**: Each workflow path optimized for specific scenarios\n",
"- **Resource Optimization**: Efficient allocation of processing resources based on content type\n",
"- **Faster Time-to-Resolution**: Direct routing to appropriate specialists and processes\n",
"\n",
"### 🛡️ **Governance & Control**\n",
"- **Audit Trails**: Complete logging of decision points and routing rationale\n",
"- **Compliance Enforcement**: Automatic application of regulatory and policy requirements\n",
"- **Risk Management**: Route high-risk content through enhanced security and review processes\n",
"- **Quality Assurance**: Ensure appropriate level of review based on content characteristics\n",
"\n",
"### 📊 **Analytics & Optimization**\n",
"- **Decision Analytics**: Track effectiveness of routing decisions and workflow paths\n",
"- **Performance Metrics**: Measure efficiency of different workflow branches\n",
"- **Continuous Improvement**: Identify optimization opportunities in conditional logic\n",
"- **Business Intelligence**: Gain insights into content patterns and processing requirements\n",
"\n",
"Let's build intelligent, decision-driven AI workflows! 🚀"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d0a6c7c7",
"metadata": {},
"outputs": [],
"source": [
"! pip install agent-framework-azure-ai -U "
]
},
{
"cell_type": "markdown",
"id": "1c80c16f",
"metadata": {},
"source": [
"requirements.txt & constraints.txt - in ./Installation\n",
"\n",
"please copy .env.examples as .env"
]
},
{
"cell_type": "markdown",
"id": "43ce2a42",
"metadata": {},
"source": [
"**Note** choose gpt-4.1-mini"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "453e5695",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"from dataclasses import dataclass\n",
"from typing_extensions import Literal\n",
"from pydantic import BaseModel"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8710bd54",
"metadata": {},
"outputs": [],
"source": [
"from azure.identity.aio import AzureCliCredential\n",
"from dotenv import load_dotenv\n",
"\n",
"from agent_framework import HostedWebSearchTool\n",
"from agent_framework.azure import AzureAIAgentClient\n",
"from agent_framework import (\n",
" AgentExecutor,\n",
" AgentExecutorRequest,\n",
" AgentExecutorResponse,\n",
" HostedCodeInterpreterTool,\n",
" ChatMessage,\n",
" Role,\n",
" WorkflowBuilder,\n",
" WorkflowContext,\n",
" WorkflowEvent,\n",
" executor,\n",
" WorkflowViz\n",
")\n",
"\n",
"\n",
"from azure.ai.agents.models import BingGroundingTool,CodeInterpreterTool"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "52042c20",
"metadata": {},
"outputs": [],
"source": [
"load_dotenv()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c0d46d0e",
"metadata": {},
"outputs": [],
"source": [
"EvangelistInstructions = \"\"\"\n",
"You are a technology evangelist create a first draft for a technical tutorials.\n",
"1. Each knowledge point in the outline must include a link. Follow the link to access the content related to the knowledge point in the outline. Expand on that content.\n",
"2. Each knowledge point must be explained in detail.\n",
"3. Rewrite the content according to the entry requirements, including the title, outline, and corresponding content. It is not necessary to follow the outline in full order.\n",
"4. The content must be more than 200 words.\n",
"4. Output draft as Markdown format. set 'draft_content' to the draft content.\n",
"5. return result as JSON with fields 'draft_content' (string).\n",
"\"\"\"\n",
"\n",
"ContentReviewerInstructions = \"\"\"\n",
"You are a content reviewer for a publishing company. You need to check whether the tutorial's draft content meets the following requirements:\n",
"\n",
"1. The draft content less than 200 words, set 'review_result' to 'No' and 'reason' to 'Content is too short'. If the draft content is more than 200 words, set 'review_result' to 'Yes' and 'reason' to 'The content is good'.\n",
"2. set 'draft_content' to the original draft content.\n",
"3. return result as JSON with fields 'review_result' (one of Yes, No) and 'reason' (string) and 'draft_content' (string).\n",
"\n",
"\"\"\"\n",
"\n",
"PublisherInstructions = \"\"\"\n",
"You are the content publisher ,run code to save the tutorial's draft content as a Markdown file. Saved file's name is marked with current date and time, such as yearmonthdayhourminsec. Note that if it is 1-9, you need to add 0, such as 20240101123045.md. \n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a51cd795",
"metadata": {},
"outputs": [],
"source": [
"OUTLINE_Content =\"\"\"\n",
"# Introduce AI Agent\n",
"\n",
"\n",
"## What's AI Agent\n",
"\n",
"https://github.com/microsoft/ai-agents-for-beginners/tree/main/01-intro-to-ai-agents\n",
"\n",
"\n",
"***Note*** Don's create any sample code \n",
"\n",
"\n",
"## Introduce Microsoft Foundry Agent Service \n",
"\n",
"https://learn.microsoft.com/en-us/azure/ai-foundry/agents/overview\n",
"\n",
"\n",
"***Note*** Don's create any sample code \n",
"\n",
"\n",
"## Microsoft Agent Framework \n",
"\n",
"https://github.com/microsoft/agent-framework/tree/main/docs/docs-templates\n",
"\n",
"\n",
"***Note*** Don's create any sample code \n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b9c19b90",
"metadata": {},
"outputs": [],
"source": [
"conn_id = os.environ[\"BING_CONNECTION_ID\"] # Ensure the BING_CONNECTION_NAME environment variable is set\n",
"\n",
"# Initialize the Bing Grounding tool\n",
"bing = BingGroundingTool(connection_id=conn_id)\n",
"\n",
"code_interpreter = CodeInterpreterTool()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c7b615a0",
"metadata": {},
"outputs": [],
"source": [
"class EvangelistAgent(BaseModel):\n",
" draft_content: str\n",
"\n",
"class ReviewAgent(BaseModel):\n",
" review_result: Literal[\"Yes\", \"No\"]\n",
" reason: str\n",
" draft_content: str\n",
"\n",
"class PublisherAgent(BaseModel):\n",
" file_path: str\n",
"\n",
"@dataclass\n",
"class ReviewResult:\n",
" review_result: str\n",
" reason: str\n",
" draft_content: str\n",
"\n",
"@executor(id=\"to_reviewer_result\")\n",
"async def to_reviewer_result(response: AgentExecutorResponse, ctx: WorkflowContext[ReviewResult]) -> None:\n",
"\n",
" print(f\"Raw response from reviewer agent: {response.agent_run_response.text}\")\n",
"\n",
" parsed = ReviewAgent.model_validate_json(response.agent_run_response.text)\n",
" await ctx.send_message(\n",
" ReviewResult(\n",
" review_result=parsed.review_result,\n",
" reason=parsed.reason,\n",
" draft_content=parsed.draft_content,\n",
" )\n",
" )\n",
"\n",
"\n",
"def select_targets(review: ReviewResult, target_ids: list[str]) -> list[str]:\n",
" # Order: [handle_review, submit_to_email_assistant, summarize_email, handle_uncertain]\n",
" handle_review_id, save_draft_id = target_ids\n",
" if review.review_result == \"Yes\":\n",
" return [save_draft_id]\n",
" else:\n",
" return [handle_review_id]\n",
" \n",
"\n",
"\n",
"@executor(id=\"handle_review\")\n",
"async def handle_review(review: ReviewResult, ctx: WorkflowContext[str]) -> None:\n",
" if review.review_result == \"No\":\n",
" await ctx.yield_output(f\"Review failed: {review.reason}, please revise the draft.\")\n",
" else:\n",
" await ctx.send_message(\n",
" AgentExecutorRequest(messages=[ChatMessage(Role.USER, text=review.draft_content)], should_respond=True)\n",
" )\n",
"\n",
"\n",
"@executor(id=\"save_draft\")\n",
"async def save_draft(review: ReviewResult, ctx: WorkflowContext[AgentExecutorRequest]) -> None:\n",
" # Only called for long NotSpam emails by selection_func\n",
" await ctx.send_message(\n",
" AgentExecutorRequest(messages=[ChatMessage(Role.USER, text=review.draft_content)], should_respond=True)\n",
" )\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe774ad9",
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import SVG, display, HTML"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a21415e7",
"metadata": {},
"outputs": [],
"source": [
"class DatabaseEvent(WorkflowEvent): ..."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "281c577c",
"metadata": {},
"outputs": [],
"source": [
"async with (\n",
" AzureCliCredential() as credential,\n",
" AzureAIAgentClient(async_credential=credential) as chat_client,\n",
" ): \n",
" try:\n",
" evangelist_agent = AgentExecutor(chat_client.create_agent(\n",
" instructions= (EvangelistInstructions),\n",
" tools=[HostedWebSearchTool()],\n",
" # response_format=EvangelistAgent\n",
" ), id=\"evangelist_agent\")\n",
" reviewer_agent = AgentExecutor(chat_client.create_agent(\n",
" instructions=(ContentReviewerInstructions),\n",
" # response_format=ReviewAgent\n",
" ), id=\"reviewer_agent\")\n",
" publisher_agent = AgentExecutor(chat_client.create_agent(\n",
" instructions=PublisherInstructions,\n",
" tools=HostedCodeInterpreterTool(),\n",
" response_format=PublisherAgent\n",
" ), id=\"publisher_agent\")\n",
"\n",
" workflow = (\n",
" WorkflowBuilder()\n",
" .set_start_executor(evangelist_agent)\n",
" .add_edge(evangelist_agent, reviewer_agent)\n",
" .add_edge(reviewer_agent, to_reviewer_result)\n",
" .add_multi_selection_edge_group(\n",
" to_reviewer_result,\n",
" [handle_review, save_draft],\n",
" selection_func=select_targets,\n",
" )\n",
" .add_edge(save_draft, publisher_agent)\n",
" .build()\n",
" )\n",
"\n",
" # workflow = SequentialBuilder().participants([evangelist_chat_agent, reviewer_chat_agent, publisher_chat_agent]).build()\n",
" print(\"Generating workflow visualization...\")\n",
" viz = WorkflowViz(workflow)\n",
" # Print out the mermaid string.\n",
" print(\"Mermaid string: \\n=======\")\n",
" print(viz.to_mermaid())\n",
" print(\"=======\")\n",
" # Print out the DiGraph string.\n",
" print(\"DiGraph string: \\n=======\")\n",
" print(viz.to_digraph())\n",
" print(\"=======\")\n",
" svg_file = viz.export(format=\"svg\")\n",
" print(f\"SVG file saved to: {svg_file}\")\n",
"\n",
" if svg_file and os.path.exists(svg_file):\n",
" try:\n",
" # Preferred: direct SVG rendering\n",
" display(SVG(filename=svg_file))\n",
" except Exception as e:\n",
" print(f\"⚠️ Direct SVG render failed: {e}. Falling back to raw HTML.\")\n",
" try:\n",
" with open(svg_file, \"r\", encoding=\"utf-8\") as f:\n",
" svg_text = f.read()\n",
" display(HTML(svg_text))\n",
" except Exception as inner:\n",
" print(f\"❌ Fallback HTML render also failed: {inner}\")\n",
" else:\n",
" print(\"❌ SVG file not found. Ensure viz.export(format='svg') ran successfully.\")\n",
"\n",
" \n",
" task = \"\"\"\n",
" You are a evangelist , need to write a draft based on the following outline and the content provided in the link corresponding to the outline. After draft create , the reviewer check it , if it meets the requirements, it will be submitted to the publisher and save it as a Markdown file, otherwise need to rewrite draft until it meets the requirements.\n",
" The provided outline content and related links is as follows:\n",
"\n",
" \"\"\" + OUTLINE_Content\n",
"\n",
" \n",
" async for event in workflow.run_stream(task):\n",
" if isinstance(event, DatabaseEvent):\n",
" print(f\"{event}\")\n",
" if isinstance(event, WorkflowEvent):\n",
" print(f\"Workflow output: {event.data}\")\n",
"\n",
"\n",
"\n",
" finally:\n",
" print(\"done\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2a0cf9db",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "agentenv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.10"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}