Skip to content

Commit 6d3c6e2

Browse files
authored
Merge pull request #45 from john0isaac/update-agent-framework
update `agent_framework` example to use latest versions of libs
2 parents cbeb594 + 203359a commit 6d3c6e2

14 files changed

Lines changed: 457 additions & 566 deletions

examples/agentframework_basic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
import os
33

4-
from agent_framework import ChatAgent
4+
from agent_framework import Agent
55
from agent_framework.openai import OpenAIChatClient
66
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
77
from dotenv import load_dotenv
@@ -35,7 +35,7 @@
3535
else:
3636
client = OpenAIChatClient(api_key=os.environ["OPENAI_API_KEY"], model_id=os.environ.get("OPENAI_MODEL", "gpt-4o"))
3737

38-
agent = ChatAgent(chat_client=client, instructions="You're an informational agent. Answer questions cheerfully.")
38+
agent = Agent(client=client, instructions="You're an informational agent. Answer questions cheerfully.")
3939

4040

4141
async def main():

examples/agentframework_hitl.py

Lines changed: 170 additions & 268 deletions
Large diffs are not rendered by default.

examples/agentframework_magenticone.py

Lines changed: 83 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
"""
22
Agent Framework MagenticOne Example - Travel Planning with Multiple Agents
3+
pip install agent-framework-orchestrations==1.0.0b260212
34
"""
45
import asyncio
6+
import json
57
import os
68
from typing import cast
79

8-
from agent_framework import (
9-
AgentRunUpdateEvent,
10-
ChatAgent,
11-
ChatMessage,
12-
MagenticBuilder,
13-
MagenticOrchestratorEvent,
14-
MagenticProgressLedger,
15-
WorkflowOutputEvent,
16-
)
10+
from agent_framework import Agent, AgentResponseUpdate, Message, WorkflowEvent
1711
from agent_framework.openai import OpenAIChatClient
12+
from agent_framework.orchestrations import MagenticBuilder, MagenticProgressLedger
1813
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
1914
from dotenv import load_dotenv
2015
from rich.console import Console
@@ -54,8 +49,8 @@
5449
console = Console()
5550

5651
# Create the agents
57-
local_agent = ChatAgent(
58-
chat_client=client,
52+
local_agent = Agent(
53+
client=client,
5954
instructions=(
6055
"You are a helpful assistant that can suggest authentic and interesting local activities "
6156
"or places to visit for a user and can utilize any context information provided."
@@ -64,8 +59,8 @@
6459
description="A local assistant that can suggest local activities or places to visit.",
6560
)
6661

67-
language_agent = ChatAgent(
68-
chat_client=client,
62+
language_agent = Agent(
63+
client=client,
6964
instructions=(
7065
"You are a helpful assistant that can review travel plans, providing feedback on important/critical "
7166
"tips about how best to address language or communication challenges for the given destination. "
@@ -75,8 +70,8 @@
7570
description="A helpful assistant that can provide language tips for a given destination.",
7671
)
7772

78-
travel_summary_agent = ChatAgent(
79-
chat_client=client,
73+
travel_summary_agent = Agent(
74+
client=client,
8075
instructions=(
8176
"You are a helpful assistant that can take in all of the suggestions and advice from the other agents "
8277
"and provide a detailed final travel plan. You must ensure that the final plan is integrated and complete. "
@@ -87,92 +82,93 @@
8782
description="A helpful assistant that can summarize the travel plan.",
8883
)
8984

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",
85+
manager_agent = Agent(
86+
client=client,
87+
description="Orchestrator that coordinates the research and coding workflow",
88+
instructions="You coordinate a team to complete complex tasks efficiently.",
89+
name="manager_agent",
9690
)
9791

98-
# Build the Magentic workflow
99-
magentic_orchestrator = (
100-
MagenticBuilder()
101-
.participants([local_agent, language_agent, travel_summary_agent])
102-
.with_manager(
103-
agent=manager_agent,
92+
magentic_orchestrator = MagenticBuilder(
93+
participants=[local_agent, language_agent, travel_summary_agent],
94+
manager_agent=manager_agent,
10495
max_round_count=20,
10596
max_stall_count=3,
10697
max_reset_count=2,
107-
)
108-
.build()
109-
)
110-
111-
112-
async 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-
117-
async for event in magentic_orchestrator.run_stream("Plan a half-day trip to Costa Rica"):
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-
)
98+
).build()
99+
100+
101+
def handle_event(event: WorkflowEvent, last_message_id: str | None) -> str | None:
102+
"""Handle streaming events and return updated last_message_id."""
103+
if event.type == "output" and isinstance(event.data, AgentResponseUpdate):
104+
message_id = event.data.message_id
105+
if message_id != last_message_id:
106+
if last_message_id is not None:
107+
console.print()
108+
console.print(f"🤖 {event.executor_id}:", end=" ")
109+
last_message_id = message_id
110+
console.print(event.data, end="")
111+
return last_message_id
112+
113+
elif event.type == "magentic_orchestrator":
114+
console.print()
115+
emoji = "✅" if event.data.event_type.name == "PROGRESS_LEDGER_UPDATED" else "🦠"
116+
if isinstance(event.data.content, MagenticProgressLedger):
117+
console.print(
118+
Panel(
119+
json.dumps(event.data.content.to_dict(), indent=2),
120+
title=f"{emoji} Orchestrator: {event.data.event_type.name}",
121+
border_style="bold yellow",
122+
padding=(1, 2),
138123
)
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-
)
124+
)
125+
elif hasattr(event.data.content, "text"):
126+
console.print(
127+
Panel(
128+
Markdown(event.data.content.text),
129+
title=f"{emoji} Orchestrator: {event.data.event_type.name}",
130+
border_style="bold green",
131+
padding=(1, 2),
156132
)
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:
133+
)
134+
else:
167135
console.print(
168136
Panel(
169-
Markdown(output_messages[-1].text),
170-
title="🌎 Final Travel Plan",
137+
Markdown(str(event.data.content)),
138+
title=f"{emoji} Orchestrator: {event.data.event_type.name}",
171139
border_style="bold green",
172140
padding=(1, 2),
173141
)
174142
)
175143

144+
return last_message_id
145+
146+
147+
def print_final_result(output_event: WorkflowEvent | None) -> None:
148+
"""Print the final travel plan."""
149+
if output_event:
150+
output_messages = cast(list[Message], output_event.data)
151+
console.print(
152+
Panel(
153+
Markdown(output_messages[-1].text),
154+
title="🌎 Final Travel Plan",
155+
border_style="bold green",
156+
padding=(1, 2),
157+
)
158+
)
159+
160+
161+
async def main():
162+
last_message_id: str | None = None
163+
output_event: WorkflowEvent | None = None
164+
165+
async for event in magentic_orchestrator.run("Plan a half-day trip to Costa Rica", stream=True):
166+
last_message_id = handle_event(event, last_message_id)
167+
if event.type == "output" and not isinstance(event.data, AgentResponseUpdate):
168+
output_event = event
169+
170+
print_final_result(output_event)
171+
176172
if async_credential:
177173
await async_credential.close()
178174

examples/agentframework_supervisor.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from datetime import datetime
66
from typing import Annotated
77

8-
from agent_framework import ChatAgent
8+
from agent_framework import tool
99
from agent_framework.openai import OpenAIChatClient
1010
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
1111
from dotenv import load_dotenv
@@ -51,7 +51,7 @@
5151
# Sub-agent 1 tools: weekend planning
5252
# ----------------------------------------------------------------------------------
5353

54-
54+
@tool(approval_mode="never_require")
5555
def get_weather(
5656
city: Annotated[str, Field(description="The city to get the weather for.")],
5757
date: Annotated[str, Field(description="The date to get weather for in format YYYY-MM-DD.")],
@@ -64,6 +64,7 @@ def get_weather(
6464
return {"temperature": 60, "description": "Rainy"}
6565

6666

67+
@tool(approval_mode="never_require")
6768
def get_activities(
6869
city: Annotated[str, Field(description="The city to get activities for.")],
6970
date: Annotated[str, Field(description="The date to get activities for in format YYYY-MM-DD.")],
@@ -76,15 +77,15 @@ def get_activities(
7677
{"name": "Museum", "location": city},
7778
]
7879

79-
80+
@tool(approval_mode="never_require")
8081
def get_current_date() -> str:
8182
"""Gets the current date from the system (YYYY-MM-DD)."""
8283
logger.info("Getting current date")
8384
return datetime.now().strftime("%Y-%m-%d")
8485

8586

86-
weekend_agent = ChatAgent(
87-
chat_client=client,
87+
weekend_agent = client.as_agent(
88+
name="WeekendPlannerAgent",
8889
instructions=(
8990
"You help users plan their weekends and choose the best activities for the given weather. "
9091
"If an activity would be unpleasant in the weather, don't suggest it. "
@@ -93,7 +94,7 @@ def get_current_date() -> str:
9394
tools=[get_weather, get_activities, get_current_date],
9495
)
9596

96-
97+
@tool(approval_mode="never_require")
9798
async def plan_weekend(query: str) -> str:
9899
"""Plan a weekend based on user query and return the final response."""
99100
logger.info("Tool: plan_weekend invoked")
@@ -105,7 +106,7 @@ async def plan_weekend(query: str) -> str:
105106
# Sub-agent 2 tools: meal planning
106107
# ----------------------------------------------------------------------------------
107108

108-
109+
@tool(approval_mode="never_require")
109110
def find_recipes(
110111
query: Annotated[str, Field(description="User query or desired meal/ingredient")],
111112
) -> list[dict]:
@@ -137,7 +138,7 @@ def find_recipes(
137138
]
138139
return recipes
139140

140-
141+
@tool(approval_mode="never_require")
141142
def check_fridge() -> list[str]:
142143
"""Returns a JSON list of ingredients currently in the fridge."""
143144
logger.info("Checking fridge for current ingredients")
@@ -148,8 +149,8 @@ def check_fridge() -> list[str]:
148149
return items
149150

150151

151-
meal_agent = ChatAgent(
152-
chat_client=client,
152+
meal_agent = client.as_agent(
153+
name="MealPlannerAgent",
153154
instructions=(
154155
"You help users plan meals and choose the best recipes. "
155156
"Include the ingredients and cooking instructions in your response. "
@@ -158,7 +159,7 @@ def check_fridge() -> list[str]:
158159
tools=[find_recipes, check_fridge],
159160
)
160161

161-
162+
@tool(approval_mode="never_require")
162163
async def plan_meal(query: str) -> str:
163164
"""Plan a meal based on user query and return the final response."""
164165
logger.info("Tool: plan_meal invoked")
@@ -170,8 +171,8 @@ async def plan_meal(query: str) -> str:
170171
# Supervisor agent orchestrating sub-agents
171172
# ----------------------------------------------------------------------------------
172173

173-
supervisor_agent = ChatAgent(
174-
chat_client=client,
174+
supervisor_agent = client.as_agent(
175+
name="SupervisorAgent",
175176
instructions=(
176177
"You are a supervisor managing two specialist agents: a weekend planning agent and a meal planning agent. "
177178
"Break down the user's request, decide which specialist (or both) to call via the available tools, "

examples/agentframework_tool.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import random
55
from typing import Annotated
66

7-
from agent_framework import ChatAgent
7+
from agent_framework import tool
88
from agent_framework.openai import OpenAIChatClient
99
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
1010
from dotenv import load_dotenv
@@ -46,7 +46,7 @@
4646
else:
4747
client = OpenAIChatClient(api_key=os.environ["OPENAI_API_KEY"], model_id=os.environ.get("OPENAI_MODEL", "gpt-4o"))
4848

49-
49+
@tool(approval_mode="never_require")
5050
def get_weather(
5151
city: Annotated[str, Field(description="City name, spelled out fully")],
5252
) -> dict:
@@ -64,8 +64,10 @@ def get_weather(
6464
}
6565

6666

67-
agent = ChatAgent(
68-
chat_client=client, instructions="You're an informational agent. Answer questions cheerfully.", tools=[get_weather]
67+
agent = client.as_agent(
68+
name="WeatherAgent",
69+
instructions="You're an informational agent. Answer questions cheerfully.",
70+
tools=[get_weather]
6971
)
7072

7173

0 commit comments

Comments
 (0)