test
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
Python - Merge - Tests / paths-filter (push) Has been cancelled
Python - Merge - Tests / Python Tests - Core (integration, ubuntu-latest, 3.10) (push) Has been cancelled
Python - Merge - Tests / Python Tests - Azure AI (integration, ubuntu-latest, 3.10) (push) Has been cancelled
Python - Merge - Tests / python-integration-tests-check (push) Has been cancelled
Python - Lab Tests / paths-filter (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.10) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.11) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.12) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.13) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (ubuntu-latest, 3.14) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.10) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.11) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.12) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.13) (push) Has been cancelled
Python - Lab Tests / Python Lab Tests (windows-latest, 3.14) (push) Has been cancelled
Check .md links / markdown-link-check (push) Has been cancelled

This commit is contained in:
2026-01-24 03:05:12 +11:00
parent f78f2388b3
commit 539852f81c
2584 changed files with 287471 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
# Chat Client Examples
This folder contains simple examples demonstrating direct usage of various chat clients.
## Examples
| File | Description |
|------|-------------|
| [`azure_assistants_client.py`](azure_assistants_client.py) | Direct usage of Azure Assistants Client for basic chat interactions with Azure OpenAI assistants. |
| [`azure_chat_client.py`](azure_chat_client.py) | Direct usage of Azure Chat Client for chat interactions with Azure OpenAI models. |
| [`azure_responses_client.py`](azure_responses_client.py) | Direct usage of Azure Responses Client for structured response generation with Azure OpenAI models. |
| [`chat_response_cancellation.py`](chat_response_cancellation.py) | Demonstrates how to cancel chat responses during streaming, showing proper cancellation handling and cleanup. |
| [`azure_ai_chat_client.py`](azure_ai_chat_client.py) | Direct usage of Azure AI Chat Client for chat interactions with Azure AI models. |
| [`openai_assistants_client.py`](openai_assistants_client.py) | Direct usage of OpenAI Assistants Client for basic chat interactions with OpenAI assistants. |
| [`openai_chat_client.py`](openai_chat_client.py) | Direct usage of OpenAI Chat Client for chat interactions with OpenAI models. |
| [`openai_responses_client.py`](openai_responses_client.py) | Direct usage of OpenAI Responses Client for structured response generation with OpenAI models. |
## Environment Variables
Depending on which client you're using, set the appropriate environment variables:
**For Azure clients:**
- `AZURE_OPENAI_ENDPOINT`: Your Azure OpenAI endpoint
- `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`: The name of your Azure OpenAI chat deployment
- `AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME`: The name of your Azure OpenAI responses deployment
**For Azure AI client:**
- `AZURE_AI_PROJECT_ENDPOINT`: Your Azure AI project endpoint
- `AZURE_AI_MODEL_DEPLOYMENT_NAME`: The name of your model deployment
**For OpenAI clients:**
- `OPENAI_API_KEY`: Your OpenAI API key
- `OPENAI_CHAT_MODEL_ID`: The OpenAI model to use for chat clients (e.g., `gpt-4o`, `gpt-4o-mini`, `gpt-3.5-turbo`)
- `OPENAI_RESPONSES_MODEL_ID`: The OpenAI model to use for responses clients (e.g., `gpt-4o`, `gpt-4o-mini`, `gpt-3.5-turbo`)
**For Ollama client:**
- `OLLAMA_HOST`: Your Ollama server URL (defaults to `http://localhost:11434` if not set)
- `OLLAMA_MODEL_ID`: The Ollama model to use for chat (e.g., `llama3.2`, `llama2`, `codellama`)
> **Note**: For Ollama, ensure you have Ollama installed and running locally with at least one model downloaded. Visit [https://ollama.com/](https://ollama.com/) for installation instructions.

View File

@@ -0,0 +1,46 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework.azure import AzureAIAgentClient
from azure.identity.aio import AzureCliCredential
from pydantic import Field
"""
Azure AI Chat Client Direct Usage Example
Demonstrates direct AzureAIChatClient usage for chat interactions with Azure AI models.
Shows function calling capabilities with custom business logic.
"""
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with AzureAIAgentClient(credential=AzureCliCredential()) as client:
message = "What's the weather in Amsterdam and in Paris?"
stream = False
print(f"User: {message}")
if stream:
print("Assistant: ", end="")
async for chunk in client.get_streaming_response(message, tools=get_weather):
if str(chunk):
print(str(chunk), end="")
print("")
else:
response = await client.get_response(message, tools=get_weather)
print(f"Assistant: {response}")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,46 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework.azure import AzureOpenAIAssistantsClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure Assistants Client Direct Usage Example
Demonstrates direct AzureAssistantsClient usage for chat interactions with Azure OpenAI assistants.
Shows function calling capabilities and automatic assistant creation.
"""
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
async with AzureOpenAIAssistantsClient(credential=AzureCliCredential()) as client:
message = "What's the weather in Amsterdam and in Paris?"
stream = False
print(f"User: {message}")
if stream:
print("Assistant: ", end="")
async for chunk in client.get_streaming_response(message, tools=get_weather):
if str(chunk):
print(str(chunk), end="")
print("")
else:
response = await client.get_response(message, tools=get_weather)
print(f"Assistant: {response}")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,46 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
from pydantic import Field
"""
Azure Chat Client Direct Usage Example
Demonstrates direct AzureChatClient usage for chat interactions with Azure OpenAI models.
Shows function calling capabilities with custom business logic.
"""
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
client = AzureOpenAIChatClient(credential=AzureCliCredential())
message = "What's the weather in Amsterdam and in Paris?"
stream = False
print(f"User: {message}")
if stream:
print("Assistant: ", end="")
async for chunk in client.get_streaming_response(message, tools=get_weather):
if str(chunk):
print(str(chunk), end="")
print("")
else:
response = await client.get_response(message, tools=get_weather)
print(f"Assistant: {response}")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,60 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import ChatResponse
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
from pydantic import BaseModel, Field
"""
Azure Responses Client Direct Usage Example
Demonstrates direct AzureResponsesClient usage for structured response generation with Azure OpenAI models.
Shows function calling capabilities with custom business logic.
"""
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
class OutputStruct(BaseModel):
"""Structured output for weather information."""
location: str
weather: str
async def main() -> None:
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
# authentication option.
client = AzureOpenAIResponsesClient(credential=AzureCliCredential())
message = "What's the weather in Amsterdam and in Paris?"
stream = True
print(f"User: {message}")
if stream:
response = await ChatResponse.from_chat_response_generator(
client.get_streaming_response(message, tools=get_weather, options={"response_format": OutputStruct}),
output_format_type=OutputStruct,
)
if result := response.try_parse_value(OutputStruct):
print(f"Assistant: {result}")
else:
print(f"Assistant: {response.text}")
else:
response = await client.get_response(message, tools=get_weather, options={"response_format": OutputStruct})
if result := response.try_parse_value(OutputStruct):
print(f"Assistant: {result}")
else:
print(f"Assistant: {response.text}")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,36 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework.openai import OpenAIChatClient
"""
Chat Response Cancellation Example
Demonstrates proper cancellation of streaming chat responses during execution.
Shows asyncio task cancellation and resource cleanup techniques.
"""
async def main() -> None:
"""
Demonstrates cancelling a chat request after 1 second.
Creates a task for the chat request, waits briefly, then cancels it to show proper cleanup.
Configuration:
- OpenAI model ID: Use "model_id" parameter or "OPENAI_CHAT_MODEL_ID" environment variable
- OpenAI API key: Use "api_key" parameter or "OPENAI_API_KEY" environment variable
"""
chat_client = OpenAIChatClient()
try:
task = asyncio.create_task(chat_client.get_response(messages=["Tell me a fantasy story."]))
await asyncio.sleep(1)
task.cancel()
await task
except asyncio.CancelledError:
print("Request was cancelled")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,44 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework.openai import OpenAIAssistantsClient
from pydantic import Field
"""
OpenAI Assistants Client Direct Usage Example
Demonstrates direct OpenAIAssistantsClient usage for chat interactions with OpenAI assistants.
Shows function calling capabilities and automatic assistant creation.
"""
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
async with OpenAIAssistantsClient() as client:
message = "What's the weather in Amsterdam and in Paris?"
stream = False
print(f"User: {message}")
if stream:
print("Assistant: ", end="")
async for chunk in client.get_streaming_response(message, tools=get_weather):
if str(chunk):
print(str(chunk), end="")
print("")
else:
response = await client.get_response(message, tools=get_weather)
print(f"Assistant: {response}")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,44 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework.openai import OpenAIChatClient
from pydantic import Field
"""
OpenAI Chat Client Direct Usage Example
Demonstrates direct OpenAIChatClient usage for chat interactions with OpenAI models.
Shows function calling capabilities with custom business logic.
"""
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
client = OpenAIChatClient()
message = "What's the weather in Amsterdam and in Paris?"
stream = True
print(f"User: {message}")
if stream:
print("Assistant: ", end="")
async for chunk in client.get_streaming_response(message, tools=get_weather):
if chunk.text:
print(chunk.text, end="")
print("")
else:
response = await client.get_response(message, tools=get_weather)
print(f"Assistant: {response}")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,44 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework.openai import OpenAIResponsesClient
from pydantic import Field
"""
OpenAI Responses Client Direct Usage Example
Demonstrates direct OpenAIResponsesClient usage for structured response generation with OpenAI models.
Shows function calling capabilities with custom business logic.
"""
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main() -> None:
client = OpenAIResponsesClient()
message = "What's the weather in Amsterdam and in Paris?"
stream = False
print(f"User: {message}")
if stream:
print("Assistant: ", end="")
async for chunk in client.get_streaming_response(message, tools=get_weather):
if chunk.text:
print(chunk.text, end="")
print("")
else:
response = await client.get_response(message, tools=get_weather)
print(f"Assistant: {response}")
if __name__ == "__main__":
asyncio.run(main())

View File

@@ -0,0 +1,182 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Literal
from agent_framework import ChatAgent
from agent_framework.anthropic import AnthropicClient
from agent_framework.openai import OpenAIChatClient, OpenAIChatOptions
"""TypedDict-based Chat Options.
In Agent Framework, we have made ChatClient and ChatAgent generic over a ChatOptions typeddict, this means that
you can override which options are available for a given client or agent by providing your own TypedDict subclass.
And we include the most common options for all ChatClient providers out of the box.
This sample demonstrates the TypedDict-based approach for chat client and agent options,
which provides:
1. IDE autocomplete for available options
2. Type checking to catch errors at development time
3. An example of defining provider-specific options by extending the base options,
including overriding unsupported options.
The sample shows usage with both OpenAI and Anthropic clients, demonstrating
how provider-specific options work for ChatClient and ChatAgent. But the same approach works for other providers too.
"""
async def demo_anthropic_chat_client() -> None:
"""Demonstrate Anthropic ChatClient with typed options and validation."""
print("\n=== Anthropic ChatClient with TypedDict Options ===\n")
# Create Anthropic client
client = AnthropicClient(model_id="claude-sonnet-4-5-20250929")
# Standard options work great:
response = await client.get_response(
"What is the capital of France?",
options={
"temperature": 0.5,
"max_tokens": 1000,
# Anthropic-specific options:
"thinking": {"type": "enabled", "budget_tokens": 1000},
# "top_k": 40, # <-- Uncomment for Anthropic-specific option
},
)
print(f"Anthropic Response: {response.text}")
print(f"Model used: {response.model_id}")
async def demo_anthropic_agent() -> None:
"""Demonstrate ChatAgent with Anthropic client and typed options."""
print("\n=== ChatAgent with Anthropic and Typed Options ===\n")
client = AnthropicClient(model_id="claude-sonnet-4-5-20250929")
# Create a typed agent for Anthropic - IDE knows Anthropic-specific options!
agent = ChatAgent(
chat_client=client,
name="claude-assistant",
instructions="You are a helpful assistant powered by Claude. Be concise.",
default_options={
"temperature": 0.5,
"max_tokens": 200,
"top_k": 40, # Anthropic-specific option, uncomment to try
},
)
# Run the agent
response = await agent.run("Explain quantum computing in one sentence.")
print(f"Agent Response: {response.text}")
class OpenAIReasoningChatOptions(OpenAIChatOptions, total=False):
"""Chat options for OpenAI reasoning models (o1, o3, o4-mini, etc.).
Reasoning models have different parameter support compared to standard models.
This TypedDict marks unsupported parameters with ``None`` type.
Examples:
.. code-block:: python
from agent_framework.openai import OpenAIReasoningChatOptions
options: OpenAIReasoningChatOptions = {
"model_id": "o3",
"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
frequency_penalty: None
presence_penalty: None
logit_bias: None
logprobs: None
top_logprobs: None
stop: None # Not supported for o3 and o4-mini
async def demo_openai_chat_client_reasoning_models() -> None:
"""Demonstrate OpenAI ChatClient with typed options for reasoning models."""
print("\n=== OpenAI ChatClient with TypedDict Options ===\n")
# Create OpenAI client
client = OpenAIChatClient[OpenAIReasoningChatOptions]()
# With specific options, you get full IDE autocomplete!
# Try typing `client.get_response("Hello", options={` and see the suggestions
response = await client.get_response(
"What is 2 + 2?",
options={
"model_id": "o3",
"max_tokens": 100,
"allow_multiple_tool_calls": True,
# OpenAI-specific options work:
"reasoning_effort": "medium",
# Unsupported options are caught by type checker (uncomment to see):
# "temperature": 0.7,
# "random": 234,
},
)
print(f"OpenAI Response: {response.text}")
print(f"Model used: {response.model_id}")
async def demo_openai_agent() -> None:
"""Demonstrate ChatAgent with OpenAI client and typed options."""
print("\n=== ChatAgent with OpenAI and Typed Options ===\n")
# Create a typed agent - IDE will autocomplete options!
# The type annotation can be done either on the agent like below,
# or on the client when constructing the client instance:
# client = OpenAIChatClient[OpenAIReasoningChatOptions]()
agent = ChatAgent[OpenAIReasoningChatOptions](
chat_client=OpenAIChatClient(),
name="weather-assistant",
instructions="You are a helpful assistant. Answer concisely.",
# Options can be set at construction time
default_options={
"model_id": "o3",
"max_tokens": 100,
"allow_multiple_tool_calls": True,
# OpenAI-specific options work:
"reasoning_effort": "medium",
# Unsupported options are caught by type checker (uncomment to see):
# "temperature": 0.7,
# "random": 234,
},
)
# Or pass options at runtime - they override construction options
response = await agent.run(
"What is 25 * 47?",
options={
"reasoning_effort": "high", # Override for a run
},
)
print(f"Agent Response: {response.text}")
async def main() -> None:
"""Run all Typed Options demonstrations."""
# # Anthropic demos (requires ANTHROPIC_API_KEY)
await demo_anthropic_chat_client()
await demo_anthropic_agent()
# OpenAI demos (requires OPENAI_API_KEY)
await demo_openai_chat_client_reasoning_models()
await demo_openai_agent()
if __name__ == "__main__":
asyncio.run(main())