mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Add Durable Agent Wrapper code (#1913)
* add initial changes * Move code and add single sample * Update logger * Remove unused code * address PR comments * cleanup code and address comments --------- Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
5686a009fb
commit
1762cda5f7
@@ -0,0 +1,49 @@
|
||||
# Single Agent Sample (Python)
|
||||
|
||||
This sample demonstrates how to use the Durable Extension for Agent Framework to create a simple Azure Functions app that hosts a single AI agent and provides direct HTTP API access for interactive conversations.
|
||||
|
||||
## Key Concepts Demonstrated
|
||||
|
||||
- Defining a simple agent with the Microsoft Agent Framework and wiring it into
|
||||
an Azure Functions app via the Durable Extension for Agent Framework.
|
||||
- Calling the agent through generated HTTP endpoints (`/api/agents/Joker/run`).
|
||||
- Managing conversation state with session identifiers, so multiple clients can
|
||||
interact with the agent concurrently without sharing context.
|
||||
|
||||
## Environment Setup
|
||||
|
||||
### 1. Create and activate a virtual environment
|
||||
|
||||
**Windows (PowerShell):**
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
**Linux/macOS:**
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
### 2. Install dependencies
|
||||
|
||||
- Azure Functions Core Tools 4.x – install from the official docs so you can run `func start` locally.
|
||||
- Azurite storage emulator – the sample uses `AzureWebJobsStorage=UseDevelopmentStorage=true`; start Azurite before launching the app.
|
||||
- Durable Task local backend – `DURABLE_TASK_SCHEDULER_CONNECTION_STRING` expects the Durable Task scheduler listening on `http://localhost:8080` (start the Durable Functions emulator if it is not already running).
|
||||
- Python dependencies – from this folder, run `pip install -r requirements.txt` (or the equivalent in your active virtual environment).
|
||||
- Environment variables – update `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME` in `local.settings.json` with your Azure OpenAI resource details; keep the other values as provided unless you are using custom infrastructure.
|
||||
|
||||
## Running the Sample
|
||||
|
||||
With the environment configured and the Functions host running, you can interact
|
||||
with the Joker agent using the provided `demo.http` file or any HTTP client. For
|
||||
example:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:7071/api/agents/Joker/run \
|
||||
-H "Content-Type: text/plain" \
|
||||
-d "Tell me a short joke about cloud computing."
|
||||
```
|
||||
|
||||
The agent responds with a JSON payload that includes the generated joke.
|
||||
@@ -0,0 +1,26 @@
|
||||
### Joker Agent Sample Interactions
|
||||
@baseUrl = http://localhost:7071
|
||||
@agentName = Joker
|
||||
@agentRoute = {{baseUrl}}/api/agents/{{agentName}}
|
||||
@healthRoute = {{baseUrl}}/api/health
|
||||
|
||||
### Health Check
|
||||
GET {{healthRoute}}
|
||||
|
||||
### Ask for a joke (JSON payload)
|
||||
POST {{agentRoute}}/run
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"message": "Add a security element to it.",
|
||||
"sessionId": "session-003",
|
||||
"waitForCompletion": true
|
||||
}
|
||||
|
||||
### Ask for a joke (plain text payload)
|
||||
POST {{agentRoute}}/run
|
||||
|
||||
Give me a programming joke about race conditions.
|
||||
|
||||
### Retrieve conversation state
|
||||
GET {{agentRoute}}/session-001
|
||||
@@ -0,0 +1,61 @@
|
||||
"""Azure Functions single-agent sample showcasing how to host a single Azure OpenAI agent.
|
||||
|
||||
The sample reads the required endpoint and deployment environment variables, configures the Azure OpenAI chat client (using either an API key or Azure CLI credentials), and registers a joke-telling agent with an Azure Functions app that can optionally expose a health check.
|
||||
|
||||
Summary: Demonstrates configuring and deploying a single 'Joker' agent via Azure Functions."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
from azure.identity import AzureCliCredential
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from agent_framework.azurefunctions import AgentFunctionApp
|
||||
|
||||
|
||||
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"
|
||||
|
||||
|
||||
def _build_client_kwargs() -> dict[str, Any]:
|
||||
"""Construct Azure OpenAI client options."""
|
||||
|
||||
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.")
|
||||
|
||||
logger.info("[SingleAgent] Using deployment '%s' at '%s'", deployment, endpoint)
|
||||
|
||||
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_agent() -> Any:
|
||||
"""Create the Joker agent."""
|
||||
|
||||
client_kwargs = _build_client_kwargs()
|
||||
return AzureOpenAIChatClient(**client_kwargs).create_agent(
|
||||
name="Joker",
|
||||
instructions="You are good at telling jokes.",
|
||||
)
|
||||
|
||||
|
||||
app = AgentFunctionApp(agents=[_create_agent()], enable_health_check=True)
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": "2.0",
|
||||
"extensionBundle": {
|
||||
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
||||
"version": "[4.*, 5.0.0)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"IsEncrypted": false,
|
||||
"Values": {
|
||||
"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>"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
agent-framework-azurefunctions
|
||||
azure-identity
|
||||
Reference in New Issue
Block a user