Python: Fix sample bugs: incorrect API params, wrong client types, and invalid options (#4983)

* Fix sample bugs: incorrect API params, wrong client types, and invalid options

- typed_options.py: Fix AnthropicClient model->model_id, wrap raw strings in Message objects for get_response(), fix reasoning_effort->reasoning dict, fix budget_tokens minimum (1024), use OpenAIChatClient not FoundryChatClient, remove unused import

- client_reasoning.py: Fix deprecated model_id to model param

- client_with_hosted_mcp.py: Remove invalid store=True kwarg from Agent.run()

- code_defined_skill.py: Fix precision kwarg to use function_invocation_kwargs

- Various other samples: Fix deprecated API usage and incorrect params

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review comments

- client_with_hosted_mcp.py: Fix remaining store=True kwarg on line 68 to use options dict

- client_with_session.py: Change store=True to store=False to match in-memory persistence demo intent

- typed_options.py: Remove non-existent import and model key from docstring example

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* new sample fixes

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Giles Odigwe
2026-03-31 09:58:51 -07:00
committed by GitHub
Unverified
parent 3d09337446
commit 7c2dae8855
13 changed files with 34 additions and 41 deletions
@@ -3,7 +3,7 @@
import asyncio
from agent_framework import Agent
from agent_framework.openai import OpenAIResponsesClient
from agent_framework.openai import OpenAIChatClient
from dotenv import load_dotenv
# Load environment variables from .env file
@@ -29,7 +29,7 @@ Prerequisites:
agent = Agent(
name="researcher",
instructions="You are a helpful research assistant. Be concise.",
client=OpenAIResponsesClient(model="o3"),
client=OpenAIChatClient(model="o3"),
)
@@ -4,6 +4,7 @@ import asyncio
from agent_framework import Message
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential
from dotenv import load_dotenv
# Load environment variables from .env file
@@ -26,7 +27,7 @@ async def main() -> None:
- OpenAI model ID: Use "model_id" parameter or "OPENAI_MODEL" environment variable
- OpenAI API key: Use "api_key" parameter or "OPENAI_API_KEY" environment variable
"""
client = FoundryChatClient()
client = FoundryChatClient(credential=AzureCliCredential())
try:
task = asyncio.create_task(
@@ -35,7 +35,7 @@ async def non_streaming_example() -> None:
print("=== Non-streaming Response Example ===")
agent = Agent(
client=AnthropicClient(),
client=AnthropicClient(model_id="claude-sonnet-4-5-20250929"),
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
@@ -52,7 +52,7 @@ async def streaming_example() -> None:
print("=== Streaming Response Example ===")
agent = Agent(
client=AnthropicClient(),
client=AnthropicClient(model_id="claude-sonnet-4-5-20250929"),
name="WeatherAgent",
instructions="You are a helpful weather agent.",
tools=get_weather,
@@ -51,9 +51,9 @@ class EchoAgent(BaseAgent):
super().__init__(
name=name,
description=description,
echo_prefix=echo_prefix, # type: ignore
**kwargs,
)
self.echo_prefix = echo_prefix
def run(
self,
@@ -25,7 +25,7 @@ In this case they are here: https://platform.openai.com/docs/api-reference/respo
agent = Agent(
client=OpenAIChatClient[OpenAIChatOptions](model_id="gpt-5"),
client=OpenAIChatClient[OpenAIChatOptions](model="gpt-5"),
name="MathHelper",
instructions="You are a personal math tutor. When asked a math question, "
"reason over how best to approach the problem and share your thought process.",
@@ -50,7 +50,7 @@ async def handle_approvals_with_session(query: str, agent: "SupportsAgentRun", s
"""Here we let the session deal with the previous responses, and we just rerun with the approval."""
from agent_framework import Message
result = await agent.run(query, session=session, store=True)
result = await agent.run(query, session=session, options={"store": True})
while len(result.user_input_requests) > 0:
new_input: list[Any] = []
for user_input_needed in result.user_input_requests:
@@ -65,7 +65,7 @@ async def handle_approvals_with_session(query: str, agent: "SupportsAgentRun", s
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
)
)
result = await agent.run(new_input, session=session, store=True)
result = await agent.run(new_input, session=session, options={"store": True})
return result
@@ -75,19 +75,19 @@ async def example_with_session_persistence_in_memory() -> None:
# First conversation
query1 = "What's the weather like in Tokyo?"
print(f"User: {query1}")
result1 = await agent.run(query1, session=session, store=False)
result1 = await agent.run(query1, session=session, options={"store": False})
print(f"Agent: {result1.text}")
# Second conversation using the same session - maintains context
query2 = "How about London?"
print(f"\nUser: {query2}")
result2 = await agent.run(query2, session=session, store=False)
result2 = await agent.run(query2, session=session, options={"store": False})
print(f"Agent: {result2.text}")
# Third conversation - agent should remember both previous cities
query3 = "Which of the cities I asked about has better weather?"
print(f"\nUser: {query3}")
result3 = await agent.run(query3, session=session, store=False)
result3 = await agent.run(query3, session=session, options={"store": False})
print(f"Agent: {result3.text}")
print("Note: The agent remembers context from previous messages in the same session.\n")
@@ -151,7 +151,7 @@ async def main() -> None:
print("-" * 60)
response = await agent.run(
"How many kilometers is a marathon (26.2 miles)? And how many pounds is 75 kilograms?",
precision=2,
function_invocation_kwargs={"precision": 2},
)
print(f"Agent: {response}\n")
@@ -4,7 +4,7 @@ import asyncio
from collections.abc import Awaitable, Callable
from agent_framework import Agent, AgentContext, AgentSession, FunctionInvocationContext, tool
from agent_framework.openai import OpenAIResponsesClient
from agent_framework.openai import OpenAIChatClient
from dotenv import load_dotenv
load_dotenv()
@@ -63,7 +63,7 @@ def recall_findings(ctx: FunctionInvocationContext) -> str:
async def main() -> None:
print("=== Agent-as-Tool: Session Propagation ===\n")
client = OpenAIResponsesClient()
client = OpenAIChatClient()
research_agent = Agent(
client=client,
@@ -4,7 +4,7 @@ import asyncio
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.openai import OpenAIResponsesClient
from agent_framework.openai import OpenAIChatClient
from dotenv import load_dotenv
# Load environment variables from .env file
@@ -81,7 +81,7 @@ async def scenario_max_iterations():
print("Scenario 1: max_iterations — limit LLM roundtrips")
print("=" * 60)
client = OpenAIResponsesClient()
client = OpenAIChatClient()
# 1. Set max_iterations to 3 — the tool loop will run at most 3 roundtrips
# to the model before forcing a text response.
@@ -116,7 +116,7 @@ async def scenario_max_function_calls():
print("Scenario 2: max_function_calls — limit total tool executions")
print("=" * 60)
client = OpenAIResponsesClient()
client = OpenAIChatClient()
# 1. Allow many iterations but cap total function calls to 4.
# If the model requests 3 parallel searches per iteration, after 2
@@ -158,7 +158,7 @@ async def scenario_max_invocations():
print("=" * 60)
agent = Agent(
client=OpenAIResponsesClient(),
client=OpenAIChatClient(),
name="APIAgent",
instructions="Use call_expensive_api when asked to analyze something.",
tools=[call_expensive_api],
@@ -214,7 +214,7 @@ async def scenario_per_agent_tool_limits():
agent_a_lookup = tool(name="lookup", approval_mode="never_require", max_invocations=2)(_do_lookup)
agent_b_lookup = tool(name="lookup", approval_mode="never_require", max_invocations=5)(_do_lookup)
client = OpenAIResponsesClient()
client = OpenAIChatClient()
agent_a = Agent(
client=client,
name="AgentA",
@@ -259,7 +259,7 @@ async def scenario_combined():
print("Scenario 5: Combined — all mechanisms together")
print("=" * 60)
client = OpenAIResponsesClient()
client = OpenAIChatClient()
# 1. Configure the client with both iteration and function call limits.
client.function_invocation_configuration["max_iterations"] = 5 # max 5 LLM roundtrips
@@ -4,7 +4,7 @@ import asyncio
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.openai import OpenAIResponsesClient
from agent_framework.openai import OpenAIChatClient
from dotenv import load_dotenv
# Load environment variables from .env file
@@ -46,7 +46,7 @@ def safe_divide(
async def main():
# tools = Tools()
agent = Agent(
client=OpenAIResponsesClient(),
client=OpenAIChatClient(),
name="ToolAgent",
instructions="Use the provided tools.",
tools=[greet, safe_divide],
@@ -5,7 +5,7 @@ from random import randrange
from typing import TYPE_CHECKING, Annotated, Any
from agent_framework import Agent, AgentResponse, Message, tool
from agent_framework.openai import OpenAIResponsesClient
from agent_framework.openai import OpenAIChatClient
from dotenv import load_dotenv
if TYPE_CHECKING:
@@ -134,7 +134,7 @@ async def run_weather_agent_with_approval(stream: bool) -> None:
print(f"\n=== Weather Agent with Approval Required ({'Streaming' if stream else 'Non-Streaming'}) ===\n")
async with Agent(
client=OpenAIResponsesClient(),
client=OpenAIChatClient(),
name="WeatherAgent",
instructions=("You are a helpful weather assistant. Use the get_weather tool to provide weather information."),
tools=[get_weather, get_weather_detail],
+8 -16
View File
@@ -1,11 +1,9 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Literal
from agent_framework import Agent, Message
from agent_framework.anthropic import AnthropicClient
from agent_framework.foundry import FoundryChatClient
from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions
from dotenv import load_dotenv
@@ -46,10 +44,10 @@ async def demo_anthropic_chat_client() -> None:
response = await client.get_response(
[Message("user", text="What is the capital of France?")],
options={
"temperature": 0.5,
"max_tokens": 1000,
"temperature": 1, # Must be 1 when thinking is enabled
"max_tokens": 2048,
# Anthropic-specific options:
"thinking": {"type": "enabled", "budget_tokens": 1000},
"thinking": {"type": "enabled", "budget_tokens": 1024},
# "top_k": 40, # <-- Uncomment for Anthropic-specific option
},
)
@@ -91,18 +89,12 @@ class OpenAIReasoningChatOptions(OpenAIChatOptions, total=False):
Examples:
.. code-block:: python
from agent_framework.openai import OpenAIReasoningChatOptions
options: OpenAIReasoningChatOptions = {
"model_id": "o3",
"reasoning_effort": "high",
"reasoning": {"effort": "high"},
"max_tokens": 4096,
}
"""
# Reasoning-specific parameters
reasoning_effort: Literal["none", "minimal", "low", "medium", "high", "xhigh"]
# Unsupported parameters for reasoning models (override with None)
temperature: None
top_p: None
@@ -129,7 +121,7 @@ async def demo_openai_chat_client_reasoning_models() -> None:
"max_tokens": 100,
"allow_multiple_tool_calls": True,
# OpenAI-specific options work:
"reasoning_effort": "medium",
"reasoning": {"effort": "medium"},
# Unsupported options are caught by type checker (uncomment to see):
# "temperature": 0.7,
# "random": 234,
@@ -149,7 +141,7 @@ async def demo_openai_agent() -> None:
# or on the client when constructing the client instance:
# client = OpenAIChatClient[OpenAIReasoningChatOptions]()
agent = Agent[OpenAIReasoningChatOptions](
client=FoundryChatClient(model="o3"),
client=OpenAIChatClient(model="o3"),
name="weather-assistant",
instructions="You are a helpful assistant. Answer concisely.",
# Options can be set at construction time
@@ -157,7 +149,7 @@ async def demo_openai_agent() -> None:
"max_tokens": 100,
"allow_multiple_tool_calls": True,
# OpenAI-specific options work:
"reasoning_effort": "medium",
"reasoning": {"effort": "medium"},
# Unsupported options are caught by type checker (uncomment to see):
# "temperature": 0.7,
# "random": 234,
@@ -168,7 +160,7 @@ async def demo_openai_agent() -> None:
response = await agent.run(
"What is 25 * 47?",
options={
"reasoning_effort": "high", # Override for a run
"reasoning": {"effort": "high"}, # Override for a run
},
)