diff --git a/dotnet/agent-framework-dotnet.slnx b/dotnet/agent-framework-dotnet.slnx
index aee9bdb1f6..80660c78b3 100644
--- a/dotnet/agent-framework-dotnet.slnx
+++ b/dotnet/agent-framework-dotnet.slnx
@@ -18,6 +18,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/samples/AzureFunctions/.editorconfig b/dotnet/samples/AzureFunctions/.editorconfig
new file mode 100644
index 0000000000..b43bf5ebd0
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/.editorconfig
@@ -0,0 +1,10 @@
+# .editorconfig
+[*.cs]
+
+# See https://github.com/Azure/azure-functions-durable-extension/issues/3173
+dotnet_diagnostic.DURABLE0001.severity = none
+dotnet_diagnostic.DURABLE0002.severity = none
+dotnet_diagnostic.DURABLE0003.severity = none
+dotnet_diagnostic.DURABLE0004.severity = none
+dotnet_diagnostic.DURABLE0005.severity = none
+dotnet_diagnostic.DURABLE0006.severity = none
diff --git a/dotnet/samples/AzureFunctions/01_SingleAgent/01_SingleAgent.csproj b/dotnet/samples/AzureFunctions/01_SingleAgent/01_SingleAgent.csproj
new file mode 100644
index 0000000000..bce1b96f7b
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/01_SingleAgent/01_SingleAgent.csproj
@@ -0,0 +1,42 @@
+
+
+ net9.0
+ v4
+ Exe
+ enable
+ enable
+
+ SingleAgent
+ SingleAgent
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/samples/AzureFunctions/01_SingleAgent/Program.cs b/dotnet/samples/AzureFunctions/01_SingleAgent/Program.cs
new file mode 100644
index 0000000000..ebb5082893
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/01_SingleAgent/Program.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Azure;
+using Azure.AI.OpenAI;
+using Azure.Identity;
+using Microsoft.Agents.AI;
+using Microsoft.Agents.AI.Hosting.AzureFunctions;
+using Microsoft.Azure.Functions.Worker.Builder;
+using Microsoft.Extensions.Hosting;
+using OpenAI;
+
+// Get the Azure OpenAI endpoint and deployment name from environment variables.
+string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
+ ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
+string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
+ ?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT is not set.");
+
+// Use Azure Key Credential if provided, otherwise use Azure CLI Credential.
+string? azureOpenAiKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY");
+AzureOpenAIClient client = !string.IsNullOrEmpty(azureOpenAiKey)
+ ? new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(azureOpenAiKey))
+ : new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential());
+
+// Set up an AI agent following the standard Microsoft Agent Framework pattern.
+const string JokerName = "Joker";
+const string JokerInstructions = "You are good at telling jokes.";
+
+AIAgent agent = client.GetChatClient(deploymentName).CreateAIAgent(JokerInstructions, JokerName);
+
+// Configure the function app to host the AI agent.
+// This will automatically generate HTTP API endpoints for the agent.
+using IHost app = FunctionsApplication
+ .CreateBuilder(args)
+ .ConfigureFunctionsWebApplication()
+ .ConfigureDurableAgents(options => options.AddAIAgent(agent))
+ .Build();
+app.Run();
diff --git a/dotnet/samples/AzureFunctions/01_SingleAgent/README.md b/dotnet/samples/AzureFunctions/01_SingleAgent/README.md
new file mode 100644
index 0000000000..b0fea90795
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/01_SingleAgent/README.md
@@ -0,0 +1,42 @@
+# Single Agent Sample
+
+This sample demonstrates how to use the Durable Agent Framework (DAFx) 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
+
+- Using the Microsoft Agent Framework to define a simple AI agent with a name and instructions.
+- Registering agents with the Function app and running them using HTTP.
+- Conversation management (via session IDs) for isolated interactions.
+
+## Environment Setup
+
+See the [README.md](../README.md) file in the parent directory for more information on how to configure the environment, including how to install and run common sample dependencies.
+
+## Running the Sample
+
+With the environment setup and function app running, you can test the sample by sending an HTTP request to the agent endpoint.
+
+You can use the `demo.http` file to send a message to the agent, or a command line tool like `curl` as shown below:
+
+Bash (Linux/macOS/WSL):
+
+```bash
+curl -X POST http://localhost:7071/api/agents/Joker/run \
+ -H "Content-Type: text/plain" \
+ -d "Tell me a joke about a pirate."
+```
+
+PowerShell:
+
+```powershell
+Invoke-RestMethod -Method Post `
+ -Uri http://localhost:7071/api/agents/Joker/run `
+ -ContentType text/plain `
+ -Body "Tell me a joke about a pirate."
+```
+
+The response from the agent will be displayed in the terminal where you ran `func start`. The expected output will look something like:
+
+```text
+Why don't pirates ever learn the alphabet? Because they always get stuck at "C"!
+```
diff --git a/dotnet/samples/AzureFunctions/01_SingleAgent/demo.http b/dotnet/samples/AzureFunctions/01_SingleAgent/demo.http
new file mode 100644
index 0000000000..3b741adf31
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/01_SingleAgent/demo.http
@@ -0,0 +1,8 @@
+# Default endpoint address for local testing
+@authority=http://localhost:7071
+
+### Prompt the agent
+POST {{authority}}/api/agents/Joker/run
+Content-Type: text/plain
+
+Tell me a joke about a pirate.
diff --git a/dotnet/samples/AzureFunctions/01_SingleAgent/host.json b/dotnet/samples/AzureFunctions/01_SingleAgent/host.json
new file mode 100644
index 0000000000..9bef705c04
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/01_SingleAgent/host.json
@@ -0,0 +1,20 @@
+{
+ "version": "2.0",
+ "logging": {
+ "logLevel": {
+ "Microsoft.Agents.AI.DurableTask": "Information",
+ "Microsoft.Agents.AI.Hosting.AzureFunctions": "Information",
+ "DurableTask": "Information",
+ "Microsoft.DurableTask": "Information"
+ }
+ },
+ "extensions": {
+ "durableTask": {
+ "hubName": "default",
+ "storageProvider": {
+ "type": "AzureManaged",
+ "connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/dotnet/samples/AzureFunctions/01_SingleAgent/local.settings.json b/dotnet/samples/AzureFunctions/01_SingleAgent/local.settings.json
new file mode 100644
index 0000000000..3411463ac4
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/01_SingleAgent/local.settings.json
@@ -0,0 +1,10 @@
+{
+ "IsEncrypted": false,
+ "Values": {
+ "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
+ "AzureWebJobsStorage": "UseDevelopmentStorage=true",
+ "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
+ "AZURE_OPENAI_ENDPOINT": "",
+ "AZURE_OPENAI_DEPLOYMENT": ""
+ }
+}
\ No newline at end of file
diff --git a/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/02_AgentOrchestration_Chaining.csproj b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/02_AgentOrchestration_Chaining.csproj
new file mode 100644
index 0000000000..4ec460450a
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/02_AgentOrchestration_Chaining.csproj
@@ -0,0 +1,42 @@
+
+
+ net9.0
+ v4
+ Exe
+ enable
+ enable
+
+ AgentOrchestration_Chaining
+ AgentOrchestration_Chaining
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/FunctionTriggers.cs b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/FunctionTriggers.cs
new file mode 100644
index 0000000000..a631e7715c
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/FunctionTriggers.cs
@@ -0,0 +1,92 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Net;
+using System.Text.Json;
+using Microsoft.Agents.AI;
+using Microsoft.Agents.AI.DurableTask;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Azure.Functions.Worker.Http;
+using Microsoft.DurableTask;
+using Microsoft.DurableTask.Client;
+
+namespace AgentOrchestration_Chaining;
+
+public static class FunctionTriggers
+{
+ public sealed record TextResponse(string Text);
+
+ [Function(nameof(RunOrchestrationAsync))]
+ public static async Task RunOrchestrationAsync([OrchestrationTrigger] TaskOrchestrationContext context)
+ {
+ DurableAIAgent writer = context.GetAgent("WriterAgent");
+ AgentThread writerThread = writer.GetNewThread();
+
+ AgentRunResponse initial = await writer.RunAsync(
+ message: "Write a concise inspirational sentence about learning.",
+ thread: writerThread);
+
+ AgentRunResponse refined = await writer.RunAsync(
+ message: $"Improve this further while keeping it under 25 words: {initial.Result.Text}",
+ thread: writerThread);
+
+ return refined.Result.Text;
+ }
+
+ // POST /singleagent/run
+ [Function(nameof(StartOrchestrationAsync))]
+ public static async Task StartOrchestrationAsync(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "singleagent/run")] HttpRequestData req,
+ [DurableClient] DurableTaskClient client)
+ {
+ string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
+ orchestratorName: nameof(RunOrchestrationAsync));
+
+ HttpResponseData response = req.CreateResponse(HttpStatusCode.Accepted);
+ await response.WriteAsJsonAsync(new
+ {
+ message = "Single-agent orchestration started.",
+ instanceId,
+ statusQueryGetUri = GetStatusQueryGetUri(req, instanceId),
+ });
+ return response;
+ }
+
+ // GET /singleagent/status/{instanceId}
+ [Function(nameof(GetOrchestrationStatusAsync))]
+ public static async Task GetOrchestrationStatusAsync(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "singleagent/status/{instanceId}")] HttpRequestData req,
+ string instanceId,
+ [DurableClient] DurableTaskClient client)
+ {
+ OrchestrationMetadata? status = await client.GetInstanceAsync(
+ instanceId,
+ getInputsAndOutputs: true,
+ req.FunctionContext.CancellationToken);
+
+ if (status is null)
+ {
+ HttpResponseData notFound = req.CreateResponse(HttpStatusCode.NotFound);
+ await notFound.WriteAsJsonAsync(new { error = "Instance not found" });
+ return notFound;
+ }
+
+ HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
+ await response.WriteAsJsonAsync(new
+ {
+ instanceId = status.InstanceId,
+ runtimeStatus = status.RuntimeStatus.ToString(),
+ input = status.SerializedInput is not null ? (object)status.ReadInputAs() : null,
+ output = status.SerializedOutput is not null ? (object)status.ReadOutputAs() : null,
+ failureDetails = status.FailureDetails
+ });
+ return response;
+ }
+
+ private static string GetStatusQueryGetUri(HttpRequestData req, string instanceId)
+ {
+ // NOTE: This can be made more robust by considering the value of
+ // request headers like "X-Forwarded-Host" and "X-Forwarded-Proto".
+ string authority = $"{req.Url.Scheme}://{req.Url.Authority}";
+ return $"{authority}/api/singleagent/status/{instanceId}";
+ }
+}
diff --git a/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/Program.cs b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/Program.cs
new file mode 100644
index 0000000000..14abd390c9
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/Program.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Azure;
+using Azure.AI.OpenAI;
+using Azure.Identity;
+using Microsoft.Agents.AI;
+using Microsoft.Agents.AI.Hosting.AzureFunctions;
+using Microsoft.Azure.Functions.Worker.Builder;
+using Microsoft.Extensions.Hosting;
+using OpenAI;
+
+// Get the Azure OpenAI endpoint and deployment name from environment variables.
+string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
+ ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
+string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT")
+ ?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT is not set.");
+
+// Use Azure Key Credential if provided, otherwise use Azure CLI Credential.
+string? azureOpenAiKey = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY");
+AzureOpenAIClient client = !string.IsNullOrEmpty(azureOpenAiKey)
+ ? new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(azureOpenAiKey))
+ : new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential());
+
+// Single agent used by the orchestration to demonstrate sequential calls on the same thread.
+const string WriterName = "WriterAgent";
+const string WriterInstructions =
+ """
+ You refine short pieces of text. When given an initial sentence you enhance it;
+ when given an improved sentence you polish it further.
+ """;
+
+AIAgent writerAgent = client.GetChatClient(deploymentName).CreateAIAgent(WriterInstructions, WriterName);
+
+using IHost app = FunctionsApplication
+ .CreateBuilder(args)
+ .ConfigureFunctionsWebApplication()
+ .ConfigureDurableAgents(options => options.AddAIAgent(writerAgent))
+ .Build();
+
+app.Run();
diff --git a/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/README.md b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/README.md
new file mode 100644
index 0000000000..e98885eced
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/README.md
@@ -0,0 +1,59 @@
+# Single Agent Orchestration Sample
+
+This sample demonstrates how to use the Durable Agent Framework (DAFx) to create a simple Azure Functions app that orchestrates sequential calls to a single AI agent using the same conversation thread for context continuity.
+
+## Key Concepts Demonstrated
+
+- Orchestrating multiple interactions with the same agent in a deterministic order
+- Using the same `AgentThread` across multiple calls to maintain conversational context
+- Durable orchestration with automatic checkpointing and resumption from failures
+- HTTP API integration for starting and monitoring orchestrations
+
+## Environment Setup
+
+See the [README.md](../README.md) file in the parent directory for more information on how to configure the environment, including how to install and run common sample dependencies.
+
+## Running the Sample
+
+With the environment setup and function app running, you can test the sample by sending an HTTP request to start the orchestration.
+
+You can use the `demo.http` file to start the orchestration, or a command line tool like `curl` as shown below:
+
+Bash (Linux/macOS/WSL):
+
+```bash
+curl -X POST http://localhost:7071/api/singleagent/run
+```
+
+PowerShell:
+
+```powershell
+Invoke-RestMethod -Method Post -Uri http://localhost:7071/api/singleagent/run
+```
+
+The response will be a JSON object that looks something like the following, which indicates that the orchestration has started.
+
+```json
+{
+ "message": "Single-agent orchestration started.",
+ "instanceId": "86313f1d45fb42eeb50b1852626bf3ff",
+ "statusQueryGetUri": "http://localhost:7071/api/singleagent/status/86313f1d45fb42eeb50b1852626bf3ff"
+}
+```
+
+The orchestration will proceed to run the WriterAgent twice in sequence:
+
+1. First, it writes an inspirational sentence about learning
+2. Then, it refines the initial output using the same conversation thread
+
+Once the orchestration has completed, you can get the status of the orchestration by sending a GET request to the `statusQueryGetUri` URL. The response will be a JSON object that looks something like the following:
+
+```json
+{
+ "failureDetails": null,
+ "input": null,
+ "instanceId": "86313f1d45fb42eeb50b1852626bf3ff",
+ "output": "Learning serves as the key, opening doors to boundless opportunities and a brighter future.",
+ "runtimeStatus": "Completed"
+}
+```
diff --git a/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/demo.http b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/demo.http
new file mode 100644
index 0000000000..aa4dcc4a16
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/demo.http
@@ -0,0 +1,3 @@
+### Start the single-agent orchestration
+POST http://localhost:7071/api/singleagent/run
+
diff --git a/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/host.json b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/host.json
new file mode 100644
index 0000000000..9384a0a583
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/host.json
@@ -0,0 +1,20 @@
+{
+ "version": "2.0",
+ "logging": {
+ "logLevel": {
+ "Microsoft.Agents.AI.DurableTask": "Information",
+ "Microsoft.Agents.AI.Hosting.AzureFunctions": "Information",
+ "DurableTask": "Information",
+ "Microsoft.DurableTask": "Information"
+ }
+ },
+ "extensions": {
+ "durableTask": {
+ "hubName": "default",
+ "storageProvider": {
+ "type": "AzureManaged",
+ "connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
+ }
+ }
+ }
+}
diff --git a/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/local.settings.json b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/local.settings.json
new file mode 100644
index 0000000000..54dfbb5664
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/02_AgentOrchestration_Chaining/local.settings.json
@@ -0,0 +1,10 @@
+{
+ "IsEncrypted": false,
+ "Values": {
+ "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
+ "AzureWebJobsStorage": "UseDevelopmentStorage=true",
+ "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None",
+ "AZURE_OPENAI_ENDPOINT": "",
+ "AZURE_OPENAI_DEPLOYMENT": ""
+ }
+}
diff --git a/dotnet/samples/AzureFunctions/03_AgentOrchestration_Concurrency/03_AgentOrchestration_Concurrency.csproj b/dotnet/samples/AzureFunctions/03_AgentOrchestration_Concurrency/03_AgentOrchestration_Concurrency.csproj
new file mode 100644
index 0000000000..8698b0a7b8
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/03_AgentOrchestration_Concurrency/03_AgentOrchestration_Concurrency.csproj
@@ -0,0 +1,42 @@
+
+
+ net9.0
+ v4
+ Exe
+ enable
+ enable
+
+ AgentOrchestration_Concurrency
+ AgentOrchestration_Concurrency
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dotnet/samples/AzureFunctions/03_AgentOrchestration_Concurrency/FunctionTriggers.cs b/dotnet/samples/AzureFunctions/03_AgentOrchestration_Concurrency/FunctionTriggers.cs
new file mode 100644
index 0000000000..2d15dd585c
--- /dev/null
+++ b/dotnet/samples/AzureFunctions/03_AgentOrchestration_Concurrency/FunctionTriggers.cs
@@ -0,0 +1,116 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using System.Net;
+using System.Text.Json;
+using Microsoft.Agents.AI;
+using Microsoft.Agents.AI.DurableTask;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Azure.Functions.Worker.Http;
+using Microsoft.DurableTask;
+using Microsoft.DurableTask.Client;
+
+namespace AgentOrchestration_Concurrency;
+
+public static class FunctionsTriggers
+{
+ public sealed record TextResponse(string Text);
+
+ [Function(nameof(RunOrchestrationAsync))]
+ public static async Task