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
@@ -1,27 +1,35 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Host a single Azure OpenAI-powered agent inside Azure Functions.
|
||||
"""Host a single Foundry-powered agent inside Azure Functions.
|
||||
|
||||
Components used in this sample:
|
||||
- AzureOpenAIChatClient to call the Azure OpenAI chat deployment.
|
||||
- FoundryChatClient to call the Foundry deployment.
|
||||
- AgentFunctionApp to expose HTTP endpoints via the Durable Functions extension.
|
||||
|
||||
Prerequisites: set `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME` (plus `AZURE_OPENAI_API_KEY` or Azure CLI authentication) before starting the Functions host."""
|
||||
Prerequisites: set `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, and sign in
|
||||
with Azure CLI before starting the Functions host."""
|
||||
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
|
||||
# 1. Instantiate the agent with the chosen deployment and instructions.
|
||||
def _create_agent() -> Any:
|
||||
"""Create the Joker agent."""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
return Agent(
|
||||
client=FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
),
|
||||
name="Joker",
|
||||
instructions="You are good at telling jokes.",
|
||||
)
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
|
||||
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Host multiple Azure OpenAI agents inside a single Azure Functions app.
|
||||
"""Host multiple Foundry-powered agents inside a single Azure Functions app.
|
||||
|
||||
Components used in this sample:
|
||||
- AzureOpenAIChatClient to create agents bound to a shared Azure OpenAI deployment.
|
||||
- FoundryChatClient to create agents bound to a shared Foundry deployment.
|
||||
- AgentFunctionApp to register multiple agents and expose dedicated HTTP endpoints.
|
||||
- Custom tool functions to demonstrate tool invocation from different agents.
|
||||
|
||||
Prerequisites: set `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, plus either
|
||||
`AZURE_OPENAI_API_KEY` or authenticate with Azure CLI before starting the Functions host."""
|
||||
Prerequisites: set `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, and sign in with Azure CLI before starting the Functions host."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import tool
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
from agent_framework import Agent, tool
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
@@ -59,15 +60,21 @@ 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.
|
||||
client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
weather_agent = client.as_agent(
|
||||
weather_agent = Agent(
|
||||
client=client,
|
||||
name="WeatherAgent",
|
||||
instructions="You are a helpful weather assistant. Provide current weather information.",
|
||||
tools=[get_weather],
|
||||
)
|
||||
|
||||
math_agent = client.as_agent(
|
||||
math_agent = Agent(
|
||||
client=client,
|
||||
name="MathAgent",
|
||||
instructions="You are a helpful math assistant. Help users with calculations like tip calculations.",
|
||||
tools=[calculate_tip],
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
|
||||
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
This sample demonstrates how to implement reliable streaming for durable agents using Redis Streams.
|
||||
|
||||
Components used in this sample:
|
||||
- AzureOpenAIChatClient to create the travel planner agent with tools.
|
||||
- FoundryChatClient to create the travel planner agent with tools.
|
||||
- AgentFunctionApp with a Redis-based callback for persistent streaming.
|
||||
- Custom HTTP endpoint to resume streaming from any point using cursor-based pagination.
|
||||
|
||||
Prerequisites:
|
||||
- Set AZURE_OPENAI_ENDPOINT and AZURE_OPENAI_CHAT_DEPLOYMENT_NAME
|
||||
- Set FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL
|
||||
- Sign in with Azure CLI (`az login`) for `AzureCliCredential`
|
||||
- Redis running (docker run -d --name redis -p 6379:6379 redis:latest)
|
||||
- DTS and Azurite running (see parent README)
|
||||
"""
|
||||
@@ -21,14 +22,14 @@ from datetime import timedelta
|
||||
|
||||
import azure.functions as func
|
||||
import redis.asyncio as aioredis
|
||||
from agent_framework import AgentResponseUpdate
|
||||
from agent_framework import Agent, AgentResponseUpdate
|
||||
from agent_framework.azure import (
|
||||
AgentCallbackContext,
|
||||
AgentFunctionApp,
|
||||
AgentResponseCallbackProtocol,
|
||||
AzureOpenAIChatClient,
|
||||
)
|
||||
from azure.identity import AzureCliCredential
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
from redis_stream_response_handler import RedisStreamResponseHandler, StreamChunk
|
||||
from tools import get_local_events, get_weather_forecast
|
||||
@@ -155,7 +156,12 @@ redis_callback = RedisStreamCallback()
|
||||
# Create the travel planner agent
|
||||
def create_travel_agent():
|
||||
"""Create the TravelPlanner agent with tools."""
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
return Agent(
|
||||
client=FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
),
|
||||
name="TravelPlanner",
|
||||
instructions="""You are an expert travel planner who creates detailed, personalized travel itineraries.
|
||||
When asked to plan a trip, you should:
|
||||
|
||||
+3
-4
@@ -5,10 +5,9 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
|
||||
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>",
|
||||
"REDIS_CONNECTION_STRING": "redis://localhost:6379",
|
||||
"REDIS_STREAM_TTL_MINUTES": "10"
|
||||
"REDIS_STREAM_TTL_MINUTES": "10",
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
# Azure authentication
|
||||
azure-identity
|
||||
|
||||
# Redis client
|
||||
redis
|
||||
|
||||
+14
-10
@@ -3,26 +3,24 @@
|
||||
"""Chain two runs of a single agent inside a Durable Functions orchestration.
|
||||
|
||||
Components used in this sample:
|
||||
- AzureOpenAIChatClient to construct the writer agent hosted by Agent Framework.
|
||||
- FoundryChatClient to construct the writer agent hosted by Agent Framework.
|
||||
- AgentFunctionApp to surface HTTP and orchestration triggers via the Azure Functions extension.
|
||||
- Durable Functions orchestration to run sequential agent invocations on the same conversation session.
|
||||
|
||||
Prerequisites: configure `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and either
|
||||
`AZURE_OPENAI_API_KEY` or authenticate with Azure CLI before starting the Functions host."""
|
||||
Prerequisites: configure `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, and sign in with Azure CLI before starting the Functions host."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
|
||||
import azure.functions as func
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.durable_functions import DurableOrchestrationClient, DurableOrchestrationContext
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -38,7 +36,13 @@ def _create_writer_agent() -> Any:
|
||||
"when given an improved sentence you polish it further."
|
||||
)
|
||||
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
_client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
return Agent(
|
||||
client=_client,
|
||||
name=WRITER_AGENT_NAME,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
|
||||
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,11 +1,13 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
|
||||
+19
-10
@@ -3,23 +3,24 @@
|
||||
"""Fan out concurrent runs across two agents inside a Durable Functions orchestration.
|
||||
|
||||
Components used in this sample:
|
||||
- AzureOpenAIChatClient to create domain-specific agents hosted by Agent Framework.
|
||||
- FoundryChatClient to create domain-specific agents hosted by Agent Framework.
|
||||
- AgentFunctionApp to expose orchestration and HTTP triggers.
|
||||
- Durable Functions orchestration that executes agent calls in parallel and aggregates results.
|
||||
|
||||
Prerequisites: configure `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and either
|
||||
`AZURE_OPENAI_API_KEY` or authenticate with Azure CLI before starting the Functions host."""
|
||||
Prerequisites: configure `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, and sign in with Azure CLI before starting the Functions host."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from collections.abc import Generator
|
||||
from typing import Any, cast
|
||||
|
||||
import azure.functions as func
|
||||
from agent_framework import AgentResponse
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
from agent_framework import Agent, AgentResponse
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.durable_functions import DurableOrchestrationClient, DurableOrchestrationContext
|
||||
from azure.identity import AzureCliCredential
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
@@ -34,14 +35,22 @@ CHEMIST_AGENT_NAME = "ChemistAgent"
|
||||
|
||||
# 2. Instantiate both agents that the orchestration will run concurrently.
|
||||
def _create_agents() -> list[Any]:
|
||||
client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
|
||||
physicist = client.as_agent(
|
||||
physicist = Agent(
|
||||
client=FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
),
|
||||
name=PHYSICIST_AGENT_NAME,
|
||||
instructions="You are an expert in physics. You answer questions from a physics perspective.",
|
||||
)
|
||||
|
||||
chemist = client.as_agent(
|
||||
chemist = Agent(
|
||||
client=FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
),
|
||||
name=CHEMIST_AGENT_NAME,
|
||||
instructions="You are an expert in chemistry. You answer questions from a chemistry perspective.",
|
||||
)
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
|
||||
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,11 +1,13 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
|
||||
+16
-12
@@ -3,29 +3,27 @@
|
||||
"""Route email requests through conditional orchestration with two agents.
|
||||
|
||||
Components used in this sample:
|
||||
- AzureOpenAIChatClient agents for spam detection and email drafting.
|
||||
- FoundryChatClient agents for spam detection and email drafting.
|
||||
- AgentFunctionApp with Durable orchestration, activity, and HTTP triggers.
|
||||
- Pydantic models that validate payloads and agent JSON responses.
|
||||
|
||||
Prerequisites: set `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`,
|
||||
and either `AZURE_OPENAI_API_KEY` or sign in with Azure CLI before running the
|
||||
Prerequisites: set `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, and sign in with Azure CLI before running the
|
||||
Functions host."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from collections.abc import Generator, Mapping
|
||||
from typing import Any
|
||||
|
||||
import azure.functions as func
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.durable_functions import DurableOrchestrationClient, DurableOrchestrationContext
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel, ValidationError
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 1. Define agent names shared across the orchestration.
|
||||
@@ -49,14 +47,20 @@ class EmailPayload(BaseModel):
|
||||
|
||||
# 2. Instantiate both agents so they can be registered with AgentFunctionApp.
|
||||
def _create_agents() -> list[Any]:
|
||||
client = AzureOpenAIChatClient(credential=AzureCliCredential())
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
spam_agent = client.as_agent(
|
||||
spam_agent = Agent(
|
||||
client=client,
|
||||
name=SPAM_AGENT_NAME,
|
||||
instructions="You are a spam detection assistant that identifies spam emails.",
|
||||
)
|
||||
|
||||
email_agent = client.as_agent(
|
||||
email_agent = Agent(
|
||||
client=client,
|
||||
name=EMAIL_AGENT_NAME,
|
||||
instructions="You are an email assistant that helps users draft responses to emails with professionalism.",
|
||||
)
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
|
||||
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,11 +1,13 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
|
||||
+3
-3
@@ -6,11 +6,11 @@ output or a maximum number of attempts is reached.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Complete the common setup instructions in `../README.md` to prepare the virtual environment, install dependencies, and configure Azure OpenAI and storage settings.
|
||||
Complete the common setup instructions in `../README.md` to prepare the virtual environment, install dependencies, and configure Foundry and storage settings.
|
||||
|
||||
## What It Shows
|
||||
- Identical environment variable usage (`AZURE_OPENAI_ENDPOINT`,
|
||||
`AZURE_OPENAI_DEPLOYMENT`) and HTTP surface area (`/api/hitl/...`).
|
||||
- Identical environment variable usage (`FOUNDRY_PROJECT_ENDPOINT`,
|
||||
`FOUNDRY_MODEL`) and HTTP surface area (`/api/hitl/...`).
|
||||
- Durable orchestrations that pause for external events while maintaining
|
||||
deterministic state (`context.wait_for_external_event` + timed cancellation).
|
||||
- Activity functions that encapsulate the out-of-band operations such as notifying
|
||||
|
||||
+14
-10
@@ -3,29 +3,27 @@
|
||||
"""Iterate on generated content with a human-in-the-loop Durable orchestration.
|
||||
|
||||
Components used in this sample:
|
||||
- AzureOpenAIChatClient for a single writer agent that emits structured JSON.
|
||||
- FoundryChatClient for a single writer agent that emits structured JSON.
|
||||
- AgentFunctionApp with Durable orchestration, HTTP triggers, and activity triggers.
|
||||
- External events that pause the workflow until a human decision arrives or times out.
|
||||
|
||||
Prerequisites: configure `AZURE_OPENAI_ENDPOINT`, `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME`, and
|
||||
either `AZURE_OPENAI_API_KEY` or sign in with Azure CLI before running `func start`."""
|
||||
Prerequisites: configure `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, and sign in with Azure CLI before running `func start`."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from collections.abc import Generator, Mapping
|
||||
from datetime import timedelta
|
||||
from typing import Any
|
||||
|
||||
import azure.functions as func
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.durable_functions import DurableOrchestrationClient, DurableOrchestrationContext
|
||||
from azure.identity import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel, ValidationError
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 1. Define orchestration constants used throughout the workflow.
|
||||
@@ -57,7 +55,13 @@ def _create_writer_agent() -> Any:
|
||||
"Return your response as JSON with 'title' and 'content' fields."
|
||||
)
|
||||
|
||||
return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
|
||||
_client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
return Agent(
|
||||
client=_client,
|
||||
name=WRITER_AGENT_NAME,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>",
|
||||
"AZURE_OPENAI_API_KEY": "<AZURE_OPENAI_API_KEY>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -1,11 +1,13 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
|
||||
@@ -30,14 +30,13 @@ See the [README.md](../README.md) file in the parent directory for complete setu
|
||||
|
||||
## Configuration
|
||||
|
||||
Update your `local.settings.json` with your Azure OpenAI credentials:
|
||||
Update your `local.settings.json` with your Foundry project settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"Values": {
|
||||
"AZURE_OPENAI_ENDPOINT": "https://your-resource.openai.azure.com/",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "your-deployment-name",
|
||||
"AZURE_OPENAI_KEY": "your-api-key-if-not-using-rbac"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "https://your-project.services.ai.azure.com/api/projects/your-project",
|
||||
"FOUNDRY_MODEL": "your-deployment-name"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""
|
||||
Example showing how to configure AI agents with different trigger configurations.
|
||||
"""Example showing how to configure AI agents with different trigger configurations.
|
||||
|
||||
This sample demonstrates how to configure agents to be accessible as both HTTP endpoints
|
||||
and Model Context Protocol (MCP) tools, enabling flexible integration patterns for AI agent
|
||||
@@ -18,37 +17,48 @@ This sample creates three agents with different trigger configurations:
|
||||
- PlantAdvisor: Both HTTP and MCP tool triggers enabled
|
||||
|
||||
Required environment variables:
|
||||
- AZURE_OPENAI_ENDPOINT: Your Azure OpenAI endpoint
|
||||
- AZURE_OPENAI_CHAT_DEPLOYMENT_NAME: Your Azure OpenAI deployment name
|
||||
- FOUNDRY_PROJECT_ENDPOINT: Your Azure AI Foundry project endpoint
|
||||
- FOUNDRY_MODEL: Your Azure AI Foundry deployment name
|
||||
|
||||
Authentication uses AzureCliCredential (Azure Identity).
|
||||
"""
|
||||
|
||||
from agent_framework.azure import AgentFunctionApp, AzureOpenAIChatClient
|
||||
import os
|
||||
|
||||
from agent_framework import Agent
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
# Create Azure OpenAI Chat Client
|
||||
# Create Foundry chat client
|
||||
# This uses AzureCliCredential for authentication (requires 'az login')
|
||||
client = AzureOpenAIChatClient()
|
||||
client = FoundryChatClient(
|
||||
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
|
||||
model=os.environ["FOUNDRY_MODEL"],
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
# Define three AI agents with different roles
|
||||
# Agent 1: Joker - HTTP trigger only (default)
|
||||
agent1 = client.as_agent(
|
||||
agent1 = Agent(
|
||||
client=client,
|
||||
name="Joker",
|
||||
instructions="You are good at telling jokes.",
|
||||
)
|
||||
|
||||
# Agent 2: StockAdvisor - MCP tool trigger only
|
||||
agent2 = client.as_agent(
|
||||
agent2 = Agent(
|
||||
client=client,
|
||||
name="StockAdvisor",
|
||||
instructions="Check stock prices.",
|
||||
)
|
||||
|
||||
# Agent 3: PlantAdvisor - Both HTTP and MCP tool triggers
|
||||
agent3 = client.as_agent(
|
||||
agent3 = Agent(
|
||||
client=client,
|
||||
name="PlantAdvisor",
|
||||
instructions="Recommend plants.",
|
||||
description="Get plant recommendations.",
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
"FUNCTIONS_WORKER_RUNTIME": "python",
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<AZURE_OPENAI_CHAT_DEPLOYMENT_NAME>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
# 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-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ SharedState allows executors to pass large payloads (like email content) by refe
|
||||
```json
|
||||
{
|
||||
"Values": {
|
||||
"AZURE_OPENAI_ENDPOINT": "https://your-resource.openai.azure.com/",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "gpt-4o"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "https://your-project.services.ai.azure.com/api/projects/your-project",
|
||||
"FOUNDRY_MODEL": "gpt-4o"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
+22
-27
@@ -13,8 +13,8 @@ Show how to:
|
||||
- Compose agent backed executors with function style executors and yield the final output when the workflow completes.
|
||||
|
||||
Prerequisites:
|
||||
- Azure OpenAI configured for AzureOpenAIChatClient with required environment variables.
|
||||
- Authentication via azure-identity. Use DefaultAzureCredential and run az login before executing the sample.
|
||||
- Configure `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_MODEL` for FoundryChatClient.
|
||||
- Authentication uses `AzureCliCredential`; run `az login` before executing the sample.
|
||||
- Familiarity with WorkflowBuilder, executors, conditional edges, and streaming runs.
|
||||
"""
|
||||
|
||||
@@ -25,6 +25,7 @@ from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
from agent_framework import (
|
||||
Agent,
|
||||
AgentExecutorRequest,
|
||||
AgentExecutorResponse,
|
||||
Message,
|
||||
@@ -33,18 +34,17 @@ from agent_framework import (
|
||||
WorkflowContext,
|
||||
executor,
|
||||
)
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from agent_framework_azurefunctions import AgentFunctionApp
|
||||
from azure.identity import AzureCliCredential
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing_extensions import Never
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Environment variable names
|
||||
AZURE_OPENAI_ENDPOINT_ENV = "AZURE_OPENAI_ENDPOINT"
|
||||
AZURE_OPENAI_DEPLOYMENT_ENV = "AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"
|
||||
AZURE_OPENAI_API_KEY_ENV = "AZURE_OPENAI_API_KEY"
|
||||
FOUNDRY_PROJECT_ENDPOINT_ENV = "FOUNDRY_PROJECT_ENDPOINT"
|
||||
AZURE_OPENAI_DEPLOYMENT_ENV = "FOUNDRY_MODEL"
|
||||
|
||||
EMAIL_STATE_PREFIX = "email:"
|
||||
CURRENT_EMAIL_ID_KEY = "current_email_id"
|
||||
@@ -172,35 +172,29 @@ async def handle_spam(detection: DetectionResult, ctx: WorkflowContext[Never, st
|
||||
|
||||
|
||||
def _build_client_kwargs() -> dict[str, Any]:
|
||||
"""Build Azure OpenAI client configuration from environment variables."""
|
||||
endpoint = os.getenv(AZURE_OPENAI_ENDPOINT_ENV)
|
||||
if not endpoint:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_ENDPOINT_ENV} environment variable is required.")
|
||||
"""Build Foundry chat client configuration from environment variables."""
|
||||
project_endpoint = os.getenv(FOUNDRY_PROJECT_ENDPOINT_ENV)
|
||||
if not project_endpoint:
|
||||
raise RuntimeError(f"{FOUNDRY_PROJECT_ENDPOINT_ENV} environment variable is required.")
|
||||
|
||||
deployment = os.getenv(AZURE_OPENAI_DEPLOYMENT_ENV)
|
||||
if not deployment:
|
||||
model = os.getenv(AZURE_OPENAI_DEPLOYMENT_ENV)
|
||||
if not model:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_DEPLOYMENT_ENV} environment variable is required.")
|
||||
|
||||
client_kwargs: dict[str, Any] = {
|
||||
"endpoint": endpoint,
|
||||
"deployment_name": deployment,
|
||||
return {
|
||||
"project_endpoint": project_endpoint,
|
||||
"model": model,
|
||||
"credential": AzureCliCredential(),
|
||||
}
|
||||
|
||||
api_key = os.getenv(AZURE_OPENAI_API_KEY_ENV)
|
||||
if api_key:
|
||||
client_kwargs["api_key"] = api_key
|
||||
else:
|
||||
client_kwargs["credential"] = AzureCliCredential()
|
||||
|
||||
return client_kwargs
|
||||
|
||||
|
||||
def _create_workflow() -> Workflow:
|
||||
"""Create the email classification workflow with conditional routing."""
|
||||
client_kwargs = _build_client_kwargs()
|
||||
chat_client = AzureOpenAIChatClient(**client_kwargs)
|
||||
chat_client = FoundryChatClient(**client_kwargs)
|
||||
|
||||
spam_detection_agent = chat_client.as_agent(
|
||||
spam_detection_agent = Agent(
|
||||
client=chat_client,
|
||||
instructions=(
|
||||
"You are a spam detection assistant that identifies spam emails. "
|
||||
"Always return JSON with fields is_spam (bool) and reason (string)."
|
||||
@@ -209,7 +203,8 @@ def _create_workflow() -> Workflow:
|
||||
name="spam_detection_agent",
|
||||
)
|
||||
|
||||
email_assistant_agent = chat_client.as_agent(
|
||||
email_assistant_agent = Agent(
|
||||
client=chat_client,
|
||||
instructions=(
|
||||
"You are an email assistant that helps users draft responses to emails with professionalism. "
|
||||
"Return JSON with a single field 'response' containing the drafted reply."
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"FUNCTIONS_WORKER_RUNTIME": "python",
|
||||
"AZURE_OPENAI_ENDPOINT": "<Your Azure OpenAI endpoint>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<Your Azure OpenAI chat deployment name>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
+14
-1
@@ -1,2 +1,15 @@
|
||||
agent-framework-azurefunctions
|
||||
# Agent Framework packages
|
||||
# To use the deployed version, uncomment the lines below and comment out the local installation lines
|
||||
# agent-framework-foundry
|
||||
# agent-framework-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
# Azure authentication
|
||||
azure-identity
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# Azure OpenAI Configuration
|
||||
AZURE_OPENAI_ENDPOINT=https://<your-resource-name>.openai.azure.com/
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME=<your-deployment-name>
|
||||
AZURE_OPENAI_API_KEY=<your-api-key>
|
||||
# Foundry Configuration
|
||||
FOUNDRY_PROJECT_ENDPOINT=https://your-project.services.ai.azure.com/api/projects/your-project
|
||||
FOUNDRY_MODEL=<your-deployment-name>
|
||||
|
||||
+25
-24
@@ -14,6 +14,11 @@ Key architectural points:
|
||||
|
||||
This approach allows using the rich structure of `WorkflowBuilder` while leveraging
|
||||
the statefulness and durability of `DurableAIAgent`s.
|
||||
|
||||
Prerequisites:
|
||||
- Configure `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_MODEL`
|
||||
- Sign in with Azure CLI (`az login`) for `AzureCliCredential`
|
||||
- Ensure Azurite and the Durable Task Scheduler emulator are running
|
||||
"""
|
||||
|
||||
import logging
|
||||
@@ -22,6 +27,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import (
|
||||
Agent,
|
||||
AgentExecutorResponse,
|
||||
Case,
|
||||
Default,
|
||||
@@ -31,17 +37,16 @@ from agent_framework import (
|
||||
WorkflowContext,
|
||||
handler,
|
||||
)
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from agent_framework_azurefunctions import AgentFunctionApp
|
||||
from azure.identity import AzureCliCredential
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing_extensions import Never
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
AZURE_OPENAI_ENDPOINT_ENV = "AZURE_OPENAI_ENDPOINT"
|
||||
AZURE_OPENAI_DEPLOYMENT_ENV = "AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"
|
||||
AZURE_OPENAI_API_KEY_ENV = "AZURE_OPENAI_API_KEY"
|
||||
FOUNDRY_PROJECT_ENDPOINT_ENV = "FOUNDRY_PROJECT_ENDPOINT"
|
||||
AZURE_OPENAI_DEPLOYMENT_ENV = "FOUNDRY_MODEL"
|
||||
SPAM_AGENT_NAME = "SpamDetectionAgent"
|
||||
EMAIL_AGENT_NAME = "EmailAssistantAgent"
|
||||
|
||||
@@ -87,27 +92,21 @@ class EmailPayload(BaseModel):
|
||||
|
||||
|
||||
def _build_client_kwargs() -> dict[str, Any]:
|
||||
endpoint = os.getenv(AZURE_OPENAI_ENDPOINT_ENV)
|
||||
if not endpoint:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_ENDPOINT_ENV} environment variable is required.")
|
||||
"""Build Foundry chat client configuration from environment variables."""
|
||||
project_endpoint = os.getenv(FOUNDRY_PROJECT_ENDPOINT_ENV)
|
||||
if not project_endpoint:
|
||||
raise RuntimeError(f"{FOUNDRY_PROJECT_ENDPOINT_ENV} environment variable is required.")
|
||||
|
||||
deployment = os.getenv(AZURE_OPENAI_DEPLOYMENT_ENV)
|
||||
if not deployment:
|
||||
model = os.getenv(AZURE_OPENAI_DEPLOYMENT_ENV)
|
||||
if not model:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_DEPLOYMENT_ENV} environment variable is required.")
|
||||
|
||||
client_kwargs: dict[str, Any] = {
|
||||
"endpoint": endpoint,
|
||||
"deployment_name": deployment,
|
||||
return {
|
||||
"project_endpoint": project_endpoint,
|
||||
"model": model,
|
||||
"credential": AzureCliCredential(),
|
||||
}
|
||||
|
||||
api_key = os.getenv(AZURE_OPENAI_API_KEY_ENV)
|
||||
if api_key:
|
||||
client_kwargs["api_key"] = api_key
|
||||
else:
|
||||
client_kwargs["credential"] = AzureCliCredential()
|
||||
|
||||
return client_kwargs
|
||||
|
||||
|
||||
# Executors for non-AI activities (defined at module level)
|
||||
class SpamHandlerExecutor(Executor):
|
||||
@@ -165,15 +164,17 @@ def is_spam_detected(message: Any) -> bool:
|
||||
def _create_workflow() -> Workflow:
|
||||
"""Create the workflow definition."""
|
||||
client_kwargs = _build_client_kwargs()
|
||||
chat_client = AzureOpenAIChatClient(**client_kwargs)
|
||||
chat_client = FoundryChatClient(**client_kwargs)
|
||||
|
||||
spam_agent = chat_client.as_agent(
|
||||
spam_agent = Agent(
|
||||
client=chat_client,
|
||||
name=SPAM_AGENT_NAME,
|
||||
instructions=SPAM_DETECTION_INSTRUCTIONS,
|
||||
default_options={"response_format": SpamDetectionResult},
|
||||
)
|
||||
|
||||
email_agent = chat_client.as_agent(
|
||||
email_agent = Agent(
|
||||
client=chat_client,
|
||||
name=EMAIL_AGENT_NAME,
|
||||
instructions=EMAIL_ASSISTANT_INSTRUCTIONS,
|
||||
default_options={"response_format": EmailResponse},
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "https://<your-resource-name>.openai.azure.com/",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<your-deployment-name>",
|
||||
"AZURE_OPENAI_API_KEY": "<your-api-key>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
+14
-2
@@ -1,3 +1,15 @@
|
||||
agent-framework-azurefunctions
|
||||
agent-framework
|
||||
# Agent Framework packages
|
||||
# To use the deployed version, uncomment the lines below and comment out the local installation lines
|
||||
# agent-framework-foundry
|
||||
# agent-framework-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
# Azure authentication
|
||||
azure-identity
|
||||
|
||||
@@ -10,5 +10,4 @@ TASKHUB_NAME=default
|
||||
|
||||
# Azure OpenAI Configuration
|
||||
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
|
||||
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME=your-deployment-name
|
||||
AZURE_OPENAI_API_KEY=your-api-key
|
||||
AZURE_OPENAI_DEPLOYMENT_NAME=your-deployment-name
|
||||
|
||||
@@ -98,7 +98,8 @@ The sample can run locally without Azure Functions infrastructure using DevUI:
|
||||
cp .env.template .env
|
||||
```
|
||||
|
||||
2. Configure `.env` with your Azure OpenAI credentials
|
||||
2. Configure `.env` with your Azure OpenAI credentials (`AZURE_OPENAI_ENDPOINT` and
|
||||
`AZURE_OPENAI_DEPLOYMENT_NAME`)
|
||||
|
||||
3. Install dependencies:
|
||||
```bash
|
||||
|
||||
@@ -19,6 +19,11 @@ Key architectural points:
|
||||
- Different agents run in parallel when they're in the same iteration
|
||||
- Activities (executors) also run in parallel when pending together
|
||||
- Mixed agent/executor fan-outs execute concurrently
|
||||
|
||||
Prerequisites:
|
||||
- Configure `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_DEPLOYMENT_NAME`
|
||||
- Sign in with Azure CLI (`az login`) for `AzureCliCredential`
|
||||
- Ensure Azurite and the Durable Task Scheduler emulator are running
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -28,6 +33,7 @@ from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import (
|
||||
Agent,
|
||||
AgentExecutorResponse,
|
||||
Executor,
|
||||
Workflow,
|
||||
@@ -36,18 +42,14 @@ from agent_framework import (
|
||||
executor,
|
||||
handler,
|
||||
)
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from agent_framework_azurefunctions import AgentFunctionApp
|
||||
from azure.identity import AzureCliCredential
|
||||
from agent_framework.azure import AgentFunctionApp
|
||||
from agent_framework.openai import OpenAIChatCompletionClient
|
||||
from azure.identity.aio import AzureCliCredential, get_bearer_token_provider
|
||||
from pydantic import BaseModel
|
||||
from typing_extensions import Never
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
AZURE_OPENAI_ENDPOINT_ENV = "AZURE_OPENAI_ENDPOINT"
|
||||
AZURE_OPENAI_DEPLOYMENT_ENV = "AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"
|
||||
AZURE_OPENAI_API_KEY_ENV = "AZURE_OPENAI_API_KEY"
|
||||
|
||||
# Agent names
|
||||
SENTIMENT_AGENT_NAME = "SentimentAnalysisAgent"
|
||||
KEYWORD_AGENT_NAME = "KeywordExtractionAgent"
|
||||
@@ -334,30 +336,6 @@ class MixedResultCollector(Executor):
|
||||
# ============================================================================
|
||||
|
||||
|
||||
def _build_client_kwargs() -> dict[str, Any]:
|
||||
"""Build Azure OpenAI client kwargs from environment variables."""
|
||||
endpoint = os.getenv(AZURE_OPENAI_ENDPOINT_ENV)
|
||||
if not endpoint:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_ENDPOINT_ENV} environment variable is required.")
|
||||
|
||||
deployment = os.getenv(AZURE_OPENAI_DEPLOYMENT_ENV)
|
||||
if not deployment:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_DEPLOYMENT_ENV} environment variable is required.")
|
||||
|
||||
client_kwargs: dict[str, Any] = {
|
||||
"endpoint": endpoint,
|
||||
"deployment_name": deployment,
|
||||
}
|
||||
|
||||
api_key = os.getenv(AZURE_OPENAI_API_KEY_ENV)
|
||||
if api_key:
|
||||
client_kwargs["api_key"] = api_key
|
||||
else:
|
||||
client_kwargs["credential"] = AzureCliCredential()
|
||||
|
||||
return client_kwargs
|
||||
|
||||
|
||||
def _create_workflow() -> Workflow:
|
||||
"""Create the parallel workflow definition.
|
||||
|
||||
@@ -381,11 +359,16 @@ def _create_workflow() -> Workflow:
|
||||
└─> statistics_processor ─┤
|
||||
└──> final_report
|
||||
"""
|
||||
client_kwargs = _build_client_kwargs()
|
||||
chat_client = AzureOpenAIChatClient(**client_kwargs)
|
||||
credential = AzureCliCredential()
|
||||
|
||||
chat_client = OpenAIChatCompletionClient(
|
||||
model=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
|
||||
api_key=get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default"),
|
||||
)
|
||||
|
||||
# Create agents for parallel analysis
|
||||
sentiment_agent = chat_client.as_agent(
|
||||
sentiment_agent = Agent(
|
||||
client=chat_client,
|
||||
name=SENTIMENT_AGENT_NAME,
|
||||
instructions=(
|
||||
"You are a sentiment analysis expert. Analyze the sentiment of the given text. "
|
||||
@@ -395,7 +378,8 @@ def _create_workflow() -> Workflow:
|
||||
default_options={"response_format": SentimentResult},
|
||||
)
|
||||
|
||||
keyword_agent = chat_client.as_agent(
|
||||
keyword_agent = Agent(
|
||||
client=chat_client,
|
||||
name=KEYWORD_AGENT_NAME,
|
||||
instructions=(
|
||||
"You are a keyword extraction expert. Extract important keywords and categories "
|
||||
@@ -406,7 +390,8 @@ def _create_workflow() -> Workflow:
|
||||
)
|
||||
|
||||
# Create summary agent for Pattern 3 (mixed parallel)
|
||||
summary_agent = chat_client.as_agent(
|
||||
summary_agent = Agent(
|
||||
client=chat_client,
|
||||
name=SUMMARY_AGENT_NAME,
|
||||
instructions=(
|
||||
"You are a summarization expert. Given analysis results (sentiment and keywords), "
|
||||
|
||||
+2
-3
@@ -5,8 +5,7 @@
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"AZURE_OPENAI_ENDPOINT": "https://<your-resource-name>.openai.azure.com/",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<your-deployment-name>",
|
||||
"AZURE_OPENAI_API_KEY": "<your-api-key>"
|
||||
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
|
||||
"AZURE_OPENAI_DEPLOYMENT_NAME": "<AZURE_OPENAI_DEPLOYMENT_NAME>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
agent-framework-azurefunctions
|
||||
agent-framework
|
||||
# Agent Framework packages
|
||||
# To use the deployed version, uncomment the lines below and comment out the local installation lines
|
||||
# agent-framework-openai
|
||||
# agent-framework-azurefunctions
|
||||
|
||||
# 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/openai # OpenAI support - dependency for Azure OpenAI chat samples
|
||||
-e ../../../../packages/durabletask # Durable Task support - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
# Azure authentication
|
||||
azure-identity
|
||||
|
||||
@@ -88,12 +88,12 @@ When running on Durable Functions, the HITL pattern maps to:
|
||||
cp local.settings.json.sample local.settings.json
|
||||
```
|
||||
|
||||
2. Update `local.settings.json` with your Azure OpenAI credentials:
|
||||
2. Update `local.settings.json` with your Foundry project settings:
|
||||
```json
|
||||
{
|
||||
"Values": {
|
||||
"AZURE_OPENAI_ENDPOINT": "https://your-resource.openai.azure.com/",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "gpt-4o"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "https://your-project.services.ai.azure.com/api/projects/your-project",
|
||||
"FOUNDRY_MODEL": "gpt-4o"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -18,7 +18,7 @@ Key architectural points:
|
||||
- Durable Functions provides durability while waiting for human input
|
||||
|
||||
Prerequisites:
|
||||
- Azure OpenAI configured with required environment variables
|
||||
- Configure `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_MODEL`
|
||||
- Durable Task Scheduler connection string
|
||||
- Authentication via Azure CLI (az login)
|
||||
"""
|
||||
@@ -30,6 +30,7 @@ from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import (
|
||||
Agent,
|
||||
AgentExecutorRequest,
|
||||
AgentExecutorResponse,
|
||||
Executor,
|
||||
@@ -40,18 +41,17 @@ from agent_framework import (
|
||||
handler,
|
||||
response_handler,
|
||||
)
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from agent_framework_azurefunctions import AgentFunctionApp
|
||||
from azure.identity import AzureCliCredential
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from pydantic import BaseModel, ValidationError
|
||||
from typing_extensions import Never
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Environment variable names
|
||||
AZURE_OPENAI_ENDPOINT_ENV = "AZURE_OPENAI_ENDPOINT"
|
||||
AZURE_OPENAI_DEPLOYMENT_ENV = "AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"
|
||||
AZURE_OPENAI_API_KEY_ENV = "AZURE_OPENAI_API_KEY"
|
||||
FOUNDRY_PROJECT_ENDPOINT_ENV = "FOUNDRY_PROJECT_ENDPOINT"
|
||||
AZURE_OPENAI_DEPLOYMENT_ENV = "FOUNDRY_MODEL"
|
||||
|
||||
# Agent names
|
||||
CONTENT_ANALYZER_AGENT_NAME = "ContentAnalyzerAgent"
|
||||
@@ -307,28 +307,21 @@ class PublishExecutor(Executor):
|
||||
|
||||
|
||||
def _build_client_kwargs() -> dict[str, Any]:
|
||||
"""Build Azure OpenAI client configuration from environment variables."""
|
||||
endpoint = os.getenv(AZURE_OPENAI_ENDPOINT_ENV)
|
||||
if not endpoint:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_ENDPOINT_ENV} environment variable is required.")
|
||||
"""Build Foundry chat client configuration from environment variables."""
|
||||
project_endpoint = os.getenv(FOUNDRY_PROJECT_ENDPOINT_ENV)
|
||||
if not project_endpoint:
|
||||
raise RuntimeError(f"{FOUNDRY_PROJECT_ENDPOINT_ENV} environment variable is required.")
|
||||
|
||||
deployment = os.getenv(AZURE_OPENAI_DEPLOYMENT_ENV)
|
||||
if not deployment:
|
||||
model = os.getenv(AZURE_OPENAI_DEPLOYMENT_ENV)
|
||||
if not model:
|
||||
raise RuntimeError(f"{AZURE_OPENAI_DEPLOYMENT_ENV} environment variable is required.")
|
||||
|
||||
client_kwargs: dict[str, Any] = {
|
||||
"endpoint": endpoint,
|
||||
"deployment_name": deployment,
|
||||
return {
|
||||
"project_endpoint": project_endpoint,
|
||||
"model": model,
|
||||
"credential": AzureCliCredential(),
|
||||
}
|
||||
|
||||
api_key = os.getenv(AZURE_OPENAI_API_KEY_ENV)
|
||||
if api_key:
|
||||
client_kwargs["api_key"] = api_key
|
||||
else:
|
||||
client_kwargs["credential"] = AzureCliCredential()
|
||||
|
||||
return client_kwargs
|
||||
|
||||
|
||||
class InputRouterExecutor(Executor):
|
||||
"""Routes incoming content submission to the analysis agent."""
|
||||
@@ -379,10 +372,11 @@ class InputRouterExecutor(Executor):
|
||||
def _create_workflow() -> Workflow:
|
||||
"""Create the content moderation workflow with HITL."""
|
||||
client_kwargs = _build_client_kwargs()
|
||||
chat_client = AzureOpenAIChatClient(**client_kwargs)
|
||||
chat_client = FoundryChatClient(**client_kwargs)
|
||||
|
||||
# Create the content analysis agent
|
||||
content_analyzer_agent = chat_client.as_agent(
|
||||
content_analyzer_agent = Agent(
|
||||
client=chat_client,
|
||||
name=CONTENT_ANALYZER_AGENT_NAME,
|
||||
instructions=CONTENT_ANALYZER_INSTRUCTIONS,
|
||||
default_options={"response_format": ContentAnalysisResult},
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
"DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
|
||||
"TASKHUB_NAME": "default",
|
||||
"FUNCTIONS_WORKER_RUNTIME": "python",
|
||||
"AZURE_OPENAI_ENDPOINT": "<Your Azure OpenAI endpoint>",
|
||||
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME": "<Your Azure OpenAI chat deployment name>"
|
||||
"FOUNDRY_PROJECT_ENDPOINT": "<FOUNDRY_PROJECT_ENDPOINT>",
|
||||
"FOUNDRY_MODEL": "<FOUNDRY_MODEL>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,15 @@
|
||||
agent-framework-azurefunctions
|
||||
# Agent Framework packages
|
||||
# To use the deployed version, uncomment the lines below and comment out the local installation lines
|
||||
# agent-framework-foundry
|
||||
# agent-framework-azurefunctions
|
||||
|
||||
# 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 - dependency of azurefunctions
|
||||
-e ../../../../packages/azurefunctions # Azure Functions integration - the main package for this sample
|
||||
|
||||
# Azure authentication
|
||||
azure-identity
|
||||
|
||||
@@ -11,7 +11,7 @@ All of these samples are set up to run in Azure Functions. Azure Functions has a
|
||||
|
||||
- Install [Azurite storage emulator](https://learn.microsoft.com/en-us/azure/storage/common/storage-install-azurite?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json&tabs=visual-studio%2Cblob-storage)
|
||||
|
||||
- Create an [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-foundry/models/openai) resource. Note the Azure OpenAI endpoint, deployment name, and the key (or ensure you can authenticate with `AzureCliCredential`).
|
||||
- Create an [Azure AI Foundry project](https://learn.microsoft.com/azure/ai-foundry/) with an OpenAI model deployment. Note the Foundry project endpoint and deployment name, and ensure you can authenticate with `AzureCliCredential`.
|
||||
|
||||
- Install a tool to execute HTTP calls, for example the [REST Client extension](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)
|
||||
|
||||
@@ -39,8 +39,7 @@ source .venv/bin/activate
|
||||
|
||||
- Install Python dependencies – from the sample directory, run `pip install -r requirements.txt` (or the equivalent in your active virtual environment).
|
||||
|
||||
- Copy `local.settings.json.template` to `local.settings.json`, then update `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME` for Azure OpenAI authentication. The samples use `AzureCliCredential` by default, so ensure you're logged in via `az login`.
|
||||
- Alternatively, you can use API key authentication by setting `AZURE_OPENAI_API_KEY` and updating the code to use `AzureOpenAIChatClient()` without the credential parameter.
|
||||
- Copy `local.settings.json.template` to `local.settings.json`, then update `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_MODEL`. The samples use `AzureCliCredential`, so ensure you're logged in via `az login`.
|
||||
- Keep `TASKHUB_NAME` set to `default` unless you plan to change the durable task hub name.
|
||||
|
||||
- Run the command `func start` from the root of the sample
|
||||
|
||||
Reference in New Issue
Block a user