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
@@ -22,11 +22,15 @@ import os
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.declarative import WorkflowFactory
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
# Pricing data for the order calculation
|
||||
ITEM_PRICES = {
|
||||
"pizza": {"small": 10.99, "medium": 14.99, "large": 18.99, "default": 14.99},
|
||||
@@ -198,14 +202,15 @@ def format_order_confirmation(order_data: dict[str, Any], order_calculation: dic
|
||||
async def main():
|
||||
"""Run the agent to function tool workflow."""
|
||||
# Create Azure OpenAI Responses client
|
||||
chat_client = AzureOpenAIResponsesClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
chat_client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
# Create the order analysis agent with structured output
|
||||
order_analysis_agent = chat_client.as_agent(
|
||||
order_analysis_agent = Agent(
|
||||
client=chat_client,
|
||||
name="OrderAnalysisAgent",
|
||||
instructions=ORDER_ANALYSIS_INSTRUCTIONS,
|
||||
default_options={"response_format": OrderAnalysis},
|
||||
|
||||
@@ -27,12 +27,13 @@ import os
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.declarative import (
|
||||
AgentExternalInputRequest,
|
||||
AgentExternalInputResponse,
|
||||
WorkflowFactory,
|
||||
)
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
from pydantic import BaseModel, Field
|
||||
@@ -168,49 +169,55 @@ async def main() -> None:
|
||||
plugin = TicketingPlugin()
|
||||
|
||||
# Create Azure OpenAI client
|
||||
client = AzureOpenAIResponsesClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
# This sample has been tested only on `gpt-5.1` and may not work as intended on other models
|
||||
# This sample is known to fail on `gpt-5-mini` reasoning input (GH issue #4059)
|
||||
deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
# Create agents with structured outputs
|
||||
self_service_agent = client.as_agent(
|
||||
self_service_agent = Agent(
|
||||
client=client,
|
||||
name="SelfServiceAgent",
|
||||
instructions=SELF_SERVICE_INSTRUCTIONS,
|
||||
default_options={"response_format": SelfServiceResponse},
|
||||
)
|
||||
|
||||
ticketing_agent = client.as_agent(
|
||||
ticketing_agent = Agent(
|
||||
client=client,
|
||||
name="TicketingAgent",
|
||||
instructions=TICKETING_INSTRUCTIONS,
|
||||
tools=plugin.get_functions(),
|
||||
default_options={"response_format": TicketingResponse},
|
||||
)
|
||||
|
||||
routing_agent = client.as_agent(
|
||||
routing_agent = Agent(
|
||||
client=client,
|
||||
name="TicketRoutingAgent",
|
||||
instructions=TICKET_ROUTING_INSTRUCTIONS,
|
||||
tools=[plugin.get_ticket],
|
||||
default_options={"response_format": RoutingResponse},
|
||||
)
|
||||
|
||||
windows_support_agent = client.as_agent(
|
||||
windows_support_agent = Agent(
|
||||
client=client,
|
||||
name="WindowsSupportAgent",
|
||||
instructions=WINDOWS_SUPPORT_INSTRUCTIONS,
|
||||
tools=[plugin.get_ticket],
|
||||
default_options={"response_format": SupportResponse},
|
||||
)
|
||||
|
||||
resolution_agent = client.as_agent(
|
||||
resolution_agent = Agent(
|
||||
client=client,
|
||||
name="TicketResolutionAgent",
|
||||
instructions=RESOLUTION_INSTRUCTIONS,
|
||||
tools=[plugin.resolve_ticket],
|
||||
)
|
||||
|
||||
escalation_agent = client.as_agent(
|
||||
escalation_agent = Agent(
|
||||
client=client,
|
||||
name="TicketEscalationAgent",
|
||||
instructions=ESCALATION_INSTRUCTIONS,
|
||||
tools=[plugin.get_ticket, plugin.send_notification],
|
||||
|
||||
@@ -25,14 +25,14 @@ import asyncio
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.declarative import WorkflowFactory
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
# Agent Instructions
|
||||
RESEARCH_INSTRUCTIONS = """In order to help begin addressing the user request, please answer the following pre-survey to the best of your ability.
|
||||
@@ -124,45 +124,52 @@ class ManagerResponse(BaseModel):
|
||||
async def main() -> None:
|
||||
"""Run the deep research workflow."""
|
||||
# Create Azure OpenAI client
|
||||
client = AzureOpenAIResponsesClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
# Create agents
|
||||
research_agent = client.as_agent(
|
||||
research_agent = Agent(
|
||||
client=client,
|
||||
name="ResearchAgent",
|
||||
instructions=RESEARCH_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
planner_agent = client.as_agent(
|
||||
planner_agent = Agent(
|
||||
client=client,
|
||||
name="PlannerAgent",
|
||||
instructions=PLANNER_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
manager_agent = client.as_agent(
|
||||
manager_agent = Agent(
|
||||
client=client,
|
||||
name="ManagerAgent",
|
||||
instructions=MANAGER_INSTRUCTIONS,
|
||||
default_options={"response_format": ManagerResponse},
|
||||
)
|
||||
|
||||
summary_agent = client.as_agent(
|
||||
summary_agent = Agent(
|
||||
client=client,
|
||||
name="SummaryAgent",
|
||||
instructions=SUMMARY_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
knowledge_agent = client.as_agent(
|
||||
knowledge_agent = Agent(
|
||||
client=client,
|
||||
name="KnowledgeAgent",
|
||||
instructions=KNOWLEDGE_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
coder_agent = client.as_agent(
|
||||
coder_agent = Agent(
|
||||
client=client,
|
||||
name="CoderAgent",
|
||||
instructions=CODER_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
weather_agent = client.as_agent(
|
||||
weather_agent = Agent(
|
||||
client=client,
|
||||
name="WeatherAgent",
|
||||
instructions=WEATHER_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
@@ -11,8 +11,8 @@ from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Annotated, Any
|
||||
|
||||
from agent_framework import FileCheckpointStorage, tool
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from agent_framework import Agent, FileCheckpointStorage, tool
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from agent_framework_declarative import ExternalInputRequest, ExternalInputResponse, WorkflowFactory
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
@@ -69,12 +69,13 @@ def get_item_price(name: Annotated[str, Field(description="Menu item name")]) ->
|
||||
|
||||
async def main():
|
||||
# Create agent with tools
|
||||
client = AzureOpenAIResponsesClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
menu_agent = client.as_agent(
|
||||
menu_agent = Agent(
|
||||
client=client,
|
||||
name="MenuAgent",
|
||||
instructions="Answer questions about menu items, specials, and prices.",
|
||||
tools=[get_menu, get_specials, get_item_price],
|
||||
|
||||
@@ -16,13 +16,13 @@ import asyncio
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.declarative import WorkflowFactory
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
ANALYST_INSTRUCTIONS = """You are a product analyst. Analyze the given product and identify:
|
||||
1. Key features and benefits
|
||||
@@ -54,21 +54,24 @@ Return the final polished version."""
|
||||
|
||||
async def main() -> None:
|
||||
"""Run the marketing workflow with real Azure AI agents."""
|
||||
client = AzureOpenAIResponsesClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
analyst_agent = client.as_agent(
|
||||
analyst_agent = Agent(
|
||||
client=client,
|
||||
name="AnalystAgent",
|
||||
instructions=ANALYST_INSTRUCTIONS,
|
||||
)
|
||||
writer_agent = client.as_agent(
|
||||
writer_agent = Agent(
|
||||
client=client,
|
||||
name="WriterAgent",
|
||||
instructions=WRITER_INSTRUCTIONS,
|
||||
)
|
||||
editor_agent = client.as_agent(
|
||||
editor_agent = Agent(
|
||||
client=client,
|
||||
name="EditorAgent",
|
||||
instructions=EDITOR_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
@@ -12,26 +12,19 @@ async def main() -> None:
|
||||
"""Run the simple greeting workflow."""
|
||||
# Create a workflow factory
|
||||
factory = WorkflowFactory()
|
||||
|
||||
# Load the workflow from YAML
|
||||
workflow_path = Path(__file__).parent / "workflow.yaml"
|
||||
workflow = factory.create_workflow_from_yaml_path(workflow_path)
|
||||
|
||||
print(f"Loaded workflow: {workflow.name}")
|
||||
print("-" * 40)
|
||||
|
||||
# Run with default name
|
||||
print("\nRunning with default name:")
|
||||
result = await workflow.run({})
|
||||
for output in result.get_outputs():
|
||||
print(f" Output: {output}")
|
||||
|
||||
# Run with a custom name
|
||||
print("\nRunning with custom name 'Alice':")
|
||||
result = await workflow.run({"name": "Alice"})
|
||||
for output in result.get_outputs():
|
||||
print(f" Output: {output}")
|
||||
|
||||
print("\n" + "-" * 40)
|
||||
print("Workflow completed!")
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ The workflow loops until the teacher gives congratulations or max turns reached.
|
||||
Prerequisites:
|
||||
- Azure OpenAI deployment with chat completion capability
|
||||
- Environment variables:
|
||||
AZURE_AI_PROJECT_ENDPOINT: Your Azure AI Foundry Agent Service (V2) project endpoint
|
||||
FOUNDRY_PROJECT_ENDPOINT: Your Azure AI Foundry Agent Service (V2) project endpoint
|
||||
AZURE_AI_MODEL_DEPLOYMENT_NAME: Your model deployment name
|
||||
"""
|
||||
|
||||
@@ -23,13 +23,13 @@ import asyncio
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from agent_framework.azure import AzureOpenAIResponsesClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.declarative import WorkflowFactory
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
|
||||
STUDENT_INSTRUCTIONS = """You are a curious math student working on understanding mathematical concepts.
|
||||
When given a problem:
|
||||
@@ -56,19 +56,21 @@ Focus on building understanding, not just getting the right answer."""
|
||||
async def main() -> None:
|
||||
"""Run the student-teacher workflow with real Azure AI agents."""
|
||||
# Create chat client
|
||||
client = AzureOpenAIResponsesClient(
|
||||
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
|
||||
deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
# Create student and teacher agents
|
||||
student_agent = client.as_agent(
|
||||
student_agent = Agent(
|
||||
client=client,
|
||||
name="StudentAgent",
|
||||
instructions=STUDENT_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
teacher_agent = client.as_agent(
|
||||
teacher_agent = Agent(
|
||||
client=client,
|
||||
name="TeacherAgent",
|
||||
instructions=TEACHER_INSTRUCTIONS,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user