From f67c55affe1e2055e54f0685c961ccf1c47c09e3 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 18:56:36 -0800 Subject: [PATCH 01/11] Fixed ollama_chat_client sample --- .../02-agents/providers/ollama/ollama_chat_client.py | 7 ++++--- .../azure_functions/12_workflow_hitl/function_app.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/python/samples/02-agents/providers/ollama/ollama_chat_client.py b/python/samples/02-agents/providers/ollama/ollama_chat_client.py index 636b7e4aa2..2c46831ba0 100644 --- a/python/samples/02-agents/providers/ollama/ollama_chat_client.py +++ b/python/samples/02-agents/providers/ollama/ollama_chat_client.py @@ -3,7 +3,7 @@ import asyncio from datetime import datetime -from agent_framework import tool +from agent_framework import Message, tool from agent_framework.ollama import OllamaChatClient """ @@ -29,16 +29,17 @@ def get_time(): async def main() -> None: client = OllamaChatClient() message = "What time is it? Use a tool call" + messages = [Message(role="user", text=message)] stream = False print(f"User: {message}") if stream: print("Assistant: ", end="") - async for chunk in client.get_response(message, tools=get_time, stream=True): + async for chunk in client.get_response(messages, tools=get_time, stream=True): if str(chunk): print(str(chunk), end="") print("") else: - response = await client.get_response(message, tools=get_time) + response = await client.get_response(messages, tools=get_time) print(f"Assistant: {response}") diff --git a/python/samples/04-hosting/azure_functions/12_workflow_hitl/function_app.py b/python/samples/04-hosting/azure_functions/12_workflow_hitl/function_app.py index f747d60919..11d11b4a92 100644 --- a/python/samples/04-hosting/azure_functions/12_workflow_hitl/function_app.py +++ b/python/samples/04-hosting/azure_functions/12_workflow_hitl/function_app.py @@ -32,8 +32,8 @@ from agent_framework import ( AgentExecutorRequest, AgentExecutorResponse, - Message, Executor, + Message, Workflow, WorkflowBuilder, WorkflowContext, From 3fcce39d71a02e1db295018c6d43200a9dc1a4b0 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 18:58:20 -0800 Subject: [PATCH 02/11] Fixed ollama_chat_multimodal sample --- .../02-agents/providers/ollama/ollama_chat_multimodal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/02-agents/providers/ollama/ollama_chat_multimodal.py b/python/samples/02-agents/providers/ollama/ollama_chat_multimodal.py index 68c1246ad2..fb299cc146 100644 --- a/python/samples/02-agents/providers/ollama/ollama_chat_multimodal.py +++ b/python/samples/02-agents/providers/ollama/ollama_chat_multimodal.py @@ -40,7 +40,7 @@ async def test_image() -> None: ], ) - response = await client.get_response(message) + response = await client.get_response([message]) print(f"Image Response: {response}") From 94cb44028912ea8c2f6dad342a2912d8b3dd3503 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:13:09 -0800 Subject: [PATCH 03/11] Fixed function_tool_with_approval_and_sessions sample --- .../tools/function_tool_with_approval_and_sessions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/samples/02-agents/tools/function_tool_with_approval_and_sessions.py b/python/samples/02-agents/tools/function_tool_with_approval_and_sessions.py index 004a182876..6acb3383d6 100644 --- a/python/samples/02-agents/tools/function_tool_with_approval_and_sessions.py +++ b/python/samples/02-agents/tools/function_tool_with_approval_and_sessions.py @@ -5,6 +5,7 @@ from agent_framework import Agent, Message, tool from agent_framework.azure import AzureOpenAIChatClient +from azure.identity import AzureCliCredential """ Tool Approvals with Sessions @@ -29,7 +30,7 @@ async def approval_example() -> None: print("=== Tool Approval with Session ===\n") agent = Agent( - client=AzureOpenAIChatClient(), + client=AzureOpenAIChatClient(credential=AzureCliCredential()), name="CalendarAgent", instructions="You are a helpful calendar assistant.", tools=[add_to_calendar], @@ -65,7 +66,7 @@ async def rejection_example() -> None: print("=== Tool Rejection with Session ===\n") agent = Agent( - client=AzureOpenAIChatClient(), + client=AzureOpenAIChatClient(credential=AzureCliCredential()), name="CalendarAgent", instructions="You are a helpful calendar assistant.", tools=[add_to_calendar], From fc035eb3fad62af5ab9b74b9c493d38527ce2a26 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:24:06 -0800 Subject: [PATCH 04/11] Updated function_tool_with_session_injection sample --- .../02-agents/tools/function_tool_with_session_injection.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/samples/02-agents/tools/function_tool_with_session_injection.py b/python/samples/02-agents/tools/function_tool_with_session_injection.py index 5e5a8322ac..e12f97cec5 100644 --- a/python/samples/02-agents/tools/function_tool_with_session_injection.py +++ b/python/samples/02-agents/tools/function_tool_with_session_injection.py @@ -43,8 +43,10 @@ async def main() -> None: session = agent.create_session() # Run the agent with the session - print(f"Agent: {await agent.run('What is the weather in London?', session=session)}") - print(f"Agent: {await agent.run('What is the weather in Amsterdam?', session=session)}") + # Pass session via additional_function_arguments so tools can access it via **kwargs + opts = {"additional_function_arguments": {"session": session}} + print(f"Agent: {await agent.run('What is the weather in London?', session=session, options=opts)}") + print(f"Agent: {await agent.run('What is the weather in Amsterdam?', session=session, options=opts)}") print(f"Agent: {await agent.run('What cities did I ask about?', session=session)}") From 896303836176cb267c6b82cfa137b20cfb674105 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:26:44 -0800 Subject: [PATCH 05/11] Small clean-up --- .../02-agents/tools/function_tool_with_max_exceptions.py | 5 ----- .../02-agents/tools/function_tool_with_max_invocations.py | 3 --- python/samples/02-agents/tools/tool_in_class.py | 2 -- 3 files changed, 10 deletions(-) diff --git a/python/samples/02-agents/tools/function_tool_with_max_exceptions.py b/python/samples/02-agents/tools/function_tool_with_max_exceptions.py index 89d883174c..4c7d2c5b47 100644 --- a/python/samples/02-agents/tools/function_tool_with_max_exceptions.py +++ b/python/samples/02-agents/tools/function_tool_with_max_exceptions.py @@ -67,8 +67,6 @@ async def main(): ============================================================ Step 1: Call divide(10, 0) - tool raises exception Tool failed with error: division by zero -[2025-10-31 15:39:53 - /Users/edvan/Work/agent-framework/python/packages/core/agent_framework/_tools.py:718 - ERROR] -Function failed. Error: division by zero Response: Division by zero is undefined in standard arithmetic. There is no finite value for 10 Γ· 0. If you want alternatives: @@ -80,9 +78,6 @@ async def main(): Would you like me to show a safe division snippet in a specific language, or compute something else? ============================================================ Step 2: Call divide(100, 0) - will refuse to execute due to max_invocations -[2025-10-31 15:40:09 - /Users/edvan/Work/agent-framework/python/packages/core/agent_framework/_tools.py:718 - ERROR] -Function failed. Error: Function 'safe_divide' has reached its maximum exception limit, you tried to use this -tool too many times and it kept failing. Response: Division by zero is undefined in standard arithmetic, so 100 Γ· 0 has no finite value. If you’re coding and want safe handling, here are quick patterns in a few languages: diff --git a/python/samples/02-agents/tools/function_tool_with_max_invocations.py b/python/samples/02-agents/tools/function_tool_with_max_invocations.py index c8bdc306c3..eedefefd82 100644 --- a/python/samples/02-agents/tools/function_tool_with_max_invocations.py +++ b/python/samples/02-agents/tools/function_tool_with_max_invocations.py @@ -58,9 +58,6 @@ async def main(): Response: Five unicorns summoned: πŸ¦„πŸ¦„πŸ¦„πŸ¦„πŸ¦„βœ¨ ============================================================ Step 2: Call unicorn_function again - will refuse to execute due to max_invocations -[2025-10-31 15:54:40 - /Users/edvan/Work/agent-framework/python/packages/core/agent_framework/_tools.py:718 - ERROR] -Function failed. Error: Function 'unicorn_function' has reached its maximum invocation limit, -you can no longer use this tool. Response: The unicorn function has reached its maximum invocation limit. I can’t call it again right now. Here are 10 unicorns manually: πŸ¦„ πŸ¦„ πŸ¦„ πŸ¦„ πŸ¦„ πŸ¦„ πŸ¦„ πŸ¦„ πŸ¦„ πŸ¦„ diff --git a/python/samples/02-agents/tools/tool_in_class.py b/python/samples/02-agents/tools/tool_in_class.py index e4fa7ca015..757acbe1a3 100644 --- a/python/samples/02-agents/tools/tool_in_class.py +++ b/python/samples/02-agents/tools/tool_in_class.py @@ -79,8 +79,6 @@ async def main(): see more on limits or handle it with a tiny epsilon? ============================================================ Step 2: Call set safe to False and call again -[2025-10-31 16:17:44 - /Users/edvan/Work/agent-framework/python/packages/core/agent_framework/_tools.py:718 - ERROR] -Function failed. Error: division by zero Response: Division by zero is undefined in standard arithmetic. There is no number y such that 0 Γ— y = 10. If you’re looking at limits: From ea5bc67c505fb2cad94bd4f9362bdebd8830f867 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:39:34 -0800 Subject: [PATCH 06/11] Update 01_round_robin_group_chat.py --- .../01_round_robin_group_chat.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py b/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py index cffaae428f..a54fe6c547 100644 --- a/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py +++ b/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py @@ -93,14 +93,16 @@ async def run_agent_framework() -> None: print("[Agent Framework] Sequential conversation:") current_executor = None async for event in workflow.run("Create a brief summary about electric vehicles", stream=True): - if event.type == "output" and isinstance(event.data, AgentResponseUpdate): - # Print executor name header when switching to a new agent - if current_executor != event.executor_id: - if current_executor is not None: - print() # Newline after previous agent's message - print(f"---------- {event.executor_id} ----------") - current_executor = event.executor_id - print(event.data.text, end="", flush=True) + if event.type == "executor_completed" and isinstance(event.data, list): + for item in event.data: + if isinstance(item, AgentResponseUpdate) and item.text: + # Print executor name header when switching to a new agent + if current_executor != event.executor_id: + if current_executor is not None: + print() # Newline after previous agent's message + print(f"---------- {event.executor_id} ----------") + current_executor = event.executor_id + print(item.text, end="", flush=True) print() # Final newline after conversation From 4a6e9e155c994c4b64e50660b60676569ff90dce Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:41:34 -0800 Subject: [PATCH 07/11] Update 02_selector_group_chat.py --- .../orchestrations/02_selector_group_chat.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py b/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py index 1d46406c0a..f3ad9bcc98 100644 --- a/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py +++ b/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py @@ -108,15 +108,16 @@ async def run_agent_framework() -> None: print("[Agent Framework] Group chat conversation:") current_executor = None async for event in workflow.run("How do I connect to a PostgreSQL database using Python?", stream=True): - if event.type == "output" and isinstance(event.data, AgentResponseUpdate): - # Print executor name header when switching to a new agent - if current_executor != event.executor_id: - if current_executor is not None: - print() # Newline after previous agent's message - print(f"---------- {event.executor_id} ----------") - current_executor = event.executor_id - if event.data: - print(event.data.text, end="", flush=True) + if event.type == "executor_completed" and isinstance(event.data, list): + for item in event.data: + if isinstance(item, AgentResponseUpdate) and item.text: + # Print executor name header when switching to a new agent + if current_executor != event.executor_id: + if current_executor is not None: + print() # Newline after previous agent's message + print(f"---------- {event.executor_id} ----------") + current_executor = event.executor_id + print(item.text, end="", flush=True) print() # Final newline after conversation From 45bd81d271fae037677d0c88e8bcc60cc0a5c20b Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:44:15 -0800 Subject: [PATCH 08/11] Update 03_swarm.py --- python/samples/autogen-migration/orchestrations/03_swarm.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/samples/autogen-migration/orchestrations/03_swarm.py b/python/samples/autogen-migration/orchestrations/03_swarm.py index d0f6c74fe1..a3c7a4f66e 100644 --- a/python/samples/autogen-migration/orchestrations/03_swarm.py +++ b/python/samples/autogen-migration/orchestrations/03_swarm.py @@ -18,7 +18,7 @@ import asyncio from agent_framework import AgentResponseUpdate, WorkflowEvent -from orderedmultidict import Any +from typing import Any async def run_autogen() -> None: @@ -197,7 +197,9 @@ async def run_agent_framework() -> None: print("---------- user ----------") print(user_response) - responses: dict[str, Any] = {req.request_id: user_response for req in pending_requests} # type: ignore + responses: dict[str, Any] = { + req.request_id: HandoffAgentUserRequest.create_response(user_response) for req in pending_requests + } # type: ignore pending_requests = [] current_executor = None stream_line_open = False From 9ed3251df2b332d8f7298151787057bf0fe5c0c0 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:50:21 -0800 Subject: [PATCH 09/11] Update 03_assistant_agent_thread_and_stream.py --- .../single_agent/03_assistant_agent_thread_and_stream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/autogen-migration/single_agent/03_assistant_agent_thread_and_stream.py b/python/samples/autogen-migration/single_agent/03_assistant_agent_thread_and_stream.py index 5e1de9d873..5e4854d1e3 100644 --- a/python/samples/autogen-migration/single_agent/03_assistant_agent_thread_and_stream.py +++ b/python/samples/autogen-migration/single_agent/03_assistant_agent_thread_and_stream.py @@ -42,7 +42,7 @@ async def run_autogen() -> None: print("\n[AutoGen] Streaming response:") # Stream response with Console for token streaming - await Console(agent.run(task="Count from 1 to 5", stream=True)) + await Console(agent.run_stream(task="Count from 1 to 5")) async def run_agent_framework() -> None: From 723eafaebcdcb8cd9bb0a7a4cbf5fcd9f2ddf7e1 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:51:06 -0800 Subject: [PATCH 10/11] Update 04_agent_as_tool.py --- .../samples/autogen-migration/single_agent/04_agent_as_tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samples/autogen-migration/single_agent/04_agent_as_tool.py b/python/samples/autogen-migration/single_agent/04_agent_as_tool.py index fadf4c64f4..c8a73f66bc 100644 --- a/python/samples/autogen-migration/single_agent/04_agent_as_tool.py +++ b/python/samples/autogen-migration/single_agent/04_agent_as_tool.py @@ -53,7 +53,7 @@ async def run_autogen() -> None: # Run coordinator with streaming - it will delegate to writer print("[AutoGen]") - await Console(coordinator.run(task="Create a tagline for a coffee shop", stream=True)) + await Console(coordinator.run_stream(task="Create a tagline for a coffee shop")) async def run_agent_framework() -> None: From acfd98b1a8a5c802d8f58c426819c812b2c3af49 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Tue, 17 Feb 2026 22:30:29 -0800 Subject: [PATCH 11/11] Resolved comments --- .../01_round_robin_group_chat.py | 19 ++++++------------- .../orchestrations/02_selector_group_chat.py | 19 ++++++------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py b/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py index a54fe6c547..9d11f9fc88 100644 --- a/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py +++ b/python/samples/autogen-migration/orchestrations/01_round_robin_group_chat.py @@ -17,7 +17,7 @@ import asyncio -from agent_framework import AgentResponseUpdate +from agent_framework import Message async def run_autogen() -> None: @@ -91,19 +91,12 @@ async def run_agent_framework() -> None: # Run the workflow print("[Agent Framework] Sequential conversation:") - current_executor = None async for event in workflow.run("Create a brief summary about electric vehicles", stream=True): - if event.type == "executor_completed" and isinstance(event.data, list): - for item in event.data: - if isinstance(item, AgentResponseUpdate) and item.text: - # Print executor name header when switching to a new agent - if current_executor != event.executor_id: - if current_executor is not None: - print() # Newline after previous agent's message - print(f"---------- {event.executor_id} ----------") - current_executor = event.executor_id - print(item.text, end="", flush=True) - print() # Final newline after conversation + if event.type == "output" and isinstance(event.data, list): + for message in event.data: + if isinstance(message, Message) and message.role == "assistant" and message.text: + print(f"---------- {message.author_name} ----------") + print(message.text) async def run_agent_framework_with_cycle() -> None: diff --git a/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py b/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py index f3ad9bcc98..6477b0af57 100644 --- a/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py +++ b/python/samples/autogen-migration/orchestrations/02_selector_group_chat.py @@ -17,7 +17,7 @@ import asyncio -from agent_framework import AgentResponseUpdate +from agent_framework import Message async def run_autogen() -> None: @@ -106,19 +106,12 @@ async def run_agent_framework() -> None: # Run with a question that requires expert selection print("[Agent Framework] Group chat conversation:") - current_executor = None async for event in workflow.run("How do I connect to a PostgreSQL database using Python?", stream=True): - if event.type == "executor_completed" and isinstance(event.data, list): - for item in event.data: - if isinstance(item, AgentResponseUpdate) and item.text: - # Print executor name header when switching to a new agent - if current_executor != event.executor_id: - if current_executor is not None: - print() # Newline after previous agent's message - print(f"---------- {event.executor_id} ----------") - current_executor = event.executor_id - print(item.text, end="", flush=True) - print() # Final newline after conversation + if event.type == "output" and isinstance(event.data, list): + for message in event.data: + if isinstance(message, Message) and message.role == "assistant" and message.text: + print(f"---------- {message.author_name} ----------") + print(message.text) async def main() -> None: