diff --git a/python/samples/02-agents/devui/.env.example b/python/samples/02-agents/devui/.env.example new file mode 100644 index 0000000000..394dc7465d --- /dev/null +++ b/python/samples/02-agents/devui/.env.example @@ -0,0 +1,15 @@ +# Shared configuration for samples/02-agents/devui +# Used by in_memory_mode.py, main.py, and as a fallback for discovered samples. +# Run `az login` before starting Azure-backed samples. + +# Microsoft Foundry samples +FOUNDRY_PROJECT_ENDPOINT=https://your-project.services.ai.azure.com +FOUNDRY_MODEL=gpt-4o + +# Azure OpenAI workflow sample +AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com +AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME=gpt-4o +# Optional fallback env name also supported by workflow_with_agents/workflow.py: +AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o +# Optional if you need to override the default API version: +AZURE_OPENAI_API_VERSION=2024-10-21 diff --git a/python/samples/02-agents/devui/README.md b/python/samples/02-agents/devui/README.md index 4315582009..8a0ed60b6f 100644 --- a/python/samples/02-agents/devui/README.md +++ b/python/samples/02-agents/devui/README.md @@ -16,76 +16,124 @@ DevUI is a sample application that provides: ## Quick Start -### Option 1: In-Memory Mode (Simplest) +### Option 1: In-Memory Mode (Programmatic Registration) -Run a single sample directly. This demonstrates how to wrap agents and workflows programmatically without needing a directory structure: +Run a single sample directly. This demonstrates how to register agents and workflows in code without using DevUI's directory discovery. + +This sample uses Azure AI Foundry. Before running it: + +1. Copy `.env.example` in this folder to `.env`, or export the same values in your shell +2. Set `FOUNDRY_PROJECT_ENDPOINT` and `FOUNDRY_MODEL` +3. Run `az login` + +Then start the sample: ```bash cd python/samples/02-agents/devui python in_memory_mode.py ``` -This opens your browser at http://localhost:8090 with pre-configured agents and a basic workflow. +This opens your browser at http://localhost:8090 with two Foundry-backed agents and a simple text transformation workflow. -### Option 2: Directory Discovery +### Option 2: Directory Discovery with Shared Root `.env` -Launch DevUI to discover all samples in this folder: +Run the folder-level launcher to load `samples/02-agents/devui/.env` and then start DevUI with directory discovery for this folder: ```bash cd python/samples/02-agents/devui -devui +python main.py ``` -This starts the server at http://localhost:8080 with all agents and workflows available. +This starts the server at http://localhost:8080 with all discoverable agents and workflows available. The root `.env` acts as shared fallback configuration for discovered samples. + +### Option 3: Directory Discovery with the `devui` CLI + +If you prefer the CLI directly, you can still launch DevUI from this folder: + +```bash +cd python/samples/02-agents/devui +devui . +``` + +DevUI discovery checks for a sample-specific `.env` first and then falls back to `.env` in `samples/02-agents/devui/`. ## Sample Structure -Each agent/workflow follows a strict structure required by DevUI's discovery system: +DevUI discovers samples from Python packages that export either `agent` or `workflow`. + +Typical agent layout: ``` agent_name/ -├── __init__.py # Must export: agent = Agent(...) +├── __init__.py # Must export: agent = ... ├── agent.py # Agent implementation -└── .env.example # Example environment variables +└── .env.example # Optional example environment variables +``` + +Typical workflow layout: + +``` +workflow_name/ +├── __init__.py # Must export: workflow = ... +├── workflow.py # Workflow implementation +├── workflow.yaml # Optional declarative definition +└── .env.example # Optional example environment variables ``` ## Available Samples ### Agents -| Sample | Description | Features | Required Environment Variables | -| ------------------------------------------------ | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -| [**weather_agent_azure/**](weather_agent_azure/) | Weather agent using Azure OpenAI with API key authentication | Azure OpenAI integration, function calling, mock weather tools | `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_DEPLOYMENT_NAME`, `AZURE_OPENAI_ENDPOINT` | -| [**foundry_agent/**](foundry_agent/) | Weather agent using Azure AI Agent (Foundry) with Azure CLI authentication (run `az login` first) | Azure AI Agent integration, Azure CLI authentication, mock weather tools | `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL` | +| Sample | What it demonstrates | Required keys / auth | +| ------ | -------------------- | -------------------- | +| [**agent_weather/**](agent_weather/) | A richer Foundry-backed weather agent that shows chat middleware, function middleware, tool calling, and an approval-required tool alongside auto-approved tools. | `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, plus Azure CLI auth via `az login` | +| [**agent_foundry/**](agent_foundry/) | A minimal Foundry-backed weather agent with current weather and forecast tools. Use this when you want the smallest possible directory-discovered agent sample. | `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, plus Azure CLI auth via `az login` | ### Workflows -| Sample | Description | Features | Required Environment Variables | -| -------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| [**declarative/**](declarative/) | Declarative YAML workflow with conditional branching | YAML-based workflow definition, conditional logic, no Python code required | None - uses mock data | -| [**workflow_agents/**](workflow_agents/) | Content review workflow with agents as executors | Agents as workflow nodes, conditional routing based on structured outputs, quality-based paths (Writer -> Reviewer -> Editor/Publisher) | `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_DEPLOYMENT_NAME`, `AZURE_OPENAI_ENDPOINT` | -| [**spam_workflow/**](spam_workflow/) | 5-step email spam detection workflow with branching logic | Sequential execution, conditional branching (spam vs. legitimate), multiple executors, mock spam detection | None - uses mock data | -| [**fanout_workflow/**](fanout_workflow/) | Advanced data processing workflow with parallel execution | Fan-out/fan-in patterns, complex state management, multi-stage processing (validation -> transformation -> quality assurance) | None - uses mock data | +| Sample | What it demonstrates | Required keys / auth | +| ------ | -------------------- | -------------------- | +| [**workflow_declarative/**](workflow_declarative/) | A YAML-defined workflow loaded through `WorkflowFactory`, with nested age-based branching and no model client code. | None | +| [**workflow_with_agents/**](workflow_with_agents/) | A content review workflow that uses agents as executors and routes based on structured review output (`Writer -> Reviewer -> Editor/Publisher -> Summarizer`). | `AZURE_OPENAI_ENDPOINT`, plus `AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME` or `AZURE_OPENAI_DEPLOYMENT_NAME`; Azure CLI auth via `az login`; `AZURE_OPENAI_API_VERSION` is optional | +| [**workflow_spam/**](workflow_spam/) | A multi-step spam detection workflow with human-in-the-loop approval, branching for spam vs. legitimate messages, and a final reporting step. | None | +| [**workflow_fanout/**](workflow_fanout/) | A larger fan-out/fan-in data processing workflow with parallel validation, multiple transformations, QA, aggregation, and demo failure toggles. | None | ### Standalone Examples -| Sample | Description | Features | -| ------------------------------------------ | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -| [**in_memory_mode.py**](in_memory_mode.py) | Demonstrates programmatic entity registration without directory structure | In-memory agent and workflow registration, multiple entities served from a single file, includes basic workflow, simplest way to get started | +| Sample | What it demonstrates | Required keys / auth | +| ------ | -------------------- | -------------------- | +| [**in_memory_mode.py**](in_memory_mode.py) | Registers multiple entities directly in Python: two Foundry-backed agents plus a simple workflow, all served from one file without directory discovery. | `FOUNDRY_PROJECT_ENDPOINT`, `FOUNDRY_MODEL`, plus Azure CLI auth via `az login` | ## Environment Variables -Each sample that requires API keys includes a `.env.example` file. To use: +For samples that require external services: -1. Copy `.env.example` to `.env` in the same directory -2. Fill in your actual API keys -3. DevUI automatically loads `.env` files from entity directories +1. Copy `.env.example` to `.env` +2. Fill in the required values +3. Run `az login` for samples that use Azure CLI authentication + +Directory discovery checks `.env` files in this order: + +1. The entity directory itself, for example `agent_weather/.env` +2. The root DevUI samples folder, `samples/02-agents/devui/.env` + +That means the root `.env.example` can hold shared defaults for multiple samples, while a sample-specific `.env` can override those values when needed. + +`in_memory_mode.py` and `main.py` both load `.env` from `samples/02-agents/devui/`, so the root `.env.example` in this folder is the right starting point for both commands. Alternatively, set environment variables globally: ```bash -export OPENAI_API_KEY="your-key-here" -export OPENAI_CHAT_MODEL="gpt-4o" +# Foundry-backed samples +export FOUNDRY_PROJECT_ENDPOINT="https://your-project.services.ai.azure.com" +export FOUNDRY_MODEL="gpt-4o" + +# Azure OpenAI workflow_with_agents sample +export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com" +export AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME="gpt-4o" +export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o" + +az login ``` ## Using DevUI with Your Own Agents @@ -145,7 +193,7 @@ curl http://localhost:8080/v1/entities ## Troubleshooting -**Missing API keys**: Check your `.env` files or environment variables. +**Missing credentials or settings**: Check your `.env` files, confirm the required variables for the sample you are running, and make sure `az login` has completed for Azure-authenticated samples. **Import errors**: Make sure you've installed the devui package: diff --git a/python/samples/02-agents/devui/agent_foundry/.env.example b/python/samples/02-agents/devui/agent_foundry/.env.example new file mode 100644 index 0000000000..c58831e971 --- /dev/null +++ b/python/samples/02-agents/devui/agent_foundry/.env.example @@ -0,0 +1,5 @@ +# Azure AI Foundry Configuration +# Make sure to run 'az login' before starting devui + +FOUNDRY_PROJECT_ENDPOINT=https://your-project.services.ai.azure.com +FOUNDRY_MODEL=gpt-4o diff --git a/python/samples/02-agents/devui/foundry_agent/__init__.py b/python/samples/02-agents/devui/agent_foundry/__init__.py similarity index 100% rename from python/samples/02-agents/devui/foundry_agent/__init__.py rename to python/samples/02-agents/devui/agent_foundry/__init__.py diff --git a/python/samples/02-agents/devui/foundry_agent/agent.py b/python/samples/02-agents/devui/agent_foundry/agent.py similarity index 98% rename from python/samples/02-agents/devui/foundry_agent/agent.py rename to python/samples/02-agents/devui/agent_foundry/agent.py index 8550c1a32c..eaeb316c2b 100644 --- a/python/samples/02-agents/devui/foundry_agent/agent.py +++ b/python/samples/02-agents/devui/agent_foundry/agent.py @@ -53,7 +53,7 @@ agent = Agent( name="FoundryWeatherAgent", client=FoundryChatClient( project_endpoint=os.environ.get("FOUNDRY_PROJECT_ENDPOINT"), - model_model=os.environ.get("FOUNDRY_MODEL"), + model=os.environ.get("FOUNDRY_MODEL"), credential=AzureCliCredential(), ), instructions=""" diff --git a/python/samples/02-agents/devui/agent_weather/.env.example b/python/samples/02-agents/devui/agent_weather/.env.example new file mode 100644 index 0000000000..c58831e971 --- /dev/null +++ b/python/samples/02-agents/devui/agent_weather/.env.example @@ -0,0 +1,5 @@ +# Azure AI Foundry Configuration +# Make sure to run 'az login' before starting devui + +FOUNDRY_PROJECT_ENDPOINT=https://your-project.services.ai.azure.com +FOUNDRY_MODEL=gpt-4o diff --git a/python/samples/02-agents/devui/weather_agent_azure/__init__.py b/python/samples/02-agents/devui/agent_weather/__init__.py similarity index 100% rename from python/samples/02-agents/devui/weather_agent_azure/__init__.py rename to python/samples/02-agents/devui/agent_weather/__init__.py diff --git a/python/samples/02-agents/devui/weather_agent_azure/agent.py b/python/samples/02-agents/devui/agent_weather/agent.py similarity index 94% rename from python/samples/02-agents/devui/weather_agent_azure/agent.py rename to python/samples/02-agents/devui/agent_weather/agent.py index 4861d7a4b8..bfbcea294b 100644 --- a/python/samples/02-agents/devui/weather_agent_azure/agent.py +++ b/python/samples/02-agents/devui/agent_weather/agent.py @@ -22,6 +22,7 @@ from agent_framework import ( ) from agent_framework.foundry import FoundryChatClient from agent_framework_devui import register_cleanup +from azure.identity.aio import AzureCliCredential from dotenv import load_dotenv # Load environment variables from .env file @@ -145,7 +146,7 @@ def send_email( # Agent instance following Agent Framework conventions agent = Agent( - name="AzureWeatherAgent", + name="WeatherAgent", description="A helpful agent that provides weather information and forecasts", instructions=""" You are a weather assistant. You can provide current weather information @@ -153,7 +154,9 @@ agent = Agent( weather information when asked. """, client=FoundryChatClient( - api_key=os.environ.get("AZURE_OPENAI_API_KEY", ""), + project_endpoint=os.environ.get("FOUNDRY_PROJECT_ENDPOINT"), + model=os.environ.get("FOUNDRY_MODEL"), + credential=AzureCliCredential(), ), tools=[get_weather, get_forecast, send_email], middleware=[security_filter_middleware, atlantis_location_filter_middleware], @@ -164,7 +167,7 @@ register_cleanup(agent, cleanup_resources) def main(): - """Launch the Azure weather agent in DevUI.""" + """Launch the Weather Agent in DevUI.""" import logging from agent_framework.devui import serve @@ -173,9 +176,9 @@ def main(): logging.basicConfig(level=logging.INFO, format="%(message)s") logger = logging.getLogger(__name__) - logger.info("Starting Azure Weather Agent") + logger.info("Starting Weather Agent") logger.info("Available at: http://localhost:8090") - logger.info("Entity ID: agent_AzureWeatherAgent") + logger.info("Entity ID: agent_WeatherAgent") # Launch server with the agent serve(entities=[agent], port=8090, auto_open=True) diff --git a/python/samples/02-agents/devui/azure_responses_agent/.env.example b/python/samples/02-agents/devui/azure_responses_agent/.env.example deleted file mode 100644 index 975324fa02..0000000000 --- a/python/samples/02-agents/devui/azure_responses_agent/.env.example +++ /dev/null @@ -1,15 +0,0 @@ -# Azure OpenAI Responses API Configuration -# The Responses API supports PDF uploads, images, and other multimodal content. -# Requires api-version 2025-03-01-preview or later. - -# Option 1: Use API key authentication -AZURE_OPENAI_API_KEY=your-azure-openai-api-key-here - -# Option 2: Use Azure CLI authentication (run 'az login' first) -# No API key needed - just leave AZURE_OPENAI_API_KEY unset - -# Required: Azure OpenAI endpoint with Responses API support -AZURE_OPENAI_ENDPOINT=https://your-resource.cognitiveservices.azure.com/ - -# Required: Deployment name (must support Responses API) -FOUNDRY_MODEL=gpt-4.1-mini diff --git a/python/samples/02-agents/devui/azure_responses_agent/__init__.py b/python/samples/02-agents/devui/azure_responses_agent/__init__.py deleted file mode 100644 index f72521a7af..0000000000 --- a/python/samples/02-agents/devui/azure_responses_agent/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. -"""Azure Responses Agent sample for DevUI.""" - -from .agent import agent - -__all__ = ["agent"] diff --git a/python/samples/02-agents/devui/azure_responses_agent/agent.py b/python/samples/02-agents/devui/azure_responses_agent/agent.py deleted file mode 100644 index bb6bda6cf6..0000000000 --- a/python/samples/02-agents/devui/azure_responses_agent/agent.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) Microsoft. All rights reserved. -"""Sample agent using Azure OpenAI Responses API for Agent Framework DevUI. - -This agent uses the Responses API which supports: -- PDF file uploads -- Image uploads -- Audio inputs -- And other multimodal content - -The Chat Completions API (FoundryChatClient) does NOT support PDF uploads. -Use this agent when you need to process documents or other file types. - -Required environment variables: -- AZURE_OPENAI_ENDPOINT: Your Azure OpenAI endpoint -- FOUNDRY_MODEL: Deployment name for Responses API - (falls back to FOUNDRY_MODEL if not set) -- AZURE_OPENAI_API_KEY: Your API key (or use Azure CLI auth) -""" - -import logging -import os -from typing import Annotated - -from agent_framework import Agent, tool -from agent_framework.foundry import FoundryChatClient -from dotenv import load_dotenv - -# Load environment variables from .env file -load_dotenv() - -logger = logging.getLogger(__name__) - -# Get deployment name - try responses-specific env var first, fall back to chat deployment -_deployment_name = os.environ.get( - "FOUNDRY_MODEL", - os.environ.get("FOUNDRY_MODEL", ""), -) - -# Get endpoint - try responses-specific env var first, fall back to default -_endpoint = os.environ.get( - "AZURE_OPENAI_RESPONSES_ENDPOINT", - os.environ.get("AZURE_OPENAI_ENDPOINT", ""), -) - - -def analyze_content( - query: Annotated[str, "What to analyze or extract from the uploaded content"], -) -> str: - """Analyze uploaded content based on the user's query. - - This is a placeholder - the actual analysis is done by the model - when processing the uploaded files. - """ - return f"Analyzing content for: {query}" - - -# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_sessions.py. -@tool(approval_mode="never_require") -def summarize_document( - length: Annotated[str, "Desired summary length: 'brief', 'medium', or 'detailed'"] = "medium", -) -> str: - """Generate a summary of the uploaded document.""" - return f"Generating {length} summary of the document..." - - -@tool(approval_mode="never_require") -def extract_key_points( - max_points: Annotated[int, "Maximum number of key points to extract"] = 5, -) -> str: - """Extract key points from the uploaded document.""" - return f"Extracting up to {max_points} key points..." - - -# Agent using Azure OpenAI Responses API (supports PDF uploads!) -agent = Agent( - name="AzureResponsesAgent", - description="An agent that can analyze PDFs, images, and other documents using Azure OpenAI Responses API", - instructions=""" - You are a helpful document analysis assistant. You can: - - 1. Analyze uploaded PDF documents and extract information - 2. Summarize document contents - 3. Answer questions about uploaded files - 4. Extract key points and insights - - When a user uploads a file, carefully analyze its contents and provide - helpful, accurate information based on what you find. - - For PDFs, you can read and understand the text, tables, and structure. - For images, you can describe what you see and extract any text. - """, - client=FoundryChatClient( - model=_deployment_name, - endpoint=_endpoint, - api_version="2025-03-01-preview", # Required for Responses API - ), - tools=[summarize_document, extract_key_points], -) - - -def main(): - """Launch the Azure Responses agent in DevUI.""" - from agent_framework_devui import serve - - logging.basicConfig(level=logging.INFO, format="%(message)s") - - logger.info("=" * 60) - logger.info("Starting Azure Responses Agent") - logger.info("=" * 60) - logger.info("") - logger.info("This agent uses the Azure OpenAI Responses API which supports:") - logger.info(" - PDF file uploads") - logger.info(" - Image uploads") - logger.info(" - Audio inputs") - logger.info("") - logger.info("Try uploading a PDF and asking questions about it!") - logger.info("") - logger.info("Required environment variables:") - logger.info(" - AZURE_OPENAI_ENDPOINT") - logger.info(" - FOUNDRY_MODEL") - logger.info(" - AZURE_OPENAI_API_KEY (or use Azure CLI auth)") - logger.info("") - - serve(entities=[agent], port=8090, auto_open=True) - - -if __name__ == "__main__": - main() diff --git a/python/samples/02-agents/devui/foundry_agent/.env.example b/python/samples/02-agents/devui/foundry_agent/.env.example deleted file mode 100644 index bd24359800..0000000000 --- a/python/samples/02-agents/devui/foundry_agent/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -# Azure AI Foundry Configuration -# Get your credentials from Azure AI Foundry portal -# Make sure to run 'az login' before starting devui - -FOUNDRY_PROJECT_ENDPOINT=https://your-project.api.azureml.ms -FOUNDRY_MODEL=gpt-4o diff --git a/python/samples/02-agents/devui/in_memory_mode.py b/python/samples/02-agents/devui/in_memory_mode.py index 9aba93b3e6..13c6c55f5d 100644 --- a/python/samples/02-agents/devui/in_memory_mode.py +++ b/python/samples/02-agents/devui/in_memory_mode.py @@ -20,6 +20,7 @@ from agent_framework import ( ) from agent_framework.devui import serve from agent_framework.foundry import FoundryChatClient +from azure.identity.aio import AzureCliCredential from dotenv import load_dotenv from typing_extensions import Never @@ -80,14 +81,13 @@ def main(): # Create Azure OpenAI chat client client = FoundryChatClient( - api_key=os.environ.get("AZURE_OPENAI_API_KEY"), model=os.environ["FOUNDRY_MODEL"], - endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"), - api_version=os.environ.get("AZURE_OPENAI_API_VERSION", "2024-10-21"), + project_endpoint=os.environ.get("FOUNDRY_PROJECT_ENDPOINT"), + credential=AzureCliCredential(), ) # Create agents - weather_agent = Agent( + weather_assistant = Agent( name="weather-assistant", description="Provides weather information and time", instructions=( @@ -120,7 +120,7 @@ def main(): ) # Collect entities for serving - entities = [weather_agent, simple_agent, basic_workflow] + entities = [weather_assistant, simple_agent, basic_workflow] logger.info("Starting DevUI on http://localhost:8090") logger.info("Entities available:") diff --git a/python/samples/02-agents/devui/main.py b/python/samples/02-agents/devui/main.py new file mode 100644 index 0000000000..1280ad24d4 --- /dev/null +++ b/python/samples/02-agents/devui/main.py @@ -0,0 +1,32 @@ +# Copyright (c) Microsoft. All rights reserved. + +"""Launch DevUI with folder discovery for the samples in this directory. + +This sample demonstrates: +- Loading a shared root `.env` file for the DevUI samples folder +- Starting DevUI in directory discovery mode for this folder +- Using root-level settings as fallbacks for discovered samples +""" + +from pathlib import Path + +from agent_framework.devui import serve +from dotenv import load_dotenv + + +def main() -> None: + """Load the root .env file and launch DevUI with folder discovery.""" + samples_dir = Path(__file__).resolve().parent + + # 1. Load shared defaults for the samples in this folder. + load_dotenv(samples_dir / ".env") + + # 2. Start DevUI and discover entities from this directory. + serve(entities_dir=str(samples_dir), auto_open=True) + + +if __name__ == "__main__": + main() + +# Sample output: +# Starting Agent Framework DevUI on 127.0.0.1:8080 diff --git a/python/samples/02-agents/devui/weather_agent_azure/.env.example b/python/samples/02-agents/devui/weather_agent_azure/.env.example deleted file mode 100644 index 70817b460c..0000000000 --- a/python/samples/02-agents/devui/weather_agent_azure/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -# Azure OpenAI API Configuration -# Get your credentials from Azure Portal - -AZURE_OPENAI_API_KEY=your-azure-openai-api-key-here -AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o -AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com diff --git a/python/samples/02-agents/devui/workflow_agents/.env.example b/python/samples/02-agents/devui/workflow_agents/.env.example deleted file mode 100644 index 1153ab182a..0000000000 --- a/python/samples/02-agents/devui/workflow_agents/.env.example +++ /dev/null @@ -1,7 +0,0 @@ -# Azure OpenAI API Configuration -# Get your credentials from Azure Portal - -AZURE_OPENAI_API_KEY=your-azure-openai-api-key-here -AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o -AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com -AZURE_OPENAI_API_VERSION=2024-10-21 diff --git a/python/samples/02-agents/devui/declarative/__init__.py b/python/samples/02-agents/devui/workflow_declarative/__init__.py similarity index 100% rename from python/samples/02-agents/devui/declarative/__init__.py rename to python/samples/02-agents/devui/workflow_declarative/__init__.py diff --git a/python/samples/02-agents/devui/declarative/workflow.py b/python/samples/02-agents/devui/workflow_declarative/workflow.py similarity index 100% rename from python/samples/02-agents/devui/declarative/workflow.py rename to python/samples/02-agents/devui/workflow_declarative/workflow.py diff --git a/python/samples/02-agents/devui/declarative/workflow.yaml b/python/samples/02-agents/devui/workflow_declarative/workflow.yaml similarity index 100% rename from python/samples/02-agents/devui/declarative/workflow.yaml rename to python/samples/02-agents/devui/workflow_declarative/workflow.yaml diff --git a/python/samples/02-agents/devui/fanout_workflow/__init__.py b/python/samples/02-agents/devui/workflow_fanout/__init__.py similarity index 100% rename from python/samples/02-agents/devui/fanout_workflow/__init__.py rename to python/samples/02-agents/devui/workflow_fanout/__init__.py diff --git a/python/samples/02-agents/devui/fanout_workflow/workflow.py b/python/samples/02-agents/devui/workflow_fanout/workflow.py similarity index 100% rename from python/samples/02-agents/devui/fanout_workflow/workflow.py rename to python/samples/02-agents/devui/workflow_fanout/workflow.py diff --git a/python/samples/02-agents/devui/spam_workflow/__init__.py b/python/samples/02-agents/devui/workflow_spam/__init__.py similarity index 100% rename from python/samples/02-agents/devui/spam_workflow/__init__.py rename to python/samples/02-agents/devui/workflow_spam/__init__.py diff --git a/python/samples/02-agents/devui/spam_workflow/workflow.py b/python/samples/02-agents/devui/workflow_spam/workflow.py similarity index 100% rename from python/samples/02-agents/devui/spam_workflow/workflow.py rename to python/samples/02-agents/devui/workflow_spam/workflow.py diff --git a/python/samples/02-agents/devui/workflow_with_agents/.env.example b/python/samples/02-agents/devui/workflow_with_agents/.env.example new file mode 100644 index 0000000000..520cd181cc --- /dev/null +++ b/python/samples/02-agents/devui/workflow_with_agents/.env.example @@ -0,0 +1,9 @@ +# Azure OpenAI configuration for the Responses-based workflow sample +# This sample uses Azure CLI auth, so run `az login` before starting DevUI. + +AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com +AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME=gpt-4o +# Optional fallback env name also supported by the client: +# AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o +# Optional if you need to override the default API version: +AZURE_OPENAI_API_VERSION=2024-10-21 diff --git a/python/samples/02-agents/devui/workflow_agents/__init__.py b/python/samples/02-agents/devui/workflow_with_agents/__init__.py similarity index 100% rename from python/samples/02-agents/devui/workflow_agents/__init__.py rename to python/samples/02-agents/devui/workflow_with_agents/__init__.py diff --git a/python/samples/02-agents/devui/workflow_agents/workflow.py b/python/samples/02-agents/devui/workflow_with_agents/workflow.py similarity index 93% rename from python/samples/02-agents/devui/workflow_agents/workflow.py rename to python/samples/02-agents/devui/workflow_with_agents/workflow.py index 750b8ac45f..cda57a67f7 100644 --- a/python/samples/02-agents/devui/workflow_agents/workflow.py +++ b/python/samples/02-agents/devui/workflow_with_agents/workflow.py @@ -18,7 +18,8 @@ import os from typing import Any from agent_framework import Agent, AgentExecutorResponse, WorkflowBuilder -from agent_framework.foundry import FoundryChatClient +from agent_framework.openai import OpenAIChatClient +from azure.identity import AzureCliCredential from dotenv import load_dotenv from pydantic import BaseModel @@ -62,8 +63,13 @@ def is_approved(message: Any) -> bool: return True -# Create Azure OpenAI chat client -client = FoundryChatClient(api_key=os.environ.get("AZURE_OPENAI_API_KEY", "")) +# Create Azure OpenAI Responses chat client +client = OpenAIChatClient( + model=os.environ.get("AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME") or os.environ.get("AZURE_OPENAI_DEPLOYMENT_NAME"), + azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"), + api_version=os.environ.get("AZURE_OPENAI_API_VERSION"), + credential=AzureCliCredential(), +) # Create Writer agent - generates content writer = Agent( diff --git a/python/samples/04-hosting/a2a/a2a_agent_as_function_tools.py b/python/samples/04-hosting/a2a/a2a_agent_as_function_tools.py index c219166fc5..ca753f2d42 100644 --- a/python/samples/04-hosting/a2a/a2a_agent_as_function_tools.py +++ b/python/samples/04-hosting/a2a/a2a_agent_as_function_tools.py @@ -48,9 +48,7 @@ async def main() -> None: project_endpoint = os.getenv("FOUNDRY_PROJECT_ENDPOINT") model = os.getenv("FOUNDRY_MODEL") if not project_endpoint or not model: - raise ValueError( - "FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL must be set" - ) + raise ValueError("FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL must be set") print(f"Connecting to A2A agent at: {a2a_agent_host}") diff --git a/python/samples/05-end-to-end/evaluation/foundry_evals/evaluate_tool_calls_sample.py b/python/samples/05-end-to-end/evaluation/foundry_evals/evaluate_tool_calls_sample.py index 4b5d892fe4..50b084606b 100644 --- a/python/samples/05-end-to-end/evaluation/foundry_evals/evaluate_tool_calls_sample.py +++ b/python/samples/05-end-to-end/evaluation/foundry_evals/evaluate_tool_calls_sample.py @@ -48,8 +48,7 @@ async def main() -> None: client=chat_client, name="travel-assistant", instructions=( - "You are a helpful travel assistant. " - "Use your tools to answer questions about weather and flights." + "You are a helpful travel assistant. Use your tools to answer questions about weather and flights." ), tools=[get_weather, get_flight_price], )