Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def get_sample_path_from_marker(request) -> tuple[Path | None, str | None]:

sample_name = marker.args[0]
repo_root = _resolve_repo_root()
sample_path = repo_root / "samples" / "getting_started" / "azure_functions" / sample_name
sample_path = repo_root / "samples" / "durable" / "azure_functions" / sample_name

if not sample_path.exists():
return None, f"Sample directory does not exist: {sample_path}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class TestSingleAgent:
pytest.fail("Test class must have @pytest.mark.sample() marker")

sample_name: str = cast(str, sample_marker.args[0]) # type: ignore[union-attr]
sample_path: Path = Path(__file__).parents[4] / "samples" / "getting_started" / "durabletask" / sample_name
sample_path: Path = Path(__file__).parents[4] / "samples" / "durable" / "console_apps" / sample_name
worker_file: Path = sample_path / "worker.py"

if not worker_file.exists():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from dt_testutils import OrchestrationHelper, create_agent_client

# Add sample directory to path to import RedisStreamResponseHandler
SAMPLE_DIR = Path(__file__).parents[4] / "samples" / "getting_started" / "durabletask" / "03_single_agent_streaming"
SAMPLE_DIR = Path(__file__).parents[4] / "samples" / "durable" / "console_apps" / "03_single_agent_streaming"
sys.path.insert(0, str(SAMPLE_DIR))

from redis_stream_response_handler import RedisStreamResponseHandler # type: ignore[reportMissingImports] # noqa: E402
Expand Down
38 changes: 21 additions & 17 deletions python/samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,32 +242,36 @@ The recommended way to use Ollama is via the native `OllamaChatClient` from the
| [`getting_started/multimodal_input/openai_chat_multimodal.py`](./getting_started/multimodal_input/openai_chat_multimodal.py) | OpenAI Chat with multimodal (image) input example |


## Azure Functions
## Durable

These samples demonstrate durable agent hosting patterns using the Durable Task Scheduler and Azure Functions with Durable Extension.

### Azure Functions

| Sample | Description |
|--------|-------------|
| [`getting_started/azure_functions/01_single_agent/`](./getting_started/azure_functions/01_single_agent/) | Host a single agent in Azure Functions with Durable Extension HTTP endpoints and per-session state. |
| [`getting_started/azure_functions/02_multi_agent/`](./getting_started/azure_functions/02_multi_agent/) | Register multiple agents in one function app with dedicated run routes and a health check endpoint. |
| [`getting_started/azure_functions/03_reliable_streaming/`](./getting_started/azure_functions/03_reliable_streaming/) | Implement reliable streaming for durable agents using Redis Streams with cursor-based resumption. |
| [`getting_started/azure_functions/04_single_agent_orchestration_chaining/`](./getting_started/azure_functions/04_single_agent_orchestration_chaining/) | Chain sequential agent executions inside a durable orchestration while preserving the shared thread context. |
| [`getting_started/azure_functions/05_multi_agent_orchestration_concurrency/`](./getting_started/azure_functions/05_multi_agent_orchestration_concurrency/) | Run two agents concurrently within a durable orchestration and combine their domain-specific outputs. |
| [`getting_started/azure_functions/06_multi_agent_orchestration_conditionals/`](./getting_started/azure_functions/06_multi_agent_orchestration_conditionals/) | Route orchestration logic based on structured agent responses for spam detection and reply drafting. |
| [`getting_started/azure_functions/07_single_agent_orchestration_hitl/`](./getting_started/azure_functions/07_single_agent_orchestration_hitl/) | Implement a human-in-the-loop approval loop that iterates on agent output inside a durable orchestration. |
| [`getting_started/azure_functions/08_mcp_server/`](./getting_started/azure_functions/08_mcp_server/) | Configure agents as both HTTP endpoints and MCP tools for flexible integration patterns. |
| [`durable/azure_functions/01_single_agent/`](./durable/azure_functions/01_single_agent/) | Host a single agent in Azure Functions with Durable Extension HTTP endpoints and per-session state. |
| [`durable/azure_functions/02_multi_agent/`](./durable/azure_functions/02_multi_agent/) | Register multiple agents in one function app with dedicated run routes and a health check endpoint. |
| [`durable/azure_functions/03_reliable_streaming/`](./durable/azure_functions/03_reliable_streaming/) | Implement reliable streaming for durable agents using Redis Streams with cursor-based resumption. |
| [`durable/azure_functions/04_single_agent_orchestration_chaining/`](./durable/azure_functions/04_single_agent_orchestration_chaining/) | Chain sequential agent executions inside a durable orchestration while preserving the shared thread context. |
| [`durable/azure_functions/05_multi_agent_orchestration_concurrency/`](./durable/azure_functions/05_multi_agent_orchestration_concurrency/) | Run two agents concurrently within a durable orchestration and combine their domain-specific outputs. |
| [`durable/azure_functions/06_multi_agent_orchestration_conditionals/`](./durable/azure_functions/06_multi_agent_orchestration_conditionals/) | Route orchestration logic based on structured agent responses for spam detection and reply drafting. |
| [`durable/azure_functions/07_single_agent_orchestration_hitl/`](./durable/azure_functions/07_single_agent_orchestration_hitl/) | Implement a human-in-the-loop approval loop that iterates on agent output inside a durable orchestration. |
| [`durable/azure_functions/08_mcp_server/`](./durable/azure_functions/08_mcp_server/) | Configure agents as both HTTP endpoints and MCP tools for flexible integration patterns. |

## Durable Task
### Console Apps

These samples demonstrate durable agent hosting using the Durable Task Scheduler with a worker-client architecture pattern, enabling distributed agent execution with persistent conversation state.

| Sample | Description |
|--------|-------------|
| [`getting_started/durabletask/01_single_agent/`](./getting_started/durabletask/01_single_agent/) | Host a single conversational agent with worker-client architecture and agent state management. |
| [`getting_started/durabletask/02_multi_agent/`](./getting_started/durabletask/02_multi_agent/) | Host multiple domain-specific agents and route requests based on question topic. |
| [`getting_started/durabletask/03_single_agent_streaming/`](./getting_started/durabletask/03_single_agent_streaming/) | Implement reliable streaming using Redis Streams with cursor-based resumption for durable agents. |
| [`getting_started/durabletask/04_single_agent_orchestration_chaining/`](./getting_started/durabletask/04_single_agent_orchestration_chaining/) | Chain multiple agent invocations using durable orchestration while preserving conversation context. |
| [`getting_started/durabletask/05_multi_agent_orchestration_concurrency/`](./getting_started/durabletask/05_multi_agent_orchestration_concurrency/) | Run multiple agents concurrently within an orchestration and aggregate their responses. |
| [`getting_started/durabletask/06_multi_agent_orchestration_conditionals/`](./getting_started/durabletask/06_multi_agent_orchestration_conditionals/) | Implement conditional branching with spam detection using structured outputs and activity functions. |
| [`getting_started/durabletask/07_single_agent_orchestration_hitl/`](./getting_started/durabletask/07_single_agent_orchestration_hitl/) | Human-in-the-loop pattern with external event handling, timeouts, and iterative refinement. |
| [`durable/console_apps/01_single_agent/`](./durable/console_apps/01_single_agent/) | Host a single conversational agent with worker-client architecture and agent state management. |
| [`durable/console_apps/02_multi_agent/`](./durable/console_apps/02_multi_agent/) | Host multiple domain-specific agents and route requests based on question topic. |
| [`durable/console_apps/03_single_agent_streaming/`](./durable/console_apps/03_single_agent_streaming/) | Implement reliable streaming using Redis Streams with cursor-based resumption for durable agents. |
| [`durable/console_apps/04_single_agent_orchestration_chaining/`](./durable/console_apps/04_single_agent_orchestration_chaining/) | Chain multiple agent invocations using durable orchestration while preserving conversation context. |
| [`durable/console_apps/05_multi_agent_orchestration_concurrency/`](./durable/console_apps/05_multi_agent_orchestration_concurrency/) | Run multiple agents concurrently within an orchestration and aggregate their responses. |
| [`durable/console_apps/06_multi_agent_orchestration_conditionals/`](./durable/console_apps/06_multi_agent_orchestration_conditionals/) | Implement conditional branching with spam detection using structured outputs and activity functions. |
| [`durable/console_apps/07_single_agent_orchestration_hitl/`](./durable/console_apps/07_single_agent_orchestration_hitl/) | Human-in-the-loop pattern with external event handling, timeouts, and iterative refinement. |

## Observability

Expand Down
52 changes: 52 additions & 0 deletions python/samples/durable/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Durable Agent Samples

This directory contains samples demonstrating durable agent hosting patterns for the Microsoft Agent Framework.

## Directory Structure

- **[azure_functions/](./azure_functions/)** - Samples for hosting durable agents in Azure Functions with the Durable Extension
- **[console_apps/](./console_apps/)** - Samples for hosting durable agents using the Durable Task Scheduler in console applications

## Overview

Durable agent hosting enables distributed agent execution with persistent conversation state, orchestration capabilities, and reliable streaming. These patterns are essential for building scalable, production-ready agent applications.

### Azure Functions

The Azure Functions samples demonstrate how to host agents in Azure Functions using the Durable Extension. These samples show HTTP endpoints for agent interaction, durable orchestrations, and integration with Azure services.

Key features:
- HTTP-triggered agent endpoints
- Durable orchestrations for multi-step workflows
- Per-session state management
- Reliable streaming with Redis
- Human-in-the-loop patterns

See the [Azure Functions README](./azure_functions/README.md) for detailed setup instructions.

### Console Apps

The Console Apps samples demonstrate the worker-client architecture pattern using the Durable Task Scheduler. These samples run locally or in any hosting environment that supports Python applications.

Key features:
- Worker-client architecture
- Distributed agent execution
- Persistent conversation state
- Orchestration patterns (chaining, concurrency, conditionals)
- Reliable streaming

See the [Console Apps README](./console_apps/README.md) for detailed setup instructions.

## Getting Started

Each subdirectory contains its own README with specific setup instructions and prerequisites. Both patterns require:

- Python 3.9 or later
- Azure OpenAI Service with a deployed model
- Appropriate durable infrastructure (Durable Task Scheduler or Azure Functions with Durable Extension)

## Related Documentation

- [Durable Task Framework Documentation](https://durabletask.github.io/)
- [Azure Functions Durable Extension](https://learn.microsoft.com/azure/azure-functions/durable/)
- [Agent Framework Documentation](https://aka.ms/agent-framework)
1 change: 1 addition & 0 deletions python/samples/durable/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Copyright (c) Microsoft. All rights reserved.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Update your `local.settings.json` with your Azure OpenAI credentials:

1. **Start the Function App**:
```bash
cd python/samples/getting_started/azure_functions/08_mcp_server
cd python/samples/durable/azure_functions/08_mcp_server
func start
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ With the environment setup, you can run the sample using the combined approach o
**Option 1: Combined (Recommended for Testing)**

```bash
cd samples/getting_started/durabletask/01_single_agent
cd samples/durable/console_apps/01_single_agent
python sample.py
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ With the environment setup, you can run the sample using the combined approach o
**Option 1: Combined (Recommended for Testing)**

```bash
cd samples/getting_started/durabletask/02_multi_agent
cd samples/durable/console_apps/02_multi_agent
python sample.py
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ With the environment setup, you can run the sample using the combined approach o
**Option 1: Combined (Recommended for Testing)**

```bash
cd samples/getting_started/durabletask/03_single_agent_streaming
cd samples/durable/console_apps/03_single_agent_streaming
python sample.py
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ With the environment setup, you can run the sample using the combined approach o
**Option 1: Combined (Recommended for Testing)**

```bash
cd samples/getting_started/durabletask/04_single_agent_orchestration_chaining
cd samples/durable/console_apps/04_single_agent_orchestration_chaining
python sample.py
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ With the environment setup, you can run the sample using the combined approach o
**Option 1: Combined (Recommended for Testing)**

```bash
cd samples/getting_started/durabletask/05_multi_agent_orchestration_concurrency
cd samples/durable/console_apps/05_multi_agent_orchestration_concurrency
python sample.py
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ With the environment setup, you can run the sample using the combined approach o
**Option 1: Combined (Recommended for Testing)**

```bash
cd samples/getting_started/durabletask/06_multi_agent_orchestration_conditionals
cd samples/durable/console_apps/06_multi_agent_orchestration_conditionals
python sample.py
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ With the environment setup, you can run the sample using the combined approach o
**Option 1: Combined (Recommended for Testing)**

```bash
cd samples/getting_started/durabletask/07_single_agent_orchestration_hitl
cd samples/durable/console_apps/07_single_agent_orchestration_hitl
python sample.py
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ $env:AZURE_OPENAI_CHAT_DEPLOYMENT_NAME="your-deployment-name"
Navigate to the sample directory and install dependencies. For example:

```bash
cd samples/getting_started/durabletask/01_single_agent
cd samples/durable/console_apps/01_single_agent
pip install -r requirements.txt
```

Expand Down