mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: [BREAKING] Python: Provider-leading client design & OpenAI package extraction (#4818)
* Python: Provider-leading client design & OpenAI package extraction Major refactoring of the Python Agent Framework client architecture: - Extract OpenAI clients into new `agent-framework-openai` package - Core package no longer depends on openai, azure-identity, azure-ai-projects - Rename clients for discoverability: OpenAIResponsesClient → OpenAIChatClient, OpenAIChatClient → OpenAIChatCompletionClient - Unify `model_id`/`deployment_name`/`model_deployment_name` → `model` param - New FoundryChatClient for Azure AI Foundry Responses API - New FoundryAgent/FoundryAgentClient for connecting to pre-configured Foundry agents - Remove OpenAIBase/OpenAIConfigMixin from non-deprecated client MRO - Deprecate AzureOpenAI* clients, AzureAIClient, OpenAIAssistantsClient - Reorganize samples: azure_openai+azure_ai+azure_ai_agent → azure/ - ADR-0020: Provider-Leading Client Design Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: missing Agent imports in samples, .model_id → .model in foundry_local sample Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: CI failures — mypy errors, coverage targets, sample imports - azure-ai mypy: add type ignores for TypedDict total=, model arg, forward ref - Coverage: replace core.azure/openai targets with openai package target - project_provider: add type annotation for opts dict Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: populate openai .pyi stub, fix broken README links, coverage targets Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fixes * updated observabilitty * reset azure init.pyi * fix errors * updated adr number * fix foundry local * fixed not renamed docstrings and comments, and added deprecated markers to old classes * fix tests and pyprojects * fix test vars * updated function tests * update durable * updated test setup for functions * Fix Foundry auth in workflow samples Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Stabilize Python integration workflows Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update hosting samples for Foundry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trigger full CI rerun Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trigger CI rerun again Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * trigger rerun * trigger rerun * fix for litellm * undo durabletask changes * Move Foundry APIs into foundry namespace Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Foundry pyproject formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Split provider samples by Foundry surface Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore hosting sample requirements Also fix the Foundry Local sample link after the provider sample move. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * updated tests * udpated foundry integration tests * removed dist from azurefunctions tests * Use separate Foundry clients for concurrent agents Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix client setup in azfunc and durable * disabled two tests * updated setup for some function and durable tests * improved azure openai setup with new clients * ignore deprecated * fixes * skip 11 * remove openai assistants int tests --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
4b533608b6
commit
5e056b672e
@@ -9,7 +9,7 @@ This client demonstrates:
|
||||
|
||||
Prerequisites:
|
||||
- The worker must be running with the TravelPlanner agent registered
|
||||
- Set AZURE_OPENAI_ENDPOINT and AZURE_OPENAI_CHAT_DEPLOYMENT_NAME
|
||||
- Set FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL
|
||||
- Redis must be running
|
||||
- Durable Task Scheduler must be running
|
||||
"""
|
||||
@@ -21,7 +21,7 @@ from datetime import timedelta
|
||||
|
||||
import redis.asyncio as aioredis
|
||||
from agent_framework.azure import DurableAIAgentClient
|
||||
from azure.identity import DefaultAzureCredential
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
from durabletask.azuremanaged.client import DurableTaskSchedulerClient
|
||||
from redis_stream_response_handler import RedisStreamResponseHandler
|
||||
@@ -76,7 +76,7 @@ def get_client(
|
||||
logger.debug(f"Using taskhub: {taskhub_name}")
|
||||
logger.debug(f"Using endpoint: {endpoint_url}")
|
||||
|
||||
credential = None if endpoint_url == "http://localhost:8080" else DefaultAzureCredential()
|
||||
credential = None if endpoint_url == "http://localhost:8080" else AzureCliCredential()
|
||||
|
||||
dts_client = DurableTaskSchedulerClient(
|
||||
host_address=endpoint_url,
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
# Agent Framework packages
|
||||
# To use the deployed version, uncomment the line below and comment out the local installation lines
|
||||
# To use the deployed version, uncomment the lines below and comment out the local installation lines
|
||||
# agent-framework-foundry
|
||||
# agent-framework-durabletask
|
||||
|
||||
# Local installation (for development and testing)
|
||||
# Each package must be listed explicitly because pip doesn't resolve uv workspace sources.
|
||||
# Without explicit entries, pip would fetch transitive dependencies from PyPI instead of local source.
|
||||
-e ../../../../packages/core # Core framework - base dependency for all packages
|
||||
-e ../../../../packages/foundry # Foundry support - dependency for hosted chat/agent samples
|
||||
-e ../../../../packages/durabletask # Durable Task support - the main package for this sample
|
||||
|
||||
# Azure authentication
|
||||
azure-identity
|
||||
|
||||
# Redis client
|
||||
redis
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Single Agent Streaming Sample - Durable Task Integration (Combined Worker + Client)
|
||||
|
||||
This sample demonstrates running both the worker and client in a single process
|
||||
with reliable Redis-based streaming for agent responses.
|
||||
|
||||
The worker is started first to register the TravelPlanner agent with Redis streaming
|
||||
callback, then client operations are performed against the running worker.
|
||||
|
||||
Prerequisites:
|
||||
- Set AZURE_OPENAI_ENDPOINT and AZURE_OPENAI_CHAT_DEPLOYMENT_NAME
|
||||
(plus AZURE_OPENAI_API_KEY or Azure CLI authentication)
|
||||
- Set FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL
|
||||
- Sign in with Azure CLI for AzureCliCredential authentication
|
||||
- Durable Task Scheduler must be running (e.g., using Docker)
|
||||
- Redis must be running (e.g., docker run -d --name redis -p 6379:6379 redis:latest)
|
||||
|
||||
To run this sample:
|
||||
python sample.py
|
||||
"""
|
||||
@@ -33,27 +29,21 @@ logger = logging.getLogger(__name__)
|
||||
def main():
|
||||
"""Main entry point - runs both worker and client in single process."""
|
||||
logger.debug("Starting Durable Task Agent Sample with Redis Streaming...")
|
||||
|
||||
silent_handler = logging.NullHandler()
|
||||
|
||||
# Create and start the worker using helper function and context manager
|
||||
with get_worker(log_handler=silent_handler) as dts_worker:
|
||||
# Register agents and callbacks using helper function
|
||||
setup_worker(dts_worker)
|
||||
|
||||
# Start the worker
|
||||
dts_worker.start()
|
||||
logger.debug("Worker started and listening for requests...")
|
||||
|
||||
# Create the client using helper function
|
||||
agent_client = get_client(log_handler=silent_handler)
|
||||
|
||||
try:
|
||||
# Run client interactions using helper function
|
||||
run_client(agent_client)
|
||||
except Exception as e:
|
||||
logger.exception(f"Error during agent interaction: {e}")
|
||||
|
||||
logger.debug("Sample completed. Worker shutting down...")
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ This worker registers the TravelPlanner agent with the Durable Task Scheduler
|
||||
and uses RedisStreamCallback to persist streaming responses to Redis for reliable delivery.
|
||||
|
||||
Prerequisites:
|
||||
- Set AZURE_OPENAI_ENDPOINT and AZURE_OPENAI_CHAT_DEPLOYMENT_NAME
|
||||
(plus AZURE_OPENAI_API_KEY or Azure CLI authentication)
|
||||
- Set FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL
|
||||
- Sign in with Azure CLI for AzureCliCredential authentication
|
||||
- Start a Durable Task Scheduler (e.g., using Docker)
|
||||
- Start Redis (e.g., docker run -d --name redis -p 6379:6379 redis:latest)
|
||||
"""
|
||||
@@ -22,10 +22,11 @@ from agent_framework import Agent, AgentResponseUpdate
|
||||
from agent_framework.azure import (
|
||||
AgentCallbackContext,
|
||||
AgentResponseCallbackProtocol,
|
||||
AzureOpenAIChatClient,
|
||||
DurableAIAgentWorker,
|
||||
)
|
||||
from azure.identity import AzureCliCredential, DefaultAzureCredential
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from azure.identity.aio import AzureCliCredential as AsyncAzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
from durabletask.azuremanaged.worker import DurableTaskSchedulerWorker
|
||||
from redis_stream_response_handler import RedisStreamResponseHandler
|
||||
@@ -153,7 +154,13 @@ def create_travel_agent() -> "Agent":
|
||||
Returns:
|
||||
Agent: The configured TravelPlanner agent with travel planning tools.
|
||||
"""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
_client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AsyncAzureCliCredential(),
|
||||
)
|
||||
return Agent(
|
||||
client=_client,
|
||||
name="TravelPlanner",
|
||||
instructions="""You are an expert travel planner who creates detailed, personalized travel itineraries.
|
||||
When asked to plan a trip, you should:
|
||||
@@ -191,7 +198,7 @@ def get_worker(
|
||||
logger.debug(f"Using taskhub: {taskhub_name}")
|
||||
logger.debug(f"Using endpoint: {endpoint_url}")
|
||||
|
||||
credential = None if endpoint_url == "http://localhost:8080" else DefaultAzureCredential()
|
||||
credential = None if endpoint_url == "http://localhost:8080" else AzureCliCredential()
|
||||
|
||||
return DurableTaskSchedulerWorker(
|
||||
host_address=endpoint_url,
|
||||
|
||||
Reference in New Issue
Block a user