mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: [BREAKING] Simplify API: ChatAgent -> Agent, ChatMessage -> Message (#3747)
* [BREAKING] Rename ChatAgent -> Agent, ChatMessage -> Message, ChatClientProtocol -> SupportsChatGetResponse Simplify the public API by removing redundant 'Chat' prefix from core types: - ChatAgent -> Agent - RawChatAgent -> RawAgent - ChatMessage -> Message - ChatClientProtocol -> SupportsChatGetResponse Also renamed internal WorkflowMessage (was Message in _runner_context) to avoid collision. No backward compatibility aliases - this is a clean breaking change. * [BREAKING] Rename Agent chat_client parameter to client * Fix rebase issues: WorkflowMessage references and broken markdown links * Fix formatting and lint issues from code quality checks * Fix import ordering in workflow sample files * fixed rebase * Fix test failures: use WorkflowMessage and A2AMessage after ChatMessage→Message rename - Replace Message(data=..., source_id=...) with WorkflowMessage(...) in workflow tests - Fix isinstance check in A2A agent to use A2AMessage instead of Message - Fix import in test_workflow_observability.py (Message→WorkflowMessage) * Fix lint, fmt, and sample errors after ChatMessage→Message rename - Auto-fix 70+ ruff lint issues across samples (ChatMessage→Message refs) - Fix HostedVectorStoreContent→Content.from_hosted_vector_store in file search sample - Fix _normalize_messages→normalize_messages in custom agent sample - Fix context.terminate→raise MiddlewareTermination in middleware samples - Fix with_update_hook→with_transform_hook in override middleware sample - Add TOptions_co import back to custom_chat_client sample - Add noqa for FastAPI File() default in chatkit sample - Fix B023 loop variable capture in weather agent sample * fix: update Agent constructor calls from chat_client to client in declaration-only tool tests * fix: add register_cleanup to devui lazy-loading proxy and type stub * fixed tests and updated new pieces * fix agui typevar * fix merge errors * fix merge conflicts * fiux merge * Remove unused links --------- Co-authored-by: Evan Mattson <evan.mattson@microsoft.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
a4c9e43afb
commit
0521f5bed8
@@ -6,7 +6,7 @@ This gallery helps AutoGen developers move to the Microsoft Agent Framework (AF)
|
||||
|
||||
### Single-Agent Parity
|
||||
|
||||
- [01_basic_assistant_agent.py](single_agent/01_basic_assistant_agent.py) — Minimal AutoGen `AssistantAgent` and AF `ChatAgent` comparison.
|
||||
- [01_basic_assistant_agent.py](single_agent/01_basic_assistant_agent.py) — Minimal AutoGen `AssistantAgent` and AF `Agent` comparison.
|
||||
- [02_assistant_agent_with_tool.py](single_agent/02_assistant_agent_with_tool.py) — Function tool integration in both SDKs.
|
||||
- [03_assistant_agent_thread_and_stream.py](single_agent/03_assistant_agent_thread_and_stream.py) — Thread management and streaming responses.
|
||||
- [04_agent_as_tool.py](single_agent/04_agent_as_tool.py) — Using agents as tools (hierarchical agent pattern) and streaming with tools.
|
||||
@@ -51,7 +51,7 @@ python samples/autogen-migration/orchestrations/04_magentic_one.py
|
||||
|
||||
## Tips for Migration
|
||||
|
||||
- **Default behavior differences**: AutoGen's `AssistantAgent` is single-turn by default (`max_tool_iterations=1`), while AF's `ChatAgent` is multi-turn and continues tool execution automatically.
|
||||
- **Default behavior differences**: AutoGen's `AssistantAgent` is single-turn by default (`max_tool_iterations=1`), while AF's `Agent` is multi-turn and continues tool execution automatically.
|
||||
- **Thread management**: AF agents are stateless by default. Use `agent.get_new_thread()` and pass it to `run()` to maintain conversation state, similar to AutoGen's conversation context.
|
||||
- **Tools**: AutoGen uses `FunctionTool` wrappers; AF uses `@tool` decorators with automatic schema inference.
|
||||
- **Orchestration patterns**:
|
||||
|
||||
@@ -21,7 +21,7 @@ from typing import cast
|
||||
|
||||
from agent_framework import (
|
||||
AgentResponseUpdate,
|
||||
ChatMessage,
|
||||
Message,
|
||||
WorkflowEvent,
|
||||
)
|
||||
from agent_framework.orchestrations import MagenticProgressLedger
|
||||
@@ -129,7 +129,7 @@ async def run_agent_framework() -> None:
|
||||
|
||||
elif event.type == "magentic_orchestrator":
|
||||
print(f"\n[Magentic Orchestrator Event] Type: {event.data.event_type.name}")
|
||||
if isinstance(event.data.content, ChatMessage):
|
||||
if isinstance(event.data.content, Message):
|
||||
print(f"Please review the plan:\n{event.data.content.text}")
|
||||
elif isinstance(event.data.content, MagenticProgressLedger):
|
||||
print(f"Please review progress ledger:\n{json.dumps(event.data.content.to_dict(), indent=2)}")
|
||||
@@ -150,7 +150,7 @@ async def run_agent_framework() -> None:
|
||||
print("Final Output:")
|
||||
# The output of the Magentic workflow is a list of ChatMessages with only one final message
|
||||
# generated by the orchestrator.
|
||||
output_messages = cast(list[ChatMessage], output_event.data)
|
||||
output_messages = cast(list[Message], output_event.data)
|
||||
if output_messages:
|
||||
output = output_messages[-1].text
|
||||
print(output)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# uv run samples/autogen-migration/single_agent/01_basic_assistant_agent.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""Basic AutoGen AssistantAgent vs Agent Framework ChatAgent.
|
||||
"""Basic AutoGen AssistantAgent vs Agent Framework Agent.
|
||||
|
||||
Both samples expect OpenAI-compatible environment variables (OPENAI_API_KEY or
|
||||
Azure OpenAI configuration). Update the prompts or client wiring to match your
|
||||
@@ -38,10 +38,10 @@ async def run_autogen() -> None:
|
||||
|
||||
|
||||
async def run_agent_framework() -> None:
|
||||
"""Call Agent Framework's ChatAgent created from OpenAIChatClient."""
|
||||
"""Call Agent Framework's Agent created from OpenAIChatClient."""
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
|
||||
# AF constructs a lightweight ChatAgent backed by OpenAIChatClient
|
||||
# AF constructs a lightweight Agent backed by OpenAIChatClient
|
||||
client = OpenAIChatClient(model_id="gpt-4.1-mini")
|
||||
agent = client.as_agent(
|
||||
name="assistant",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# uv run samples/autogen-migration/single_agent/02_assistant_agent_with_tool.py
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
"""AutoGen AssistantAgent vs Agent Framework ChatAgent with function tools.
|
||||
"""AutoGen AssistantAgent vs Agent Framework Agent with function tools.
|
||||
|
||||
Demonstrates how to create and attach tools to agents in both frameworks.
|
||||
"""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""Background Responses Sample.
|
||||
@@ -22,10 +22,10 @@ Prerequisites:
|
||||
|
||||
|
||||
# 1. Create the agent with an OpenAI Responses client.
|
||||
agent = ChatAgent(
|
||||
agent = Agent(
|
||||
name="researcher",
|
||||
instructions="You are a helpful research assistant. Be concise.",
|
||||
chat_client=OpenAIResponsesClient(model_id="o3"),
|
||||
client=OpenAIResponsesClient(model_id="o3"),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -94,9 +94,9 @@ final = await response_stream.get_final_response() # Get the aggregated result
|
||||
|
||||
=== Chaining with .map() and .with_finalizer() ===
|
||||
|
||||
When building a ChatAgent on top of a ChatClient, we face a challenge:
|
||||
When building a Agent on top of a ChatClient, we face a challenge:
|
||||
- The ChatClient returns a ResponseStream[ChatResponseUpdate, ChatResponse]
|
||||
- The ChatAgent needs to return a ResponseStream[AgentResponseUpdate, AgentResponse]
|
||||
- The Agent needs to return a ResponseStream[AgentResponseUpdate, AgentResponse]
|
||||
- We can't iterate the ChatClient's stream twice!
|
||||
|
||||
The `.map()` and `.with_finalizer()` methods solve this by creating new ResponseStreams that:
|
||||
@@ -123,8 +123,8 @@ provider notifications, telemetry, thread updates) are still executed even when
|
||||
stream is wrapped/mapped.
|
||||
|
||||
```python
|
||||
# ChatAgent does something like this internally:
|
||||
chat_stream = chat_client.get_response(messages, stream=True)
|
||||
# Agent does something like this internally:
|
||||
chat_stream = client.get_response(messages, stream=True)
|
||||
agent_stream = (
|
||||
chat_stream
|
||||
.map(_to_agent_update, _to_agent_response)
|
||||
@@ -135,7 +135,7 @@ agent_stream = (
|
||||
This ensures:
|
||||
- The underlying ChatClient stream is only consumed once
|
||||
- The agent can add its own transform hooks, result hooks, and cleanup logic
|
||||
- Each layer (ChatClient, ChatAgent, middleware) can add independent behavior
|
||||
- Each layer (ChatClient, Agent, middleware) can add independent behavior
|
||||
- Inner stream post-processing (like context provider notification) still runs
|
||||
- Types flow naturally through the chain
|
||||
"""
|
||||
@@ -281,7 +281,7 @@ async def main() -> None:
|
||||
# Simulate what ChatClient returns
|
||||
inner_stream = ResponseStream(generate_updates(), finalizer=combine_updates)
|
||||
|
||||
# Simulate what ChatAgent does: wrap the inner stream
|
||||
# Simulate what Agent does: wrap the inner stream
|
||||
def to_agent_format(update: ChatResponseUpdate) -> ChatResponseUpdate:
|
||||
"""Map ChatResponseUpdate to agent format (simulated transformation)."""
|
||||
# In real code, this would convert to AgentResponseUpdate
|
||||
|
||||
@@ -20,7 +20,7 @@ sequenceDiagram
|
||||
participant Agent as Agent.run()
|
||||
participant AML as AgentMiddlewareLayer
|
||||
participant AMP as AgentMiddlewarePipeline
|
||||
participant RawAgent as RawChatAgent.run()
|
||||
participant RawAgent as RawAgent.run()
|
||||
participant CML as ChatMiddlewareLayer
|
||||
participant CMP as ChatMiddlewarePipeline
|
||||
participant FIL as FunctionInvocationLayer
|
||||
@@ -46,14 +46,14 @@ sequenceDiagram
|
||||
alt Non-Streaming (stream=False)
|
||||
RawAgent->>RawAgent: _prepare_run_context() [async]
|
||||
Note right of RawAgent: Builds: thread_messages, chat_options, tools
|
||||
RawAgent->>CML: chat_client.get_response(stream=False)
|
||||
RawAgent->>CML: client.get_response(stream=False)
|
||||
else Streaming (stream=True)
|
||||
RawAgent->>RawAgent: ResponseStream.from_awaitable()
|
||||
Note right of RawAgent: Defers async prep to stream consumption
|
||||
RawAgent-->>User: Returns ResponseStream immediately
|
||||
Note over RawAgent,CML: Async work happens on iteration
|
||||
RawAgent->>RawAgent: _prepare_run_context() [deferred]
|
||||
RawAgent->>CML: chat_client.get_response(stream=True)
|
||||
RawAgent->>CML: client.get_response(stream=True)
|
||||
end
|
||||
|
||||
Note over CML,CMP: Chat Middleware Layer
|
||||
@@ -132,7 +132,7 @@ sequenceDiagram
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `agent` | `SupportsAgentRun` | The agent being invoked |
|
||||
| `messages` | `list[ChatMessage]` | Input messages (mutable) |
|
||||
| `messages` | `list[Message]` | Input messages (mutable) |
|
||||
| `thread` | `AgentThread \| None` | Conversation thread |
|
||||
| `options` | `Mapping[str, Any]` | Chat options dict |
|
||||
| `stream` | `bool` | Whether streaming is enabled |
|
||||
@@ -142,9 +142,9 @@ sequenceDiagram
|
||||
|
||||
**Key Operations:**
|
||||
1. `categorize_middleware()` separates middleware by type (agent, chat, function)
|
||||
2. Chat and function middleware are forwarded to `chat_client`
|
||||
2. Chat and function middleware are forwarded to `client`
|
||||
3. `AgentMiddlewarePipeline.execute()` runs the agent middleware chain
|
||||
4. Final handler calls `RawChatAgent.run()`
|
||||
4. Final handler calls `RawAgent.run()`
|
||||
|
||||
**What Can Be Modified:**
|
||||
- `context.messages` - Add, remove, or modify input messages
|
||||
@@ -154,14 +154,14 @@ sequenceDiagram
|
||||
|
||||
### 2. Chat Middleware Layer (`ChatMiddlewareLayer`)
|
||||
|
||||
**Entry Point:** `chat_client.get_response(messages, options)`
|
||||
**Entry Point:** `client.get_response(messages, options)`
|
||||
|
||||
**Context Object:** `ChatContext`
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `chat_client` | `ChatClientProtocol` | The chat client |
|
||||
| `messages` | `Sequence[ChatMessage]` | Messages to send |
|
||||
| `client` | `SupportsChatGetResponse` | The chat client |
|
||||
| `messages` | `Sequence[Message]` | Messages to send |
|
||||
| `options` | `Mapping[str, Any]` | Chat options |
|
||||
| `stream` | `bool` | Whether streaming |
|
||||
| `metadata` | `dict` | Shared data between middleware |
|
||||
@@ -275,7 +275,7 @@ class TerminatingMiddleware(FunctionMiddleware):
|
||||
### Agent Layer → Chat Layer
|
||||
|
||||
```python
|
||||
# RawChatAgent._prepare_run_context() builds:
|
||||
# RawAgent._prepare_run_context() builds:
|
||||
{
|
||||
"thread": AgentThread, # Validated/created thread
|
||||
"input_messages": [...], # Normalized input messages
|
||||
@@ -463,7 +463,7 @@ Returns `Awaitable[AgentResponse]`:
|
||||
```python
|
||||
async def _run_non_streaming():
|
||||
ctx = await self._prepare_run_context(...) # Async preparation
|
||||
response = await self.chat_client.get_response(stream=False, ...)
|
||||
response = await self.client.get_response(stream=False, ...)
|
||||
await self._finalize_response_and_update_thread(...)
|
||||
return AgentResponse(...)
|
||||
```
|
||||
@@ -476,7 +476,7 @@ Returns `ResponseStream[AgentResponseUpdate, AgentResponse]` **synchronously**:
|
||||
# Async preparation is deferred using ResponseStream.from_awaitable()
|
||||
async def _get_stream():
|
||||
ctx = await self._prepare_run_context(...) # Deferred until iteration
|
||||
return self.chat_client.get_response(stream=True, ...)
|
||||
return self.client.get_response(stream=True, ...)
|
||||
|
||||
return (
|
||||
ResponseStream.from_awaitable(_get_stream())
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
import asyncio
|
||||
from typing import Literal
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
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
|
||||
In Agent Framework, we have made ChatClient and Agent 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.
|
||||
|
||||
@@ -21,7 +21,7 @@ which provides:
|
||||
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.
|
||||
how provider-specific options work for ChatClient and Agent. But the same approach works for other providers too.
|
||||
"""
|
||||
|
||||
|
||||
@@ -49,14 +49,14 @@ async def demo_anthropic_chat_client() -> None:
|
||||
|
||||
|
||||
async def demo_anthropic_agent() -> None:
|
||||
"""Demonstrate ChatAgent with Anthropic client and typed options."""
|
||||
print("\n=== ChatAgent with Anthropic and Typed Options ===\n")
|
||||
"""Demonstrate Agent with Anthropic client and typed options."""
|
||||
print("\n=== Agent 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,
|
||||
agent = Agent(
|
||||
client=client,
|
||||
name="claude-assistant",
|
||||
instructions="You are a helpful assistant powered by Claude. Be concise.",
|
||||
default_options={
|
||||
@@ -132,15 +132,15 @@ async def demo_openai_chat_client_reasoning_models() -> None:
|
||||
|
||||
|
||||
async def demo_openai_agent() -> None:
|
||||
"""Demonstrate ChatAgent with OpenAI client and typed options."""
|
||||
print("\n=== ChatAgent with OpenAI and Typed Options ===\n")
|
||||
"""Demonstrate Agent with OpenAI client and typed options."""
|
||||
print("\n=== Agent 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(),
|
||||
agent = Agent[OpenAIReasoningChatOptions](
|
||||
client=OpenAIChatClient(),
|
||||
name="weather-assistant",
|
||||
instructions="You are a helpful assistant. Answer concisely.",
|
||||
# Options can be set at construction time
|
||||
|
||||
@@ -38,7 +38,7 @@ graph TB
|
||||
subgraph Integration["Agent Framework Integration"]
|
||||
Converter[ThreadItemConverter]
|
||||
Streamer[stream_agent_response]
|
||||
Agent[ChatAgent]
|
||||
Agent[Agent]
|
||||
end
|
||||
|
||||
Widgets[Widget Rendering<br/>render_weather_widget<br/>render_city_selector_widget]
|
||||
@@ -61,7 +61,7 @@ graph TB
|
||||
AttStore -.->|save files| Files
|
||||
AttStore -.->|save metadata| SQLite
|
||||
|
||||
Converter -->|ChatMessage array| Agent
|
||||
Converter -->|Message array| Agent
|
||||
Agent -->|AgentResponseUpdate| Streamer
|
||||
Streamer -->|ThreadStreamEvent| ChatKit
|
||||
|
||||
@@ -88,7 +88,7 @@ The sample implements a ChatKit server using the `ChatKitServer` base class from
|
||||
- **`WeatherChatKitServer`**: Custom ChatKit server implementation that:
|
||||
|
||||
- Extends `ChatKitServer[dict[str, Any]]`
|
||||
- Uses Agent Framework's `ChatAgent` with Azure OpenAI
|
||||
- Uses Agent Framework's `Agent` with Azure OpenAI
|
||||
- Converts ChatKit messages to Agent Framework format using `ThreadItemConverter`
|
||||
- Streams responses back to ChatKit using `stream_agent_response`
|
||||
- Creates and streams interactive widgets after agent responses
|
||||
|
||||
@@ -28,7 +28,7 @@ from typing import Annotated, Any
|
||||
import uvicorn
|
||||
|
||||
# Agent Framework imports
|
||||
from agent_framework import AgentResponseUpdate, ChatAgent, ChatMessage, tool
|
||||
from agent_framework import Agent, AgentResponseUpdate, FunctionResultContent, Message, Role, tool
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
|
||||
# Agent Framework ChatKit integration
|
||||
@@ -217,8 +217,8 @@ class WeatherChatKitServer(ChatKitServer[dict[str, Any]]):
|
||||
# Create Agent Framework agent with Azure OpenAI
|
||||
# For authentication, run `az login` command in terminal
|
||||
try:
|
||||
self.weather_agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
self.weather_agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions=(
|
||||
"You are a helpful weather assistant with image analysis capabilities. "
|
||||
"You can provide weather information for any location, tell the current time, "
|
||||
@@ -290,8 +290,8 @@ class WeatherChatKitServer(ChatKitServer[dict[str, Any]]):
|
||||
conversation_context = "\n".join(user_messages[:3])
|
||||
|
||||
title_prompt = [
|
||||
ChatMessage(
|
||||
role="user",
|
||||
Message(
|
||||
role=Role.USER,
|
||||
text=(
|
||||
f"Generate a very short, concise title (max 40 characters) for a conversation "
|
||||
f"that starts with:\n\n{conversation_context}\n\n"
|
||||
@@ -301,7 +301,7 @@ class WeatherChatKitServer(ChatKitServer[dict[str, Any]]):
|
||||
]
|
||||
|
||||
# Use the chat client directly for a quick, lightweight call
|
||||
response = await self.weather_agent.chat_client.get_response(
|
||||
response = await self.weather_agent.client.get_response(
|
||||
messages=title_prompt,
|
||||
options={
|
||||
"temperature": 0.3,
|
||||
@@ -342,6 +342,7 @@ class WeatherChatKitServer(ChatKitServer[dict[str, Any]]):
|
||||
runs the agent, converts the response back to ChatKit events using stream_agent_response,
|
||||
and creates interactive weather widgets when weather data is queried.
|
||||
"""
|
||||
from agent_framework import FunctionResultContent
|
||||
|
||||
if input_user_message is None:
|
||||
logger.debug("Received None user message, skipping")
|
||||
@@ -384,7 +385,7 @@ class WeatherChatKitServer(ChatKitServer[dict[str, Any]]):
|
||||
# Check for function results in the update
|
||||
if update.contents:
|
||||
for content in update.contents:
|
||||
if content.type == "function_result":
|
||||
if isinstance(content, FunctionResultContent):
|
||||
result = content.result
|
||||
|
||||
# Check if it's a WeatherResponse (string subclass with weather_data attribute)
|
||||
@@ -467,7 +468,7 @@ class WeatherChatKitServer(ChatKitServer[dict[str, Any]]):
|
||||
weather_data: WeatherData | None = None
|
||||
|
||||
# Create an agent message asking about the weather
|
||||
agent_messages = [ChatMessage(role="user", text=f"What's the weather in {city_label}?")]
|
||||
agent_messages = [Message(role=Role.USER, text=f"What's the weather in {city_label}?")]
|
||||
|
||||
logger.debug(f"Processing weather query: {agent_messages[0].text}")
|
||||
|
||||
@@ -481,7 +482,7 @@ class WeatherChatKitServer(ChatKitServer[dict[str, Any]]):
|
||||
# Check for function results in the update
|
||||
if update.contents:
|
||||
for content in update.contents:
|
||||
if content.type == "function_result":
|
||||
if isinstance(content, FunctionResultContent):
|
||||
result = content.result
|
||||
|
||||
# Check if it's a WeatherResponse (string subclass with weather_data attribute)
|
||||
@@ -572,7 +573,7 @@ async def chatkit_endpoint(request: Request):
|
||||
|
||||
|
||||
@app.post("/upload/{attachment_id}")
|
||||
async def upload_file(attachment_id: str, file: Annotated[UploadFile, File()]):
|
||||
async def upload_file(attachment_id: str, file: UploadFile = File(...)): # noqa: B008
|
||||
"""Handle file upload for two-phase upload.
|
||||
|
||||
The client POSTs the file bytes here after creating the attachment
|
||||
@@ -594,7 +595,7 @@ async def upload_file(attachment_id: str, file: Annotated[UploadFile, File()]):
|
||||
attachment = await data_store.load_attachment(attachment_id, {"user_id": DEFAULT_USER_ID})
|
||||
|
||||
# Clear the upload_url since upload is complete
|
||||
attachment.upload_url = None # type: ignore[union-attr]
|
||||
attachment.upload_url = None
|
||||
|
||||
# Save the updated attachment back to the store
|
||||
await data_store.save_attachment(attachment, {"user_id": DEFAULT_USER_ID})
|
||||
|
||||
@@ -6,7 +6,7 @@ from collections.abc import MutableSequence
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import ChatMessage, Context, ContextProvider
|
||||
from agent_framework import Context, ContextProvider, Message
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.ai.agentserver.agentframework import from_agent_framework # pyright: ignore[reportUnknownVariableType]
|
||||
from azure.identity import DefaultAzureCredential
|
||||
@@ -27,16 +27,16 @@ class TextSearchResult:
|
||||
class TextSearchContextProvider(ContextProvider):
|
||||
"""A simple context provider that simulates text search results based on keywords in the user's message."""
|
||||
|
||||
def _get_most_recent_message(self, messages: ChatMessage | MutableSequence[ChatMessage]) -> ChatMessage:
|
||||
def _get_most_recent_message(self, messages: Message | MutableSequence[Message]) -> Message:
|
||||
"""Helper method to extract the most recent message from the input."""
|
||||
if isinstance(messages, ChatMessage):
|
||||
if isinstance(messages, Message):
|
||||
return messages
|
||||
if messages:
|
||||
return messages[-1]
|
||||
raise ValueError("No messages provided")
|
||||
|
||||
@override
|
||||
async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
|
||||
async def invoking(self, messages: Message | MutableSequence[Message], **kwargs: Any) -> Context:
|
||||
message = self._get_most_recent_message(messages)
|
||||
query = message.text.lower()
|
||||
|
||||
@@ -84,7 +84,7 @@ class TextSearchContextProvider(ContextProvider):
|
||||
|
||||
return Context(
|
||||
messages=[
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user", text="\n\n".join(json.dumps(result.__dict__, indent=2) for result in results)
|
||||
)
|
||||
]
|
||||
|
||||
@@ -18,7 +18,7 @@ from dataclasses import dataclass
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
from aiohttp import web
|
||||
from aiohttp.web_middlewares import middleware
|
||||
@@ -95,7 +95,7 @@ def get_weather(
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
def build_agent() -> ChatAgent:
|
||||
def build_agent() -> Agent:
|
||||
"""Create and return the chat agent instance with weather tool registered."""
|
||||
return OpenAIChatClient().as_agent(
|
||||
name="WeatherAgent", instructions="You are a helpful weather agent.", tools=get_weather
|
||||
|
||||
@@ -48,8 +48,8 @@ from _tools import (
|
||||
from agent_framework import (
|
||||
AgentExecutorResponse,
|
||||
AgentResponseUpdate,
|
||||
ChatMessage,
|
||||
Executor,
|
||||
Message,
|
||||
WorkflowBuilder,
|
||||
WorkflowContext,
|
||||
executor,
|
||||
@@ -65,17 +65,17 @@ load_dotenv()
|
||||
|
||||
|
||||
@executor(id="start_executor")
|
||||
async def start_executor(input: str, ctx: WorkflowContext[list[ChatMessage]]) -> None:
|
||||
async def start_executor(input: str, ctx: WorkflowContext[list[Message]]) -> None:
|
||||
"""Initiates the workflow by sending the user query to all specialized agents."""
|
||||
await ctx.send_message([ChatMessage("user", [input])])
|
||||
await ctx.send_message([Message("user", [input])])
|
||||
|
||||
|
||||
class ResearchLead(Executor):
|
||||
"""Aggregates and summarizes travel planning findings from all specialized agents."""
|
||||
|
||||
def __init__(self, chat_client: AzureAIClient, id: str = "travel-planning-coordinator"):
|
||||
def __init__(self, client: AzureAIClient, id: str = "travel-planning-coordinator"):
|
||||
# store=True to preserve conversation history for evaluation
|
||||
self.agent = chat_client.as_agent(
|
||||
self.agent = client.as_agent(
|
||||
id="travel-planning-coordinator",
|
||||
instructions=(
|
||||
"You are the final coordinator. You will receive responses from multiple agents: "
|
||||
@@ -102,11 +102,11 @@ class ResearchLead(Executor):
|
||||
|
||||
# Generate comprehensive travel plan summary
|
||||
messages = [
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="system",
|
||||
text="You are a travel planning coordinator. Summarize findings from multiple specialized travel agents and provide a clear, comprehensive travel plan based on the user's query.",
|
||||
),
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user",
|
||||
text=f"Original query: {user_query}\n\nFindings from specialized travel agents:\n{summary_text}\n\nPlease provide a comprehensive travel plan based on these findings.",
|
||||
),
|
||||
@@ -142,17 +142,17 @@ class ResearchLead(Executor):
|
||||
return agent_findings
|
||||
|
||||
|
||||
async def run_workflow_with_response_tracking(query: str, chat_client: AzureAIClient | None = None) -> dict:
|
||||
async def run_workflow_with_response_tracking(query: str, client: AzureAIClient | None = None) -> dict:
|
||||
"""Run multi-agent workflow and track conversation IDs, response IDs, and interaction sequence.
|
||||
|
||||
Args:
|
||||
query: The user query to process through the multi-agent workflow
|
||||
chat_client: Optional AzureAIClient instance
|
||||
client: Optional AzureAIClient instance
|
||||
|
||||
Returns:
|
||||
Dictionary containing interaction sequence, conversation/response IDs, and conversation analysis
|
||||
"""
|
||||
if chat_client is None:
|
||||
if client is None:
|
||||
try:
|
||||
async with DefaultAzureCredential() as credential:
|
||||
# Create AIProjectClient with the correct API version for V2 prompt agents
|
||||
@@ -171,10 +171,10 @@ async def run_workflow_with_response_tracking(query: str, chat_client: AzureAICl
|
||||
print(f"Error during workflow execution: {e}")
|
||||
raise
|
||||
else:
|
||||
return await _run_workflow_with_client(query, chat_client)
|
||||
return await _run_workflow_with_client(query, client)
|
||||
|
||||
|
||||
async def _run_workflow_with_client(query: str, chat_client: AzureAIClient) -> dict:
|
||||
async def _run_workflow_with_client(query: str, client: AzureAIClient) -> dict:
|
||||
"""Execute workflow with given client and track all interactions."""
|
||||
|
||||
# Initialize tracking variables - use lists to track multiple responses per agent
|
||||
@@ -184,7 +184,7 @@ async def _run_workflow_with_client(query: str, chat_client: AzureAIClient) -> d
|
||||
|
||||
# Create workflow components and keep agent references
|
||||
# Pass project_client and credential to create separate client instances per agent
|
||||
workflow, agent_map = await _create_workflow(chat_client.project_client, chat_client.credential)
|
||||
workflow, agent_map = await _create_workflow(client.project_client, client.credential)
|
||||
|
||||
# Process workflow events
|
||||
events = workflow.run(query, stream=True)
|
||||
@@ -210,7 +210,7 @@ async def _create_workflow(project_client, credential):
|
||||
final_coordinator_client = AzureAIClient(
|
||||
project_client=project_client, credential=credential, agent_name="final-coordinator"
|
||||
)
|
||||
final_coordinator = ResearchLead(chat_client=final_coordinator_client, id="final-coordinator")
|
||||
final_coordinator = ResearchLead(client=final_coordinator_client, id="final-coordinator")
|
||||
|
||||
# Agent 1: Travel Request Handler (initial coordinator)
|
||||
# Create separate client with unique agent_name
|
||||
|
||||
@@ -23,7 +23,7 @@ This sample demonstrates the three main methods of AzureAIProjectAgentProvider:
|
||||
It also shows how to use a single provider instance to spawn multiple agents
|
||||
with different configurations, which is efficient for multi-agent scenarios.
|
||||
|
||||
Each method returns a ChatAgent that can be used for conversations.
|
||||
Each method returns a Agent that can be used for conversations.
|
||||
"""
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ async def create_agent_example() -> None:
|
||||
"""Example of using provider.create_agent() to create a new agent.
|
||||
|
||||
This method creates a new agent version on the Azure AI service and returns
|
||||
a ChatAgent. Use this when you want to create a fresh agent with
|
||||
a Agent. Use this when you want to create a fresh agent with
|
||||
specific configuration.
|
||||
"""
|
||||
print("=== provider.create_agent() Example ===")
|
||||
@@ -199,7 +199,7 @@ async def multiple_agents_example() -> None:
|
||||
async def as_agent_example() -> None:
|
||||
"""Example of using provider.as_agent() to wrap an SDK object without HTTP calls.
|
||||
|
||||
This method wraps an existing AgentVersionDetails into a ChatAgent without
|
||||
This method wraps an existing AgentVersionDetails into a Agent without
|
||||
making additional HTTP calls. Use this when you already have the full
|
||||
AgentVersionDetails from a previous SDK operation.
|
||||
"""
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.ai.projects.aio import AIProjectClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
@@ -23,8 +23,8 @@ async def main() -> None:
|
||||
# Endpoint here should be application endpoint with format:
|
||||
# /api/projects/<project-name>/applications/<application-name>/protocols
|
||||
AIProjectClient(endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"], credential=credential) as project_client,
|
||||
ChatAgent(
|
||||
chat_client=AzureAIClient(
|
||||
Agent(
|
||||
client=AzureAIClient(
|
||||
project_client=project_client,
|
||||
),
|
||||
) as agent,
|
||||
|
||||
+5
-5
@@ -5,9 +5,9 @@ import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework import (
|
||||
Agent,
|
||||
AgentResponseUpdate,
|
||||
Annotation,
|
||||
ChatAgent,
|
||||
Content,
|
||||
HostedCodeInterpreterTool,
|
||||
)
|
||||
@@ -33,7 +33,7 @@ QUERY = (
|
||||
)
|
||||
|
||||
|
||||
async def download_container_files(file_contents: list[Annotation | Content], agent: ChatAgent) -> list[Path]:
|
||||
async def download_container_files(file_contents: list[Annotation | Content], agent: Agent) -> list[Path]:
|
||||
"""Download container files using the OpenAI containers API.
|
||||
|
||||
Code interpreter generates files in containers, which require both file_id
|
||||
@@ -45,7 +45,7 @@ async def download_container_files(file_contents: list[Annotation | Content], ag
|
||||
Args:
|
||||
file_contents: List of Annotation or Content objects
|
||||
containing file_id and container_id.
|
||||
agent: The ChatAgent instance with access to the AzureAIClient.
|
||||
agent: The Agent instance with access to the AzureAIClient.
|
||||
|
||||
Returns:
|
||||
List of Path objects for successfully downloaded files.
|
||||
@@ -61,7 +61,7 @@ async def download_container_files(file_contents: list[Annotation | Content], ag
|
||||
print(f"\nDownloading {len(file_contents)} container file(s) to {output_dir.absolute()}...")
|
||||
|
||||
# Access the OpenAI client from AzureAIClient
|
||||
openai_client = agent.chat_client.client # type: ignore[attr-defined]
|
||||
openai_client = agent.client.client # type: ignore[attr-defined]
|
||||
|
||||
downloaded_files: list[Path] = []
|
||||
|
||||
@@ -139,7 +139,7 @@ async def non_streaming_example() -> None:
|
||||
|
||||
# Check for annotations in the response
|
||||
annotations_found: list[Annotation] = []
|
||||
# AgentResponse has messages property, which contains ChatMessage objects
|
||||
# AgentResponse has messages property, which contains Message objects
|
||||
for message in result.messages:
|
||||
for content in message.contents:
|
||||
if content.type == "text" and content.annotations:
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ async def non_streaming_example() -> None:
|
||||
|
||||
# Check for annotations in the response
|
||||
annotations_found: list[str] = []
|
||||
# AgentResponse has messages property, which contains ChatMessage objects
|
||||
# AgentResponse has messages property, which contains Message objects
|
||||
for message in result.messages:
|
||||
for content in message.contents:
|
||||
if content.type == "text" and content.annotations:
|
||||
|
||||
@@ -36,7 +36,7 @@ async def using_provider_get_agent() -> None:
|
||||
)
|
||||
|
||||
try:
|
||||
# Get newly created agent as ChatAgent by using provider.get_agent()
|
||||
# Get newly created agent as Agent by using provider.get_agent()
|
||||
provider = AzureAIProjectAgentProvider(project_client=project_client)
|
||||
agent = await provider.get_agent(name=azure_ai_agent.name)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import AgentResponse, AgentThread, ChatMessage, HostedMCPTool, SupportsAgentRun
|
||||
from agent_framework import AgentResponse, AgentThread, HostedMCPTool, Message, SupportsAgentRun
|
||||
from agent_framework.azure import AzureAIProjectAgentProvider
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
@@ -25,10 +25,10 @@ async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun")
|
||||
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
|
||||
f" with arguments: {user_input_needed.function_call.arguments}"
|
||||
)
|
||||
new_inputs.append(ChatMessage("assistant", [user_input_needed]))
|
||||
new_inputs.append(Message("assistant", [user_input_needed]))
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_inputs.append(
|
||||
ChatMessage("user", [user_input_needed.to_function_approval_response(user_approval.lower() == "y")])
|
||||
Message("user", [user_input_needed.to_function_approval_response(user_approval.lower() == "y")])
|
||||
)
|
||||
|
||||
result = await agent.run(new_inputs, store=False)
|
||||
@@ -48,7 +48,7 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user",
|
||||
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
|
||||
)
|
||||
|
||||
@@ -8,7 +8,7 @@ All examples in this folder use the `AzureAIAgentsProvider` class which provides
|
||||
|
||||
- **`create_agent()`** - Create a new agent on the Azure AI service
|
||||
- **`get_agent()`** - Retrieve an existing agent by ID or from a pre-fetched Agent object
|
||||
- **`as_agent()`** - Wrap an SDK Agent object as a ChatAgent without HTTP calls
|
||||
- **`as_agent()`** - Wrap an SDK Agent object as a Agent without HTTP calls
|
||||
|
||||
```python
|
||||
from agent_framework.azure import AzureAIAgentsProvider
|
||||
|
||||
@@ -17,7 +17,7 @@ servers, including user approval workflows for function call security.
|
||||
|
||||
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread") -> AgentResponse:
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
result = await agent.run(query, thread=thread, store=True)
|
||||
while len(result.user_input_requests) > 0:
|
||||
@@ -29,7 +29,7 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user",
|
||||
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
|
||||
)
|
||||
|
||||
@@ -51,7 +51,7 @@ async def mcp_tools_on_agent_level() -> None:
|
||||
print("=== Tools Defined on Agent Level ===")
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The ChatAgent will connect to the MCP server through its context manager
|
||||
# The Agent will connect to the MCP server through its context manager
|
||||
# and discover tools at runtime
|
||||
async with (
|
||||
AzureCliCredential() as credential,
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ def get_time() -> str:
|
||||
|
||||
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
result = await agent.run(query, thread=thread, store=True)
|
||||
while len(result.user_input_requests) > 0:
|
||||
@@ -57,7 +57,7 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user",
|
||||
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
|
||||
)
|
||||
|
||||
@@ -6,17 +6,17 @@ This folder contains examples demonstrating different ways to create and use age
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`azure_assistants_basic.py`](azure_assistants_basic.py) | The simplest way to create an agent using `ChatAgent` with `AzureOpenAIAssistantsClient`. Shows both streaming and non-streaming responses with automatic assistant creation and cleanup. |
|
||||
| [`azure_assistants_basic.py`](azure_assistants_basic.py) | The simplest way to create an agent using `Agent` with `AzureOpenAIAssistantsClient`. Shows both streaming and non-streaming responses with automatic assistant creation and cleanup. |
|
||||
| [`azure_assistants_with_code_interpreter.py`](azure_assistants_with_code_interpreter.py) | Shows how to use the HostedCodeInterpreterTool with Azure agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
|
||||
| [`azure_assistants_with_existing_assistant.py`](azure_assistants_with_existing_assistant.py) | Shows how to work with a pre-existing assistant by providing the assistant ID to the Azure Assistants client. Demonstrates proper cleanup of manually created assistants. |
|
||||
| [`azure_assistants_with_explicit_settings.py`](azure_assistants_with_explicit_settings.py) | Shows how to initialize an agent with a specific assistants client, configuring settings explicitly including endpoint and deployment name. |
|
||||
| [`azure_assistants_with_function_tools.py`](azure_assistants_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). |
|
||||
| [`azure_assistants_with_thread.py`](azure_assistants_with_thread.py) | Demonstrates thread management with Azure agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
| [`azure_chat_client_basic.py`](azure_chat_client_basic.py) | The simplest way to create an agent using `ChatAgent` with `AzureOpenAIChatClient`. Shows both streaming and non-streaming responses for chat-based interactions with Azure OpenAI models. |
|
||||
| [`azure_chat_client_basic.py`](azure_chat_client_basic.py) | The simplest way to create an agent using `Agent` with `AzureOpenAIChatClient`. Shows both streaming and non-streaming responses for chat-based interactions with Azure OpenAI models. |
|
||||
| [`azure_chat_client_with_explicit_settings.py`](azure_chat_client_with_explicit_settings.py) | Shows how to initialize an agent with a specific chat client, configuring settings explicitly including endpoint and deployment name. |
|
||||
| [`azure_chat_client_with_function_tools.py`](azure_chat_client_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). |
|
||||
| [`azure_chat_client_with_thread.py`](azure_chat_client_with_thread.py) | Demonstrates thread management with Azure agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
| [`azure_responses_client_basic.py`](azure_responses_client_basic.py) | The simplest way to create an agent using `ChatAgent` with `AzureOpenAIResponsesClient`. Shows both streaming and non-streaming responses for structured response generation with Azure OpenAI models. |
|
||||
| [`azure_responses_client_basic.py`](azure_responses_client_basic.py) | The simplest way to create an agent using `Agent` with `AzureOpenAIResponsesClient`. Shows both streaming and non-streaming responses for structured response generation with Azure OpenAI models. |
|
||||
| [`azure_responses_client_code_interpreter_files.py`](azure_responses_client_code_interpreter_files.py) | Demonstrates using HostedCodeInterpreterTool with file uploads for data analysis. Shows how to create, upload, and analyze CSV files using Python code execution with Azure OpenAI Responses. |
|
||||
| [`azure_responses_client_image_analysis.py`](azure_responses_client_image_analysis.py) | Shows how to use Azure OpenAI Responses for image analysis and vision tasks. Demonstrates multi-modal messages combining text and image content using remote URLs. |
|
||||
| [`azure_responses_client_with_code_interpreter.py`](azure_responses_client_with_code_interpreter.py) | Shows how to use the HostedCodeInterpreterTool with Azure agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import AgentResponseUpdate, ChatAgent, ChatResponseUpdate, HostedCodeInterpreterTool
|
||||
from agent_framework import Agent, AgentResponseUpdate, ChatResponseUpdate, HostedCodeInterpreterTool
|
||||
from agent_framework.azure import AzureOpenAIAssistantsClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from openai.types.beta.threads.runs import (
|
||||
@@ -46,8 +46,8 @@ async def main() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant that can write and execute Python code to solve problems.",
|
||||
tools=HostedCodeInterpreterTool(),
|
||||
) as agent:
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ import os
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.azure import AzureOpenAIAssistantsClient
|
||||
from azure.identity import AzureCliCredential, get_bearer_token_provider
|
||||
from openai import AsyncAzureOpenAI
|
||||
@@ -46,8 +46,8 @@ async def main() -> None:
|
||||
)
|
||||
|
||||
try:
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(async_client=client, assistant_id=created_assistant.id),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(async_client=client, assistant_id=created_assistant.id),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent:
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@ from datetime import datetime, timezone
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.azure import AzureOpenAIAssistantsClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from pydantic import Field
|
||||
@@ -43,8 +43,8 @@ async def tools_on_agent_level() -> None:
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant that can provide weather and time information.",
|
||||
tools=[get_weather, get_time], # Tools defined at agent creation
|
||||
) as agent:
|
||||
@@ -74,8 +74,8 @@ async def tools_on_run_level() -> None:
|
||||
# Agent created without tools
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant.",
|
||||
# No tools defined here
|
||||
) as agent:
|
||||
@@ -105,8 +105,8 @@ async def mixed_tools_example() -> None:
|
||||
# Agent created with some base tools
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
instructions="You are a comprehensive assistant that can help with various information requests.",
|
||||
tools=[get_weather], # Base tool available for all queries
|
||||
) as agent:
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import AgentThread, ChatAgent, tool
|
||||
from agent_framework import Agent, AgentThread, tool
|
||||
from agent_framework.azure import AzureOpenAIAssistantsClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from pydantic import Field
|
||||
@@ -33,8 +33,8 @@ async def example_with_automatic_thread_creation() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent:
|
||||
@@ -59,8 +59,8 @@ async def example_with_thread_persistence() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent:
|
||||
@@ -97,8 +97,8 @@ async def example_with_existing_thread_id() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent:
|
||||
@@ -117,8 +117,8 @@ async def example_with_existing_thread_id() -> None:
|
||||
print("\n--- Continuing with the same thread ID in a new agent instance ---")
|
||||
|
||||
# Create a new agent instance but use the existing thread ID
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIAssistantsClient(thread_id=existing_thread_id, credential=AzureCliCredential()),
|
||||
async with Agent(
|
||||
client=AzureOpenAIAssistantsClient(thread_id=existing_thread_id, credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
) as agent:
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@ from datetime import datetime, timezone
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from pydantic import Field
|
||||
@@ -43,8 +43,8 @@ async def tools_on_agent_level() -> None:
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant that can provide weather and time information.",
|
||||
tools=[get_weather, get_time], # Tools defined at agent creation
|
||||
)
|
||||
@@ -75,8 +75,8 @@ async def tools_on_run_level() -> None:
|
||||
# Agent created without tools
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant.",
|
||||
# No tools defined here
|
||||
)
|
||||
@@ -107,8 +107,8 @@ async def mixed_tools_example() -> None:
|
||||
# Agent created with some base tools
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions="You are a comprehensive assistant that can help with various information requests.",
|
||||
tools=[get_weather], # Base tool available for all queries
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import AgentThread, ChatAgent, ChatMessageStore, tool
|
||||
from agent_framework import Agent, AgentThread, ChatMessageStore, tool
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from pydantic import Field
|
||||
@@ -33,8 +33,8 @@ async def example_with_automatic_thread_creation() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -60,8 +60,8 @@ async def example_with_thread_persistence() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -95,8 +95,8 @@ async def example_with_existing_thread_messages() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -117,8 +117,8 @@ async def example_with_existing_thread_messages() -> None:
|
||||
print("\n--- Continuing with the same thread in a new agent instance ---")
|
||||
|
||||
# Create a new agent instance but use the existing thread with its message history
|
||||
new_agent = ChatAgent(
|
||||
chat_client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
new_agent = Agent(
|
||||
client=AzureOpenAIChatClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@ import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from agent_framework import ChatAgent, HostedCodeInterpreterTool
|
||||
from agent_framework import Agent, HostedCodeInterpreterTool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from openai import AsyncAzureOpenAI
|
||||
@@ -76,8 +76,8 @@ async def main() -> None:
|
||||
temp_file_path, file_id = await create_sample_file_and_upload(openai_client)
|
||||
|
||||
# Create agent using Azure OpenAI Responses client
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=credential),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=credential),
|
||||
instructions="You are a helpful assistant that can analyze data files using Python code.",
|
||||
tools=HostedCodeInterpreterTool(inputs=[{"file_id": file_id}]),
|
||||
)
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatMessage, Content
|
||||
from agent_framework import Content, Message
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
@@ -24,7 +24,7 @@ async def main():
|
||||
)
|
||||
|
||||
# 2. Create a simple message with both text and image content
|
||||
user_message = ChatMessage(
|
||||
user_message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What do you see in this image?"),
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent, ChatResponse, HostedCodeInterpreterTool
|
||||
from agent_framework import Agent, ChatResponse, HostedCodeInterpreterTool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from openai.types.responses.response import Response as OpenAIResponse
|
||||
@@ -22,8 +22,8 @@ async def main() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant that can write and execute Python code to solve problems.",
|
||||
tools=HostedCodeInterpreterTool(),
|
||||
)
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent, Content, HostedFileSearchTool
|
||||
from agent_framework import Agent, Content, HostedFileSearchTool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
@@ -53,8 +53,8 @@ async def main() -> None:
|
||||
|
||||
file_id, vector_store = await create_vector_store(client)
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=client,
|
||||
agent = Agent(
|
||||
client=client,
|
||||
instructions="You are a helpful assistant that can search through files to find information.",
|
||||
tools=[HostedFileSearchTool(inputs=vector_store)],
|
||||
)
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@ from datetime import datetime, timezone
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from pydantic import Field
|
||||
@@ -43,8 +43,8 @@ async def tools_on_agent_level() -> None:
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant that can provide weather and time information.",
|
||||
tools=[get_weather, get_time], # Tools defined at agent creation
|
||||
)
|
||||
@@ -75,8 +75,8 @@ async def tools_on_run_level() -> None:
|
||||
# Agent created without tools
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful assistant.",
|
||||
# No tools defined here
|
||||
)
|
||||
@@ -107,8 +107,8 @@ async def mixed_tools_example() -> None:
|
||||
# Agent created with some base tools
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a comprehensive assistant that can help with various information requests.",
|
||||
tools=[get_weather], # Base tool available for all queries
|
||||
)
|
||||
|
||||
+18
-18
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from agent_framework import ChatAgent, HostedMCPTool
|
||||
from agent_framework import Agent, HostedMCPTool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
|
||||
|
||||
async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun"):
|
||||
"""When we don't have a thread, we need to ensure we return with the input, approval request and approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
result = await agent.run(query)
|
||||
while len(result.user_input_requests) > 0:
|
||||
@@ -30,10 +30,10 @@ async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun")
|
||||
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
|
||||
f" with arguments: {user_input_needed.function_call.arguments}"
|
||||
)
|
||||
new_inputs.append(ChatMessage(role="assistant", contents=[user_input_needed]))
|
||||
new_inputs.append(Message(role="assistant", contents=[user_input_needed]))
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_inputs.append(
|
||||
ChatMessage(role="user", contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")])
|
||||
Message(role="user", contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")])
|
||||
)
|
||||
|
||||
result = await agent.run(new_inputs)
|
||||
@@ -42,7 +42,7 @@ async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun")
|
||||
|
||||
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
result = await agent.run(query, thread=thread, store=True)
|
||||
while len(result.user_input_requests) > 0:
|
||||
@@ -54,7 +54,7 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user",
|
||||
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
|
||||
)
|
||||
@@ -65,13 +65,13 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
|
||||
|
||||
async def handle_approvals_with_thread_streaming(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
new_input: list[ChatMessage] = []
|
||||
new_input: list[Message] = []
|
||||
new_input_added = True
|
||||
while new_input_added:
|
||||
new_input_added = False
|
||||
new_input.append(ChatMessage(role="user", text=query))
|
||||
new_input.append(Message(role="user", text=query))
|
||||
async for update in agent.run(new_input, thread=thread, options={"store": True}, stream=True):
|
||||
if update.user_input_requests:
|
||||
for user_input_needed in update.user_input_requests:
|
||||
@@ -81,7 +81,7 @@ async def handle_approvals_with_thread_streaming(query: str, agent: "SupportsAge
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user", contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")]
|
||||
)
|
||||
)
|
||||
@@ -96,8 +96,8 @@ async def run_hosted_mcp_without_thread_and_specific_approval() -> None:
|
||||
credential = AzureCliCredential()
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(
|
||||
async with Agent(
|
||||
client=AzureOpenAIResponsesClient(
|
||||
credential=credential,
|
||||
),
|
||||
name="DocsAgent",
|
||||
@@ -129,8 +129,8 @@ async def run_hosted_mcp_without_approval() -> None:
|
||||
credential = AzureCliCredential()
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(
|
||||
async with Agent(
|
||||
client=AzureOpenAIResponsesClient(
|
||||
credential=credential,
|
||||
),
|
||||
name="DocsAgent",
|
||||
@@ -163,8 +163,8 @@ async def run_hosted_mcp_with_thread() -> None:
|
||||
credential = AzureCliCredential()
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(
|
||||
async with Agent(
|
||||
client=AzureOpenAIResponsesClient(
|
||||
credential=credential,
|
||||
),
|
||||
name="DocsAgent",
|
||||
@@ -196,8 +196,8 @@ async def run_hosted_mcp_with_thread_streaming() -> None:
|
||||
credential = AzureCliCredential()
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(
|
||||
async with Agent(
|
||||
client=AzureOpenAIResponsesClient(
|
||||
credential=credential,
|
||||
),
|
||||
name="DocsAgent",
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent, MCPStreamableHTTPTool
|
||||
from agent_framework import Agent, MCPStreamableHTTPTool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
@@ -37,7 +37,7 @@ async def main():
|
||||
credential=credential,
|
||||
)
|
||||
|
||||
agent: ChatAgent = responses_client.as_agent(
|
||||
agent: Agent = responses_client.as_agent(
|
||||
name="DocsAgent",
|
||||
instructions=("You are a helpful assistant that can help with Microsoft documentation questions."),
|
||||
)
|
||||
|
||||
+9
-9
@@ -4,7 +4,7 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import AgentThread, ChatAgent, tool
|
||||
from agent_framework import Agent, AgentThread, tool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from pydantic import Field
|
||||
@@ -33,8 +33,8 @@ async def example_with_automatic_thread_creation() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -62,8 +62,8 @@ async def example_with_thread_persistence_in_memory() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -103,8 +103,8 @@ async def example_with_existing_thread_id() -> None:
|
||||
|
||||
# For authentication, run `az login` command in terminal or replace AzureCliCredential with preferred
|
||||
# authentication option.
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -125,8 +125,8 @@ async def example_with_existing_thread_id() -> None:
|
||||
if existing_thread_id:
|
||||
print("\n--- Continuing with the same thread ID in a new agent instance ---")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
agent = Agent(
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ This folder contains examples demonstrating how to implement custom agents and c
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`custom_agent.py`](custom_agent.py) | Shows how to create custom agents by extending the `BaseAgent` class. Demonstrates the `EchoAgent` implementation with both streaming and non-streaming responses, proper thread management, and message history handling. |
|
||||
| [`custom_chat_client.py`](../../chat_client/custom_chat_client.py) | Demonstrates how to create custom chat clients by extending the `BaseChatClient` class. Shows a `EchoingChatClient` implementation and how to integrate it with `ChatAgent` using the `as_agent()` method. |
|
||||
| [`custom_chat_client.py`](../../chat_client/custom_chat_client.py) | Demonstrates how to create custom chat clients by extending the `BaseChatClient` class. Shows a `EchoingChatClient` implementation and how to integrate it with `Agent` using the `as_agent()` method. |
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
@@ -20,7 +20,7 @@ This folder contains examples demonstrating how to implement custom agents and c
|
||||
### Custom Chat Clients
|
||||
- Custom chat clients allow you to integrate any backend service or create new LLM providers
|
||||
- You must implement `_inner_get_response()` with a stream parameter to handle both streaming and non-streaming responses
|
||||
- Custom chat clients can be used with `ChatAgent` to leverage all agent framework features
|
||||
- Custom chat clients can be used with `Agent` to leverage all agent framework features
|
||||
- Use the `as_agent()` method to easily create agents from your custom chat clients
|
||||
|
||||
Both approaches allow you to extend the framework for your specific use cases while maintaining compatibility with the broader Agent Framework ecosystem.
|
||||
|
||||
@@ -9,8 +9,8 @@ from agent_framework import (
|
||||
AgentResponseUpdate,
|
||||
AgentThread,
|
||||
BaseAgent,
|
||||
ChatMessage,
|
||||
Content,
|
||||
Message,
|
||||
Role,
|
||||
normalize_messages,
|
||||
)
|
||||
@@ -57,7 +57,7 @@ class EchoAgent(BaseAgent):
|
||||
|
||||
def run(
|
||||
self,
|
||||
messages: str | ChatMessage | list[str] | list[ChatMessage] | None = None,
|
||||
messages: str | Message | list[str] | list[Message] | None = None,
|
||||
*,
|
||||
stream: bool = False,
|
||||
thread: AgentThread | None = None,
|
||||
@@ -81,7 +81,7 @@ class EchoAgent(BaseAgent):
|
||||
|
||||
async def _run(
|
||||
self,
|
||||
messages: str | ChatMessage | list[str] | list[ChatMessage] | None = None,
|
||||
messages: str | Message | list[str] | list[Message] | None = None,
|
||||
*,
|
||||
thread: AgentThread | None = None,
|
||||
**kwargs: Any,
|
||||
@@ -91,11 +91,9 @@ class EchoAgent(BaseAgent):
|
||||
normalized_messages = normalize_messages(messages)
|
||||
|
||||
if not normalized_messages:
|
||||
response_message = ChatMessage(
|
||||
response_message = Message(
|
||||
role=Role.ASSISTANT,
|
||||
contents=[
|
||||
Content.from_text(text="Hello! I'm a custom echo agent. Send me a message and I'll echo it back.")
|
||||
],
|
||||
contents=[Content.from_text(text="Hello! I'm a custom echo agent. Send me a message and I'll echo it back.")],
|
||||
)
|
||||
else:
|
||||
# For simplicity, echo the last user message
|
||||
@@ -105,7 +103,7 @@ class EchoAgent(BaseAgent):
|
||||
else:
|
||||
echo_text = f"{self.echo_prefix}[Non-text message received]"
|
||||
|
||||
response_message = ChatMessage(role=Role.ASSISTANT, contents=[Content.from_text(text=echo_text)])
|
||||
response_message = Message(role=Role.ASSISTANT, contents=[Content.from_text(text=echo_text)])
|
||||
|
||||
# Notify the thread of new messages if provided
|
||||
if thread is not None:
|
||||
@@ -115,7 +113,7 @@ class EchoAgent(BaseAgent):
|
||||
|
||||
async def _run_stream(
|
||||
self,
|
||||
messages: str | ChatMessage | list[str] | list[ChatMessage] | None = None,
|
||||
messages: str | Message | list[str] | list[Message] | None = None,
|
||||
*,
|
||||
thread: AgentThread | None = None,
|
||||
**kwargs: Any,
|
||||
@@ -150,7 +148,7 @@ class EchoAgent(BaseAgent):
|
||||
|
||||
# Notify the thread of the complete response if provided
|
||||
if thread is not None:
|
||||
complete_response = ChatMessage(role=Role.ASSISTANT, contents=[Content.from_text(text=response_text)])
|
||||
complete_response = Message(role=Role.ASSISTANT, contents=[Content.from_text(text=response_text)])
|
||||
await self._notify_thread_of_new_messages(thread, normalized_messages, complete_response)
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatMessage, Content
|
||||
from agent_framework import Content, Message
|
||||
from agent_framework.ollama import OllamaChatClient
|
||||
|
||||
"""
|
||||
@@ -32,7 +32,7 @@ async def test_image() -> None:
|
||||
|
||||
image_uri = create_sample_image()
|
||||
|
||||
message = ChatMessage(
|
||||
message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What's in this image?"),
|
||||
|
||||
@@ -15,14 +15,14 @@ This folder contains examples demonstrating different ways to create and use age
|
||||
| [`openai_assistants_with_function_tools.py`](openai_assistants_with_function_tools.py) | Function tools with `OpenAIAssistantProvider` at both agent-level and query-level. |
|
||||
| [`openai_assistants_with_response_format.py`](openai_assistants_with_response_format.py) | Structured outputs with `OpenAIAssistantProvider` using Pydantic models. |
|
||||
| [`openai_assistants_with_thread.py`](openai_assistants_with_thread.py) | Thread management with `OpenAIAssistantProvider` for conversation context persistence. |
|
||||
| [`openai_chat_client_basic.py`](openai_chat_client_basic.py) | The simplest way to create an agent using `ChatAgent` with `OpenAIChatClient`. Shows both streaming and non-streaming responses for chat-based interactions with OpenAI models. |
|
||||
| [`openai_chat_client_basic.py`](openai_chat_client_basic.py) | The simplest way to create an agent using `Agent` with `OpenAIChatClient`. Shows both streaming and non-streaming responses for chat-based interactions with OpenAI models. |
|
||||
| [`openai_chat_client_with_explicit_settings.py`](openai_chat_client_with_explicit_settings.py) | Shows how to initialize an agent with a specific chat client, configuring settings explicitly including API key and model ID. |
|
||||
| [`openai_chat_client_with_function_tools.py`](openai_chat_client_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). |
|
||||
| [`openai_chat_client_with_local_mcp.py`](openai_chat_client_with_local_mcp.py) | Shows how to integrate OpenAI agents with local Model Context Protocol (MCP) servers for enhanced functionality and tool integration. |
|
||||
| [`openai_chat_client_with_thread.py`](openai_chat_client_with_thread.py) | Demonstrates thread management with OpenAI agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
| [`openai_chat_client_with_web_search.py`](openai_chat_client_with_web_search.py) | Shows how to use web search capabilities with OpenAI agents to retrieve and use information from the internet in responses. |
|
||||
| [`openai_chat_client_with_runtime_json_schema.py`](openai_chat_client_with_runtime_json_schema.py) | Shows how to supply a runtime JSON Schema via `additional_chat_options` for structured output without defining a Pydantic model. |
|
||||
| [`openai_responses_client_basic.py`](openai_responses_client_basic.py) | The simplest way to create an agent using `ChatAgent` with `OpenAIResponsesClient`. Shows both streaming and non-streaming responses for structured response generation with OpenAI models. |
|
||||
| [`openai_responses_client_basic.py`](openai_responses_client_basic.py) | The simplest way to create an agent using `Agent` with `OpenAIResponsesClient`. Shows both streaming and non-streaming responses for structured response generation with OpenAI models. |
|
||||
| [`openai_responses_client_image_analysis.py`](openai_responses_client_image_analysis.py) | Demonstrates how to use vision capabilities with agents to analyze images. |
|
||||
| [`openai_responses_client_image_generation.py`](openai_responses_client_image_generation.py) | Demonstrates how to use image generation capabilities with OpenAI agents to create images based on text descriptions. Requires PIL (Pillow) for image display. |
|
||||
| [`openai_responses_client_reasoning.py`](openai_responses_client_reasoning.py) | Demonstrates how to use reasoning capabilities with OpenAI agents, showing how the agent can provide detailed reasoning for its responses. |
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@ from datetime import datetime, timezone
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
from pydantic import Field
|
||||
|
||||
@@ -40,8 +40,8 @@ async def tools_on_agent_level() -> None:
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
instructions="You are a helpful assistant that can provide weather and time information.",
|
||||
tools=[get_weather, get_time], # Tools defined at agent creation
|
||||
)
|
||||
@@ -70,8 +70,8 @@ async def tools_on_run_level() -> None:
|
||||
print("=== Tools Passed to Run Method ===")
|
||||
|
||||
# Agent created without tools
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
instructions="You are a helpful assistant.",
|
||||
# No tools defined here
|
||||
)
|
||||
@@ -100,8 +100,8 @@ async def mixed_tools_example() -> None:
|
||||
print("=== Mixed Tools Example (Agent + Run Method) ===")
|
||||
|
||||
# Agent created with some base tools
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
instructions="You are a comprehensive assistant that can help with various information requests.",
|
||||
tools=[get_weather], # Base tool available for all queries
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent, MCPStreamableHTTPTool
|
||||
from agent_framework import Agent, MCPStreamableHTTPTool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
|
||||
"""
|
||||
@@ -29,8 +29,8 @@ async def mcp_tools_on_run_level() -> None:
|
||||
name="Microsoft Learn MCP",
|
||||
url="https://learn.microsoft.com/api/mcp",
|
||||
) as mcp_server,
|
||||
ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
Agent(
|
||||
client=OpenAIChatClient(),
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
) as agent,
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import AgentThread, ChatAgent, ChatMessageStore, tool
|
||||
from agent_framework import Agent, AgentThread, ChatMessageStore, tool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
from pydantic import Field
|
||||
|
||||
@@ -30,8 +30,8 @@ async def example_with_automatic_thread_creation() -> None:
|
||||
"""Example showing automatic thread creation (service-managed thread)."""
|
||||
print("=== Automatic Thread Creation Example ===")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -55,8 +55,8 @@ async def example_with_thread_persistence() -> None:
|
||||
print("=== Thread Persistence Example ===")
|
||||
print("Using the same thread across multiple conversations to maintain context.\n")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -88,8 +88,8 @@ async def example_with_existing_thread_messages() -> None:
|
||||
"""Example showing how to work with existing thread messages for OpenAI."""
|
||||
print("=== Existing Thread Messages Example ===")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -110,8 +110,8 @@ async def example_with_existing_thread_messages() -> None:
|
||||
print("\n--- Continuing with the same thread in a new agent instance ---")
|
||||
|
||||
# Create a new agent instance but use the existing thread with its message history
|
||||
new_agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
new_agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent, HostedWebSearchTool
|
||||
from agent_framework import Agent, HostedWebSearchTool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
|
||||
"""
|
||||
@@ -22,8 +22,8 @@ async def main() -> None:
|
||||
}
|
||||
}
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(model_id="gpt-4o-search-preview"),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(model_id="gpt-4o-search-preview"),
|
||||
instructions="You are a helpful assistant that can search the web for current information.",
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
)
|
||||
|
||||
@@ -6,11 +6,12 @@ from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import (
|
||||
ChatAgent,
|
||||
Agent,
|
||||
ChatContext,
|
||||
ChatMessage,
|
||||
ChatResponse,
|
||||
Message,
|
||||
MiddlewareTermination,
|
||||
Role,
|
||||
chat_middleware,
|
||||
tool,
|
||||
)
|
||||
@@ -46,8 +47,8 @@ async def security_and_override_middleware(
|
||||
# Override the response instead of calling AI
|
||||
context.result = ChatResponse(
|
||||
messages=[
|
||||
ChatMessage(
|
||||
role="assistant",
|
||||
Message(
|
||||
role=Role.ASSISTANT,
|
||||
text="I cannot process requests containing sensitive information. "
|
||||
"Please rephrase your question without including passwords, secrets, or other "
|
||||
"sensitive data.",
|
||||
@@ -55,8 +56,8 @@ async def security_and_override_middleware(
|
||||
]
|
||||
)
|
||||
|
||||
# Set terminate flag to stop execution
|
||||
raise MiddlewareTermination
|
||||
# Terminate middleware execution with the blocked response
|
||||
raise MiddlewareTermination(result=context.result)
|
||||
|
||||
# Continue to next middleware or AI execution
|
||||
await call_next(context)
|
||||
@@ -79,8 +80,8 @@ async def non_streaming_example() -> None:
|
||||
"""Example of non-streaming response (get the complete result at once)."""
|
||||
print("=== Non-streaming Response Example ===")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -95,8 +96,8 @@ async def streaming_example() -> None:
|
||||
"""Example of streaming response (get results as they are generated)."""
|
||||
print("=== Streaming Response Example ===")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(
|
||||
middleware=[security_and_override_middleware],
|
||||
),
|
||||
instructions="You are a helpful weather agent.",
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatMessage, Content
|
||||
from agent_framework import Content, Message
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""
|
||||
@@ -23,7 +23,7 @@ async def main():
|
||||
)
|
||||
|
||||
# 2. Create a simple message with both text and image content
|
||||
user_message = ChatMessage(
|
||||
user_message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What do you see in this image?"),
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
|
||||
from agent_framework import (
|
||||
ChatAgent,
|
||||
Agent,
|
||||
HostedCodeInterpreterTool,
|
||||
)
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
@@ -20,8 +20,8 @@ async def main() -> None:
|
||||
"""Example showing how to use the HostedCodeInterpreterTool with OpenAI Responses."""
|
||||
print("=== OpenAI Responses Agent with Code Interpreter Example ===")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful assistant that can write and execute Python code to solve problems.",
|
||||
tools=HostedCodeInterpreterTool(),
|
||||
)
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@ import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from agent_framework import ChatAgent, HostedCodeInterpreterTool
|
||||
from agent_framework import Agent, HostedCodeInterpreterTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
from openai import AsyncOpenAI
|
||||
|
||||
@@ -66,8 +66,8 @@ async def main() -> None:
|
||||
temp_file_path, file_id = await create_sample_file_and_upload(openai_client)
|
||||
|
||||
# Create agent using OpenAI Responses client
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful assistant that can analyze data files using Python code.",
|
||||
tools=HostedCodeInterpreterTool(inputs=[{"file_id": file_id}]),
|
||||
)
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent, Content, HostedFileSearchTool
|
||||
from agent_framework import Agent, Content, HostedFileSearchTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""
|
||||
@@ -47,8 +47,8 @@ async def main() -> None:
|
||||
print(f"User: {message}")
|
||||
file_id, vector_store = await create_vector_store(client)
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=client,
|
||||
agent = Agent(
|
||||
client=client,
|
||||
instructions="You are a helpful assistant that can search through files to find information.",
|
||||
tools=[HostedFileSearchTool(inputs=vector_store)],
|
||||
)
|
||||
|
||||
+7
-7
@@ -5,7 +5,7 @@ from datetime import datetime, timezone
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
from pydantic import Field
|
||||
|
||||
@@ -40,8 +40,8 @@ async def tools_on_agent_level() -> None:
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful assistant that can provide weather and time information.",
|
||||
tools=[get_weather, get_time], # Tools defined at agent creation
|
||||
)
|
||||
@@ -70,8 +70,8 @@ async def tools_on_run_level() -> None:
|
||||
print("=== Tools Passed to Run Method ===")
|
||||
|
||||
# Agent created without tools
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful assistant.",
|
||||
# No tools defined here
|
||||
)
|
||||
@@ -100,8 +100,8 @@ async def mixed_tools_example() -> None:
|
||||
print("=== Mixed Tools Example (Agent + Run Method) ===")
|
||||
|
||||
# Agent created with some base tools
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a comprehensive assistant that can help with various information requests.",
|
||||
tools=[get_weather], # Base tool available for all queries
|
||||
)
|
||||
|
||||
+18
-18
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from agent_framework import ChatAgent, HostedMCPTool
|
||||
from agent_framework import Agent, HostedMCPTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""
|
||||
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
|
||||
|
||||
async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun"):
|
||||
"""When we don't have a thread, we need to ensure we return with the input, approval request and approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
result = await agent.run(query)
|
||||
while len(result.user_input_requests) > 0:
|
||||
@@ -29,10 +29,10 @@ async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun")
|
||||
f"User Input Request for function from {agent.name}: {user_input_needed.function_call.name}"
|
||||
f" with arguments: {user_input_needed.function_call.arguments}"
|
||||
)
|
||||
new_inputs.append(ChatMessage(role="assistant", contents=[user_input_needed]))
|
||||
new_inputs.append(Message(role="assistant", contents=[user_input_needed]))
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_inputs.append(
|
||||
ChatMessage(role="user", contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")])
|
||||
Message(role="user", contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")])
|
||||
)
|
||||
|
||||
result = await agent.run(new_inputs)
|
||||
@@ -41,7 +41,7 @@ async def handle_approvals_without_thread(query: str, agent: "SupportsAgentRun")
|
||||
|
||||
async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
result = await agent.run(query, thread=thread, store=True)
|
||||
while len(result.user_input_requests) > 0:
|
||||
@@ -53,7 +53,7 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user",
|
||||
contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")],
|
||||
)
|
||||
@@ -64,13 +64,13 @@ async def handle_approvals_with_thread(query: str, agent: "SupportsAgentRun", th
|
||||
|
||||
async def handle_approvals_with_thread_streaming(query: str, agent: "SupportsAgentRun", thread: "AgentThread"):
|
||||
"""Here we let the thread deal with the previous responses, and we just rerun with the approval."""
|
||||
from agent_framework import ChatMessage
|
||||
from agent_framework import Message
|
||||
|
||||
new_input: list[ChatMessage] = []
|
||||
new_input: list[Message] = []
|
||||
new_input_added = True
|
||||
while new_input_added:
|
||||
new_input_added = False
|
||||
new_input.append(ChatMessage(role="user", text=query))
|
||||
new_input.append(Message(role="user", text=query))
|
||||
async for update in agent.run(new_input, thread=thread, stream=True, options={"store": True}):
|
||||
if update.user_input_requests:
|
||||
for user_input_needed in update.user_input_requests:
|
||||
@@ -80,7 +80,7 @@ async def handle_approvals_with_thread_streaming(query: str, agent: "SupportsAge
|
||||
)
|
||||
user_approval = input("Approve function call? (y/n): ")
|
||||
new_input.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="user", contents=[user_input_needed.to_function_approval_response(user_approval.lower() == "y")]
|
||||
)
|
||||
)
|
||||
@@ -95,8 +95,8 @@ async def run_hosted_mcp_without_thread_and_specific_approval() -> None:
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
async with Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
tools=HostedMCPTool(
|
||||
@@ -126,8 +126,8 @@ async def run_hosted_mcp_without_approval() -> None:
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
async with Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
tools=HostedMCPTool(
|
||||
@@ -158,8 +158,8 @@ async def run_hosted_mcp_with_thread() -> None:
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
async with Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
tools=HostedMCPTool(
|
||||
@@ -189,8 +189,8 @@ async def run_hosted_mcp_with_thread_streaming() -> None:
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
async with Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
tools=HostedMCPTool(
|
||||
|
||||
+5
-5
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent, MCPStreamableHTTPTool
|
||||
from agent_framework import Agent, MCPStreamableHTTPTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""
|
||||
@@ -22,8 +22,8 @@ async def streaming_with_mcp(show_raw_stream: bool = False) -> None:
|
||||
print("=== Tools Defined on Agent Level ===")
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
async with Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
tools=MCPStreamableHTTPTool( # Tools defined at agent creation
|
||||
@@ -60,8 +60,8 @@ async def run_with_mcp() -> None:
|
||||
|
||||
# Tools are provided when creating the agent
|
||||
# The agent can use these tools for any query during its lifetime
|
||||
async with ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
async with Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="DocsAgent",
|
||||
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
|
||||
tools=MCPStreamableHTTPTool( # Tools defined at agent creation
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import AgentThread, ChatAgent, tool
|
||||
from agent_framework import Agent, AgentThread, tool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
from pydantic import Field
|
||||
|
||||
@@ -30,8 +30,8 @@ async def example_with_automatic_thread_creation() -> None:
|
||||
"""Example showing automatic thread creation."""
|
||||
print("=== Automatic Thread Creation Example ===")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -57,8 +57,8 @@ async def example_with_thread_persistence_in_memory() -> None:
|
||||
"""
|
||||
print("=== Thread Persistence Example (In-Memory) ===")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -96,8 +96,8 @@ async def example_with_existing_thread_id() -> None:
|
||||
# First, create a conversation and capture the thread ID
|
||||
existing_thread_id = None
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
@@ -117,8 +117,8 @@ async def example_with_existing_thread_id() -> None:
|
||||
if existing_thread_id:
|
||||
print("\n--- Continuing with the same thread ID in a new agent instance ---")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful weather agent.",
|
||||
tools=get_weather,
|
||||
)
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatAgent, HostedWebSearchTool
|
||||
from agent_framework import Agent, HostedWebSearchTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
|
||||
"""
|
||||
@@ -22,8 +22,8 @@ async def main() -> None:
|
||||
}
|
||||
}
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
instructions="You are a helpful assistant that can search the web for current information.",
|
||||
tools=[HostedWebSearchTool(additional_properties=additional_properties)],
|
||||
)
|
||||
|
||||
@@ -76,8 +76,8 @@ Expected response:
|
||||
{
|
||||
"status": "healthy",
|
||||
"agents": [
|
||||
{"name": "WeatherAgent", "type": "ChatAgent"},
|
||||
{"name": "MathAgent", "type": "ChatAgent"}
|
||||
{"name": "WeatherAgent", "type": "Agent"},
|
||||
{"name": "MathAgent", "type": "Agent"}
|
||||
],
|
||||
"agent_count": 2
|
||||
}
|
||||
|
||||
@@ -56,15 +56,15 @@ def calculate_tip(bill_amount: float, tip_percentage: float = 15.0) -> dict[str,
|
||||
|
||||
|
||||
# 1. Create multiple agents, each with its own instruction set and tools.
|
||||
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
|
||||
weather_agent = chat_client.as_agent(
|
||||
weather_agent = client.as_agent(
|
||||
name="WeatherAgent",
|
||||
instructions="You are a helpful weather assistant. Provide current weather information.",
|
||||
tools=[get_weather],
|
||||
)
|
||||
|
||||
math_agent = chat_client.as_agent(
|
||||
math_agent = client.as_agent(
|
||||
name="MathAgent",
|
||||
instructions="You are a helpful math assistant. Help users with calculations like tip calculations.",
|
||||
tools=[calculate_tip],
|
||||
|
||||
+3
-3
@@ -30,14 +30,14 @@ CHEMIST_AGENT_NAME = "ChemistAgent"
|
||||
|
||||
# 2. Instantiate both agents that the orchestration will run concurrently.
|
||||
def _create_agents() -> list[Any]:
|
||||
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
|
||||
physicist = chat_client.as_agent(
|
||||
physicist = client.as_agent(
|
||||
name=PHYSICIST_AGENT_NAME,
|
||||
instructions="You are an expert in physics. You answer questions from a physics perspective.",
|
||||
)
|
||||
|
||||
chemist = chat_client.as_agent(
|
||||
chemist = client.as_agent(
|
||||
name=CHEMIST_AGENT_NAME,
|
||||
instructions="You are an expert in chemistry. You answer questions from a chemistry perspective.",
|
||||
)
|
||||
|
||||
+3
-3
@@ -45,14 +45,14 @@ class EmailPayload(BaseModel):
|
||||
|
||||
# 2. Instantiate both agents so they can be registered with AgentFunctionApp.
|
||||
def _create_agents() -> list[Any]:
|
||||
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
|
||||
spam_agent = chat_client.as_agent(
|
||||
spam_agent = client.as_agent(
|
||||
name=SPAM_AGENT_NAME,
|
||||
instructions="You are a spam detection assistant that identifies spam emails.",
|
||||
)
|
||||
|
||||
email_agent = chat_client.as_agent(
|
||||
email_agent = client.as_agent(
|
||||
name=EMAIL_AGENT_NAME,
|
||||
instructions="You are an email assistant that helps users draft responses to emails with professionalism.",
|
||||
)
|
||||
|
||||
@@ -142,20 +142,20 @@ The sample shows how to enable MCP tool triggers with flexible agent configurati
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
|
||||
# Create Azure OpenAI Chat Client
|
||||
chat_client = AzureOpenAIChatClient()
|
||||
client = AzureOpenAIChatClient()
|
||||
|
||||
# Define agents with different roles
|
||||
joker_agent = chat_client.as_agent(
|
||||
joker_agent = client.as_agent(
|
||||
name="Joker",
|
||||
instructions="You are good at telling jokes.",
|
||||
)
|
||||
|
||||
stock_agent = chat_client.as_agent(
|
||||
stock_agent = client.as_agent(
|
||||
name="StockAdvisor",
|
||||
instructions="Check stock prices.",
|
||||
)
|
||||
|
||||
plant_agent = chat_client.as_agent(
|
||||
plant_agent = client.as_agent(
|
||||
name="PlantAdvisor",
|
||||
instructions="Recommend plants.",
|
||||
description="Get plant recommendations.",
|
||||
|
||||
@@ -28,23 +28,23 @@ from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
|
||||
# Create Azure OpenAI Chat Client
|
||||
# This uses AzureCliCredential for authentication (requires 'az login')
|
||||
chat_client = AzureOpenAIChatClient()
|
||||
client = AzureOpenAIChatClient()
|
||||
|
||||
# Define three AI agents with different roles
|
||||
# Agent 1: Joker - HTTP trigger only (default)
|
||||
agent1 = chat_client.as_agent(
|
||||
agent1 = client.as_agent(
|
||||
name="Joker",
|
||||
instructions="You are good at telling jokes.",
|
||||
)
|
||||
|
||||
# Agent 2: StockAdvisor - MCP tool trigger only
|
||||
agent2 = chat_client.as_agent(
|
||||
agent2 = client.as_agent(
|
||||
name="StockAdvisor",
|
||||
instructions="Check stock prices.",
|
||||
)
|
||||
|
||||
# Agent 3: PlantAdvisor - Both HTTP and MCP tool triggers
|
||||
agent3 = chat_client.as_agent(
|
||||
agent3 = client.as_agent(
|
||||
name="PlantAdvisor",
|
||||
instructions="Recommend plants.",
|
||||
description="Get plant recommendations.",
|
||||
|
||||
@@ -14,7 +14,7 @@ This folder contains simple examples demonstrating direct usage of various chat
|
||||
| [`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. |
|
||||
| [`custom_chat_client.py`](custom_chat_client.py) | Demonstrates how to create custom chat clients by extending the `BaseChatClient` class. Shows a `EchoingChatClient` implementation and how to integrate it with `ChatAgent` using the `as_agent()` method. |
|
||||
| [`custom_chat_client.py`](custom_chat_client.py) | Demonstrates how to create custom chat clients by extending the `BaseChatClient` class. Shows a `EchoingChatClient` implementation and how to integrate it with `Agent` using the `as_agent()` method. |
|
||||
|
||||
## Environment Variables
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ async def main() -> None:
|
||||
- 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()
|
||||
client = OpenAIChatClient()
|
||||
|
||||
try:
|
||||
task = asyncio.create_task(chat_client.get_response(messages=["Tell me a fantasy story."]))
|
||||
task = asyncio.create_task(client.get_response(messages=["Tell me a fantasy story."]))
|
||||
await asyncio.sleep(1)
|
||||
task.cancel()
|
||||
await task
|
||||
|
||||
@@ -8,12 +8,12 @@ from typing import Any, ClassVar, Generic
|
||||
|
||||
from agent_framework import (
|
||||
BaseChatClient,
|
||||
ChatMessage,
|
||||
ChatMiddlewareLayer,
|
||||
ChatResponse,
|
||||
ChatResponseUpdate,
|
||||
Content,
|
||||
FunctionInvocationLayer,
|
||||
Message,
|
||||
ResponseStream,
|
||||
Role,
|
||||
)
|
||||
@@ -61,7 +61,7 @@ class EchoingChatClient(BaseChatClient[OptionsCoT], Generic[OptionsCoT]):
|
||||
def _inner_get_response(
|
||||
self,
|
||||
*,
|
||||
messages: Sequence[ChatMessage],
|
||||
messages: Sequence[Message],
|
||||
stream: bool = False,
|
||||
options: Mapping[str, Any],
|
||||
**kwargs: Any,
|
||||
@@ -82,7 +82,7 @@ class EchoingChatClient(BaseChatClient[OptionsCoT], Generic[OptionsCoT]):
|
||||
else:
|
||||
response_text = f"{self.prefix} [No text message found]"
|
||||
|
||||
response_message = ChatMessage(role=Role.ASSISTANT, contents=[Content.from_text(response_text)])
|
||||
response_message = Message(role=Role.ASSISTANT, contents=[Content.from_text(response_text)])
|
||||
|
||||
response = ChatResponse(
|
||||
messages=[response_message],
|
||||
@@ -124,7 +124,7 @@ class EchoingChatClientWithLayers( # type: ignore[misc,type-var]
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
"""Demonstrates how to implement and use a custom chat client with ChatAgent."""
|
||||
"""Demonstrates how to implement and use a custom chat client with Agent."""
|
||||
print("=== Custom Chat Client Example ===\n")
|
||||
|
||||
# Create the custom chat client
|
||||
|
||||
@@ -139,14 +139,14 @@ Different agents with isolated or shared memory configurations.
|
||||
To create a custom context provider, implement the `ContextProvider` protocol:
|
||||
|
||||
```python
|
||||
from agent_framework import ContextProvider, Context, ChatMessage
|
||||
from agent_framework import ContextProvider, Context, Message
|
||||
from collections.abc import MutableSequence, Sequence
|
||||
from typing import Any
|
||||
|
||||
class MyContextProvider(ContextProvider):
|
||||
async def invoking(
|
||||
self,
|
||||
messages: ChatMessage | MutableSequence[ChatMessage],
|
||||
messages: Message | MutableSequence[Message],
|
||||
**kwargs: Any
|
||||
) -> Context:
|
||||
"""Provide context before the agent processes the request."""
|
||||
@@ -155,8 +155,8 @@ class MyContextProvider(ContextProvider):
|
||||
|
||||
async def invoked(
|
||||
self,
|
||||
request_messages: ChatMessage | Sequence[ChatMessage],
|
||||
response_messages: ChatMessage | Sequence[ChatMessage] | None = None,
|
||||
request_messages: Message | Sequence[Message],
|
||||
response_messages: Message | Sequence[Message] | None = None,
|
||||
invoke_exception: Exception | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
|
||||
@@ -17,7 +17,7 @@ from contextlib import AsyncExitStack
|
||||
from types import TracebackType
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
from agent_framework import ChatAgent, ChatMessage, Context, ContextProvider
|
||||
from agent_framework import Agent, Context, ContextProvider, Message
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
@@ -47,7 +47,7 @@ class AggregateContextProvider(ContextProvider):
|
||||
Examples:
|
||||
.. code-block:: python
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
|
||||
# Create multiple context providers
|
||||
provider1 = CustomContextProvider1()
|
||||
@@ -58,7 +58,7 @@ class AggregateContextProvider(ContextProvider):
|
||||
aggregate = AggregateContextProvider([provider1, provider2, provider3])
|
||||
|
||||
# Pass the aggregate to the agent
|
||||
agent = ChatAgent(chat_client=client, name="assistant", context_provider=aggregate)
|
||||
agent = Agent(client=client, name="assistant", context_provider=aggregate)
|
||||
|
||||
# You can also add more providers later
|
||||
provider4 = CustomContextProvider4()
|
||||
@@ -90,10 +90,10 @@ class AggregateContextProvider(ContextProvider):
|
||||
await asyncio.gather(*[x.thread_created(thread_id) for x in self.providers])
|
||||
|
||||
@override
|
||||
async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
|
||||
async def invoking(self, messages: Message | MutableSequence[Message], **kwargs: Any) -> Context:
|
||||
contexts = await asyncio.gather(*[provider.invoking(messages, **kwargs) for provider in self.providers])
|
||||
instructions: str = ""
|
||||
return_messages: list[ChatMessage] = []
|
||||
return_messages: list[Message] = []
|
||||
tools: list["ToolProtocol"] = []
|
||||
for ctx in contexts:
|
||||
if ctx.instructions:
|
||||
@@ -107,8 +107,8 @@ class AggregateContextProvider(ContextProvider):
|
||||
@override
|
||||
async def invoked(
|
||||
self,
|
||||
request_messages: ChatMessage | Sequence[ChatMessage],
|
||||
response_messages: ChatMessage | Sequence[ChatMessage] | None = None,
|
||||
request_messages: Message | Sequence[Message],
|
||||
response_messages: Message | Sequence[Message] | None = None,
|
||||
invoke_exception: Exception | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
@@ -167,7 +167,7 @@ class TimeContextProvider(ContextProvider):
|
||||
"""A simple context provider that adds time-related instructions."""
|
||||
|
||||
@override
|
||||
async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
|
||||
async def invoking(self, messages: Message | MutableSequence[Message], **kwargs: Any) -> Context:
|
||||
from datetime import datetime
|
||||
|
||||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
@@ -181,7 +181,7 @@ class PersonaContextProvider(ContextProvider):
|
||||
self.persona = persona
|
||||
|
||||
@override
|
||||
async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
|
||||
async def invoking(self, messages: Message | MutableSequence[Message], **kwargs: Any) -> Context:
|
||||
return Context(instructions=f"Your persona: {self.persona}. ")
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ class PreferencesContextProvider(ContextProvider):
|
||||
self.preferences: dict[str, str] = {}
|
||||
|
||||
@override
|
||||
async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
|
||||
async def invoking(self, messages: Message | MutableSequence[Message], **kwargs: Any) -> Context:
|
||||
if not self.preferences:
|
||||
return Context()
|
||||
prefs_str = ", ".join(f"{k}: {v}" for k, v in self.preferences.items())
|
||||
@@ -201,14 +201,14 @@ class PreferencesContextProvider(ContextProvider):
|
||||
@override
|
||||
async def invoked(
|
||||
self,
|
||||
request_messages: ChatMessage | Sequence[ChatMessage],
|
||||
response_messages: ChatMessage | Sequence[ChatMessage] | None = None,
|
||||
request_messages: Message | Sequence[Message],
|
||||
response_messages: Message | Sequence[Message] | None = None,
|
||||
invoke_exception: Exception | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
# Simple example: extract and store preferences from user messages
|
||||
# In a real implementation, you might use structured extraction
|
||||
msgs = [request_messages] if isinstance(request_messages, ChatMessage) else list(request_messages)
|
||||
msgs = [request_messages] if isinstance(request_messages, Message) else list(request_messages)
|
||||
|
||||
for msg in msgs:
|
||||
content = msg.text if hasattr(msg, "text") else ""
|
||||
@@ -230,7 +230,7 @@ class PreferencesContextProvider(ContextProvider):
|
||||
async def main():
|
||||
"""Demonstrate using AggregateContextProvider to combine multiple providers."""
|
||||
async with AzureCliCredential() as credential:
|
||||
chat_client = AzureAIClient(credential=credential)
|
||||
client = AzureAIClient(credential=credential)
|
||||
|
||||
# Create individual context providers
|
||||
time_provider = TimeContextProvider()
|
||||
@@ -245,8 +245,8 @@ async def main():
|
||||
])
|
||||
|
||||
# Create the agent with the aggregate provider
|
||||
async with ChatAgent(
|
||||
chat_client=chat_client,
|
||||
async with Agent(
|
||||
client=client,
|
||||
instructions="You are a helpful assistant.",
|
||||
context_provider=aggregate_provider,
|
||||
) as agent:
|
||||
|
||||
@@ -126,7 +126,7 @@ AZURE_OPENAI_RESOURCE_URL=https://myresource.openai.azure.com
|
||||
### Semantic Mode
|
||||
|
||||
```python
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AzureAIAgentClient, AzureAISearchContextProvider
|
||||
from azure.identity.aio import DefaultAzureCredential
|
||||
|
||||
@@ -141,8 +141,8 @@ search_provider = AzureAISearchContextProvider(
|
||||
|
||||
# Create agent with search context
|
||||
async with AzureAIAgentClient(credential=DefaultAzureCredential()) as client:
|
||||
async with ChatAgent(
|
||||
chat_client=client,
|
||||
async with Agent(
|
||||
client=client,
|
||||
model=model_deployment,
|
||||
context_provider=search_provider,
|
||||
) as agent:
|
||||
@@ -166,8 +166,8 @@ search_provider = AzureAISearchContextProvider(
|
||||
)
|
||||
|
||||
# Use with agent (same as semantic mode)
|
||||
async with ChatAgent(
|
||||
chat_client=client,
|
||||
async with Agent(
|
||||
client=client,
|
||||
model=model_deployment,
|
||||
context_provider=search_provider,
|
||||
) as agent:
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AzureAIAgentClient, AzureAISearchContextProvider
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
@@ -112,8 +112,8 @@ async def main() -> None:
|
||||
model_deployment_name=model_deployment,
|
||||
credential=AzureCliCredential(),
|
||||
) as client,
|
||||
ChatAgent(
|
||||
chat_client=client,
|
||||
Agent(
|
||||
client=client,
|
||||
name="SearchAgent",
|
||||
instructions=(
|
||||
"You are a helpful assistant with advanced reasoning capabilities. "
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AzureAIAgentClient, AzureAISearchContextProvider
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
@@ -69,8 +69,8 @@ async def main() -> None:
|
||||
model_deployment_name=model_deployment,
|
||||
credential=AzureCliCredential(),
|
||||
) as client,
|
||||
ChatAgent(
|
||||
chat_client=client,
|
||||
Agent(
|
||||
client=client,
|
||||
name="SearchAgent",
|
||||
instructions=(
|
||||
"You are a helpful assistant. Use the provided context from the "
|
||||
|
||||
@@ -30,7 +30,7 @@ Run:
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatMessage, tool
|
||||
from agent_framework import Message, tool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
from agent_framework_redis._provider import RedisProvider
|
||||
from redisvl.extensions.cache.embeddings import EmbeddingsCache
|
||||
@@ -128,9 +128,9 @@ async def main() -> None:
|
||||
|
||||
# Build sample chat messages to persist to Redis
|
||||
messages = [
|
||||
ChatMessage("user", ["runA CONVO: User Message"]),
|
||||
ChatMessage("assistant", ["runA CONVO: Assistant Message"]),
|
||||
ChatMessage("system", ["runA CONVO: System Message"]),
|
||||
Message("user", ["runA CONVO: User Message"]),
|
||||
Message("assistant", ["runA CONVO: Assistant Message"]),
|
||||
Message("system", ["runA CONVO: System Message"]),
|
||||
]
|
||||
|
||||
# Declare/start a conversation/thread and write messages under 'runA'.
|
||||
@@ -142,7 +142,7 @@ async def main() -> None:
|
||||
# Retrieve relevant memories for a hypothetical model call. The provider uses
|
||||
# the current request messages as the retrieval query and returns context to
|
||||
# be injected into the model's instructions.
|
||||
ctx = await provider.invoking([ChatMessage("system", ["B: Assistant Message"])])
|
||||
ctx = await provider.invoking([Message("system", ["B: Assistant Message"])])
|
||||
|
||||
# Inspect retrieved memories that would be injected into instructions
|
||||
# (Debug-only output so you can verify retrieval works as expected.)
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
from collections.abc import MutableSequence, Sequence
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import ChatAgent, ChatClientProtocol, ChatMessage, Context, ContextProvider
|
||||
from agent_framework import Agent, Context, ContextProvider, Message, SupportsChatGetResponse
|
||||
from agent_framework.azure import AzureAIClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel
|
||||
@@ -16,13 +16,13 @@ class UserInfo(BaseModel):
|
||||
|
||||
|
||||
class UserInfoMemory(ContextProvider):
|
||||
def __init__(self, chat_client: ChatClientProtocol, user_info: UserInfo | None = None, **kwargs: Any):
|
||||
def __init__(self, client: SupportsChatGetResponse, user_info: UserInfo | None = None, **kwargs: Any):
|
||||
"""Create the memory.
|
||||
|
||||
If you pass in kwargs, they will be attempted to be used to create a UserInfo object.
|
||||
"""
|
||||
|
||||
self._chat_client = chat_client
|
||||
self._chat_client = client
|
||||
if user_info:
|
||||
self.user_info = user_info
|
||||
elif kwargs:
|
||||
@@ -32,8 +32,8 @@ class UserInfoMemory(ContextProvider):
|
||||
|
||||
async def invoked(
|
||||
self,
|
||||
request_messages: ChatMessage | Sequence[ChatMessage],
|
||||
response_messages: ChatMessage | Sequence[ChatMessage] | None = None,
|
||||
request_messages: Message | Sequence[Message],
|
||||
response_messages: Message | Sequence[Message] | None = None,
|
||||
invoke_exception: Exception | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
@@ -64,7 +64,7 @@ class UserInfoMemory(ContextProvider):
|
||||
except Exception:
|
||||
pass # Failed to extract, continue without updating
|
||||
|
||||
async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
|
||||
async def invoking(self, messages: Message | MutableSequence[Message], **kwargs: Any) -> Context:
|
||||
"""Provide user information context before each agent call."""
|
||||
instructions: list[str] = []
|
||||
|
||||
@@ -92,14 +92,14 @@ class UserInfoMemory(ContextProvider):
|
||||
|
||||
async def main():
|
||||
async with AzureCliCredential() as credential:
|
||||
chat_client = AzureAIClient(credential=credential)
|
||||
client = AzureAIClient(credential=credential)
|
||||
|
||||
# Create the memory provider
|
||||
memory_provider = UserInfoMemory(chat_client)
|
||||
memory_provider = UserInfoMemory(client)
|
||||
|
||||
# Create the agent with memory
|
||||
async with ChatAgent(
|
||||
chat_client=chat_client,
|
||||
async with Agent(
|
||||
client=client,
|
||||
instructions="You are a friendly assistant. Always address the user by their name.",
|
||||
context_provider=memory_provider,
|
||||
) as agent:
|
||||
|
||||
@@ -175,7 +175,7 @@ agent = agent_factory.create_agent_from_yaml_path(Path("custom_provider.yaml"))
|
||||
|
||||
This allows you to extend the declarative framework with custom chat client implementations. The mapping requires:
|
||||
- **package**: The Python package/module to import from
|
||||
- **name**: The class name of your ChatClientProtocol implementation
|
||||
- **name**: The class name of your SupportsChatGetResponse implementation
|
||||
- **model_id_field**: The constructor parameter name that accepts the value of the `model.id` field from the YAML
|
||||
|
||||
You can reference your custom provider using either `Provider.ApiType` format or just `Provider` in your YAML configuration, as long as it matches the registered mapping.
|
||||
|
||||
@@ -26,7 +26,7 @@ async def main():
|
||||
|
||||
# create the AgentFactory with a chat client and bindings
|
||||
agent_factory = AgentFactory(
|
||||
chat_client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
client=AzureOpenAIResponsesClient(credential=AzureCliCredential()),
|
||||
bindings={"get_weather": get_weather},
|
||||
)
|
||||
# create the agent from the yaml
|
||||
|
||||
@@ -44,7 +44,7 @@ Each agent/workflow follows a strict structure required by DevUI's discovery sys
|
||||
|
||||
```
|
||||
agent_name/
|
||||
├── __init__.py # Must export: agent = ChatAgent(...)
|
||||
├── __init__.py # Must export: agent = Agent(...)
|
||||
├── agent.py # Agent implementation
|
||||
└── .env.example # Example environment variables
|
||||
```
|
||||
@@ -100,13 +100,13 @@ Example:
|
||||
|
||||
```python
|
||||
# my_agent/__init__.py
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
|
||||
agent = ChatAgent(
|
||||
agent = Agent(
|
||||
name="MyAgent",
|
||||
description="My custom agent",
|
||||
chat_client=OpenAIChatClient(),
|
||||
client=OpenAIChatClient(),
|
||||
# ... your configuration
|
||||
)
|
||||
```
|
||||
|
||||
@@ -21,7 +21,7 @@ import logging
|
||||
import os
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -68,7 +68,7 @@ def extract_key_points(
|
||||
|
||||
|
||||
# Agent using Azure OpenAI Responses API (supports PDF uploads!)
|
||||
agent = ChatAgent(
|
||||
agent = Agent(
|
||||
name="AzureResponsesAgent",
|
||||
description="An agent that can analyze PDFs, images, and other documents using Azure OpenAI Responses API",
|
||||
instructions="""
|
||||
@@ -85,7 +85,7 @@ agent = ChatAgent(
|
||||
For PDFs, you can read and understand the text, tables, and structure.
|
||||
For images, you can describe what you see and extract any text.
|
||||
""",
|
||||
chat_client=AzureOpenAIResponsesClient(
|
||||
client=AzureOpenAIResponsesClient(
|
||||
deployment_name=_deployment_name,
|
||||
endpoint=_endpoint,
|
||||
api_version="2025-03-01-preview", # Required for Responses API
|
||||
|
||||
@@ -8,7 +8,7 @@ Make sure to run 'az login' before starting devui.
|
||||
import os
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import Field
|
||||
@@ -43,9 +43,9 @@ def get_forecast(
|
||||
|
||||
|
||||
# Agent instance following Agent Framework conventions
|
||||
agent = ChatAgent(
|
||||
agent = Agent(
|
||||
name="FoundryWeatherAgent",
|
||||
chat_client=AzureAIAgentClient(
|
||||
client=AzureAIAgentClient(
|
||||
project_endpoint=os.environ.get("AZURE_AI_PROJECT_ENDPOINT"),
|
||||
model_deployment_name=os.environ.get("FOUNDRY_MODEL_DEPLOYMENT_NAME"),
|
||||
credential=AzureCliCredential(),
|
||||
|
||||
@@ -10,7 +10,7 @@ import logging
|
||||
import os
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, Executor, WorkflowBuilder, WorkflowContext, handler, tool
|
||||
from agent_framework import Agent, Executor, WorkflowBuilder, WorkflowContext, handler, tool
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from agent_framework.devui import serve
|
||||
from typing_extensions import Never
|
||||
@@ -68,7 +68,7 @@ def main():
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Create Azure OpenAI chat client
|
||||
chat_client = AzureOpenAIChatClient(
|
||||
client = AzureOpenAIChatClient(
|
||||
api_key=os.environ.get("AZURE_OPENAI_API_KEY"),
|
||||
azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"),
|
||||
api_version=os.environ.get("AZURE_OPENAI_API_VERSION", "2024-10-21"),
|
||||
@@ -76,22 +76,22 @@ def main():
|
||||
)
|
||||
|
||||
# Create agents
|
||||
weather_agent = ChatAgent(
|
||||
weather_agent = Agent(
|
||||
name="weather-assistant",
|
||||
description="Provides weather information and time",
|
||||
instructions=(
|
||||
"You are a helpful weather and time assistant. Use the available tools to "
|
||||
"provide accurate weather information and current time for any location."
|
||||
),
|
||||
chat_client=chat_client,
|
||||
client=client,
|
||||
tools=[get_weather, get_time],
|
||||
)
|
||||
|
||||
simple_agent = ChatAgent(
|
||||
simple_agent = Agent(
|
||||
name="general-assistant",
|
||||
description="A simple conversational agent",
|
||||
instructions="You are a helpful assistant.",
|
||||
chat_client=chat_client,
|
||||
client=client,
|
||||
)
|
||||
|
||||
# Create a basic workflow: Input -> UpperCase -> AddExclamation -> Output
|
||||
|
||||
@@ -7,15 +7,16 @@ from collections.abc import AsyncIterable, Awaitable, Callable
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import (
|
||||
ChatAgent,
|
||||
Agent,
|
||||
ChatContext,
|
||||
ChatMessage,
|
||||
ChatResponse,
|
||||
ChatResponseUpdate,
|
||||
Content,
|
||||
FunctionInvocationContext,
|
||||
Message,
|
||||
MiddlewareTermination,
|
||||
ResponseStream,
|
||||
Role,
|
||||
chat_middleware,
|
||||
function_middleware,
|
||||
tool,
|
||||
@@ -44,7 +45,7 @@ async def security_filter_middleware(
|
||||
|
||||
# Check only the last message (most recent user input)
|
||||
last_message = context.messages[-1] if context.messages else None
|
||||
if last_message and last_message.role == "user" and last_message.text:
|
||||
if last_message and last_message.role == Role.USER and last_message.text:
|
||||
message_lower = last_message.text.lower()
|
||||
for term in blocked_terms:
|
||||
if term in message_lower:
|
||||
@@ -55,26 +56,29 @@ async def security_filter_middleware(
|
||||
)
|
||||
|
||||
if context.stream:
|
||||
# Streaming mode: return async generator
|
||||
# Streaming mode: wrap in ResponseStream
|
||||
async def blocked_stream(msg: str = error_message) -> AsyncIterable[ChatResponseUpdate]:
|
||||
yield ChatResponseUpdate(
|
||||
contents=[Content.from_text(text=msg)],
|
||||
role="assistant",
|
||||
role=Role.ASSISTANT,
|
||||
)
|
||||
|
||||
context.result = ResponseStream(blocked_stream(), finalizer=ChatResponse.from_updates)
|
||||
response = ChatResponse(
|
||||
messages=[Message(role=Role.ASSISTANT, text=error_message)]
|
||||
)
|
||||
context.result = ResponseStream(blocked_stream(), finalizer=lambda _, r=response: r)
|
||||
else:
|
||||
# Non-streaming mode: return complete response
|
||||
context.result = ChatResponse(
|
||||
messages=[
|
||||
ChatMessage(
|
||||
role="assistant",
|
||||
Message(
|
||||
role=Role.ASSISTANT,
|
||||
text=error_message,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
raise MiddlewareTermination
|
||||
raise MiddlewareTermination(result=context.result)
|
||||
|
||||
await call_next(context)
|
||||
|
||||
@@ -92,7 +96,7 @@ async def atlantis_location_filter_middleware(
|
||||
"Blocked! Hold up right there!! Tell the user that "
|
||||
"'Atlantis is a special place, we must never ask about the weather there!!'"
|
||||
)
|
||||
raise MiddlewareTermination
|
||||
raise MiddlewareTermination(result=context.result)
|
||||
|
||||
await call_next(context)
|
||||
|
||||
@@ -136,7 +140,7 @@ def send_email(
|
||||
|
||||
|
||||
# Agent instance following Agent Framework conventions
|
||||
agent = ChatAgent(
|
||||
agent = Agent(
|
||||
name="AzureWeatherAgent",
|
||||
description="A helpful agent that provides weather information and forecasts",
|
||||
instructions="""
|
||||
@@ -144,7 +148,7 @@ agent = ChatAgent(
|
||||
and forecasts for any location. Always be helpful and provide detailed
|
||||
weather information when asked.
|
||||
""",
|
||||
chat_client=AzureOpenAIChatClient(
|
||||
client=AzureOpenAIChatClient(
|
||||
api_key=os.environ.get("AZURE_OPENAI_API_KEY", ""),
|
||||
),
|
||||
tools=[get_weather, get_forecast, send_email],
|
||||
|
||||
@@ -59,10 +59,10 @@ def is_approved(message: Any) -> bool:
|
||||
|
||||
|
||||
# Create Azure OpenAI chat client
|
||||
chat_client = AzureOpenAIChatClient(api_key=os.environ.get("AZURE_OPENAI_API_KEY", ""))
|
||||
client = AzureOpenAIChatClient(api_key=os.environ.get("AZURE_OPENAI_API_KEY", ""))
|
||||
|
||||
# Create Writer agent - generates content
|
||||
writer = chat_client.as_agent(
|
||||
writer = client.as_agent(
|
||||
name="Writer",
|
||||
instructions=(
|
||||
"You are an excellent content writer. "
|
||||
@@ -72,7 +72,7 @@ writer = chat_client.as_agent(
|
||||
)
|
||||
|
||||
# Create Reviewer agent - evaluates and provides structured feedback
|
||||
reviewer = chat_client.as_agent(
|
||||
reviewer = client.as_agent(
|
||||
name="Reviewer",
|
||||
instructions=(
|
||||
"You are an expert content reviewer. "
|
||||
@@ -90,7 +90,7 @@ reviewer = chat_client.as_agent(
|
||||
)
|
||||
|
||||
# Create Editor agent - improves content based on feedback
|
||||
editor = chat_client.as_agent(
|
||||
editor = client.as_agent(
|
||||
name="Editor",
|
||||
instructions=(
|
||||
"You are a skilled editor. "
|
||||
@@ -101,7 +101,7 @@ editor = chat_client.as_agent(
|
||||
)
|
||||
|
||||
# Create Publisher agent - formats content for publication
|
||||
publisher = chat_client.as_agent(
|
||||
publisher = client.as_agent(
|
||||
name="Publisher",
|
||||
instructions=(
|
||||
"You are a publishing agent. "
|
||||
@@ -111,7 +111,7 @@ publisher = chat_client.as_agent(
|
||||
)
|
||||
|
||||
# Create Summarizer agent - creates final publication report
|
||||
summarizer = chat_client.as_agent(
|
||||
summarizer = client.as_agent(
|
||||
name="Summarizer",
|
||||
instructions=(
|
||||
"You are a summarizer agent. "
|
||||
|
||||
@@ -15,7 +15,7 @@ import asyncio
|
||||
import logging
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AzureOpenAIChatClient, DurableAIAgentWorker
|
||||
from azure.identity import AzureCliCredential, DefaultAzureCredential
|
||||
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
|
||||
@@ -25,11 +25,11 @@ logging.basicConfig(level=logging.WARNING)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_joker_agent() -> ChatAgent:
|
||||
def create_joker_agent() -> Agent:
|
||||
"""Create the Joker agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Joker agent
|
||||
Agent: The configured Joker agent
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name="Joker",
|
||||
|
||||
@@ -65,7 +65,7 @@ def create_weather_agent():
|
||||
"""Create the Weather agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Weather agent with weather tool
|
||||
Agent: The configured Weather agent with weather tool
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name=WEATHER_AGENT_NAME,
|
||||
@@ -78,7 +78,7 @@ def create_math_agent():
|
||||
"""Create the Math agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Math agent with calculation tools
|
||||
Agent: The configured Math agent with calculation tools
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name=MATH_AGENT_NAME,
|
||||
|
||||
@@ -18,7 +18,7 @@ import os
|
||||
from datetime import timedelta
|
||||
|
||||
import redis.asyncio as aioredis
|
||||
from agent_framework import AgentResponseUpdate, ChatAgent
|
||||
from agent_framework import Agent, AgentResponseUpdate
|
||||
from agent_framework.azure import (
|
||||
AgentCallbackContext,
|
||||
AgentResponseCallbackProtocol,
|
||||
@@ -143,11 +143,11 @@ class RedisStreamCallback(AgentResponseCallbackProtocol):
|
||||
logger.error(f"Error writing end-of-stream marker: {ex}", exc_info=True)
|
||||
|
||||
|
||||
def create_travel_agent() -> "ChatAgent":
|
||||
def create_travel_agent() -> "Agent":
|
||||
"""Create the TravelPlanner agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured TravelPlanner agent with travel planning tools.
|
||||
Agent: The configured TravelPlanner agent with travel planning tools.
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name="TravelPlanner",
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@ import logging
|
||||
import os
|
||||
from collections.abc import Generator
|
||||
|
||||
from agent_framework import AgentResponse, ChatAgent
|
||||
from agent_framework import Agent, AgentResponse
|
||||
from agent_framework.azure import AzureOpenAIChatClient, DurableAIAgentOrchestrationContext, DurableAIAgentWorker
|
||||
from azure.identity import AzureCliCredential, DefaultAzureCredential
|
||||
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
|
||||
@@ -31,14 +31,14 @@ logger = logging.getLogger(__name__)
|
||||
WRITER_AGENT_NAME = "WriterAgent"
|
||||
|
||||
|
||||
def create_writer_agent() -> "ChatAgent":
|
||||
def create_writer_agent() -> "Agent":
|
||||
"""Create the Writer agent using Azure OpenAI.
|
||||
|
||||
This agent refines short pieces of text, enhancing initial sentences
|
||||
and polishing improved versions further.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Writer agent
|
||||
Agent: The configured Writer agent
|
||||
"""
|
||||
instructions = (
|
||||
"You refine short pieces of text. When given an initial sentence you enhance it;\n"
|
||||
|
||||
+5
-5
@@ -18,7 +18,7 @@ import os
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import AgentResponse, ChatAgent
|
||||
from agent_framework import Agent, AgentResponse
|
||||
from agent_framework.azure import AzureOpenAIChatClient, DurableAIAgentOrchestrationContext, DurableAIAgentWorker
|
||||
from azure.identity import AzureCliCredential, DefaultAzureCredential
|
||||
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
|
||||
@@ -33,11 +33,11 @@ PHYSICIST_AGENT_NAME = "PhysicistAgent"
|
||||
CHEMIST_AGENT_NAME = "ChemistAgent"
|
||||
|
||||
|
||||
def create_physicist_agent() -> "ChatAgent":
|
||||
def create_physicist_agent() -> "Agent":
|
||||
"""Create the Physicist agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Physicist agent
|
||||
Agent: The configured Physicist agent
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name=PHYSICIST_AGENT_NAME,
|
||||
@@ -45,11 +45,11 @@ def create_physicist_agent() -> "ChatAgent":
|
||||
)
|
||||
|
||||
|
||||
def create_chemist_agent() -> "ChatAgent":
|
||||
def create_chemist_agent() -> "Agent":
|
||||
"""Create the Chemist agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Chemist agent
|
||||
Agent: The configured Chemist agent
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name=CHEMIST_AGENT_NAME,
|
||||
|
||||
+5
-5
@@ -18,7 +18,7 @@ import os
|
||||
from collections.abc import Generator
|
||||
from typing import Any, cast
|
||||
|
||||
from agent_framework import AgentResponse, ChatAgent
|
||||
from agent_framework import Agent, AgentResponse
|
||||
from agent_framework.azure import AzureOpenAIChatClient, DurableAIAgentOrchestrationContext, DurableAIAgentWorker
|
||||
from azure.identity import AzureCliCredential, DefaultAzureCredential
|
||||
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
|
||||
@@ -51,11 +51,11 @@ class EmailPayload(BaseModel):
|
||||
email_content: str
|
||||
|
||||
|
||||
def create_spam_agent() -> "ChatAgent":
|
||||
def create_spam_agent() -> "Agent":
|
||||
"""Create the Spam Detection agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Spam Detection agent
|
||||
Agent: The configured Spam Detection agent
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name=SPAM_AGENT_NAME,
|
||||
@@ -63,11 +63,11 @@ def create_spam_agent() -> "ChatAgent":
|
||||
)
|
||||
|
||||
|
||||
def create_email_agent() -> "ChatAgent":
|
||||
def create_email_agent() -> "Agent":
|
||||
"""Create the Email Assistant agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Email Assistant agent
|
||||
Agent: The configured Email Assistant agent
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
name=EMAIL_AGENT_NAME,
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@ from collections.abc import Generator
|
||||
from datetime import timedelta
|
||||
from typing import Any, cast
|
||||
|
||||
from agent_framework import AgentResponse, ChatAgent
|
||||
from agent_framework import Agent, AgentResponse
|
||||
from agent_framework.azure import AzureOpenAIChatClient, DurableAIAgentOrchestrationContext, DurableAIAgentWorker
|
||||
from azure.identity import AzureCliCredential, DefaultAzureCredential
|
||||
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
|
||||
@@ -54,11 +54,11 @@ class HumanApproval(BaseModel):
|
||||
feedback: str = ""
|
||||
|
||||
|
||||
def create_writer_agent() -> "ChatAgent":
|
||||
def create_writer_agent() -> "Agent":
|
||||
"""Create the Writer agent using Azure OpenAI.
|
||||
|
||||
Returns:
|
||||
ChatAgent: The configured Writer agent
|
||||
Agent: The configured Writer agent
|
||||
"""
|
||||
instructions = (
|
||||
"You are a professional content writer who creates high-quality articles on various topics. "
|
||||
|
||||
@@ -17,7 +17,7 @@ from typing import Any
|
||||
|
||||
import openai
|
||||
import pandas as pd
|
||||
from agent_framework import ChatAgent, ChatMessage
|
||||
from agent_framework import Agent, Message
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.ai.projects import AIProjectClient
|
||||
from azure.identity import AzureCliCredential
|
||||
@@ -142,7 +142,7 @@ def run_eval(
|
||||
async def execute_query_with_self_reflection(
|
||||
*,
|
||||
client: openai.OpenAI,
|
||||
agent: ChatAgent,
|
||||
agent: Agent,
|
||||
eval_object: openai.types.EvalCreateResponse,
|
||||
full_user_query: str,
|
||||
context: str,
|
||||
@@ -152,7 +152,7 @@ async def execute_query_with_self_reflection(
|
||||
Execute a query with self-reflection loop.
|
||||
|
||||
Args:
|
||||
agent: ChatAgent instance to use for generating responses
|
||||
agent: Agent instance to use for generating responses
|
||||
full_user_query: Complete prompt including system prompt, user request, and context
|
||||
context: Context document for groundedness evaluation
|
||||
evaluator: Groundedness evaluator function
|
||||
@@ -170,7 +170,7 @@ async def execute_query_with_self_reflection(
|
||||
- total_groundedness_eval_time: Time spent on evaluations (seconds)
|
||||
- total_end_to_end_time: Total execution time (seconds)
|
||||
"""
|
||||
messages = [ChatMessage("user", [full_user_query])]
|
||||
messages = [Message("user", [full_user_query])]
|
||||
|
||||
best_score = 0
|
||||
max_score = 5
|
||||
@@ -223,14 +223,14 @@ async def execute_query_with_self_reflection(
|
||||
print(f" → No improvement (score: {score}/{max_score}). Trying again...")
|
||||
|
||||
# Add to conversation history
|
||||
messages.append(ChatMessage("assistant", [agent_response]))
|
||||
messages.append(Message("assistant", [agent_response]))
|
||||
|
||||
# Request improvement
|
||||
reflection_prompt = (
|
||||
f"The groundedness score of your response is {score}/{max_score}. "
|
||||
f"Reflect on your answer and improve it to get the maximum score of {max_score} "
|
||||
)
|
||||
messages.append(ChatMessage("user", [reflection_prompt]))
|
||||
messages.append(Message("user", [reflection_prompt]))
|
||||
|
||||
end_time = time.time()
|
||||
latency = end_time - start_time
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent, MCPStreamableHTTPTool
|
||||
from agent_framework import Agent, MCPStreamableHTTPTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
from httpx import AsyncClient
|
||||
|
||||
@@ -43,8 +43,8 @@ async def api_key_auth_example() -> None:
|
||||
url=mcp_server_url,
|
||||
http_client=http_client, # Pass HTTP client with authentication headers
|
||||
) as mcp_tool,
|
||||
ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="Agent",
|
||||
instructions="You are a helpful assistant.",
|
||||
tools=mcp_tool,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework import ChatAgent, HostedMCPTool
|
||||
from agent_framework import Agent, HostedMCPTool
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@@ -54,8 +54,8 @@ async def github_mcp_example() -> None:
|
||||
)
|
||||
|
||||
# 5. Create agent with the GitHub MCP tool
|
||||
async with ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
async with Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
name="GitHubAgent",
|
||||
instructions=(
|
||||
"You are a helpful assistant that can help users interact with GitHub. "
|
||||
|
||||
@@ -7,9 +7,9 @@ from typing import Annotated
|
||||
|
||||
from agent_framework import (
|
||||
ChatContext,
|
||||
ChatMessage,
|
||||
ChatMiddleware,
|
||||
ChatResponse,
|
||||
Message,
|
||||
MiddlewareTermination,
|
||||
chat_middleware,
|
||||
tool,
|
||||
@@ -69,7 +69,7 @@ class InputObserverMiddleware(ChatMiddleware):
|
||||
print(f"[InputObserverMiddleware] Total messages: {len(context.messages)}")
|
||||
|
||||
# Modify user messages by creating new messages with enhanced text
|
||||
modified_messages: list[ChatMessage] = []
|
||||
modified_messages: list[Message] = []
|
||||
modified_count = 0
|
||||
|
||||
for message in context.messages:
|
||||
@@ -81,7 +81,7 @@ class InputObserverMiddleware(ChatMiddleware):
|
||||
updated_text = self.replacement
|
||||
print(f"[InputObserverMiddleware] Updated: '{original_text}' -> '{updated_text}'")
|
||||
|
||||
modified_message = ChatMessage(message.role, [updated_text])
|
||||
modified_message = Message(message.role, [updated_text])
|
||||
modified_messages.append(modified_message)
|
||||
modified_count += 1
|
||||
else:
|
||||
@@ -118,7 +118,7 @@ async def security_and_override_middleware(
|
||||
# Override the response instead of calling AI
|
||||
context.result = ChatResponse(
|
||||
messages=[
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="assistant",
|
||||
text="I cannot process requests containing sensitive information. "
|
||||
"Please rephrase your question without including passwords, secrets, or other "
|
||||
|
||||
@@ -10,9 +10,9 @@ from agent_framework import (
|
||||
AgentContext,
|
||||
AgentMiddleware,
|
||||
AgentResponse,
|
||||
ChatMessage,
|
||||
FunctionInvocationContext,
|
||||
FunctionMiddleware,
|
||||
Message,
|
||||
tool,
|
||||
)
|
||||
from agent_framework.azure import AzureAIAgentClient
|
||||
@@ -61,7 +61,7 @@ class SecurityAgentMiddleware(AgentMiddleware):
|
||||
print("[SecurityAgentMiddleware] Security Warning: Detected sensitive information, blocking request.")
|
||||
# Override the result with warning message
|
||||
context.result = AgentResponse(
|
||||
messages=[ChatMessage("assistant", ["Detected sensitive information, the request is blocked."])]
|
||||
messages=[Message("assistant", ["Detected sensitive information, the request is blocked."])]
|
||||
)
|
||||
# Simply don't call call_next() to prevent execution
|
||||
return
|
||||
|
||||
@@ -9,7 +9,7 @@ from agent_framework import (
|
||||
AgentContext,
|
||||
AgentMiddleware,
|
||||
AgentResponse,
|
||||
ChatMessage,
|
||||
Message,
|
||||
MiddlewareTermination,
|
||||
tool,
|
||||
)
|
||||
@@ -62,7 +62,7 @@ class PreTerminationMiddleware(AgentMiddleware):
|
||||
# Set a custom response
|
||||
context.result = AgentResponse(
|
||||
messages=[
|
||||
ChatMessage(
|
||||
Message(
|
||||
role="assistant",
|
||||
text=(
|
||||
f"Sorry, I cannot process requests containing '{blocked_word}'. "
|
||||
@@ -72,8 +72,8 @@ class PreTerminationMiddleware(AgentMiddleware):
|
||||
]
|
||||
)
|
||||
|
||||
# Set terminate flag to prevent further processing
|
||||
raise MiddlewareTermination
|
||||
# Terminate to prevent further processing
|
||||
raise MiddlewareTermination(result=context.result)
|
||||
|
||||
await call_next(context)
|
||||
|
||||
|
||||
@@ -11,10 +11,11 @@ from agent_framework import (
|
||||
AgentResponse,
|
||||
AgentResponseUpdate,
|
||||
ChatContext,
|
||||
ChatMessage,
|
||||
ChatResponse,
|
||||
ChatResponseUpdate,
|
||||
Message,
|
||||
ResponseStream,
|
||||
Role,
|
||||
tool,
|
||||
)
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
@@ -78,9 +79,9 @@ async def weather_override_middleware(context: ChatContext, call_next: Callable[
|
||||
context.result.with_transform_hook(_update_hook)
|
||||
else:
|
||||
# For non-streaming: just replace with a new message
|
||||
current_text = context.result.text or "" # type: ignore
|
||||
current_text = context.result.text if isinstance(context.result, ChatResponse) else ""
|
||||
custom_message = f"Weather Advisory: [0] {''.join(chunks)} Original message was: {current_text}"
|
||||
context.result = ChatResponse(messages=[ChatMessage(role="assistant", text=custom_message)])
|
||||
context.result = ChatResponse(messages=[Message(role=Role.ASSISTANT, text=custom_message)])
|
||||
|
||||
|
||||
async def validate_weather_middleware(context: ChatContext, call_next: Callable[[ChatContext], Awaitable[None]]) -> None:
|
||||
@@ -95,12 +96,12 @@ async def validate_weather_middleware(context: ChatContext, call_next: Callable[
|
||||
if context.stream and isinstance(context.result, ResponseStream):
|
||||
|
||||
def _append_validation_note(response: ChatResponse) -> ChatResponse:
|
||||
response.messages.append(ChatMessage(role="assistant", text=validation_note))
|
||||
response.messages.append(Message(role=Role.ASSISTANT, text=validation_note))
|
||||
return response
|
||||
|
||||
context.result.with_result_hook(_append_validation_note)
|
||||
context.result.with_finalizer(_append_validation_note)
|
||||
elif isinstance(context.result, ChatResponse):
|
||||
context.result.messages.append(ChatMessage(role="assistant", text=validation_note))
|
||||
context.result.messages.append(Message(role=Role.ASSISTANT, text=validation_note))
|
||||
|
||||
|
||||
async def agent_cleanup_middleware(context: AgentContext, call_next: Callable[[AgentContext], Awaitable[None]]) -> None:
|
||||
@@ -117,7 +118,7 @@ async def agent_cleanup_middleware(context: AgentContext, call_next: Callable[[A
|
||||
def _sanitize(response: AgentResponse) -> AgentResponse:
|
||||
found_prefix = state["found_prefix"]
|
||||
found_validation = False
|
||||
cleaned_messages: list[ChatMessage] = []
|
||||
cleaned_messages: list[Message] = []
|
||||
|
||||
for message in response.messages:
|
||||
text = message.text
|
||||
@@ -138,7 +139,7 @@ async def agent_cleanup_middleware(context: AgentContext, call_next: Callable[[A
|
||||
text = re.sub(r"\[\d+\]\s*", "", text)
|
||||
|
||||
cleaned_messages.append(
|
||||
ChatMessage(
|
||||
Message(
|
||||
role=message.role,
|
||||
text=text.strip(),
|
||||
author_name=message.author_name,
|
||||
@@ -153,7 +154,7 @@ async def agent_cleanup_middleware(context: AgentContext, call_next: Callable[[A
|
||||
if not found_validation:
|
||||
raise RuntimeError("Expected validation note not found in agent response.")
|
||||
|
||||
cleaned_messages.append(ChatMessage(role="assistant", text=" Agent: OK"))
|
||||
cleaned_messages.append(Message(role=Role.ASSISTANT, text=" Agent: OK"))
|
||||
response.messages = cleaned_messages
|
||||
return response
|
||||
|
||||
@@ -172,7 +173,7 @@ async def agent_cleanup_middleware(context: AgentContext, call_next: Callable[[A
|
||||
return update
|
||||
|
||||
context.result.with_transform_hook(_clean_update)
|
||||
context.result.with_result_hook(_sanitize)
|
||||
context.result.with_finalizer(_sanitize)
|
||||
elif isinstance(context.result, AgentResponse):
|
||||
context.result = _sanitize(context.result)
|
||||
|
||||
@@ -191,19 +192,6 @@ async def main() -> None:
|
||||
tools=get_weather,
|
||||
middleware=[agent_cleanup_middleware],
|
||||
)
|
||||
# Streaming example
|
||||
print("\n--- Streaming Example ---")
|
||||
query = "What's the weather like in Portland?"
|
||||
print(f"User: {query}")
|
||||
print("Agent: ", end="", flush=True)
|
||||
response = agent.run(query, stream=True)
|
||||
# add the hooks to print what you want to see
|
||||
response.with_transform_hook(lambda chunk: print(chunk.text, end="", flush=True)).with_result_hook(
|
||||
lambda final: print(f"\nFinal streamed response: {final.text}", flush=True)
|
||||
)
|
||||
# consume the stream to trigger the hooks
|
||||
await response.get_final_response()
|
||||
|
||||
# Non-streaming example
|
||||
print("\n--- Non-streaming Example ---")
|
||||
query = "What's the weather like in Seattle?"
|
||||
@@ -211,6 +199,18 @@ async def main() -> None:
|
||||
result = await agent.run(query)
|
||||
print(f"Agent: {result}")
|
||||
|
||||
# Streaming example
|
||||
print("\n--- Streaming Example ---")
|
||||
query = "What's the weather like in Portland?"
|
||||
print(f"User: {query}")
|
||||
print("Agent: ", end="", flush=True)
|
||||
response = agent.run(query, stream=True)
|
||||
async for chunk in response:
|
||||
if chunk.text:
|
||||
print(chunk.text, end="", flush=True)
|
||||
print("\n")
|
||||
print(f"Final Result: {(await response.get_final_response()).text}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
|
||||
from agent_framework import ChatMessage, Content
|
||||
from agent_framework import Content, Message
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
@@ -24,7 +24,7 @@ async def test_image() -> None:
|
||||
client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
|
||||
image_uri = create_sample_image()
|
||||
message = ChatMessage(
|
||||
message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What's in this image?"),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework import ChatMessage, Content
|
||||
from agent_framework import Content, Message
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
@@ -33,7 +33,7 @@ async def test_image() -> None:
|
||||
client = AzureOpenAIResponsesClient(credential=AzureCliCredential())
|
||||
|
||||
image_uri = create_sample_image()
|
||||
message = ChatMessage(
|
||||
message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What's in this image?"),
|
||||
@@ -50,7 +50,7 @@ async def test_pdf() -> None:
|
||||
client = AzureOpenAIResponsesClient(credential=AzureCliCredential())
|
||||
|
||||
pdf_bytes = load_sample_pdf()
|
||||
message = ChatMessage(
|
||||
message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What information can you extract from this document?"),
|
||||
|
||||
@@ -5,7 +5,7 @@ import base64
|
||||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework import ChatMessage, Content
|
||||
from agent_framework import Content, Message
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
|
||||
ASSETS_DIR = Path(__file__).resolve().parent.parent / "sample_assets"
|
||||
@@ -45,7 +45,7 @@ async def test_image() -> None:
|
||||
client = OpenAIChatClient(model_id="gpt-4o")
|
||||
|
||||
image_uri = create_sample_image()
|
||||
message = ChatMessage(
|
||||
message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What's in this image?"),
|
||||
@@ -62,7 +62,7 @@ async def test_audio() -> None:
|
||||
client = OpenAIChatClient(model_id="gpt-4o-audio-preview")
|
||||
|
||||
audio_uri = create_sample_audio()
|
||||
message = ChatMessage(
|
||||
message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What do you hear in this audio?"),
|
||||
@@ -79,7 +79,7 @@ async def test_pdf() -> None:
|
||||
client = OpenAIChatClient(model_id="gpt-4o")
|
||||
|
||||
pdf_bytes = load_sample_pdf()
|
||||
message = ChatMessage(
|
||||
message = Message(
|
||||
role="user",
|
||||
contents=[
|
||||
Content.from_text(text="What information can you extract from this document?"),
|
||||
|
||||
@@ -12,7 +12,7 @@ from opentelemetry.trace.span import format_trace_id
|
||||
from pydantic import Field
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from agent_framework import ChatClientProtocol
|
||||
from agent_framework import SupportsChatGetResponse
|
||||
|
||||
|
||||
"""
|
||||
@@ -51,7 +51,7 @@ async def get_weather(
|
||||
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
|
||||
|
||||
|
||||
async def run_chat_client(client: "ChatClientProtocol", stream: bool = False) -> None:
|
||||
async def run_chat_client(client: "SupportsChatGetResponse", stream: bool = False) -> None:
|
||||
"""Run an AI service.
|
||||
|
||||
This function runs an AI service and prints the output.
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.observability import configure_otel_providers, get_tracer
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
from opentelemetry.trace import SpanKind
|
||||
@@ -39,8 +39,8 @@ async def main():
|
||||
with get_tracer().start_as_current_span("Scenario: Agent Chat", kind=SpanKind.CLIENT) as current_span:
|
||||
print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIChatClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIChatClient(),
|
||||
tools=get_weather,
|
||||
name="WeatherAgent",
|
||||
instructions="You are a weather assistant.",
|
||||
|
||||
@@ -16,7 +16,7 @@ from random import randint
|
||||
from typing import Annotated
|
||||
|
||||
import dotenv
|
||||
from agent_framework import ChatAgent, tool
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.observability import create_resource, enable_instrumentation, get_tracer
|
||||
from agent_framework.openai import OpenAIResponsesClient
|
||||
from azure.ai.projects.aio import AIProjectClient
|
||||
@@ -30,7 +30,7 @@ from pydantic import Field
|
||||
This sample shows you can can setup telemetry in Microsoft Foundry for a custom agent.
|
||||
First ensure you have a Foundry workspace with Application Insights enabled.
|
||||
And use the Operate tab to Register an Agent.
|
||||
Set the OpenTelemetry agent ID to the value used below in the ChatAgent creation: `weather-agent` (or change both).
|
||||
Set the OpenTelemetry agent ID to the value used below in the Agent creation: `weather-agent` (or change both).
|
||||
The sample uses the Azure Monitor OpenTelemetry exporter to send traces to Application Insights.
|
||||
So ensure you have the `azure-monitor-opentelemetry` package installed.
|
||||
"""
|
||||
@@ -85,8 +85,8 @@ async def main():
|
||||
with get_tracer().start_as_current_span("Weather Agent Chat", kind=SpanKind.CLIENT) as current_span:
|
||||
print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")
|
||||
|
||||
agent = ChatAgent(
|
||||
chat_client=OpenAIResponsesClient(),
|
||||
agent = Agent(
|
||||
client=OpenAIResponsesClient(),
|
||||
tools=get_weather,
|
||||
name="WeatherAgent",
|
||||
instructions="You are a weather assistant.",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user