33"""
44import asyncio
55import os
6+ from typing import cast
67
78from agent_framework import (
9+ AgentRunUpdateEvent ,
810 ChatAgent ,
9- MagenticAgentMessageEvent ,
11+ ChatMessage ,
1012 MagenticBuilder ,
11- MagenticCallbackEvent ,
12- MagenticCallbackMode ,
13- MagenticOrchestratorMessageEvent ,
13+ MagenticOrchestratorEvent ,
14+ MagenticProgressLedger ,
1415 WorkflowOutputEvent ,
1516)
1617from agent_framework .openai import OpenAIChatClient
1920from rich .console import Console
2021from rich .markdown import Markdown
2122from rich .panel import Panel
23+ from rich .rule import Rule
2224
2325# Configure OpenAI client based on environment
2426load_dotenv (override = True )
8587 description = "A helpful assistant that can summarize the travel plan." ,
8688)
8789
90+ # Create a manager agent for orchestration
91+ manager_agent = ChatAgent (
92+ chat_client = client ,
93+ instructions = "You coordinate a team to complete travel planning tasks efficiently." ,
94+ name = "magentic_manager" ,
95+ description = "Orchestrator that coordinates the travel planning workflow" ,
96+ )
8897
89- # Event callback for streaming output with rich formatting
90- async def on_event (event : MagenticCallbackEvent ) -> None :
91- if isinstance (event , MagenticOrchestratorMessageEvent ):
92- emoji = "✅" if event .kind == "task_ledger" else "🦠"
93- console .print (
94- Panel (
95- Markdown (event .message .text ),
96- title = f"{ emoji } orchestrator: { event .kind } " ,
97- border_style = "bold green" ,
98- padding = (1 , 2 ),
99- )
100- )
101- elif isinstance (event , MagenticAgentMessageEvent ):
102- console .print (
103- Panel (
104- Markdown (event .message .text ),
105- title = f"🤖 { event .agent_id } " ,
106- border_style = "bold blue" ,
107- padding = (1 , 2 ),
108- )
109- )
110-
111-
98+ # Build the Magentic workflow
11299magentic_orchestrator = (
113100 MagenticBuilder ()
114- .participants (
115- local_agent = local_agent ,
116- language_agent = language_agent ,
117- travel_summary_agent = travel_summary_agent ,
118- )
119- .on_event (on_event , mode = MagenticCallbackMode .NON_STREAMING )
120- .with_standard_manager (
121- chat_client = client ,
101+ .participants ([local_agent , language_agent , travel_summary_agent ])
102+ .with_manager (
103+ agent = manager_agent ,
122104 max_round_count = 20 ,
123105 max_stall_count = 3 ,
124106 max_reset_count = 2 ,
@@ -128,17 +110,69 @@ async def on_event(event: MagenticCallbackEvent) -> None:
128110
129111
130112async def main ():
113+ # Keep track of the last message to format output nicely in streaming mode
114+ last_message_id : str | None = None
115+ output_event : WorkflowOutputEvent | None = None
116+
131117 async for event in magentic_orchestrator .run_stream ("Plan a half-day trip to Costa Rica" ):
132- if isinstance (event , WorkflowOutputEvent ):
133- final_result = event .data
118+ if isinstance (event , AgentRunUpdateEvent ):
119+ message_id = event .data .message_id
120+ if message_id != last_message_id :
121+ if last_message_id is not None :
122+ console .print () # Add spacing after previous message
123+ console .print (Rule (f"🤖 { event .executor_id } " , style = "bold blue" ))
124+ last_message_id = message_id
125+ console .print (event .data , end = "" )
126+
127+ elif isinstance (event , MagenticOrchestratorEvent ):
128+ console .print () # Ensure panel starts on a new line
129+ if isinstance (event .data , ChatMessage ):
130+ # Show the plan creation in a panel
131+ console .print (
132+ Panel (
133+ Markdown (event .data .text ),
134+ title = f"📋 Orchestrator: { event .event_type .name } " ,
135+ border_style = "bold green" ,
136+ padding = (1 , 2 ),
137+ )
138+ )
139+ elif isinstance (event .data , MagenticProgressLedger ):
140+ # Show a compact progress summary in a panel
141+ ledger = event .data
142+ satisfied = "✅" if ledger .is_request_satisfied .answer else "⏳ Steps pending"
143+ progress = "✅" if ledger .is_progress_being_made .answer else "❌ Progress stalled"
144+ loop = "⚠️ Loop detected" if ledger .is_in_loop .answer else ""
145+ next_agent = ledger .next_speaker .answer
146+ instruction = ledger .instruction_or_question .answer
147+
148+ status_text = f"Plan satisfied? { satisfied } | Making progress? { progress } { loop } \n \n ➡️ Next step: [bold]{ next_agent } [/bold]\n { instruction } "
149+ console .print (
150+ Panel (
151+ status_text ,
152+ title = f"📊 Orchestrator: { event .event_type .name } " ,
153+ border_style = "bold yellow" ,
154+ padding = (1 , 2 ),
155+ )
156+ )
157+
158+
159+ elif isinstance (event , WorkflowOutputEvent ):
160+ output_event = event
161+
162+ if output_event :
163+ console .print () # Add spacing
164+ # The output of the Magentic workflow is a list of ChatMessages with only one final message
165+ output_messages = cast (list [ChatMessage ], output_event .data )
166+ if output_messages :
134167 console .print (
135168 Panel (
136- Markdown (final_result .text ),
137- title = "🌎 final travel plan " ,
169+ Markdown (output_messages [ - 1 ] .text ),
170+ title = "🌎 Final Travel Plan " ,
138171 border_style = "bold green" ,
139172 padding = (1 , 2 ),
140173 )
141174 )
175+
142176 if async_credential :
143177 await async_credential .close ()
144178
0 commit comments