Compare commits

...
Author SHA1 Message Date
Shyju Krishnankutty b5e4553f05 WIP 2026-02-12 16:28:24 -08:00
Shyju Krishnankutty 310d1b8e10 Adding azure functions support 2026-02-12 14:49:48 -08:00
Shyju KrishnankuttyandGitHub e8d0bd9051 .NET: [Feature Branch] Add basic durable workflow support (#3648)
* Add basic durable workflow support.

* PR feedback fixes

* Add conditional edge sample.

* PR feedback fixes.

* Minor cleanup.

* Minor cleanup

* Minor formatting improvements.

* Improve comments/documentation on the execution flow.
2026-02-06 16:02:42 -08:00
Dmytro StrukandGitHub 98cd72839e Update readme (#3576)
* Updated README.md

* More updates
2026-02-02 16:24:31 +00:00
Evan MattsonandGitHub 184ee9d518 Fix AzureAIAgentClient dropping agent instructions in sequential workflows (#3563)
In _prepare_options(), the 'instructions' key was excluded from run_options
but never re-added. This caused instructions passed via as_agent(instructions=...)
to be silently dropped, making agents in sequential workflows ignore their
configured instructions.

Fixes #3507
2026-02-01 09:05:35 +00:00
Rishabh ChawlaandGitHub 2f7250fe0f Python: Add tests to Purview Package (#3513)
* Add tests to increase code coverage

* Add tests to increase code coverage
2026-01-30 23:08:39 +00:00
Dmytro StrukandGitHub 493891620d Python: Replaced obsolete create_response method in samples (#3542)
* Replaced obsolete create_response method in samples

* Addressed PR comments
2026-01-30 22:22:00 +00:00
Giles OdigweandGitHub f3e0be9555 Python: Disable mem0 telemetry by default (#3506)
* disable mem0 telemetry by default

* test fix

* addressed comments
2026-01-30 21:17:52 +00:00
Dmytro StrukandGitHub 8b475afe17 Python: Add BaseAgent implementation for Claude Agent SDK (#3509)
* Added ClaudeAgent implementation

* Updated streaming logic

* Small updates

* Small update

* Fixes

* Small fix

* Naming improvements

* Updated imports

* Addressed comments

* Updated package versions
2026-01-30 18:11:41 +00:00
Tao ChenandGitHub 0fcf075ea7 Python: Add sample on how to share a thread between agents in a workflow (#3405)
* Add sample on how to share a thread between agents in a workflow

* Fix sample

* Fix formatting

* Comments

* comment
2026-01-30 18:07:58 +00:00
ff7041b990 .NET: Workflows - Support fidelity when converting to and from ChatMessage in declarative workflows (#3505)
* Builds locally and tests pass

* Fix typo

* Updated

* Updated

* Fixed tests failing on net472 but not on dotnet10

---------

Co-authored-by: Chris Rickman <crickman@microsoft.com>
2026-01-30 17:14:24 +00:00
CopilotGitHubrogerbarretocopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
924211a518 .Net: Update Anthropic and Anthropic.Foundry package versions (#3517)
* Initial plan

* Update Anthropic packages to v12.3.0 and Anthropic.Foundry to v0.4.1

Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>

* Fix AnthropicClient not being disposed in sample

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
2026-01-30 16:48:19 +00:00
Laveesh RohraandGitHub cd7661bbb7 Python: Fix dependencies for durabletask (#3493)
* Fix dependencies

* Use local packages

* fix typing
2026-01-30 16:38:49 +00:00
Tao ChenandGitHub 0a0de4ac21 Python: Add coverage threshold gate for PR checks (#3392) (#3510)
* Python: Add coverage threshold gate for PR checks (#3392)

- Add python-check-coverage.py script to enforce coverage threshold on specific modules
- Modify python-test-coverage.yml to run coverage check after tests
- Initial enforced module: agent_framework_azure_ai at 85% threshold
- Other modules are reported for visibility but don't block merges

* Fail if module not found

* Force unit test job to run

* Comment 1

* Fix coverage check to use full package paths for submodule support

* Update report format
2026-01-29 23:58:52 +00:00
Shyju KrishnankuttyandGitHub 96f30bdf57 .NET: Consolidate durable agent samples into Durable/Agents folder (#3471)
* Durable samples reorganization.

* Add local.settings.json

* Fix broken link in samples root markdown file.

* Add a link for console app samples.

* Fixed samples path in integration test.

* Fix consols app test path.
2026-01-29 23:15:14 +00:00
Giles OdigweandGitHub e5cddecf04 Python: Add core types and agents unit tests (#3470)
* Add core types and agents unit tests to improve coverage (#3356)

* Address PR comments: move imports to top, fix naming (schema->scheme)

* fix failing test

* improved agents coverage
2026-01-29 19:50:13 +00:00
Giles OdigweandGitHub 81a317714f Python: Add core utilities unit tests (#3487)
* Add core utilities unit tests to improve coverage (#3356)

* Address PR comments: remove redundant imports and fix misleading test

* Refactor tests to use module-level mock class instead of inline classes

* Remove unnecessary tests for trivial base class implementations

* Restore base class tests with module-level helper class
2026-01-29 18:35:00 +00:00
Giles OdigweandGitHub d418794b1e Python: Add observability unit tests to improve coverage (#3469)
* Add observability unit tests to improve coverage from 72% to 86% (#3356)

* Address PR review comments for observability tests
2026-01-29 18:33:39 +00:00
Giles OdigweandGitHub f6c4e078ec Python: Improved AzureAI Package Test Coverage (#3452)
* improved azureai test coverage

* small fix

* fix failing tests
2026-01-29 18:32:53 +00:00
Laveesh RohraandGitHub 474b31393d Update durabletask package (#3492) 2026-01-28 21:41:37 +00:00
Eduard van ValkenburgandGitHub 1226828ec2 Python: added generic types to ChatOptions and ChatResponse/AgentResponse for Response Format (#3305)
* added generic types to ChatOptions and ChatResponse/AgentResponse for response format

* fix typevar import

* fix for older python versions

* fix missing import

* fixed imports

* fixed mypy

* mypy fix
2026-01-28 21:23:02 +00:00
336 changed files with 15351 additions and 1430 deletions
+266
View File
@@ -0,0 +1,266 @@
#!/usr/bin/env python3
# Copyright (c) Microsoft. All rights reserved.
"""Check Python test coverage against threshold for enforced modules.
This script parses a Cobertura XML coverage report and enforces a minimum
coverage threshold on specific modules. Non-enforced modules are reported
for visibility but don't block the build.
Usage:
python python-check-coverage.py <coverage-xml-path> <threshold>
Example:
python python-check-coverage.py python-coverage.xml 85
"""
import sys
import xml.etree.ElementTree as ET
from dataclasses import dataclass
# =============================================================================
# ENFORCED MODULES CONFIGURATION
# =============================================================================
# Add or remove modules from this set to control which packages must meet
# the coverage threshold. Only these modules will fail the build if below
# threshold. Other modules are reported for visibility only.
#
# Module paths should match the package paths as they appear in the coverage
# report (e.g., "packages.azure-ai.agent_framework_azure_ai" for packages/azure-ai).
# Sub-modules can be included by specifying their full path.
# =============================================================================
ENFORCED_MODULES: set[str] = {
"packages.azure-ai.agent_framework_azure_ai",
# Add more modules here as coverage improves:
# "packages.core.agent_framework",
# "packages.core.agent_framework._workflows",
# "packages.anthropic.agent_framework_anthropic",
}
@dataclass
class PackageCoverage:
"""Coverage data for a single package."""
name: str
line_rate: float
branch_rate: float
lines_valid: int
lines_covered: int
branches_valid: int
branches_covered: int
@property
def line_coverage_percent(self) -> float:
"""Return line coverage as a percentage."""
return self.line_rate * 100
@property
def branch_coverage_percent(self) -> float:
"""Return branch coverage as a percentage."""
return self.branch_rate * 100
def parse_coverage_xml(xml_path: str) -> tuple[dict[str, PackageCoverage], float, float]:
"""Parse Cobertura XML and extract per-package coverage data.
Args:
xml_path: Path to the Cobertura XML coverage report.
Returns:
A tuple of (packages_dict, overall_line_rate, overall_branch_rate).
"""
tree = ET.parse(xml_path)
root = tree.getroot()
# Get overall coverage from root element
overall_line_rate = float(root.get("line-rate", 0))
overall_branch_rate = float(root.get("branch-rate", 0))
packages: dict[str, PackageCoverage] = {}
for package in root.findall(".//package"):
package_path = package.get("name", "unknown")
line_rate = float(package.get("line-rate", 0))
branch_rate = float(package.get("branch-rate", 0))
# Count lines and branches from classes within this package
lines_valid = 0
lines_covered = 0
branches_valid = 0
branches_covered = 0
for class_elem in package.findall(".//class"):
for line in class_elem.findall(".//line"):
lines_valid += 1
if int(line.get("hits", 0)) > 0:
lines_covered += 1
# Branch coverage from line elements
if line.get("branch") == "true":
condition_coverage = line.get("condition-coverage", "")
if condition_coverage:
# Parse "X% (covered/total)" format
try:
coverage_parts = condition_coverage.split("(")[1].rstrip(")").split("/")
branches_covered += int(coverage_parts[0])
branches_valid += int(coverage_parts[1])
except (IndexError, ValueError):
# Ignore malformed condition-coverage strings; treat this line as having no branch data.
pass
# Use full package path as the key (no aggregation)
packages[package_path] = PackageCoverage(
name=package_path,
line_rate=line_rate if lines_valid == 0 else lines_covered / lines_valid,
branch_rate=branch_rate if branches_valid == 0 else branches_covered / branches_valid,
lines_valid=lines_valid,
lines_covered=lines_covered,
branches_valid=branches_valid,
branches_covered=branches_covered,
)
return packages, overall_line_rate, overall_branch_rate
def format_coverage_value(coverage: float, threshold: float, is_enforced: bool) -> str:
"""Format a coverage value with optional pass/fail indicator.
Args:
coverage: Coverage percentage (0-100).
threshold: Minimum required coverage percentage.
is_enforced: Whether this module is enforced.
Returns:
Formatted string like "85.5%" or "85.5% ✅" or "75.0% ❌".
"""
formatted = f"{coverage:.1f}%"
if is_enforced:
icon = "✅" if coverage >= threshold else "❌"
formatted = f"{formatted} {icon}"
return formatted
def print_coverage_table(
packages: dict[str, PackageCoverage],
threshold: float,
overall_line_rate: float,
overall_branch_rate: float,
) -> None:
"""Print a formatted coverage summary table.
Args:
packages: Dictionary of package name to coverage data.
threshold: Minimum required coverage percentage.
overall_line_rate: Overall line coverage rate (0-1).
overall_branch_rate: Overall branch coverage rate (0-1).
"""
print("\n" + "=" * 80)
print("PYTHON TEST COVERAGE REPORT")
print("=" * 80)
# Overall coverage
print(f"\nOverall Line Coverage: {overall_line_rate * 100:.1f}%")
print(f"Overall Branch Coverage: {overall_branch_rate * 100:.1f}%")
print(f"Threshold: {threshold}%")
# Package table
print("\n" + "-" * 110)
print(f"{'Package':<80} {'Lines':<15} {'Line Cov':<15}")
print("-" * 110)
# Sort: enforced modules first, then alphabetically
sorted_packages = sorted(
packages.values(),
key=lambda p: (p.name not in ENFORCED_MODULES, p.name),
)
for pkg in sorted_packages:
is_enforced = pkg.name in ENFORCED_MODULES
enforced_marker = "[ENFORCED] " if is_enforced else ""
line_cov = format_coverage_value(pkg.line_coverage_percent, threshold, is_enforced)
lines_info = f"{pkg.lines_covered}/{pkg.lines_valid}"
package_label = f"{enforced_marker}{pkg.name}"
print(f"{package_label:<80} {lines_info:<15} {line_cov:<15}")
print("-" * 110)
def check_coverage(xml_path: str, threshold: float) -> bool:
"""Check if all enforced modules meet the coverage threshold.
Args:
xml_path: Path to the Cobertura XML coverage report.
threshold: Minimum required coverage percentage.
Returns:
True if all enforced modules pass, False otherwise.
"""
packages, overall_line_rate, overall_branch_rate = parse_coverage_xml(xml_path)
print_coverage_table(packages, threshold, overall_line_rate, overall_branch_rate)
# Check enforced modules
failed_modules: list[str] = []
missing_modules: list[str] = []
for module_name in ENFORCED_MODULES:
if module_name not in packages:
missing_modules.append(module_name)
continue
pkg = packages[module_name]
if pkg.line_coverage_percent < threshold:
failed_modules.append(f"{module_name} ({pkg.line_coverage_percent:.1f}%)")
# Report results
if missing_modules:
print(f"\n❌ FAILED: Enforced modules not found in coverage report: {', '.join(missing_modules)}")
return False
if failed_modules:
print(f"\n❌ FAILED: The following enforced modules are below {threshold}% coverage threshold:")
for module in failed_modules:
print(f" - {module}")
print("\nTo fix: Add more tests to improve coverage for the failing modules.")
return False
if ENFORCED_MODULES:
found_enforced = [m for m in ENFORCED_MODULES if m in packages]
if found_enforced:
print(f"\nâś… PASSED: All enforced modules meet the {threshold}% coverage threshold.")
return True
def main() -> int:
"""Main entry point.
Returns:
Exit code: 0 for success, 1 for failure.
"""
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <coverage-xml-path> <threshold>")
print(f"Example: {sys.argv[0]} python-coverage.xml 85")
return 1
xml_path = sys.argv[1]
try:
threshold = float(sys.argv[2])
except ValueError:
print(f"Error: Invalid threshold value: {sys.argv[2]}")
return 1
try:
success = check_coverage(xml_path, threshold)
return 0 if success else 1
except FileNotFoundError:
print(f"Error: Coverage file not found: {xml_path}")
return 1
except ET.ParseError as e:
print(f"Error: Failed to parse coverage XML: {e}")
return 1
if __name__ == "__main__":
sys.exit(main())
@@ -9,6 +9,8 @@ on:
env:
# Configure a constant location for the uv cache
UV_CACHE_DIR: /tmp/.uv-cache
# Coverage threshold percentage for enforced modules
COVERAGE_THRESHOLD: 85
jobs:
python-tests-coverage:
@@ -37,6 +39,8 @@ jobs:
UV_CACHE_DIR: /tmp/.uv-cache
- name: Run all tests with coverage report
run: uv run poe all-tests-cov --cov-report=xml:python-coverage.xml -q --junitxml=pytest.xml
- name: Check coverage threshold
run: python ${{ github.workspace }}/.github/workflows/python-check-coverage.py python-coverage.xml ${{ env.COVERAGE_THRESHOLD }}
- name: Upload coverage report
uses: actions/upload-artifact@v6
with:
+3 -3
View File
@@ -108,7 +108,7 @@ async def main():
# api_version=os.environ["AZURE_OPENAI_API_VERSION"],
# api_key=os.environ["AZURE_OPENAI_API_KEY"], # Optional if using AzureCliCredential
credential=AzureCliCredential(), # Optional, if using api_key
).create_agent(
).as_agent(
name="HaikuBot",
instructions="You are an upbeat assistant that writes beautifully.",
)
@@ -131,7 +131,7 @@ using OpenAI;
// Replace the <apikey> with your OpenAI API key.
var agent = new OpenAIClient("<apikey>")
.GetOpenAIResponseClient("gpt-4o-mini")
.CreateAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
.AsAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
Console.WriteLine(await agent.RunAsync("Write a haiku about Microsoft Agent Framework."));
```
@@ -150,7 +150,7 @@ var agent = new OpenAIClient(
new BearerTokenPolicy(new AzureCliCredential(), "https://ai.azure.com/.default"),
new OpenAIClientOptions() { Endpoint = new Uri("https://<resource>.openai.azure.com/openai/v1") })
.GetOpenAIResponseClient("gpt-4o-mini")
.CreateAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
.AsAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
Console.WriteLine(await agent.RunAsync("Write a haiku about Microsoft Agent Framework."));
```
+8 -8
View File
@@ -11,8 +11,8 @@
</PropertyGroup>
<ItemGroup>
<!-- Aspire.* -->
<PackageVersion Include="Anthropic" Version="12.0.1" />
<PackageVersion Include="Anthropic.Foundry" Version="0.1.0" />
<PackageVersion Include="Anthropic" Version="12.3.0" />
<PackageVersion Include="Anthropic.Foundry" Version="0.4.1" />
<PackageVersion Include="Aspire.Azure.AI.OpenAI" Version="13.0.0-preview.1.25560.3" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireAppHostSdkVersion)" />
<PackageVersion Include="Aspire.Hosting.Azure.CognitiveServices" Version="$(AspireAppHostSdkVersion)" />
@@ -42,7 +42,7 @@
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="10.0.2" />
<PackageVersion Include="System.Linq.AsyncEnumerable" Version="10.0.0" />
<PackageVersion Include="System.Net.Http.Json" Version="10.0.0" />
<PackageVersion Include="System.Net.ServerSentEvents" Version="10.0.0" />
<PackageVersion Include="System.Net.ServerSentEvents" Version="10.0.1" />
<PackageVersion Include="System.Text.Json" Version="10.0.2" />
<PackageVersion Include="System.Threading.Channels" Version="10.0.2" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.3" />
@@ -113,14 +113,14 @@
<PackageVersion Include="Microsoft.Agents.ObjectModel.PowerFx" Version="2026.1.2.3" />
<PackageVersion Include="Microsoft.PowerFx.Interpreter" Version="1.5.0-build.20251008-1002" />
<!-- Durable Task -->
<PackageVersion Include="Microsoft.DurableTask.Client" Version="1.18.0" />
<PackageVersion Include="Microsoft.DurableTask.Client.AzureManaged" Version="1.18.0" />
<PackageVersion Include="Microsoft.DurableTask.Worker" Version="1.18.0" />
<PackageVersion Include="Microsoft.DurableTask.Worker.AzureManaged" Version="1.18.0" />
<PackageVersion Include="Microsoft.DurableTask.Client" Version="1.19.1" />
<PackageVersion Include="Microsoft.DurableTask.Client.AzureManaged" Version="1.19.0" />
<PackageVersion Include="Microsoft.DurableTask.Worker" Version="1.19.0" />
<PackageVersion Include="Microsoft.DurableTask.Worker.AzureManaged" Version="1.19.0" />
<!-- Azure Functions -->
<PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="2.50.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.50.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.11.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" Version="1.13.1" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask.AzureManaged" Version="1.0.1" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.3.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.1.0" />
+39 -25
View File
@@ -23,29 +23,43 @@
<Project Path="samples/AGUIClientServer/AGUIDojoServer/AGUIDojoServer.csproj" />
<Project Path="samples/AGUIClientServer/AGUIServer/AGUIServer.csproj" />
</Folder>
<Folder Name="/Samples/AzureFunctions/">
<File Path="samples/AzureFunctions/.editorconfig" />
<File Path="samples/AzureFunctions/README.md" />
<Project Path="samples/AzureFunctions/01_SingleAgent/01_SingleAgent.csproj" />
<Project Path="samples/AzureFunctions/02_AgentOrchestration_Chaining/02_AgentOrchestration_Chaining.csproj" />
<Project Path="samples/AzureFunctions/03_AgentOrchestration_Concurrency/03_AgentOrchestration_Concurrency.csproj" />
<Project Path="samples/AzureFunctions/04_AgentOrchestration_Conditionals/04_AgentOrchestration_Conditionals.csproj" />
<Project Path="samples/AzureFunctions/05_AgentOrchestration_HITL/05_AgentOrchestration_HITL.csproj" />
<Project Path="samples/AzureFunctions/06_LongRunningTools/06_LongRunningTools.csproj" />
<Project Path="samples/AzureFunctions/07_AgentAsMcpTool/07_AgentAsMcpTool.csproj" />
<Project Path="samples/AzureFunctions/08_ReliableStreaming/08_ReliableStreaming.csproj" />
<Folder Name="/Samples/Durable/" />
<Folder Name="/Samples/Durable/Agents/" />
<Folder Name="/Samples/Durable/Agents/AzureFunctions/">
<File Path="samples/Durable/Agents/AzureFunctions/.editorconfig" />
<File Path="samples/Durable/Agents/AzureFunctions/README.md" />
<Project Path="samples/Durable/Agents/AzureFunctions/01_SingleAgent/01_SingleAgent.csproj" />
<Project Path="samples/Durable/Agents/AzureFunctions/02_AgentOrchestration_Chaining/02_AgentOrchestration_Chaining.csproj" />
<Project Path="samples/Durable/Agents/AzureFunctions/03_AgentOrchestration_Concurrency/03_AgentOrchestration_Concurrency.csproj" />
<Project Path="samples/Durable/Agents/AzureFunctions/04_AgentOrchestration_Conditionals/04_AgentOrchestration_Conditionals.csproj" />
<Project Path="samples/Durable/Agents/AzureFunctions/05_AgentOrchestration_HITL/05_AgentOrchestration_HITL.csproj" />
<Project Path="samples/Durable/Agents/AzureFunctions/06_LongRunningTools/06_LongRunningTools.csproj" />
<Project Path="samples/Durable/Agents/AzureFunctions/07_AgentAsMcpTool/07_AgentAsMcpTool.csproj" />
<Project Path="samples/Durable/Agents/AzureFunctions/08_ReliableStreaming/08_ReliableStreaming.csproj" />
</Folder>
<Folder Name="/Samples/DurableAgents/">
<File Path="samples/DurableAgents/ConsoleApps/README.md" />
<Folder Name="/Samples/Durable/Agents/ConsoleApps/">
<File Path="samples/Durable/Agents/ConsoleApps/README.md" />
<Project Path="samples/Durable/Agents/ConsoleApps/01_SingleAgent/01_SingleAgent.csproj" />
<Project Path="samples/Durable/Agents/ConsoleApps/02_AgentOrchestration_Chaining/02_AgentOrchestration_Chaining.csproj" />
<Project Path="samples/Durable/Agents/ConsoleApps/03_AgentOrchestration_Concurrency/03_AgentOrchestration_Concurrency.csproj" />
<Project Path="samples/Durable/Agents/ConsoleApps/04_AgentOrchestration_Conditionals/04_AgentOrchestration_Conditionals.csproj" />
<Project Path="samples/Durable/Agents/ConsoleApps/05_AgentOrchestration_HITL/05_AgentOrchestration_HITL.csproj" />
<Project Path="samples/Durable/Agents/ConsoleApps/06_LongRunningTools/06_LongRunningTools.csproj" />
<Project Path="samples/Durable/Agents/ConsoleApps/07_ReliableStreaming/07_ReliableStreaming.csproj" />
</Folder>
<Folder Name="/Samples/DurableAgents/ConsoleApps/">
<Project Path="samples/DurableAgents/ConsoleApps/01_SingleAgent/01_SingleAgent.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/02_AgentOrchestration_Chaining/02_AgentOrchestration_Chaining.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/03_AgentOrchestration_Concurrency/03_AgentOrchestration_Concurrency.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/04_AgentOrchestration_Conditionals/04_AgentOrchestration_Conditionals.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/05_AgentOrchestration_HITL/05_AgentOrchestration_HITL.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/06_LongRunningTools/06_LongRunningTools.csproj" />
<Project Path="samples/DurableAgents/ConsoleApps/07_ReliableStreaming/07_ReliableStreaming.csproj" />
<Folder Name="/Samples/Durable/Workflows/">
<Project Path="samples/Durable/Workflow/ConsoleApps/01_SequentialWorkflow/01_SequentialWorkflow.csproj" />
<Project Path="samples/Durable/Workflow/ConsoleApps/02_ConcurrentWorkflow/02_ConcurrentWorkflow.csproj" />
<Project Path="samples/Durable/Workflow/ConsoleApps/03_ConditionalEdges/03_ConditionalEdges.csproj" />
<Project Path="samples/Durable/Workflow/ConsoleApps/04_WorkflowAndAgents/04_WorkflowAndAgents.csproj" />
<Project Path="samples/Durable/Workflow/ConsoleApps/05_NestedWorkflows/05_NestedWorkflows.csproj" />
</Folder>
<Folder Name="/Samples/Durable/Workflows/AzureFunctions/">
<Project Path="samples/Durable/Workflow/AzureFunctions/01_SequentialWorkflow/01_SequentialWorkflow.csproj" />
<Project Path="samples/Durable/Workflow/AzureFunctions/02_ConcurrentWorkflow/02_ConcurrentWorkflow.csproj" />
<Project Path="samples/Durable/Workflow/AzureFunctions/03_ConditionalEdges/03_ConditionalEdges.csproj" />
<Project Path="samples/Durable/Workflow/AzureFunctions/04_NestedWorkflows/04_NestedWorkflows.csproj" />
<Project Path="samples/Durable/Workflow/AzureFunctions/05_WorkflowAndAgents/05_WorkflowAndAgents.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/">
<File Path="samples/GettingStarted/README.md" />
@@ -397,7 +411,6 @@
<Project Path="src/Microsoft.Agents.AI.Abstractions/Microsoft.Agents.AI.Abstractions.csproj" />
<Project Path="src/Microsoft.Agents.AI.AGUI/Microsoft.Agents.AI.AGUI.csproj" />
<Project Path="src/Microsoft.Agents.AI.Anthropic/Microsoft.Agents.AI.Anthropic.csproj" />
<Project Path="src/Microsoft.Agents.AI.GitHub.Copilot/Microsoft.Agents.AI.GitHub.Copilot.csproj" />
<Project Path="src/Microsoft.Agents.AI.AzureAI.Persistent/Microsoft.Agents.AI.AzureAI.Persistent.csproj" />
<Project Path="src/Microsoft.Agents.AI.AzureAI/Microsoft.Agents.AI.AzureAI.csproj" />
<Project Path="src/Microsoft.Agents.AI.CopilotStudio/Microsoft.Agents.AI.CopilotStudio.csproj" />
@@ -405,6 +418,7 @@
<Project Path="src/Microsoft.Agents.AI.Declarative/Microsoft.Agents.AI.Declarative.csproj" />
<Project Path="src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.csproj" />
<Project Path="src/Microsoft.Agents.AI.DurableTask/Microsoft.Agents.AI.DurableTask.csproj" />
<Project Path="src/Microsoft.Agents.AI.GitHub.Copilot/Microsoft.Agents.AI.GitHub.Copilot.csproj" />
<Project Path="src/Microsoft.Agents.AI.Hosting.A2A.AspNetCore/Microsoft.Agents.AI.Hosting.A2A.AspNetCore.csproj" />
<Project Path="src/Microsoft.Agents.AI.Hosting.A2A/Microsoft.Agents.AI.Hosting.A2A.csproj" />
<Project Path="src/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.csproj" />
@@ -416,8 +430,8 @@
<Project Path="src/Microsoft.Agents.AI.Purview/Microsoft.Agents.AI.Purview.csproj" />
<Project Path="src/Microsoft.Agents.AI.Workflows.Declarative.AzureAI/Microsoft.Agents.AI.Workflows.Declarative.AzureAI.csproj" />
<Project Path="src/Microsoft.Agents.AI.Workflows.Declarative/Microsoft.Agents.AI.Workflows.Declarative.csproj" />
<Project Path="src/Microsoft.Agents.AI.Workflows/Microsoft.Agents.AI.Workflows.csproj" />
<Project Path="src/Microsoft.Agents.AI.Workflows.Generators/Microsoft.Agents.AI.Workflows.Generators.csproj" />
<Project Path="src/Microsoft.Agents.AI.Workflows/Microsoft.Agents.AI.Workflows.csproj" />
<Project Path="src/Microsoft.Agents.AI/Microsoft.Agents.AI.csproj" />
</Folder>
<Folder Name="/Tests/" />
@@ -427,8 +441,8 @@
<Project Path="tests/AzureAI.IntegrationTests/AzureAI.IntegrationTests.csproj" />
<Project Path="tests/AzureAIAgentsPersistent.IntegrationTests/AzureAIAgentsPersistent.IntegrationTests.csproj" />
<Project Path="tests/CopilotStudio.IntegrationTests/CopilotStudio.IntegrationTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.GitHub.Copilot.IntegrationTests/Microsoft.Agents.AI.GitHub.Copilot.IntegrationTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.DurableTask.IntegrationTests/Microsoft.Agents.AI.DurableTask.IntegrationTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.GitHub.Copilot.IntegrationTests/Microsoft.Agents.AI.GitHub.Copilot.IntegrationTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.IntegrationTests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.IntegrationTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests/Microsoft.Agents.AI.Hosting.AzureFunctions.IntegrationTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Mem0.IntegrationTests/Microsoft.Agents.AI.Mem0.IntegrationTests.csproj" />
@@ -442,13 +456,13 @@
<Project Path="tests/Microsoft.Agents.AI.Abstractions.UnitTests/Microsoft.Agents.AI.Abstractions.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.AGUI.UnitTests/Microsoft.Agents.AI.AGUI.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Anthropic.UnitTests/Microsoft.Agents.AI.Anthropic.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.GitHub.Copilot.UnitTests/Microsoft.Agents.AI.GitHub.Copilot.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests/Microsoft.Agents.AI.AzureAI.Persistent.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.AzureAI.UnitTests/Microsoft.Agents.AI.AzureAI.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.CosmosNoSql.UnitTests/Microsoft.Agents.AI.CosmosNoSql.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Declarative.UnitTests/Microsoft.Agents.AI.Declarative.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.DevUI.UnitTests/Microsoft.Agents.AI.DevUI.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.DurableTask.UnitTests/Microsoft.Agents.AI.DurableTask.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.GitHub.Copilot.UnitTests/Microsoft.Agents.AI.GitHub.Copilot.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Hosting.A2A.UnitTests/Microsoft.Agents.AI.Hosting.A2A.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.UnitTests/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore.UnitTests.csproj" />
<Project Path="tests/Microsoft.Agents.AI.Hosting.AzureFunctions.UnitTests/Microsoft.Agents.AI.Hosting.AzureFunctions.UnitTests.csproj" />
@@ -36,7 +36,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -36,7 +36,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -36,7 +36,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -36,7 +36,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -37,7 +37,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -36,7 +36,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0</TargetFrameworks>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
@@ -36,7 +36,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -7,4 +7,4 @@
"AZURE_OPENAI_ENDPOINT": "<AZURE_OPENAI_ENDPOINT>",
"AZURE_OPENAI_DEPLOYMENT": "<AZURE_OPENAI_DEPLOYMENT>"
}
}
}
@@ -41,7 +41,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -24,7 +24,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -24,7 +24,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -24,7 +24,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -24,7 +24,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -24,7 +24,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -24,7 +24,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -25,7 +25,7 @@
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.DurableTask\Microsoft.Agents.AI.DurableTask.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0</TargetFrameworks>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- The Functions build tools don't like namespaces that start with a number -->
<AssemblyName>SequentialWorkflowFunctionApp</AssemblyName>
<RootNamespace>SequentialWorkflowFunctionApp</RootNamespace>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<!-- Azure Functions packages -->
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.DurableTask.AzureManaged" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>
<!-- Local projects that should be switched to package references when using the sample outside of this MAF repo -->
<!--
<ItemGroup>
<PackageReference Include="Microsoft.Agents.AI.Hosting.AzureFunctions" />
<PackageReference Include="Microsoft.Agents.AI.OpenAI" />
</ItemGroup>
-->
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Hosting.AzureFunctions\Microsoft.Agents.AI.Hosting.AzureFunctions.csproj" />
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace SequentialWorkflowFunctionApp;
public class Function
{
private readonly ILogger<Function> _logger;
public Function(ILogger<Function> logger)
{
_logger = logger;
}
[Function("Function")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult("Welcome to Azure Functions!");
}
}
@@ -0,0 +1,59 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI.Workflows;
namespace SequentialWorkflow;
/// <summary>
/// Parses an Order ID from a string input and returns an Order object populated.
/// </summary>
internal sealed class OrderLookup() : Executor<string, Order>("OrderLookup")
{
public override async ValueTask<Order> HandleAsync(string message, IWorkflowContext context, CancellationToken cancellationToken = default)
{
// Populate Order information from OrderId.
return new Order(message, 100.0m);
}
}
/// <summary>
/// Enriches an Order object with additional information.
/// </summary>
internal sealed class OrderEnrich() : Executor<Order, Order>("EnrichOrder")
{
public override async ValueTask<Order> HandleAsync(Order message, IWorkflowContext context, CancellationToken cancellationToken = default)
{
if (message.Customer is null)
{
// populate customer information for the order from database.
message.Customer = new Customer(1, "Jerry");
}
return message;
}
}
internal sealed class PaymentProcessor() : Executor<Order, Order>("ProcessPayment")
{
public override async ValueTask<Order> HandleAsync(Order message, IWorkflowContext context, CancellationToken cancellationToken = default)
{
message.PaymentReferenceNumber = Guid.NewGuid().ToString()[^4..];
return message;
}
}
internal sealed class Order
{
public Order(string id, decimal amount)
{
this.Id = id;
this.Amount = amount;
}
public string Id { get; }
public decimal Amount { get; }
public Customer? Customer { get; set; }
public string? PaymentReferenceNumber { get; set; }
}
public sealed record Customer(int Id, string Name);
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.Agents.AI.Workflows;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Agents.AI.Hosting.AzureFunctions;
using Microsoft.Extensions.Hosting;
using SequentialWorkflow;
OrderLookup orderLookupExecutor = new();
OrderEnrich orderEnricherExeecutor = new();
PaymentProcessor paymentProcessorExecutor = new();
Workflow fulfillOrder = new WorkflowBuilder(orderLookupExecutor)
.WithName("FulfillOrder")
.WithDescription("Looks up an order by ID and run payment processing")
.AddEdge(orderLookupExecutor, orderEnricherExeecutor)
.AddEdge(orderEnricherExeecutor, paymentProcessorExecutor)
.Build();
// 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()
.ConfigureDurableOptions(durableOption =>
{
// Add a workflow.
durableOption.Workflows.AddWorkflow(fulfillOrder);
})
.Build();
app.Run();
@@ -0,0 +1,8 @@
# Default endpoint address for local testing
@authority=http://localhost:7071
### Prompt the agent
POST {{authority}}/api/workflows/FulfillOrder/run
Content-Type: text/plain
987
@@ -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"
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More