mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Compare commits
59
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf13e35c73 | ||
|
|
5353b9a2f0 | ||
|
|
04e711cd55 | ||
|
|
ab3d898979 | ||
|
|
02af2bc0ef | ||
|
|
e5b63a1041 | ||
|
|
b575b631c8 | ||
|
|
ce738cc6bc | ||
|
|
f99dca033f | ||
|
|
6ae32f007d | ||
|
|
039e49f353 | ||
|
|
61dbacd6f8 | ||
|
|
c7a8c12296 | ||
|
|
d714b91a14 | ||
|
|
99689add09 | ||
|
|
4fcc5a4b7d | ||
|
|
79bb87061b | ||
|
|
b3e96b80ae | ||
|
|
92df9e14bf | ||
|
|
d2d0f46e15 | ||
|
|
84e2c0cc22 | ||
|
|
4e339f841a | ||
|
|
34a00f1b8a | ||
|
|
d5165e2532 | ||
|
|
f83c39f924 | ||
|
|
037349ff90 | ||
|
|
293abf5b56 | ||
|
|
e2d2299a4f | ||
|
|
8a7260140a | ||
|
|
1da9107f4a | ||
|
|
03b74bfad4 | ||
|
|
f6cd329a32 | ||
|
|
1f0ffc159c | ||
|
|
d50371729a | ||
|
|
77247a304e | ||
|
|
e413c5a285 | ||
|
|
ea066771d9 | ||
|
|
c361ad8d33 | ||
|
|
132597957a | ||
|
|
e7ac655b82 | ||
|
|
57ca139f8c | ||
|
|
e32f93dcb5 | ||
|
|
fcc3f1b6c0 | ||
|
|
45dba6b825 | ||
|
+2 |
e706f07868 | ||
|
|
580a0c431a | ||
|
|
c7e7020c32 | ||
|
|
939c2d69f9 | ||
|
|
c1786b38a7 | ||
|
|
8b3732795c | ||
|
|
9e69e66cfe | ||
|
|
8d7e01e2ee | ||
|
|
37e7c842e0 | ||
|
|
36c1217605 | ||
|
|
a2a9922cde | ||
|
|
aba3076203 | ||
|
|
8458b4ade7 | ||
|
|
e516322918 | ||
|
|
b19860b8a8 |
@@ -11,9 +11,6 @@ updates:
|
||||
schedule:
|
||||
interval: "cron"
|
||||
cronjob: "0 8 * * 4,0" # Every Thursday(4) and Sunday(0) at 8:00 UTC
|
||||
experimental:
|
||||
nuget-native-updater: false
|
||||
enable-cooldown-metrics-collection: false
|
||||
ignore:
|
||||
# For all System.* and Microsoft.Extensions/Bcl.* packages, ignore all major version updates
|
||||
- dependency-name: "System.*"
|
||||
@@ -28,6 +25,14 @@ updates:
|
||||
- "dependencies"
|
||||
|
||||
# Maintain dependencies for python
|
||||
- package-ecosystem: "pip"
|
||||
directory: "python/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
labels:
|
||||
- "python"
|
||||
- "dependencies"
|
||||
- package-ecosystem: "uv"
|
||||
directory: "python/"
|
||||
schedule:
|
||||
|
||||
@@ -28,6 +28,8 @@ jobs:
|
||||
UV_PYTHON: ${{ matrix.python-version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up python and install the project
|
||||
id: python-setup
|
||||
uses: ./.github/actions/python-setup
|
||||
@@ -46,4 +48,6 @@ jobs:
|
||||
with:
|
||||
extra_args: --config python/.pre-commit-config.yaml --all-files
|
||||
- name: Run Mypy
|
||||
run: uv run poe mypy
|
||||
env:
|
||||
GITHUB_BASE_REF: ${{ github.event.pull_request.base.ref || github.base_ref || 'main' }}
|
||||
run: uv run poe ci-mypy
|
||||
|
||||
@@ -204,6 +204,8 @@ agents.md
|
||||
# AI
|
||||
.claude/
|
||||
WARP.md
|
||||
**/memory-bank/
|
||||
**/projectBrief.md
|
||||
|
||||
# Azurite storage emulator files
|
||||
*/__azurite_db_blob__.json
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# Declarative Agents
|
||||
|
||||
This folder contains sample agent definitions than be ran using the declarative agent support, for python see the [declarative agent python sample folder](../python/samples/getting_started/declarative/).
|
||||
@@ -0,0 +1,25 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format. You must include Chat as the type in your response.
|
||||
model:
|
||||
id: =Env.AZURE_OPENAI_DEPLOYMENT_NAME
|
||||
provider: AzureOpenAI
|
||||
apiType: Chat
|
||||
options:
|
||||
temperature: 0.9
|
||||
topP: 0.95
|
||||
outputSchema:
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
type:
|
||||
kind: string
|
||||
required: true
|
||||
description: The type of the response.
|
||||
@@ -0,0 +1,25 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format. You must include Assistants as the type in your response.
|
||||
model:
|
||||
id: =Env.AZURE_OPENAI_DEPLOYMENT_NAME
|
||||
provider: AzureOpenAI
|
||||
apiType: Assistants
|
||||
options:
|
||||
temperature: 0.9
|
||||
topP: 0.95
|
||||
outputSchema:
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
type:
|
||||
kind: string
|
||||
required: true
|
||||
description: The type of the response.
|
||||
@@ -0,0 +1,28 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format. You must include Responses as the type in your response.
|
||||
model:
|
||||
id: =Env.AZURE_OPENAI_DEPLOYMENT_NAME
|
||||
provider: AzureOpenAI
|
||||
apiType: Responses
|
||||
options:
|
||||
text:
|
||||
verbosity: medium
|
||||
connection:
|
||||
kind: remote
|
||||
endpoint: =Env.AZURE_OPENAI_ENDPOINT
|
||||
outputSchema:
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
type:
|
||||
kind: string
|
||||
required: true
|
||||
description: The type of the response.
|
||||
@@ -0,0 +1,18 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format.
|
||||
model:
|
||||
options:
|
||||
temperature: 0.9
|
||||
topP: 0.95
|
||||
outputSchema:
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
@@ -0,0 +1,27 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions using the tools provided.
|
||||
model:
|
||||
options:
|
||||
allowMultipleToolCalls: true
|
||||
chatToolMode: auto
|
||||
tools:
|
||||
- kind: function
|
||||
name: GetWeather
|
||||
description: Get the weather for a given location.
|
||||
bindings:
|
||||
get_weather: get_weather
|
||||
parameters:
|
||||
properties:
|
||||
location:
|
||||
kind: string
|
||||
description: The city and state, e.g. San Francisco, CA
|
||||
required: true
|
||||
unit:
|
||||
kind: string
|
||||
description: The unit of temperature. Possible values are 'celsius' and 'fahrenheit'.
|
||||
required: false
|
||||
enum:
|
||||
- celsius
|
||||
- fahrenheit
|
||||
@@ -0,0 +1,21 @@
|
||||
kind: Prompt
|
||||
name: MicrosoftLearnAgent
|
||||
description: Microsoft Learn Agent
|
||||
instructions: You answer questions by searching the Microsoft Learn content only.
|
||||
model:
|
||||
id: =Env.AZURE_FOUNDRY_PROJECT_MODEL_ID
|
||||
options:
|
||||
temperature: 0.9
|
||||
topP: 0.95
|
||||
connection:
|
||||
kind: remote
|
||||
endpoint: =Env.AZURE_FOUNDRY_PROJECT_ENDPOINT
|
||||
tools:
|
||||
- kind: mcp
|
||||
name: microsoft_learn
|
||||
description: Get information from Microsoft Learn.
|
||||
url: https://learn.microsoft.com/api/mcp
|
||||
approvalMode:
|
||||
kind: never
|
||||
allowedTools:
|
||||
- microsoft_docs_search
|
||||
@@ -0,0 +1,22 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format.
|
||||
model:
|
||||
id: =Env.AZURE_FOUNDRY_PROJECT_MODEL_ID
|
||||
options:
|
||||
temperature: 0.9
|
||||
topP: 0.95
|
||||
connection:
|
||||
kind: remote
|
||||
endpoint: =Env.AZURE_FOUNDRY_PROJECT_ENDPOINT
|
||||
outputSchema:
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
@@ -0,0 +1,28 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format. You must include Chat as the type in your response.
|
||||
model:
|
||||
id: =Env.OPENAI_MODEL
|
||||
provider: OpenAI
|
||||
apiType: Chat
|
||||
options:
|
||||
temperature: 0.9
|
||||
topP: 0.95
|
||||
connection:
|
||||
kind: key
|
||||
key: =Env.OPENAI_API_KEY
|
||||
outputSchema:
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
type:
|
||||
kind: string
|
||||
required: true
|
||||
description: The type of the response.
|
||||
@@ -0,0 +1,30 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format. You must include Assistants as the type in your response.
|
||||
model:
|
||||
id: =Env.OPENAI_MODEL
|
||||
provider: OpenAI
|
||||
apiType: Assistants
|
||||
options:
|
||||
temperature: 0.9
|
||||
topP: 0.95
|
||||
connection:
|
||||
kind: key
|
||||
key: =Env.OPENAI_APIKEY
|
||||
outputSchema:
|
||||
name: AssistantResponse
|
||||
description: The response from the assistant.
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
type:
|
||||
kind: string
|
||||
required: true
|
||||
description: The type of the response.
|
||||
@@ -0,0 +1,28 @@
|
||||
kind: Prompt
|
||||
name: Assistant
|
||||
description: Helpful assistant
|
||||
instructions: You are a helpful assistant. You answer questions is the language specified by the user. You return your answers in a JSON format. You must include Responses as the type in your response.
|
||||
model:
|
||||
id: =Env.OPENAI_MODEL
|
||||
provider: OpenAI
|
||||
apiType: Responses
|
||||
options:
|
||||
text:
|
||||
verbosity: medium
|
||||
connection:
|
||||
kind: key
|
||||
key: =Env.OPENAI_APIKEY
|
||||
outputSchema:
|
||||
properties:
|
||||
language:
|
||||
kind: string
|
||||
required: true
|
||||
description: The language of the answer.
|
||||
answer:
|
||||
kind: string
|
||||
required: true
|
||||
description: The answer text.
|
||||
type:
|
||||
kind: string
|
||||
required: true
|
||||
description: The type of the response.
|
||||
@@ -15,8 +15,10 @@
|
||||
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireAppHostSdkVersion)" />
|
||||
<PackageVersion Include="Aspire.Hosting.Azure.CognitiveServices" Version="$(AspireAppHostSdkVersion)" />
|
||||
<PackageVersion Include="Aspire.Microsoft.Azure.Cosmos" Version="$(AspireAppHostSdkVersion)" />
|
||||
<PackageVersion Include="CommunityToolkit.Aspire.OllamaSharp" Version="13.0.0-beta.435" />
|
||||
<PackageVersion Include="CommunityToolkit.Aspire.OllamaSharp" Version="13.0.0-beta.440" />
|
||||
<!-- Azure.* -->
|
||||
<PackageVersion Include="Azure.AI.Projects" Version="1.2.0-beta.3" />
|
||||
<PackageVersion Include="Azure.AI.Projects.OpenAI" Version="1.0.0-beta.3" />
|
||||
<PackageVersion Include="Azure.AI.Agents.Persistent" Version="1.2.0-beta.7" />
|
||||
<PackageVersion Include="Azure.AI.OpenAI" Version="2.5.0-beta.1" />
|
||||
<PackageVersion Include="Azure.Identity" Version="1.17.0" />
|
||||
@@ -79,6 +81,10 @@
|
||||
<PackageVersion Include="Microsoft.SemanticKernel.Plugins.OpenApi" Version="1.67.0" />
|
||||
<!-- Agent SDKs -->
|
||||
<PackageVersion Include="Microsoft.Agents.CopilotStudio.Client" Version="1.2.41" />
|
||||
<!-- M365 Agents SDK -->
|
||||
<PackageVersion Include="AdaptiveCards" Version="3.1.0" />
|
||||
<PackageVersion Include="Microsoft.Agents.Authentication.Msal" Version="1.2.41" />
|
||||
<PackageVersion Include="Microsoft.Agents.Hosting.AspNetCore" Version="1.2.41" />
|
||||
<!-- A2A -->
|
||||
<PackageVersion Include="A2A" Version="0.3.3-preview" />
|
||||
<PackageVersion Include="A2A.AspNetCore" Version="0.3.3-preview" />
|
||||
@@ -93,10 +99,10 @@
|
||||
<!-- Identity -->
|
||||
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.78.0" />
|
||||
<!-- Workflows -->
|
||||
<PackageVersion Include="Microsoft.Bot.ObjectModel" Version="1.2025.1003.2" />
|
||||
<PackageVersion Include="Microsoft.Bot.ObjectModel.Json" Version="1.2025.1003.2" />
|
||||
<PackageVersion Include="Microsoft.Bot.ObjectModel.PowerFx" Version="1.2025.1003.2" />
|
||||
<PackageVersion Include="Microsoft.PowerFx.Interpreter" Version="1.4.0" />
|
||||
<PackageVersion Include="Microsoft.Bot.ObjectModel" Version="1.2025.1106.1" />
|
||||
<PackageVersion Include="Microsoft.Bot.ObjectModel.Json" Version="1.2025.1106.1" />
|
||||
<PackageVersion Include="Microsoft.Bot.ObjectModel.PowerFx" Version="1.2025.1106.1" />
|
||||
<PackageVersion Include="Microsoft.PowerFx.Interpreter" Version="1.5.0-build.20251008-1002" />
|
||||
<!-- Durable Task -->
|
||||
<PackageVersion Include="Microsoft.DurableTask.Client" Version="1.16.2" />
|
||||
<PackageVersion Include="Microsoft.DurableTask.Client.AzureManaged" Version="1.16.2-preview.1" />
|
||||
@@ -118,8 +124,6 @@
|
||||
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="9.0.11" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
|
||||
<PackageVersion Include="Moq" Version="[4.18.4]" />
|
||||
<PackageVersion Include="Microsoft.SemanticKernel.Agents.Abstractions" Version="1.67.0" />
|
||||
<PackageVersion Include="Microsoft.SemanticKernel.Agents.Yaml" Version="1.67.0-beta" />
|
||||
<PackageVersion Include="xunit" Version="2.9.3" />
|
||||
<PackageVersion Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.3" />
|
||||
@@ -165,4 +169,4 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
<Folder Name="/Samples/GettingStarted/AgentProviders/">
|
||||
<File Path="samples/GettingStarted/AgentProviders/README.md" />
|
||||
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_A2A/Agent_With_A2A.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureFoundryAgent/Agent_With_AzureFoundryAgent.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureAIAgentsPersistent/Agent_With_AzureAIAgentsPersistent.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureAIProject/Agent_With_AzureAIProject.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureFoundryModel/Agent_With_AzureFoundryModel.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureOpenAIChatCompletion/Agent_With_AzureOpenAIChatCompletion.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureOpenAIResponses/Agent_With_AzureOpenAIResponses.csproj" />
|
||||
@@ -91,11 +92,35 @@
|
||||
<Project Path="samples/GettingStarted/AgentWithOpenAI/Agent_OpenAI_Step01_Running/Agent_OpenAI_Step01_Running.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentWithOpenAI/Agent_OpenAI_Step02_Reasoning/Agent_OpenAI_Step02_Reasoning.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/Purview/" />
|
||||
<Folder Name="/Samples/Purview/AgentWithPurview/">
|
||||
<Project Path="samples/Purview/AgentWithPurview/AgentWithPurview.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/AgentWithRAG/">
|
||||
<File Path="samples/GettingStarted/AgentWithRAG/README.md" />
|
||||
<Project Path="samples/GettingStarted/AgentWithRAG/AgentWithRAG_Step01_BasicTextRAG/AgentWithRAG_Step01_BasicTextRAG.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentWithRAG/AgentWithRAG_Step02_CustomVectorStoreRAG/AgentWithRAG_Step02_CustomVectorStoreRAG.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentWithRAG/AgentWithRAG_Step03_CustomRAGDataSource/AgentWithRAG_Step03_CustomRAGDataSource.csproj" />
|
||||
<Project Path="samples/GettingStarted/AgentWithRAG/AgentWithRAG_Step04_FoundryServiceRAG/AgentWithRAG_Step04_FoundryServiceRAG.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/FoundryAgents/">
|
||||
<File Path="samples/GettingStarted/FoundryAgents/README.md" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.1_Basics/FoundryAgents_Step01.1_Basics.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step01.2_Running/FoundryAgents_Step01.2_Running.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step02_MultiturnConversation/FoundryAgents_Step02_MultiturnConversation.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step03_UsingFunctionTools/FoundryAgents_Step03_UsingFunctionTools.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step04_UsingFunctionToolsWithApprovals/FoundryAgents_Step04_UsingFunctionToolsWithApprovals.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step05_StructuredOutput/FoundryAgents_Step05_StructuredOutput.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step06_PersistedConversations/FoundryAgents_Step06_PersistedConversations.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step07_Observability/FoundryAgents_Step07_Observability.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step08_DependencyInjection/FoundryAgents_Step08_DependencyInjection.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step09_UsingMcpClientAsTools/FoundryAgents_Step09_UsingMcpClientAsTools.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step10_UsingImages/FoundryAgents_Step10_UsingImages.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step11_AsFunctionTool/FoundryAgents_Step11_AsFunctionTool.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step12_Middleware/FoundryAgents_Step12_Middleware.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step13_Plugins/FoundryAgents_Step13_Plugins.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step14_CodeInterpreter/FoundryAgents_Step14_CodeInterpreter.csproj" />
|
||||
<Project Path="samples/GettingStarted/FoundryAgents/FoundryAgents_Step15_ComputerUse/FoundryAgents_Step15_ComputerUse.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/ModelContextProtocol/">
|
||||
<File Path="samples/GettingStarted/ModelContextProtocol/README.md" />
|
||||
@@ -121,13 +146,22 @@
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/Workflows/Declarative/">
|
||||
<File Path="samples/GettingStarted/Workflows/Declarative/README.md" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/ConfirmInput/ConfirmInput.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/CustomerSupport/CustomerSupport.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/DeepResearch/DeepResearch.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/ExecuteCode/ExecuteCode.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/ExecuteWorkflow/ExecuteWorkflow.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/FunctionTools/FunctionTools.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/GenerateCode/GenerateCode.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/HostedWorkflow/HostedWorkflow.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/InputArguments/InputArguments.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/Marketing/Marketing.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/StudentTeacher/StudentTeacher.csproj" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Declarative/ToolApproval/ToolApproval.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/Workflows/Declarative/Examples/">
|
||||
<File Path="../workflow-samples/ConfirmInput.yaml" />
|
||||
<File Path="../workflow-samples/DeepResearch.yaml" />
|
||||
<File Path="../workflow-samples/HumanInLoop.yaml" />
|
||||
<File Path="../workflow-samples/Marketing.yaml" />
|
||||
<File Path="../workflow-samples/MathChat.yaml" />
|
||||
<File Path="../workflow-samples/README.md" />
|
||||
@@ -158,7 +192,7 @@
|
||||
<Project Path="samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/WorkflowAsAnAgentObservability.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/Workflows/Visualization/">
|
||||
<Project Path="samples/GettingStarted/Workflows/Visualization/Visualization.csproj" Id="99bf0bc6-2440-428e-b3e7-d880e4b7a5fd" />
|
||||
<Project Path="samples/GettingStarted/Workflows/Visualization/Visualization.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/Workflows/_Foundational/">
|
||||
<Project Path="samples/GettingStarted/Workflows/_Foundational/01_ExecutorsAndEdges/01_ExecutorsAndEdges.csproj" />
|
||||
@@ -172,8 +206,11 @@
|
||||
</Folder>
|
||||
<Folder Name="/Samples/HostedAgents/">
|
||||
<Project Path="samples/HostedAgents/AgentsInWorkflows/AgentsInWorkflows.csproj" />
|
||||
<Project Path="samples/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj" />
|
||||
<Project Path="samples/HostedAgents/AgentWithHostedMCP/AgentWithHostedMCP.csproj" />
|
||||
<Project Path="samples/HostedAgents/AgentWithTextSearchRag/AgentWithTextSearchRag.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/M365Agent/">
|
||||
<Project Path="samples/M365Agent/M365Agent.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Solution Items/">
|
||||
<File Path=".editorconfig" />
|
||||
@@ -299,6 +336,7 @@
|
||||
<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.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" />
|
||||
<Project Path="src/Microsoft.Agents.AI.DevUI/Microsoft.Agents.AI.DevUI.csproj" />
|
||||
<Project Path="src/Microsoft.Agents.AI.DurableTask/Microsoft.Agents.AI.DurableTask.csproj" />
|
||||
@@ -310,6 +348,8 @@
|
||||
<Project Path="src/Microsoft.Agents.AI.Hosting/Microsoft.Agents.AI.Hosting.csproj" />
|
||||
<Project Path="src/Microsoft.Agents.AI.Mem0/Microsoft.Agents.AI.Mem0.csproj" />
|
||||
<Project Path="src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj" />
|
||||
<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/Microsoft.Agents.AI.csproj" />
|
||||
@@ -317,6 +357,7 @@
|
||||
<Folder Name="/Tests/" />
|
||||
<Folder Name="/Tests/IntegrationTests/">
|
||||
<Project Path="tests/AgentConformance.IntegrationTests/AgentConformance.IntegrationTests.csproj" />
|
||||
<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.DurableTask.IntegrationTests/Microsoft.Agents.AI.DurableTask.IntegrationTests.csproj" />
|
||||
@@ -333,6 +374,8 @@
|
||||
<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.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.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.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" />
|
||||
@@ -341,6 +384,7 @@
|
||||
<Project Path="tests/Microsoft.Agents.AI.Hosting.UnitTests/Microsoft.Agents.AI.Hosting.UnitTests.csproj" />
|
||||
<Project Path="tests/Microsoft.Agents.AI.Mem0.UnitTests/Microsoft.Agents.AI.Mem0.UnitTests.csproj" />
|
||||
<Project Path="tests/Microsoft.Agents.AI.OpenAI.UnitTests/Microsoft.Agents.AI.OpenAI.UnitTests.csproj" />
|
||||
<Project Path="tests/Microsoft.Agents.AI.Purview.UnitTests/Microsoft.Agents.AI.Purview.UnitTests.csproj" />
|
||||
<Project Path="tests/Microsoft.Agents.AI.UnitTests/Microsoft.Agents.AI.UnitTests.csproj" />
|
||||
<Project Path="tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests.csproj" />
|
||||
<Project Path="tests/Microsoft.Agents.AI.Workflows.UnitTests/Microsoft.Agents.AI.Workflows.UnitTests.csproj" />
|
||||
|
||||
@@ -11,4 +11,13 @@
|
||||
<ItemGroup Condition="'$(InjectSharedBuildTestCode)' == 'true'">
|
||||
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\CodeTests\*.cs" LinkBase="Shared\CodeTests" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(InjectSharedWorkflowsExecution)' == 'true'">
|
||||
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Workflows\Execution\*.cs" LinkBase="Shared\Workflows" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(InjectSharedWorkflowsSettings)' == 'true'">
|
||||
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Workflows\Settings\*.cs" LinkBase="Shared\Workflows" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(InjectSharedFoundryAgents)' == 'true'">
|
||||
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Foundry\Agents\*.cs" LinkBase="Shared\Foundry" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<PropertyGroup>
|
||||
<!-- Central version prefix - applies to all nuget packages. -->
|
||||
<VersionPrefix>1.0.0</VersionPrefix>
|
||||
<PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix).251112.1</PackageVersion>
|
||||
<PackageVersion Condition="'$(VersionSuffix)' == ''">$(VersionPrefix)-preview.251112.1</PackageVersion>
|
||||
<GitTag>1.0.0-preview.251112.1</GitTag>
|
||||
<PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix).251114.1</PackageVersion>
|
||||
<PackageVersion Condition="'$(VersionSuffix)' == ''">$(VersionPrefix)-preview.251114.1</PackageVersion>
|
||||
<GitTag>1.0.0-preview.251114.1</GitTag>
|
||||
|
||||
<Configurations>Debug;Release;Publish</Configurations>
|
||||
<IsPackable>true</IsPackable>
|
||||
|
||||
+18
-18
@@ -2,7 +2,7 @@
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.Agents.AI.Hosting;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
namespace AgentWebChat.AgentHost;
|
||||
|
||||
@@ -10,24 +10,24 @@ internal static class ActorFrameworkWebApplicationExtensions
|
||||
{
|
||||
public static void MapAgentDiscovery(this IEndpointRouteBuilder endpoints, [StringSyntax("Route")] string path)
|
||||
{
|
||||
var routeGroup = endpoints.MapGroup(path);
|
||||
routeGroup.MapGet("/", async (
|
||||
AgentCatalog agentCatalog,
|
||||
CancellationToken cancellationToken) =>
|
||||
{
|
||||
var results = new List<AgentDiscoveryCard>();
|
||||
await foreach (var result in agentCatalog.GetAgentsAsync(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
results.Add(new AgentDiscoveryCard
|
||||
{
|
||||
Name = result.Name!,
|
||||
Description = result.Description,
|
||||
});
|
||||
}
|
||||
var registeredAIAgents = endpoints.ServiceProvider.GetKeyedServices<AIAgent>(KeyedService.AnyKey);
|
||||
|
||||
return Results.Ok(results);
|
||||
})
|
||||
.WithName("GetAgents");
|
||||
var routeGroup = endpoints.MapGroup(path);
|
||||
routeGroup.MapGet("/", async (CancellationToken cancellationToken) =>
|
||||
{
|
||||
var results = new List<AgentDiscoveryCard>();
|
||||
foreach (var result in registeredAIAgents)
|
||||
{
|
||||
results.Add(new AgentDiscoveryCard
|
||||
{
|
||||
Name = result.Name!,
|
||||
Description = result.Description,
|
||||
});
|
||||
}
|
||||
|
||||
return Results.Ok(results);
|
||||
})
|
||||
.WithName("GetAgents");
|
||||
}
|
||||
|
||||
internal sealed class AgentDiscoveryCard
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.DevUI\Microsoft.Agents.AI.DevUI.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Workflows\Microsoft.Agents.AI.Workflows.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting\Microsoft.Agents.AI.Hosting.csproj" />
|
||||
|
||||
@@ -5,6 +5,7 @@ using AgentWebChat.AgentHost;
|
||||
using AgentWebChat.AgentHost.Custom;
|
||||
using AgentWebChat.AgentHost.Utilities;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.DevUI;
|
||||
using Microsoft.Agents.AI.Hosting;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Extensions.AI;
|
||||
@@ -21,6 +22,13 @@ builder.Services.AddProblemDetails();
|
||||
// Configure the chat model and our agent.
|
||||
builder.AddKeyedChatClient("chat-model");
|
||||
|
||||
// Add DevUI services
|
||||
builder.AddDevUI();
|
||||
|
||||
// Add OpenAI services
|
||||
builder.AddOpenAIChatCompletions();
|
||||
builder.AddOpenAIResponses();
|
||||
|
||||
var pirateAgentBuilder = builder.AddAIAgent(
|
||||
"pirate",
|
||||
instructions: "You are a pirate. Speak like a pirate",
|
||||
@@ -95,8 +103,48 @@ var scienceConcurrentWorkflow = builder.AddWorkflow("science-concurrent-workflow
|
||||
return AgentWorkflowBuilder.BuildConcurrent(workflowName: key, agents: agents);
|
||||
}).AddAsAIAgent();
|
||||
|
||||
builder.AddOpenAIChatCompletions();
|
||||
builder.AddOpenAIResponses();
|
||||
builder.AddWorkflow("nonAgentWorkflow", (sp, key) =>
|
||||
{
|
||||
List<IHostedAgentBuilder> usedAgents = [pirateAgentBuilder, chemistryAgent];
|
||||
var agents = usedAgents.Select(ab => sp.GetRequiredKeyedService<AIAgent>(ab.Name));
|
||||
return AgentWorkflowBuilder.BuildSequential(workflowName: key, agents: agents);
|
||||
});
|
||||
|
||||
builder.Services.AddKeyedSingleton("NonAgentAndNonmatchingDINameWorkflow", (sp, key) =>
|
||||
{
|
||||
List<IHostedAgentBuilder> usedAgents = [pirateAgentBuilder, chemistryAgent];
|
||||
var agents = usedAgents.Select(ab => sp.GetRequiredKeyedService<AIAgent>(ab.Name));
|
||||
return AgentWorkflowBuilder.BuildSequential(workflowName: "random-name", agents: agents);
|
||||
});
|
||||
|
||||
builder.Services.AddSingleton<AIAgent>(sp =>
|
||||
{
|
||||
var chatClient = sp.GetRequiredKeyedService<IChatClient>("chat-model");
|
||||
return new ChatClientAgent(chatClient, name: "default-agent", instructions: "you are a default agent.");
|
||||
});
|
||||
|
||||
builder.Services.AddKeyedSingleton<AIAgent>("my-di-nonmatching-agent", (sp, name) =>
|
||||
{
|
||||
var chatClient = sp.GetRequiredKeyedService<IChatClient>("chat-model");
|
||||
return new ChatClientAgent(
|
||||
chatClient,
|
||||
name: "some-random-name", // demonstrating registration can be different for DI and actual agent
|
||||
instructions: "you are a dependency inject agent. Tell me all about dependency injection.");
|
||||
});
|
||||
|
||||
builder.Services.AddKeyedSingleton<AIAgent>("my-di-matchingname-agent", (sp, name) =>
|
||||
{
|
||||
if (name is not string nameStr)
|
||||
{
|
||||
throw new NotSupportedException("Name should be passed as a key");
|
||||
}
|
||||
|
||||
var chatClient = sp.GetRequiredKeyedService<IChatClient>("chat-model");
|
||||
return new ChatClientAgent(
|
||||
chatClient,
|
||||
name: nameStr, // demonstrating registration with the same name
|
||||
instructions: "you are a dependency inject agent. Tell me all about dependency injection.");
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -118,7 +166,10 @@ app.MapA2A(knightsKnavesAgentBuilder, path: "/a2a/knights-and-knaves", agentCard
|
||||
// Url = "http://localhost:5390/a2a/knights-and-knaves"
|
||||
});
|
||||
|
||||
app.MapDevUI();
|
||||
|
||||
app.MapOpenAIResponses();
|
||||
app.MapOpenAIConversations();
|
||||
|
||||
app.MapOpenAIChatCompletions(pirateAgentBuilder);
|
||||
app.MapOpenAIChatCompletions(knightsKnavesAgentBuilder);
|
||||
|
||||
@@ -9,7 +9,9 @@ var azOpenAiResourceGroup = builder.AddParameterFromConfiguration("AzureOpenAIRe
|
||||
var chatModel = builder.AddAIModel("chat-model").AsAzureOpenAI("gpt-4o", o => o.AsExisting(azOpenAiResource, azOpenAiResourceGroup));
|
||||
|
||||
var agentHost = builder.AddProject<Projects.AgentWebChat_AgentHost>("agenthost")
|
||||
.WithReference(chatModel);
|
||||
.WithHttpEndpoint(name: "devui")
|
||||
.WithUrlForEndpoint("devui", (url) => new() { Url = "/devui", DisplayText = "Dev UI" })
|
||||
.WithReference(chatModel);
|
||||
|
||||
builder.AddProject<Projects.AgentWebChat_Web>("webfrontend")
|
||||
.WithExternalHttpEndpoints()
|
||||
|
||||
@@ -47,7 +47,7 @@ curl -X POST http://localhost:7071/api/agents/Joker/run \
|
||||
To continue a conversation, include the `thread_id` in the query string or JSON body:
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:7071/api/agents/Joker/run?thread_id=@dafx-joker@your-thread-id" \
|
||||
curl -X POST "http://localhost:7071/api/agents/Joker/run?thread_id=your-thread-id" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-d '{"message": "Tell me another one."}'
|
||||
@@ -64,7 +64,7 @@ The expected `application/json` output will look something like:
|
||||
```json
|
||||
{
|
||||
"status": 200,
|
||||
"thread_id": "@dafx-joker@your-thread-id",
|
||||
"thread_id": "ee6e47a0-f24b-40b1-ade8-16fcebb9eb40",
|
||||
"response": {
|
||||
"Messages": [
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ The response will be a text string that looks something like the following, indi
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/plain
|
||||
x-ms-thread-id: @publisher@351ec855-7f4d-4527-a60d-498301ced36d
|
||||
x-ms-thread-id: 351ec855-7f4d-4527-a60d-498301ced36d
|
||||
|
||||
The content generation workflow for the topic "The Future of Artificial Intelligence" has been successfully started, and the instance ID is **6a04276e8d824d8d941e1dc4142cc254**. If you need any further assistance or updates on the workflow, feel free to ask!
|
||||
```
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);IDE0059</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to create and use a AI agents with Azure Foundry Agents as the backend.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
var endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
var deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string JokerInstructions = "You are good at telling jokes.";
|
||||
const string JokerName = "JokerAgent";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
var aiProjectClient = new AIProjectClient(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
var agentVersionCreationOptions = new AgentVersionCreationOptions(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions });
|
||||
// Azure.AI.Agents SDK creates and manages agent by name and versions.
|
||||
// You can create a server side agent version with the Azure.AI.Agents SDK client below.
|
||||
var agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options: agentVersionCreationOptions);
|
||||
|
||||
// Note:
|
||||
// agentVersion.Id = "<agentName>:<versionNumber>",
|
||||
// agentVersion.Version = <versionNumber>,
|
||||
// agentVersion.Name = <agentName>
|
||||
|
||||
// You can retrieve an AIAgent for a already created server side agent version.
|
||||
AIAgent jokerAgentV1 = aiProjectClient.GetAIAgent(agentVersion);
|
||||
|
||||
// You can also create another AIAgent version (V2) by providing the same name with a different definition.
|
||||
AIAgent jokerAgentV2 = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions + "V2");
|
||||
|
||||
// You can also get the AIAgent latest version just providing its name.
|
||||
AIAgent jokerAgentLatest = aiProjectClient.GetAIAgent(name: JokerName);
|
||||
var latestVersion = jokerAgentLatest.GetService<AgentVersion>()!;
|
||||
|
||||
// The AIAgent version can be accessed via the GetService method.
|
||||
Console.WriteLine($"Latest agent version id: {latestVersion.Id}");
|
||||
|
||||
// Once you have the AIAgent, you can invoke it like any other AIAgent.
|
||||
AgentThread thread = jokerAgentLatest.GetNewThread();
|
||||
Console.WriteLine(await jokerAgentLatest.RunAsync("Tell me a joke about a pirate.", thread));
|
||||
|
||||
// This will use the same thread to continue the conversation.
|
||||
Console.WriteLine(await jokerAgentLatest.RunAsync("Now tell me a joke about a cat and a dog using last joke as the anchor.", thread));
|
||||
|
||||
// Cleanup by agent name removes both agent versions created (jokerAgentV1 + jokerAgentV2).
|
||||
aiProjectClient.Agents.DeleteAgent(jokerAgentV1.Name);
|
||||
@@ -0,0 +1,16 @@
|
||||
# Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
@@ -15,7 +15,8 @@ See the README.md for each sample for the prerequisites for that sample.
|
||||
|Sample|Description|
|
||||
|---|---|
|
||||
|[Creating an AIAgent with A2A](./Agent_With_A2A/)|This sample demonstrates how to create AIAgent for an existing A2A agent.|
|
||||
|[Creating an AIAgent with AzureFoundry Agent](./Agent_With_AzureFoundryAgent/)|This sample demonstrates how to create an Azure Foundry agent and expose it as an AIAgent|
|
||||
|[Creating an AIAgent with Foundry Agents using Azure.AI.Agents.Persistent](./Agent_With_AzureAIAgentsPersistent/)|This sample demonstrates how to create a Foundry Persistent agent and expose it as an AIAgent using the Azure.AI.Agents.Persistent SDK|
|
||||
|[Creating an AIAgent with Foundry Agents using Azure.AI.Project](./Agent_With_AzureAIProject/)|This sample demonstrates how to create an Foundry Project agent and expose it as an AIAgent using the Azure.AI.Project SDK|
|
||||
|[Creating an AIAgent with AzureFoundry Model](./Agent_With_AzureFoundryModel/)|This sample demonstrates how to use any model deployed to Azure Foundry to create an AIAgent|
|
||||
|[Creating an AIAgent with Azure OpenAI ChatCompletion](./Agent_With_AzureOpenAIChatCompletion/)|This sample demonstrates how to create an AIAgent using Azure OpenAI ChatCompletion as the underlying inference service|
|
||||
|[Creating an AIAgent with Azure OpenAI Responses](./Agent_With_AzureOpenAIResponses/)|This sample demonstrates how to create an AIAgent using Azure OpenAI Responses as the underlying inference service|
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="contoso-outdoors-knowledge-base.md">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to use the built in RAG capabilities that the Foundry service provides when using AI Agents provided by Foundry.
|
||||
|
||||
using System.ClientModel;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
using OpenAI;
|
||||
using OpenAI.Files;
|
||||
using OpenAI.VectorStores;
|
||||
|
||||
var endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
var deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
// Create an AI Project client and get an OpenAI client that works with the foundry service.
|
||||
AIProjectClient aiProjectClient = new(
|
||||
new Uri(endpoint),
|
||||
new AzureCliCredential());
|
||||
OpenAIClient openAIClient = aiProjectClient.GetProjectOpenAIClient();
|
||||
|
||||
// Upload the file that contains the data to be used for RAG to the Foundry service.
|
||||
OpenAIFileClient fileClient = openAIClient.GetOpenAIFileClient();
|
||||
ClientResult<OpenAIFile> uploadResult = await fileClient.UploadFileAsync(
|
||||
filePath: "contoso-outdoors-knowledge-base.md",
|
||||
purpose: FileUploadPurpose.Assistants);
|
||||
|
||||
// Create a vector store in the Foundry service using the uploaded file.
|
||||
VectorStoreClient vectorStoreClient = openAIClient.GetVectorStoreClient();
|
||||
ClientResult<VectorStore> vectorStoreCreate = await vectorStoreClient.CreateVectorStoreAsync(options: new VectorStoreCreationOptions()
|
||||
{
|
||||
Name = "contoso-outdoors-knowledge-base",
|
||||
FileIds = { uploadResult.Value.Id }
|
||||
});
|
||||
|
||||
var fileSearchTool = new HostedFileSearchTool() { Inputs = [new HostedVectorStoreContent(vectorStoreCreate.Value.Id)] };
|
||||
|
||||
AIAgent agent = await aiProjectClient
|
||||
.CreateAIAgentAsync(
|
||||
model: deploymentName,
|
||||
name: "AskContoso",
|
||||
instructions: "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available.",
|
||||
tools: [fileSearchTool]);
|
||||
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
|
||||
Console.WriteLine(">> Asking about returns\n");
|
||||
Console.WriteLine(await agent.RunAsync("Hi! I need help understanding the return policy.", thread));
|
||||
|
||||
Console.WriteLine("\n>> Asking about shipping\n");
|
||||
Console.WriteLine(await agent.RunAsync("How long does standard shipping usually take?", thread));
|
||||
|
||||
Console.WriteLine("\n>> Asking about product care\n");
|
||||
Console.WriteLine(await agent.RunAsync("What is the best way to maintain the TrailRunner tent fabric?", thread));
|
||||
|
||||
// Cleanup
|
||||
await fileClient.DeleteFileAsync(uploadResult.Value.Id);
|
||||
await vectorStoreClient.DeleteVectorStoreAsync(vectorStoreCreate.Value.Id);
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# Contoso Outdoors Knowledge Base
|
||||
|
||||
## Contoso Outdoors Return Policy
|
||||
|
||||
Customers may return any item within 30 days of delivery. Items should be unused and include original packaging. Refunds are issued to the original payment method within 5 business days of inspection.
|
||||
|
||||
## Contoso Outdoors Shipping Guide
|
||||
|
||||
Standard shipping is free on orders over $50 and typically arrives in 3-5 business days within the continental United States. Expedited options are available at checkout.
|
||||
|
||||
## Product Information
|
||||
|
||||
### TrailRunner Tent
|
||||
|
||||
The TrailRunner Tent is a lightweight, 2-person tent designed for easy setup and durability. It features waterproof materials, ventilation windows, and a compact carry bag.
|
||||
|
||||
#### Care Instructions
|
||||
|
||||
Clean the tent fabric with lukewarm water and a non-detergent soap. Allow it to air dry completely before storage and avoid prolonged UV exposure to extend the lifespan of the waterproof coating.
|
||||
@@ -7,3 +7,4 @@ These samples show how to create an agent with the Agent Framework that uses Ret
|
||||
|[Basic Text RAG](./AgentWithRAG_Step01_BasicTextRAG/)|This sample demonstrates how to create and run a basic agent with simple text Retrieval Augmented Generation (RAG).|
|
||||
|[RAG with Vector Store and custom schema](./AgentWithRAG_Step02_CustomVectorStoreRAG/)|This sample demonstrates how to create and run an agent that uses Retrieval Augmented Generation (RAG) with a vector store. It also uses a custom schema for the documents stored in the vector store.|
|
||||
|[RAG with custom RAG data source](./AgentWithRAG_Step03_CustomRAGDataSource/)|This sample demonstrates how to create and run an agent that uses Retrieval Augmented Generation (RAG) with a custom RAG data source.|
|
||||
|[RAG with Foundry VectorStore service](./AgentWithRAG_Step04_FoundryServiceRAG/)|This sample demonstrates how to create and run an agent that uses Retrieval Augmented Generation (RAG) with the Foundry VectorStore service.|
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);IDE0059</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to create and use AI agents with Azure Foundry Agents as the backend.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string JokerInstructionsV1 = "You are good at telling jokes.";
|
||||
const string JokerInstructionsV2 = "You are extremely hilarious at telling jokes.";
|
||||
const string JokerName = "JokerAgent";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructionsV1 });
|
||||
|
||||
// Azure.AI.Agents SDK creates and manages agent by name and versions.
|
||||
// You can create a server side agent version with the Azure.AI.Agents SDK client below.
|
||||
AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options);
|
||||
|
||||
// Note:
|
||||
// agentVersion.Id = "<agentName>:<versionNumber>",
|
||||
// agentVersion.Version = <versionNumber>,
|
||||
// agentVersion.Name = <agentName>
|
||||
|
||||
// You can retrieve an AIAgent for an already created server side agent version.
|
||||
AIAgent jokerAgentV1 = aiProjectClient.GetAIAgent(agentVersion);
|
||||
|
||||
// You can also create another AIAgent version (V2) by providing the same name with a different definition/instruction.
|
||||
AIAgent jokerAgentV2 = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructionsV2);
|
||||
|
||||
// You can also get the AIAgent latest version by just providing its name.
|
||||
AIAgent jokerAgentLatest = aiProjectClient.GetAIAgent(name: JokerName);
|
||||
AgentVersion latestVersion = jokerAgentLatest.GetService<AgentVersion>()!;
|
||||
|
||||
// The AIAgent version can be accessed via the GetService method.
|
||||
Console.WriteLine($"Latest agent version id: {latestVersion.Id}");
|
||||
|
||||
// Once you have the AIAgent, you can invoke it like any other AIAgent.
|
||||
Console.WriteLine(await jokerAgentLatest.RunAsync("Tell me a joke about a pirate."));
|
||||
|
||||
// Cleanup by agent name removes both agent versions created (jokerAgentV1 + jokerAgentV2).
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(jokerAgentV1.Name);
|
||||
@@ -0,0 +1,40 @@
|
||||
# Creating and Managing AI Agents with Versioning
|
||||
|
||||
This sample demonstrates how to create and manage AI agents with Azure Foundry Agents, including:
|
||||
- Creating agents with different versions
|
||||
- Retrieving agents by version or latest version
|
||||
- Running multi-turn conversations with agents
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step01.1_Basics
|
||||
```
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
1. **Creating agents with versions**: Shows how to create multiple versions of the same agent with different instructions
|
||||
2. **Retrieving agents**: Demonstrates retrieving agents by specific version or getting the latest version
|
||||
3. **Multi-turn conversations**: Shows how to use threads to maintain conversation context across multiple agent runs
|
||||
4. **Agent cleanup**: Demonstrates proper resource cleanup by deleting agents
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string JokerInstructions = "You are good at telling jokes.";
|
||||
const string JokerName = "JokerAgent";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions });
|
||||
|
||||
// Azure.AI.Agents SDK creates and manages agent by name and versions.
|
||||
// You can create a server side agent version with the Azure.AI.Agents SDK client below.
|
||||
AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options);
|
||||
|
||||
// You can retrieve an AIAgent for a already created server side agent version.
|
||||
AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion);
|
||||
|
||||
// Invoke the agent with streaming support.
|
||||
await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate."))
|
||||
{
|
||||
Console.WriteLine(update);
|
||||
}
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(jokerAgent.Name);
|
||||
@@ -0,0 +1,46 @@
|
||||
# Running a Simple AI Agent with Streaming
|
||||
|
||||
This sample demonstrates how to create and run a simple AI agent with Azure Foundry Agents, including both text and streaming responses.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating a simple AI agent with instructions
|
||||
- Running an agent with text output
|
||||
- Running an agent with streaming output
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step01.2_Running
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create an agent named "JokerAgent" with instructions to tell jokes
|
||||
2. Run the agent with a text prompt and display the response
|
||||
3. Run the agent again with streaming to display the response as it's generated
|
||||
4. Clean up resources by deleting the agent
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to create and use a simple AI agent with a multi-turn conversation.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string JokerInstructions = "You are good at telling jokes.";
|
||||
const string JokerName = "JokerAgent";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AgentVersionCreationOptions options = new(new PromptAgentDefinition(model: deploymentName) { Instructions = JokerInstructions });
|
||||
|
||||
// Create a server side agent version with the Azure.AI.Agents SDK client.
|
||||
AgentVersion agentVersion = aiProjectClient.Agents.CreateAgentVersion(agentName: JokerName, options);
|
||||
|
||||
// Retrieve an AIAgent for the created server side agent version.
|
||||
AIAgent jokerAgent = aiProjectClient.GetAIAgent(agentVersion);
|
||||
|
||||
// Invoke the agent with a multi-turn conversation, where the context is preserved in the thread object.
|
||||
AgentThread thread = jokerAgent.GetNewThread();
|
||||
Console.WriteLine(await jokerAgent.RunAsync("Tell me a joke about a pirate.", thread));
|
||||
Console.WriteLine(await jokerAgent.RunAsync("Now add some emojis to the joke and tell it in the voice of a pirate's parrot.", thread));
|
||||
|
||||
// Invoke the agent with a multi-turn conversation and streaming, where the context is preserved in the thread object.
|
||||
thread = jokerAgent.GetNewThread();
|
||||
await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Tell me a joke about a pirate.", thread))
|
||||
{
|
||||
Console.WriteLine(update);
|
||||
}
|
||||
await foreach (AgentRunResponseUpdate update in jokerAgent.RunStreamingAsync("Now add some emojis to the joke and tell it in the voice of a pirate's parrot.", thread))
|
||||
{
|
||||
Console.WriteLine(update);
|
||||
}
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(jokerAgent.Name);
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# Multi-turn Conversation with AI Agents
|
||||
|
||||
This sample demonstrates how to implement multi-turn conversations with AI agents, where context is preserved across multiple agent runs using threads.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating an AI agent with instructions
|
||||
- Using threads to maintain conversation context
|
||||
- Running multi-turn conversations with text output
|
||||
- Running multi-turn conversations with streaming output
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step02_MultiturnConversation
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create an agent named "JokerAgent" with instructions to tell jokes
|
||||
2. Create a thread for conversation context
|
||||
3. Run the agent with a text prompt and display the response
|
||||
4. Send a follow-up message to the same thread, demonstrating context preservation
|
||||
5. Create a new thread and run the agent with streaming
|
||||
6. Send a follow-up streaming message to demonstrate multi-turn streaming
|
||||
7. Clean up resources by deleting the agent
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample demonstrates how to use an agent with function tools.
|
||||
// It shows both non-streaming and streaming agent interactions using weather-related tools.
|
||||
|
||||
using System.ComponentModel;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
[Description("Get the weather for a given location.")]
|
||||
static string GetWeather([Description("The location to get the weather for.")] string location)
|
||||
=> $"The weather in {location} is cloudy with a high of 15°C.";
|
||||
|
||||
const string AssistantInstructions = "You are a helpful assistant that can get weather information.";
|
||||
const string AssistantName = "WeatherAssistant";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent with function tools.
|
||||
AITool tool = AIFunctionFactory.Create(GetWeather);
|
||||
|
||||
// Create AIAgent directly
|
||||
var newAgent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [tool]);
|
||||
|
||||
// Getting an already existing agent by name with tools.
|
||||
/*
|
||||
* IMPORTANT: Since agents that are stored in the server only know the definition of the function tools (JSON Schema),
|
||||
* you need to provided all invocable function tools when retrieving the agent so it can invoke them automatically.
|
||||
* If no invocable tools are provided, the function calling needs to handled manually.
|
||||
*/
|
||||
var existingAgent = await aiProjectClient.GetAIAgentAsync(name: AssistantName, tools: [tool]);
|
||||
|
||||
// Non-streaming agent interaction with function tools.
|
||||
AgentThread thread = existingAgent.GetNewThread();
|
||||
Console.WriteLine(await existingAgent.RunAsync("What is the weather like in Amsterdam?", thread));
|
||||
|
||||
// Streaming agent interaction with function tools.
|
||||
thread = existingAgent.GetNewThread();
|
||||
await foreach (AgentRunResponseUpdate update in existingAgent.RunStreamingAsync("What is the weather like in Amsterdam?", thread))
|
||||
{
|
||||
Console.WriteLine(update);
|
||||
}
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(existingAgent.Name);
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# Using Function Tools with AI Agents
|
||||
|
||||
This sample demonstrates how to use function tools with AI agents, allowing agents to call custom functions to retrieve information.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating function tools using AIFunctionFactory
|
||||
- Passing function tools to an AI agent
|
||||
- Running agents with function tools (text output)
|
||||
- Running agents with function tools (streaming output)
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step03.1_UsingFunctionTools
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create an agent named "WeatherAssistant" with a GetWeather function tool
|
||||
2. Run the agent with a text prompt asking about weather
|
||||
3. The agent will invoke the GetWeather function tool to retrieve weather information
|
||||
4. Run the agent again with streaming to display the response as it's generated
|
||||
5. Clean up resources by deleting the agent
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample demonstrates how to use an agent with function tools that require a human in the loop for approvals.
|
||||
// It shows both non-streaming and streaming agent interactions using weather-related tools.
|
||||
// If the agent is hosted in a service, with a remote user, combine this sample with the Persisted Conversations sample to persist the chat history
|
||||
// while the agent is waiting for user input.
|
||||
|
||||
using System.ComponentModel;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
// Create a sample function tool that the agent can use.
|
||||
[Description("Get the weather for a given location.")]
|
||||
static string GetWeather([Description("The location to get the weather for.")] string location)
|
||||
=> $"The weather in {location} is cloudy with a high of 15°C.";
|
||||
|
||||
const string AssistantInstructions = "You are a helpful assistant that can get weather information.";
|
||||
const string AssistantName = "WeatherAssistant";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
ApprovalRequiredAIFunction approvalTool = new(AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather)));
|
||||
|
||||
// Create AIAgent directly
|
||||
AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: AssistantName, model: deploymentName, instructions: AssistantInstructions, tools: [approvalTool]);
|
||||
|
||||
// Call the agent with approval-required function tools.
|
||||
// The agent will request approval before invoking the function.
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
AgentRunResponse response = await agent.RunAsync("What is the weather like in Amsterdam?", thread);
|
||||
|
||||
// Check if there are any user input requests (approvals needed).
|
||||
List<UserInputRequestContent> userInputRequests = response.UserInputRequests.ToList();
|
||||
|
||||
while (userInputRequests.Count > 0)
|
||||
{
|
||||
// Ask the user to approve each function call request.
|
||||
// For simplicity, we are assuming here that only function approval requests are being made.
|
||||
List<ChatMessage> userInputMessages = userInputRequests
|
||||
.OfType<FunctionApprovalRequestContent>()
|
||||
.Select(functionApprovalRequest =>
|
||||
{
|
||||
Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {functionApprovalRequest.FunctionCall.Name}");
|
||||
bool approved = Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false;
|
||||
return new ChatMessage(ChatRole.User, [functionApprovalRequest.CreateResponse(approved)]);
|
||||
})
|
||||
.ToList();
|
||||
|
||||
// Pass the user input responses back to the agent for further processing.
|
||||
response = await agent.RunAsync(userInputMessages, thread);
|
||||
|
||||
userInputRequests = response.UserInputRequests.ToList();
|
||||
}
|
||||
|
||||
Console.WriteLine($"\nAgent: {response}");
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# Using Function Tools with Approvals (Human-in-the-Loop)
|
||||
|
||||
This sample demonstrates how to use function tools that require human approval before execution, implementing a human-in-the-loop workflow.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating approval-required function tools using ApprovalRequiredAIFunction
|
||||
- Handling user input requests for function approvals
|
||||
- Implementing human-in-the-loop approval workflows
|
||||
- Processing agent responses with pending approvals
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step04_UsingFunctionToolsWithApprovals
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create an agent named "WeatherAssistant" with an approval-required GetWeather function tool
|
||||
2. Run the agent with a prompt asking about weather
|
||||
3. The agent will request approval before invoking the GetWeather function
|
||||
4. The sample will prompt the user to approve or deny the function call (enter 'Y' to approve)
|
||||
5. After approval, the function will be executed and the result returned to the agent
|
||||
6. Clean up resources by deleting the agent
|
||||
|
||||
**Note**: For hosted agents with remote users, combine this sample with the Persisted Conversations sample to persist chat history while waiting for user approval.
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to configure an agent to produce structured output.
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using SampleApp;
|
||||
|
||||
#pragma warning disable CA5399
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string AssistantInstructions = "You are a helpful assistant that extracts structured information about people.";
|
||||
const string AssistantName = "StructuredOutputAssistant";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Create ChatClientAgent directly
|
||||
ChatClientAgent agent = await aiProjectClient.CreateAIAgentAsync(
|
||||
model: deploymentName,
|
||||
new ChatClientAgentOptions(name: AssistantName, instructions: AssistantInstructions)
|
||||
{
|
||||
ChatOptions = new()
|
||||
{
|
||||
ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>()
|
||||
}
|
||||
});
|
||||
|
||||
// Set PersonInfo as the type parameter of RunAsync method to specify the expected structured output from the agent and invoke the agent with some unstructured input.
|
||||
AgentRunResponse<PersonInfo> response = await agent.RunAsync<PersonInfo>("Please provide information about John Smith, who is a 35-year-old software engineer.");
|
||||
|
||||
// Access the structured output via the Result property of the agent response.
|
||||
Console.WriteLine("Assistant Output:");
|
||||
Console.WriteLine($"Name: {response.Result.Name}");
|
||||
Console.WriteLine($"Age: {response.Result.Age}");
|
||||
Console.WriteLine($"Occupation: {response.Result.Occupation}");
|
||||
|
||||
// Create the ChatClientAgent with the specified name, instructions, and expected structured output the agent should produce.
|
||||
ChatClientAgent agentWithPersonInfo = aiProjectClient.CreateAIAgent(
|
||||
model: deploymentName,
|
||||
new ChatClientAgentOptions(name: AssistantName, instructions: AssistantInstructions)
|
||||
{
|
||||
ChatOptions = new()
|
||||
{
|
||||
ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>()
|
||||
}
|
||||
});
|
||||
|
||||
// Invoke the agent with some unstructured input while streaming, to extract the structured information from.
|
||||
IAsyncEnumerable<AgentRunResponseUpdate> updates = agentWithPersonInfo.RunStreamingAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");
|
||||
|
||||
// Assemble all the parts of the streamed output, since we can only deserialize once we have the full json,
|
||||
// then deserialize the response into the PersonInfo class.
|
||||
PersonInfo personInfo = (await updates.ToAgentRunResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
|
||||
|
||||
Console.WriteLine("Assistant Output:");
|
||||
Console.WriteLine($"Name: {personInfo.Name}");
|
||||
Console.WriteLine($"Age: {personInfo.Age}");
|
||||
Console.WriteLine($"Occupation: {personInfo.Occupation}");
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
|
||||
namespace SampleApp
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents information about a person, including their name, age, and occupation, matched to the JSON schema used in the agent.
|
||||
/// </summary>
|
||||
[Description("Information about a person including their name, age, and occupation")]
|
||||
public class PersonInfo
|
||||
{
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
[JsonPropertyName("age")]
|
||||
public int? Age { get; set; }
|
||||
|
||||
[JsonPropertyName("occupation")]
|
||||
public string? Occupation { get; set; }
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
# Structured Output with AI Agents
|
||||
|
||||
This sample demonstrates how to configure AI agents to produce structured output in JSON format using JSON schemas.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Configuring agents with JSON schema response formats
|
||||
- Using generic RunAsync<T> method for structured output
|
||||
- Deserializing structured responses into typed objects
|
||||
- Running agents with streaming and structured output
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step05_StructuredOutput
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create an agent named "StructuredOutputAssistant" configured to produce JSON output
|
||||
2. Run the agent with a prompt to extract person information
|
||||
3. Deserialize the JSON response into a PersonInfo object
|
||||
4. Display the structured data (Name, Age, Occupation)
|
||||
5. Run the agent again with streaming and deserialize the streamed JSON response
|
||||
6. Clean up resources by deleting the agent
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to create and use a simple AI agent with a conversation that can be persisted to disk.
|
||||
|
||||
using System.Text.Json;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string JokerInstructions = "You are good at telling jokes.";
|
||||
const string JokerName = "JokerAgent";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
AIAgent agent = await aiProjectClient.CreateAIAgentAsync(name: JokerName, model: deploymentName, instructions: JokerInstructions);
|
||||
|
||||
// Start a new thread for the agent conversation.
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
|
||||
// Run the agent with a new thread.
|
||||
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));
|
||||
|
||||
// Serialize the thread state to a JsonElement, so it can be stored for later use.
|
||||
JsonElement serializedThread = thread.Serialize();
|
||||
|
||||
// Save the serialized thread to a temporary file (for demonstration purposes).
|
||||
string tempFilePath = Path.GetTempFileName();
|
||||
await File.WriteAllTextAsync(tempFilePath, JsonSerializer.Serialize(serializedThread));
|
||||
|
||||
// Load the serialized thread from the temporary file (for demonstration purposes).
|
||||
JsonElement reloadedSerializedThread = JsonSerializer.Deserialize<JsonElement>(await File.ReadAllTextAsync(tempFilePath))!;
|
||||
|
||||
// Deserialize the thread state after loading from storage.
|
||||
AgentThread resumedThread = agent.DeserializeThread(reloadedSerializedThread);
|
||||
|
||||
// Run the agent again with the resumed thread.
|
||||
Console.WriteLine(await agent.RunAsync("Now tell the same joke in the voice of a pirate, and add some emojis to the joke.", resumedThread));
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# Persisted Conversations with AI Agents
|
||||
|
||||
This sample demonstrates how to serialize and persist agent conversation threads to storage, allowing conversations to be resumed later.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Serializing agent threads to JSON
|
||||
- Persisting thread state to disk
|
||||
- Loading and deserializing thread state from storage
|
||||
- Resuming conversations with persisted threads
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step06_PersistedConversations
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create an agent named "JokerAgent" with instructions to tell jokes
|
||||
2. Create a thread and run the agent with an initial prompt
|
||||
3. Serialize the thread state to JSON
|
||||
4. Save the serialized thread to a temporary file
|
||||
5. Load the thread from the file and deserialize it
|
||||
6. Resume the conversation with the same thread using a follow-up prompt
|
||||
7. Clean up resources by deleting the agent
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" />
|
||||
<PackageReference Include="OpenTelemetry" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Console" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend that logs telemetry using OpenTelemetry.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Azure.Monitor.OpenTelemetry.Exporter;
|
||||
using Microsoft.Agents.AI;
|
||||
using OpenTelemetry;
|
||||
using OpenTelemetry.Trace;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
string? applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING");
|
||||
|
||||
const string JokerInstructions = "You are good at telling jokes.";
|
||||
const string JokerName = "JokerAgent";
|
||||
|
||||
// Create TracerProvider with console exporter
|
||||
// This will output the telemetry data to the console.
|
||||
string sourceName = Guid.NewGuid().ToString("N");
|
||||
TracerProviderBuilder tracerProviderBuilder = Sdk.CreateTracerProviderBuilder()
|
||||
.AddSource(sourceName)
|
||||
.AddConsoleExporter();
|
||||
if (!string.IsNullOrWhiteSpace(applicationInsightsConnectionString))
|
||||
{
|
||||
tracerProviderBuilder.AddAzureMonitorTraceExporter(options => options.ConnectionString = applicationInsightsConnectionString);
|
||||
}
|
||||
using var tracerProvider = tracerProviderBuilder.Build();
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AIAgent agent = aiProjectClient.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions)
|
||||
.AsBuilder()
|
||||
.UseOpenTelemetry(sourceName: sourceName)
|
||||
.Build();
|
||||
|
||||
// Invoke the agent and output the text result.
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));
|
||||
|
||||
// Invoke the agent with streaming support.
|
||||
thread = agent.GetNewThread();
|
||||
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync("Tell me a joke about a pirate.", thread))
|
||||
{
|
||||
Console.WriteLine(update);
|
||||
}
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# Observability with OpenTelemetry
|
||||
|
||||
This sample demonstrates how to add observability to AI agents using OpenTelemetry for tracing and monitoring.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Setting up OpenTelemetry TracerProvider
|
||||
- Configuring console exporter for telemetry output
|
||||
- Configuring Azure Monitor exporter for Application Insights
|
||||
- Adding OpenTelemetry middleware to agents
|
||||
- Running agents with telemetry collection (text and streaming)
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
- (Optional) Application Insights connection string for Azure Monitor integration
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
$env:APPLICATIONINSIGHTS_CONNECTION_STRING="your-connection-string" # Optional, for Azure Monitor integration
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step07_Observability
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create a TracerProvider with console exporter (and optionally Azure Monitor exporter)
|
||||
2. Create an agent named "JokerAgent" with OpenTelemetry middleware
|
||||
3. Run the agent with a text prompt and display telemetry traces to console
|
||||
4. Run the agent again with streaming and display telemetry traces
|
||||
5. Clean up resources by deleting the agent
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
<NoWarn>$(NoWarn);CA1812</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to use dependency injection to register an AIAgent and use it from a hosted service with a user input chat loop.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string JokerInstructions = "You are good at telling jokes.";
|
||||
const string JokerName = "JokerAgent";
|
||||
|
||||
// Create a host builder that we will register services with and then run.
|
||||
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
|
||||
|
||||
// Add the agents client to the service collection.
|
||||
builder.Services.AddSingleton((sp) => new AIProjectClient(new Uri(endpoint), new AzureCliCredential()));
|
||||
|
||||
// Add the AI agent to the service collection.
|
||||
builder.Services.AddSingleton<AIAgent>((sp)
|
||||
=> sp.GetRequiredService<AIProjectClient>()
|
||||
.CreateAIAgent(name: JokerName, model: deploymentName, instructions: JokerInstructions));
|
||||
|
||||
// Add a sample service that will use the agent to respond to user input.
|
||||
builder.Services.AddHostedService<SampleService>();
|
||||
|
||||
// Build and run the host.
|
||||
using IHost host = builder.Build();
|
||||
await host.RunAsync().ConfigureAwait(false);
|
||||
|
||||
/// <summary>
|
||||
/// A sample service that uses an AI agent to respond to user input.
|
||||
/// </summary>
|
||||
internal sealed class SampleService(AIProjectClient client, AIAgent agent, IHostApplicationLifetime appLifetime) : IHostedService
|
||||
{
|
||||
private AgentThread? _thread;
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// Create a thread that will be used for the entirety of the service lifetime so that the user can ask follow up questions.
|
||||
this._thread = agent.GetNewThread();
|
||||
_ = this.RunAsync(appLifetime.ApplicationStopping);
|
||||
}
|
||||
|
||||
public async Task RunAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// Delay a little to allow the service to finish starting.
|
||||
await Task.Delay(100, cancellationToken);
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
Console.WriteLine("\nAgent: Ask me to tell you a joke about a specific topic. To exit just press Ctrl+C or enter without any input.\n");
|
||||
Console.Write("> ");
|
||||
string? input = Console.ReadLine();
|
||||
|
||||
// If the user enters no input, signal the application to shut down.
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
appLifetime.StopApplication();
|
||||
break;
|
||||
}
|
||||
|
||||
// Stream the output to the console as it is generated.
|
||||
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(input, this._thread, cancellationToken: cancellationToken))
|
||||
{
|
||||
Console.Write(update);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
Console.WriteLine("\nDeleting agent ...");
|
||||
await client.Agents.DeleteAgentAsync(agent.Name, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# Dependency Injection with AI Agents
|
||||
|
||||
This sample demonstrates how to use dependency injection to register and manage AI agents within a hosted service application.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Setting up dependency injection with HostApplicationBuilder
|
||||
- Registering AIProjectClient as a singleton service
|
||||
- Registering AIAgent as a singleton service
|
||||
- Using agents in hosted services
|
||||
- Interactive chat loop with streaming responses
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step08_DependencyInjection
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create a host with dependency injection configured
|
||||
2. Register AIProjectClient and AIAgent as services
|
||||
3. Create an agent named "JokerAgent" with instructions to tell jokes
|
||||
4. Start an interactive chat loop where you can ask the agent questions
|
||||
5. The agent will respond with streaming output
|
||||
6. Enter an empty line or press Ctrl+C to exit
|
||||
7. Clean up resources by deleting the agent
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>3afc9b74-af74-4d8e-ae96-fa1c511d11ac</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Agents.Persistent" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||
<PackageReference Include="ModelContextProtocol" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to expose an AI agent as an MCP tool.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
using ModelContextProtocol.Client;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
Console.WriteLine("Starting MCP Stdio for @modelcontextprotocol/server-github ... ");
|
||||
|
||||
// Create an MCPClient for the GitHub server
|
||||
await using var mcpClient = await McpClient.CreateAsync(new StdioClientTransport(new()
|
||||
{
|
||||
Name = "MCPServer",
|
||||
Command = "npx",
|
||||
Arguments = ["-y", "--verbose", "@modelcontextprotocol/server-github"],
|
||||
}));
|
||||
|
||||
// Retrieve the list of tools available on the GitHub server
|
||||
IList<McpClientTool> mcpTools = await mcpClient.ListToolsAsync();
|
||||
string agentName = "AgentWithMCP";
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
Console.WriteLine($"Creating the agent '{agentName}' ...");
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AIAgent agent = aiProjectClient.CreateAIAgent(
|
||||
name: agentName,
|
||||
model: deploymentName,
|
||||
instructions: "You answer questions related to GitHub repositories only.",
|
||||
tools: [.. mcpTools.Cast<AITool>()]);
|
||||
|
||||
string prompt = "Summarize the last four commits to the microsoft/semantic-kernel repository?";
|
||||
|
||||
Console.WriteLine($"Invoking agent '{agent.Name}' with prompt: {prompt} ...");
|
||||
|
||||
// Invoke the agent and output the text result.
|
||||
Console.WriteLine(await agent.RunAsync(prompt));
|
||||
|
||||
// Clean up the agent after use.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# Using MCP Client Tools with AI Agents
|
||||
|
||||
This sample demonstrates how to use Model Context Protocol (MCP) client tools with AI agents, allowing agents to access tools provided by MCP servers. This sample uses the GitHub MCP server to provide tools for querying GitHub repositories.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating MCP clients to connect to MCP servers (GitHub server)
|
||||
- Retrieving tools from MCP servers
|
||||
- Using MCP tools with AI agents
|
||||
- Running agents with MCP-provided function tools
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
- Node.js and npm installed (for running the GitHub MCP server)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step09_UsingMcpClientAsTools
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Start the GitHub MCP server using `@modelcontextprotocol/server-github`
|
||||
2. Create an MCP client to connect to the GitHub server
|
||||
3. Retrieve the available tools from the GitHub MCP server
|
||||
4. Create an agent named "AgentWithMCP" with the GitHub tools
|
||||
5. Run the agent with a prompt to summarize the last four commits to the microsoft/semantic-kernel repository
|
||||
6. The agent will use the GitHub MCP tools to query the repository information
|
||||
7. Clean up resources by deleting the agent
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
+26
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\walkway.jpg">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to use Image Multi-Modality with an AI agent.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o";
|
||||
|
||||
const string VisionInstructions = "You are a helpful agent that can analyze images";
|
||||
const string VisionName = "VisionAgent";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AIAgent agent = aiProjectClient.CreateAIAgent(name: VisionName, model: deploymentName, instructions: VisionInstructions);
|
||||
|
||||
ChatMessage message = new(ChatRole.User, [
|
||||
new TextContent("What do you see in this image?"),
|
||||
new DataContent(File.ReadAllBytes("assets/walkway.jpg"), "image/jpeg")
|
||||
]);
|
||||
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
|
||||
await foreach (AgentRunResponseUpdate update in agent.RunStreamingAsync(message, thread))
|
||||
{
|
||||
Console.WriteLine(update);
|
||||
}
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
# Using Images with AI Agents
|
||||
|
||||
This sample demonstrates how to use image multi-modality with an AI agent. It shows how to create a vision-enabled agent that can analyze and describe images using Azure Foundry Agents.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating a vision-enabled AI agent with image analysis capabilities
|
||||
- Sending both text and image content to an agent in a single message
|
||||
- Using `UriContent` for URI-referenced images
|
||||
- Processing multimodal input (text + image) with an AI agent
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Key features
|
||||
|
||||
- **Vision Agent**: Creates an agent specifically instructed to analyze images
|
||||
- **Multimodal Input**: Combines text questions with image URI in a single message
|
||||
- **Azure Foundry Agents Integration**: Uses Azure Foundry Agents with vision capabilities
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before running this sample, ensure you have:
|
||||
|
||||
1. An Azure OpenAI project set up
|
||||
2. A compatible model deployment (e.g., gpt-4o)
|
||||
3. Azure CLI installed and authenticated
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-resource.openai.azure.com/" # Replace with your Azure Foundry Project endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o" # Replace with your model deployment name (optional, defaults to gpt-4o)
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step10_UsingImages
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create a vision-enabled agent named "VisionAgent"
|
||||
2. Send a message containing both text ("What do you see in this image?") and a URI-referenced image of a green walkway (nature boardwalk)
|
||||
3. The agent will analyze the image and provide a description
|
||||
4. Clean up resources by deleting the agent
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>3afc9b74-af74-4d8e-ae96-fa1c511d11ac</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to create and use an Azure Foundry Agents AI agent as a function tool.
|
||||
|
||||
using System.ComponentModel;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string WeatherInstructions = "You answer questions about the weather.";
|
||||
const string WeatherName = "WeatherAgent";
|
||||
const string MainInstructions = "You are a helpful assistant who responds in French.";
|
||||
const string MainName = "MainAgent";
|
||||
|
||||
[Description("Get the weather for a given location.")]
|
||||
static string GetWeather([Description("The location to get the weather for.")] string location)
|
||||
=> $"The weather in {location} is cloudy with a high of 15°C.";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Create the weather agent with function tools.
|
||||
AITool weatherTool = AIFunctionFactory.Create(GetWeather);
|
||||
AIAgent weatherAgent = aiProjectClient.CreateAIAgent(
|
||||
name: WeatherName,
|
||||
model: deploymentName,
|
||||
instructions: WeatherInstructions,
|
||||
tools: [weatherTool]);
|
||||
|
||||
// Create the main agent, and provide the weather agent as a function tool.
|
||||
AIAgent agent = aiProjectClient.CreateAIAgent(
|
||||
name: MainName,
|
||||
model: deploymentName,
|
||||
instructions: MainInstructions,
|
||||
tools: [weatherAgent.AsAIFunction()]);
|
||||
|
||||
// Invoke the agent and output the text result.
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?", thread));
|
||||
|
||||
// Cleanup by agent name removes the agent versions created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(weatherAgent.Name);
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
# Using AI Agents as Function Tools (Nested Agents)
|
||||
|
||||
This sample demonstrates how to expose an AI agent as a function tool, enabling nested agent scenarios where one agent can invoke another agent as a tool.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating an AI agent that can be used as a function tool
|
||||
- Wrapping an agent as an AIFunction
|
||||
- Using nested agents where one agent calls another
|
||||
- Managing multiple agent instances
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step11_AsFunctionTool
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create a "JokerAgent" that tells jokes
|
||||
2. Wrap the JokerAgent as a function tool
|
||||
3. Create a "CoordinatorAgent" that has the JokerAgent as a function tool
|
||||
4. Run the CoordinatorAgent with a prompt that triggers it to call the JokerAgent
|
||||
5. The CoordinatorAgent will invoke the JokerAgent as a function tool
|
||||
6. Clean up resources by deleting both agents
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows multiple middleware layers working together with Azure Foundry Agents:
|
||||
// agent run (PII filtering and guardrails),
|
||||
// function invocation (logging and result overrides), and human-in-the-loop
|
||||
// approval workflows for sensitive function calls.
|
||||
|
||||
using System.ComponentModel;
|
||||
using System.Text.RegularExpressions;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
|
||||
// Get Azure AI Foundry configuration from environment variables
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = System.Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o";
|
||||
|
||||
const string AssistantInstructions = "You are an AI assistant that helps people find information.";
|
||||
const string AssistantName = "InformationAssistant";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
[Description("Get the weather for a given location.")]
|
||||
static string GetWeather([Description("The location to get the weather for.")] string location)
|
||||
=> $"The weather in {location} is cloudy with a high of 15°C.";
|
||||
|
||||
[Description("The current datetime offset.")]
|
||||
static string GetDateTime()
|
||||
=> DateTimeOffset.Now.ToString();
|
||||
|
||||
AITool dateTimeTool = AIFunctionFactory.Create(GetDateTime, name: nameof(GetDateTime));
|
||||
AITool getWeatherTool = AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather));
|
||||
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AIAgent originalAgent = aiProjectClient.CreateAIAgent(
|
||||
name: AssistantName,
|
||||
model: deploymentName,
|
||||
instructions: AssistantInstructions,
|
||||
tools: [getWeatherTool, dateTimeTool]);
|
||||
|
||||
// Adding middleware to the agent level
|
||||
AIAgent middlewareEnabledAgent = originalAgent
|
||||
.AsBuilder()
|
||||
.Use(FunctionCallMiddleware)
|
||||
.Use(FunctionCallOverrideWeather)
|
||||
.Use(PIIMiddleware, null)
|
||||
.Use(GuardrailMiddleware, null)
|
||||
.Build();
|
||||
|
||||
AgentThread thread = middlewareEnabledAgent.GetNewThread();
|
||||
|
||||
Console.WriteLine("\n\n=== Example 1: Wording Guardrail ===");
|
||||
AgentRunResponse guardRailedResponse = await middlewareEnabledAgent.RunAsync("Tell me something harmful.");
|
||||
Console.WriteLine($"Guard railed response: {guardRailedResponse}");
|
||||
|
||||
Console.WriteLine("\n\n=== Example 2: PII detection ===");
|
||||
AgentRunResponse piiResponse = await middlewareEnabledAgent.RunAsync("My name is John Doe, call me at 123-456-7890 or email me at john@something.com");
|
||||
Console.WriteLine($"Pii filtered response: {piiResponse}");
|
||||
|
||||
Console.WriteLine("\n\n=== Example 3: Agent function middleware ===");
|
||||
|
||||
// Agent function middleware support is limited to agents that wraps a upstream ChatClientAgent or derived from it.
|
||||
|
||||
AgentRunResponse functionCallResponse = await middlewareEnabledAgent.RunAsync("What's the current time and the weather in Seattle?", thread);
|
||||
Console.WriteLine($"Function calling response: {functionCallResponse}");
|
||||
|
||||
// Special per-request middleware agent.
|
||||
Console.WriteLine("\n\n=== Example 4: Middleware with human in the loop function approval ===");
|
||||
|
||||
AIAgent humanInTheLoopAgent = aiProjectClient.CreateAIAgent(
|
||||
name: "HumanInTheLoopAgent",
|
||||
model: deploymentName,
|
||||
instructions: "You are an Human in the loop testing AI assistant that helps people find information.",
|
||||
|
||||
// Adding a function with approval required
|
||||
tools: [new ApprovalRequiredAIFunction(AIFunctionFactory.Create(GetWeather, name: nameof(GetWeather)))]);
|
||||
|
||||
// Using the ConsolePromptingApprovalMiddleware for a specific request to handle user approval during function calls.
|
||||
AgentRunResponse response = await humanInTheLoopAgent
|
||||
.AsBuilder()
|
||||
.Use(ConsolePromptingApprovalMiddleware, null)
|
||||
.Build()
|
||||
.RunAsync("What's the current time and the weather in Seattle?");
|
||||
|
||||
Console.WriteLine($"HumanInTheLoopAgent agent middleware response: {response}");
|
||||
|
||||
// Function invocation middleware that logs before and after function calls.
|
||||
async ValueTask<object?> FunctionCallMiddleware(AIAgent agent, FunctionInvocationContext context, Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next, CancellationToken cancellationToken)
|
||||
{
|
||||
Console.WriteLine($"Function Name: {context!.Function.Name} - Middleware 1 Pre-Invoke");
|
||||
var result = await next(context, cancellationToken);
|
||||
Console.WriteLine($"Function Name: {context!.Function.Name} - Middleware 1 Post-Invoke");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Function invocation middleware that overrides the result of the GetWeather function.
|
||||
async ValueTask<object?> FunctionCallOverrideWeather(AIAgent agent, FunctionInvocationContext context, Func<FunctionInvocationContext, CancellationToken, ValueTask<object?>> next, CancellationToken cancellationToken)
|
||||
{
|
||||
Console.WriteLine($"Function Name: {context!.Function.Name} - Middleware 2 Pre-Invoke");
|
||||
|
||||
var result = await next(context, cancellationToken);
|
||||
|
||||
if (context.Function.Name == nameof(GetWeather))
|
||||
{
|
||||
// Override the result of the GetWeather function
|
||||
result = "The weather is sunny with a high of 25°C.";
|
||||
}
|
||||
Console.WriteLine($"Function Name: {context!.Function.Name} - Middleware 2 Post-Invoke");
|
||||
return result;
|
||||
}
|
||||
|
||||
// This middleware redacts PII information from input and output messages.
|
||||
async Task<AgentRunResponse> PIIMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
|
||||
{
|
||||
// Redact PII information from input messages
|
||||
var filteredMessages = FilterMessages(messages);
|
||||
Console.WriteLine("Pii Middleware - Filtered Messages Pre-Run");
|
||||
|
||||
var response = await innerAgent.RunAsync(filteredMessages, thread, options, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Redact PII information from output messages
|
||||
response.Messages = FilterMessages(response.Messages);
|
||||
|
||||
Console.WriteLine("Pii Middleware - Filtered Messages Post-Run");
|
||||
|
||||
return response;
|
||||
|
||||
static IList<ChatMessage> FilterMessages(IEnumerable<ChatMessage> messages)
|
||||
{
|
||||
return messages.Select(m => new ChatMessage(m.Role, FilterPii(m.Text))).ToList();
|
||||
}
|
||||
|
||||
static string FilterPii(string content)
|
||||
{
|
||||
// Regex patterns for PII detection (simplified for demonstration)
|
||||
Regex[] piiPatterns = [
|
||||
new(@"\b\d{3}-\d{3}-\d{4}\b", RegexOptions.Compiled), // Phone number (e.g., 123-456-7890)
|
||||
new(@"\b[\w\.-]+@[\w\.-]+\.\w+\b", RegexOptions.Compiled), // Email address
|
||||
new(@"\b[A-Z][a-z]+\s[A-Z][a-z]+\b", RegexOptions.Compiled) // Full name (e.g., John Doe)
|
||||
];
|
||||
|
||||
foreach (var pattern in piiPatterns)
|
||||
{
|
||||
content = pattern.Replace(content, "[REDACTED: PII]");
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
// This middleware enforces guardrails by redacting certain keywords from input and output messages.
|
||||
async Task<AgentRunResponse> GuardrailMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
|
||||
{
|
||||
// Redact keywords from input messages
|
||||
var filteredMessages = FilterMessages(messages);
|
||||
|
||||
Console.WriteLine("Guardrail Middleware - Filtered messages Pre-Run");
|
||||
|
||||
// Proceed with the agent run
|
||||
var response = await innerAgent.RunAsync(filteredMessages, thread, options, cancellationToken);
|
||||
|
||||
// Redact keywords from output messages
|
||||
response.Messages = FilterMessages(response.Messages);
|
||||
|
||||
Console.WriteLine("Guardrail Middleware - Filtered messages Post-Run");
|
||||
|
||||
return response;
|
||||
|
||||
List<ChatMessage> FilterMessages(IEnumerable<ChatMessage> messages)
|
||||
{
|
||||
return messages.Select(m => new ChatMessage(m.Role, FilterContent(m.Text))).ToList();
|
||||
}
|
||||
|
||||
static string FilterContent(string content)
|
||||
{
|
||||
foreach (var keyword in new[] { "harmful", "illegal", "violence" })
|
||||
{
|
||||
if (content.Contains(keyword, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "[REDACTED: Forbidden content]";
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
// This middleware handles Human in the loop console interaction for any user approval required during function calling.
|
||||
async Task<AgentRunResponse> ConsolePromptingApprovalMiddleware(IEnumerable<ChatMessage> messages, AgentThread? thread, AgentRunOptions? options, AIAgent innerAgent, CancellationToken cancellationToken)
|
||||
{
|
||||
AgentRunResponse response = await innerAgent.RunAsync(messages, thread, options, cancellationToken);
|
||||
|
||||
List<UserInputRequestContent> userInputRequests = response.UserInputRequests.ToList();
|
||||
|
||||
while (userInputRequests.Count > 0)
|
||||
{
|
||||
// Ask the user to approve each function call request.
|
||||
// For simplicity, we are assuming here that only function approval requests are being made.
|
||||
|
||||
// Pass the user input responses back to the agent for further processing.
|
||||
response.Messages = userInputRequests
|
||||
.OfType<FunctionApprovalRequestContent>()
|
||||
.Select(functionApprovalRequest =>
|
||||
{
|
||||
Console.WriteLine($"The agent would like to invoke the following function, please reply Y to approve: Name {functionApprovalRequest.FunctionCall.Name}");
|
||||
bool approved = Console.ReadLine()?.Equals("Y", StringComparison.OrdinalIgnoreCase) ?? false;
|
||||
return new ChatMessage(ChatRole.User, [functionApprovalRequest.CreateResponse(approved)]);
|
||||
})
|
||||
.ToList();
|
||||
|
||||
response = await innerAgent.RunAsync(response.Messages, thread, options, cancellationToken);
|
||||
|
||||
userInputRequests = response.UserInputRequests.ToList();
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(middlewareEnabledAgent.Name);
|
||||
@@ -0,0 +1,58 @@
|
||||
# Agent Middleware
|
||||
|
||||
This sample demonstrates how to add middleware to intercept agent runs and function calls to implement cross-cutting concerns like logging, validation, and guardrails.
|
||||
|
||||
## What This Sample Shows
|
||||
|
||||
1. Azure Foundry Agents integration via `AIProjectClient` and `AzureCliCredential`
|
||||
2. Agent run middleware (logging and monitoring)
|
||||
3. Function invocation middleware (logging and overriding tool results)
|
||||
4. Per-request agent run middleware
|
||||
5. Per-request function pipeline with approval
|
||||
6. Combining agent-level and per-request middleware
|
||||
|
||||
## Function Invocation Middleware
|
||||
|
||||
Not all agents support function invocation middleware.
|
||||
|
||||
Attempting to use function middleware on agents that do not wrap a ChatClientAgent or derives from it will throw an InvalidOperationException.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Running the Sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step12_Middleware
|
||||
```
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
When you run this sample, you will see the following demonstrations:
|
||||
|
||||
1. **Example 1: Wording Guardrail** - The agent receives a request for harmful content. The guardrail middleware intercepts the request and prevents the agent from responding to harmful prompts, returning a safe response instead.
|
||||
|
||||
2. **Example 2: PII Detection** - The agent receives a message containing personally identifiable information (name, phone number, email). The PII middleware detects and filters this sensitive information before processing.
|
||||
|
||||
3. **Example 3: Agent Function Middleware** - The agent uses function tools (GetDateTime and GetWeather) to answer a question about the current time and weather in Seattle. The function middleware logs the function calls and can override results if needed.
|
||||
|
||||
4. **Example 4: Human-in-the-Loop Function Approval** - The agent attempts to call a weather function, but the approval middleware intercepts the call and prompts the user to approve or deny the function invocation before it executes. The user can respond with "Y" to approve or any other input to deny.
|
||||
|
||||
Each example demonstrates how middleware can be used to implement cross-cutting concerns and control agent behavior at different levels (agent-level and per-request).
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);CA1812</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,139 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to use plugins with an AI agent. Plugin classes can
|
||||
// depend on other services that need to be injected. In this sample, the
|
||||
// AgentPlugin class uses the WeatherProvider and CurrentTimeProvider classes
|
||||
// to get weather and current time information. Both services are registered
|
||||
// in the service collection and injected into the plugin.
|
||||
// Plugin classes may have many methods, but only some are intended to be used
|
||||
// as AI functions. The AsAITools method of the plugin class shows how to specify
|
||||
// which methods should be exposed to the AI agent.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string AssistantInstructions = "You are a helpful assistant that helps people find information.";
|
||||
const string AssistantName = "PluginAssistant";
|
||||
|
||||
// Create a service collection to hold the agent plugin and its dependencies.
|
||||
ServiceCollection services = new();
|
||||
services.AddSingleton<WeatherProvider>();
|
||||
services.AddSingleton<CurrentTimeProvider>();
|
||||
services.AddSingleton<AgentPlugin>(); // The plugin depends on WeatherProvider and CurrentTimeProvider registered above.
|
||||
|
||||
IServiceProvider serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Define the agent with plugin tools
|
||||
// Define the agent you want to create. (Prompt Agent in this case)
|
||||
AIAgent agent = aiProjectClient.CreateAIAgent(
|
||||
name: AssistantName,
|
||||
model: deploymentName,
|
||||
instructions: AssistantInstructions,
|
||||
tools: serviceProvider.GetRequiredService<AgentPlugin>().AsAITools().ToList(),
|
||||
services: serviceProvider);
|
||||
|
||||
// Invoke the agent and output the text result.
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
Console.WriteLine(await agent.RunAsync("Tell me current time and weather in Seattle.", thread));
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agent.Name);
|
||||
|
||||
/// <summary>
|
||||
/// The agent plugin that provides weather and current time information.
|
||||
/// </summary>
|
||||
/// <param name="weatherProvider">The weather provider to get weather information.</param>
|
||||
internal sealed class AgentPlugin(WeatherProvider weatherProvider)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the weather information for the specified location.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method demonstrates how to use the dependency that was injected into the plugin class.
|
||||
/// </remarks>
|
||||
/// <param name="location">The location to get the weather for.</param>
|
||||
/// <returns>The weather information for the specified location.</returns>
|
||||
public string GetWeather(string location)
|
||||
{
|
||||
return weatherProvider.GetWeather(location);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current date and time for the specified location.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method demonstrates how to resolve a dependency using the service provider passed to the method.
|
||||
/// </remarks>
|
||||
/// <param name="sp">The service provider to resolve the <see cref="CurrentTimeProvider"/>.</param>
|
||||
/// <param name="location">The location to get the current time for.</param>
|
||||
/// <returns>The current date and time as a <see cref="DateTimeOffset"/>.</returns>
|
||||
public DateTimeOffset GetCurrentTime(IServiceProvider sp, string location)
|
||||
{
|
||||
// Resolve the CurrentTimeProvider from the service provider
|
||||
CurrentTimeProvider currentTimeProvider = sp.GetRequiredService<CurrentTimeProvider>();
|
||||
|
||||
return currentTimeProvider.GetCurrentTime(location);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the functions provided by this plugin.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// In real world scenarios, a class may have many methods and only a subset of them may be intended to be exposed as AI functions.
|
||||
/// This method demonstrates how to explicitly specify which methods should be exposed to the AI agent.
|
||||
/// </remarks>
|
||||
/// <returns>The functions provided by this plugin.</returns>
|
||||
public IEnumerable<AITool> AsAITools()
|
||||
{
|
||||
yield return AIFunctionFactory.Create(this.GetWeather);
|
||||
yield return AIFunctionFactory.Create(this.GetCurrentTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The weather provider that returns weather information.
|
||||
/// </summary>
|
||||
internal sealed class WeatherProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the weather information for the specified location.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The weather information is hardcoded for demonstration purposes.
|
||||
/// In a real application, this could call a weather API to get actual weather data.
|
||||
/// </remarks>
|
||||
/// <param name="location">The location to get the weather for.</param>
|
||||
/// <returns>The weather information for the specified location.</returns>
|
||||
public string GetWeather(string location)
|
||||
{
|
||||
return $"The weather in {location} is cloudy with a high of 15°C.";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the current date and time.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class returns the current date and time using the system's clock.
|
||||
/// </remarks>
|
||||
internal sealed class CurrentTimeProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current date and time.
|
||||
/// </summary>
|
||||
/// <param name="location">The location to get the current time for (not used in this implementation).</param>
|
||||
/// <returns>The current date and time as a <see cref="DateTimeOffset"/>.</returns>
|
||||
public DateTimeOffset GetCurrentTime(string location)
|
||||
{
|
||||
return DateTimeOffset.Now;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
# Using Plugins with AI Agents
|
||||
|
||||
This sample demonstrates how to use plugins with AI agents, where plugins are services registered in dependency injection that expose methods as AI function tools.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating plugin services with methods to expose as tools
|
||||
- Using AsAITools() to selectively expose plugin methods
|
||||
- Registering plugins in dependency injection
|
||||
- Using plugins with AI agents
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step13_Plugins
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create a plugin service with methods to expose as tools
|
||||
2. Register the plugin in dependency injection
|
||||
3. Create an agent named "PluginAgent" with the plugin methods as function tools
|
||||
4. Run the agent with a prompt that triggers it to call plugin methods
|
||||
5. The agent will invoke the plugin methods to retrieve information
|
||||
6. Clean up resources by deleting the agent
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);CA1812</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Azure.AI.Projects" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to use Code Interpreter Tool with AI Agents.
|
||||
|
||||
using System.Text;
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
using OpenAI.Assistants;
|
||||
using OpenAI.Responses;
|
||||
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
|
||||
|
||||
const string AgentInstructions = "You are a personal math tutor. When asked a math question, write and run code using the python tool to answer the question.";
|
||||
const string AgentNameMEAI = "CoderAgent-MEAI";
|
||||
const string AgentNameNative = "CoderAgent-NATIVE";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
|
||||
// Option 1 - Using HostedCodeInterpreterTool + AgentOptions (MEAI + AgentFramework)
|
||||
// Create the server side agent version
|
||||
AIAgent agentOption1 = await aiProjectClient.CreateAIAgentAsync(
|
||||
model: deploymentName,
|
||||
name: AgentNameMEAI,
|
||||
instructions: AgentInstructions,
|
||||
tools: [new HostedCodeInterpreterTool() { Inputs = [] }]);
|
||||
|
||||
// Option 2 - Using PromptAgentDefinition SDK native type
|
||||
// Create the server side agent version
|
||||
AIAgent agentOption2 = await aiProjectClient.CreateAIAgentAsync(
|
||||
name: AgentNameNative,
|
||||
creationOptions: new AgentVersionCreationOptions(
|
||||
new PromptAgentDefinition(model: deploymentName)
|
||||
{
|
||||
Instructions = AgentInstructions,
|
||||
Tools = {
|
||||
ResponseTool.CreateCodeInterpreterTool(
|
||||
new CodeInterpreterToolContainer(
|
||||
CodeInterpreterToolContainerConfiguration.CreateAutomaticContainerConfiguration(fileIds: [])
|
||||
)
|
||||
),
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// Either invoke option1 or option2 agent, should have same result
|
||||
// Option 1
|
||||
AgentRunResponse response = await agentOption1.RunAsync("I need to solve the equation sin(x) + x^2 = 42");
|
||||
|
||||
// Option 2
|
||||
// AgentRunResponse response = await agentOption2.RunAsync("I need to solve the equation sin(x) + x^2 = 42");
|
||||
|
||||
// Get the CodeInterpreterToolCallContent
|
||||
CodeInterpreterToolCallContent? toolCallContent = response.Messages.SelectMany(m => m.Contents).OfType<CodeInterpreterToolCallContent>().FirstOrDefault();
|
||||
if (toolCallContent?.Inputs is not null)
|
||||
{
|
||||
DataContent? codeInput = toolCallContent.Inputs.OfType<DataContent>().FirstOrDefault();
|
||||
if (codeInput?.HasTopLevelMediaType("text") ?? false)
|
||||
{
|
||||
Console.WriteLine($"Code Input: {Encoding.UTF8.GetString(codeInput.Data.ToArray()) ?? "Not available"}");
|
||||
}
|
||||
}
|
||||
|
||||
// Get the CodeInterpreterToolResultContent
|
||||
CodeInterpreterToolResultContent? toolResultContent = response.Messages.SelectMany(m => m.Contents).OfType<CodeInterpreterToolResultContent>().FirstOrDefault();
|
||||
if (toolResultContent?.Outputs is not null && toolResultContent.Outputs.OfType<TextContent>().FirstOrDefault() is { } resultOutput)
|
||||
{
|
||||
Console.WriteLine($"Code Tool Result: {resultOutput.Text}");
|
||||
}
|
||||
|
||||
// Getting any annotations generated by the tool
|
||||
foreach (AIAnnotation annotation in response.Messages.SelectMany(m => m.Contents).SelectMany(C => C.Annotations ?? []))
|
||||
{
|
||||
if (annotation.RawRepresentation is TextAnnotationUpdate citationAnnotation)
|
||||
{
|
||||
Console.WriteLine($$"""
|
||||
File Id: {{citationAnnotation.OutputFileId}}
|
||||
Text to Replace: {{citationAnnotation.TextToReplace}}
|
||||
Filename: {{Path.GetFileName(citationAnnotation.TextToReplace)}}
|
||||
""");
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agentOption1.Name);
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agentOption2.Name);
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
# Using Code Interpreter with AI Agents
|
||||
|
||||
This sample demonstrates how to use the code interpreter tool with AI agents. The code interpreter allows agents to write and execute Python code to solve problems, perform calculations, and analyze data.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating agents with code interpreter capabilities
|
||||
- Using HostedCodeInterpreterTool (MEAI abstraction)
|
||||
- Using native SDK code interpreter tools (ResponseTool.CreateCodeInterpreterTool)
|
||||
- Extracting code inputs and results from agent responses
|
||||
- Handling code interpreter annotations
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step14_CodeInterpreter
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create two agents with code interpreter capabilities:
|
||||
- Option 1: Using HostedCodeInterpreterTool (MEAI abstraction)
|
||||
- Option 2: Using native SDK code interpreter tools
|
||||
2. Run the agent with a mathematical problem: "I need to solve the equation sin(x) + x^2 = 42"
|
||||
3. The agent will use the code interpreter to write and execute Python code to solve the equation
|
||||
4. Extract and display the code that was executed
|
||||
5. Display the results from the code execution
|
||||
6. Display any annotations generated by the code interpreter tool
|
||||
7. Clean up resources by deleting both agents
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
+98
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using OpenAI.Responses;
|
||||
|
||||
namespace Demo.ComputerUse;
|
||||
|
||||
/// <summary>
|
||||
/// Enum for tracking the state of the simulated web search flow.
|
||||
/// </summary>
|
||||
internal enum SearchState
|
||||
{
|
||||
Initial, // Browser search page
|
||||
Typed, // Text entered in search box
|
||||
PressedEnter // Enter key pressed, transitioning to results
|
||||
}
|
||||
|
||||
internal static class ComputerUseUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// Load and convert screenshot images to base64 data URLs.
|
||||
/// </summary>
|
||||
internal static Dictionary<string, byte[]> LoadScreenshotAssets()
|
||||
{
|
||||
string baseDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets");
|
||||
|
||||
ReadOnlySpan<(string key, string fileName)> screenshotFiles =
|
||||
[
|
||||
("browser_search", "cua_browser_search.png"),
|
||||
("search_typed", "cua_search_typed.png"),
|
||||
("search_results", "cua_search_results.png")
|
||||
];
|
||||
|
||||
Dictionary<string, byte[]> screenshots = [];
|
||||
foreach (var (key, fileName) in screenshotFiles)
|
||||
{
|
||||
string fullPath = Path.GetFullPath(Path.Combine(baseDir, fileName));
|
||||
screenshots[key] = File.ReadAllBytes(fullPath);
|
||||
}
|
||||
|
||||
return screenshots;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process a computer action and simulate its execution.
|
||||
/// </summary>
|
||||
internal static (SearchState CurrentState, byte[] ImageBytes) HandleComputerActionAndTakeScreenshot(
|
||||
ComputerCallAction action,
|
||||
SearchState currentState,
|
||||
Dictionary<string, byte[]> screenshots)
|
||||
{
|
||||
Console.WriteLine($"Simulating the execution of computer action: {action.Kind}");
|
||||
|
||||
SearchState newState = DetermineNextState(action, currentState);
|
||||
string imageKey = GetImageKey(newState);
|
||||
|
||||
return (newState, screenshots[imageKey]);
|
||||
}
|
||||
|
||||
private static SearchState DetermineNextState(ComputerCallAction action, SearchState currentState)
|
||||
{
|
||||
string actionType = action.Kind.ToString();
|
||||
|
||||
if (actionType.Equals("type", StringComparison.OrdinalIgnoreCase) && action.TypeText is not null)
|
||||
{
|
||||
return SearchState.Typed;
|
||||
}
|
||||
|
||||
if (IsEnterKeyAction(action, actionType))
|
||||
{
|
||||
Console.WriteLine(" -> Detected ENTER key press");
|
||||
return SearchState.PressedEnter;
|
||||
}
|
||||
|
||||
if (actionType.Equals("click", StringComparison.OrdinalIgnoreCase) && currentState == SearchState.Typed)
|
||||
{
|
||||
Console.WriteLine(" -> Detected click after typing");
|
||||
return SearchState.PressedEnter;
|
||||
}
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
private static bool IsEnterKeyAction(ComputerCallAction action, string actionType)
|
||||
{
|
||||
return (actionType.Equals("key", StringComparison.OrdinalIgnoreCase) ||
|
||||
actionType.Equals("keypress", StringComparison.OrdinalIgnoreCase)) &&
|
||||
action.KeyPressKeyCodes is not null &&
|
||||
(action.KeyPressKeyCodes.Contains("Return", StringComparer.OrdinalIgnoreCase) ||
|
||||
action.KeyPressKeyCodes.Contains("Enter", StringComparer.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
private static string GetImageKey(SearchState state) => state switch
|
||||
{
|
||||
SearchState.PressedEnter => "search_results",
|
||||
SearchState.Typed => "search_typed",
|
||||
_ => "browser_search"
|
||||
};
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);OPENAICUA001</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Identity" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.AzureAI\Microsoft.Agents.AI.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\cua_browser_search.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Assets\cua_search_results.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Assets\cua_search_typed.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to use Computer Use Tool with AI Agents.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
using OpenAI.Responses;
|
||||
|
||||
namespace Demo.ComputerUse;
|
||||
|
||||
internal sealed class Program
|
||||
{
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
string endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_PROJECT_ENDPOINT is not set.");
|
||||
string deploymentName = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME") ?? "computer-use-preview";
|
||||
|
||||
// Get a client to create/retrieve/delete server side agents with Azure Foundry Agents.
|
||||
AIProjectClient aiProjectClient = new(new Uri(endpoint), new AzureCliCredential());
|
||||
const string AgentInstructions = @"
|
||||
You are a computer automation assistant.
|
||||
|
||||
Be direct and efficient. When you reach the search results page, read and describe the actual search result titles and descriptions you can see.
|
||||
";
|
||||
|
||||
const string AgentNameMEAI = "ComputerAgent-MEAI";
|
||||
const string AgentNameNative = "ComputerAgent-NATIVE";
|
||||
|
||||
// Option 1 - Using ComputerUseTool + AgentOptions (MEAI + AgentFramework)
|
||||
// Create AIAgent directly
|
||||
AIAgent agentOption1 = await aiProjectClient.CreateAIAgentAsync(
|
||||
name: AgentNameMEAI,
|
||||
model: deploymentName,
|
||||
instructions: AgentInstructions,
|
||||
description: "Computer automation agent with screen interaction capabilities.",
|
||||
tools: [
|
||||
ResponseTool.CreateComputerTool(ComputerToolEnvironment.Browser, 1026, 769).AsAITool(),
|
||||
]);
|
||||
|
||||
// Option 2 - Using PromptAgentDefinition SDK native type
|
||||
// Create the server side agent version
|
||||
AIAgent agentOption2 = await aiProjectClient.CreateAIAgentAsync(
|
||||
name: AgentNameNative,
|
||||
creationOptions: new AgentVersionCreationOptions(
|
||||
new PromptAgentDefinition(model: deploymentName)
|
||||
{
|
||||
Instructions = AgentInstructions,
|
||||
Tools = { ResponseTool.CreateComputerTool(
|
||||
environment: new ComputerToolEnvironment("windows"),
|
||||
displayWidth: 1026,
|
||||
displayHeight: 769) }
|
||||
})
|
||||
);
|
||||
|
||||
// Either invoke option1 or option2 agent, should have same result
|
||||
// Option 1
|
||||
await InvokeComputerUseAgentAsync(agentOption1);
|
||||
|
||||
// Option 2
|
||||
//await InvokeComputerUseAgentAsync(agentOption2);
|
||||
|
||||
// Cleanup by agent name removes the agent version created.
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agentOption1.Name);
|
||||
await aiProjectClient.Agents.DeleteAgentAsync(agentOption2.Name);
|
||||
}
|
||||
|
||||
private static async Task InvokeComputerUseAgentAsync(AIAgent agent)
|
||||
{
|
||||
// Load screenshot assets
|
||||
Dictionary<string, byte[]> screenshots = ComputerUseUtil.LoadScreenshotAssets();
|
||||
|
||||
ChatOptions chatOptions = new();
|
||||
ResponseCreationOptions responseCreationOptions = new()
|
||||
{
|
||||
TruncationMode = ResponseTruncationMode.Auto
|
||||
};
|
||||
chatOptions.RawRepresentationFactory = (_) => responseCreationOptions;
|
||||
ChatClientAgentRunOptions runOptions = new(chatOptions)
|
||||
{
|
||||
AllowBackgroundResponses = true,
|
||||
};
|
||||
|
||||
AgentThread thread = agent.GetNewThread();
|
||||
|
||||
ChatMessage message = new(ChatRole.User, [
|
||||
new TextContent("I need you to help me search for 'OpenAI news'. Please type 'OpenAI news' and submit the search. Once you see search results, the task is complete."),
|
||||
new DataContent(new BinaryData(screenshots["browser_search"]), "image/png")
|
||||
]);
|
||||
|
||||
// Initial request with screenshot - start with Bing search page
|
||||
Console.WriteLine("Starting computer automation session (initial screenshot: cua_browser_search.png)...");
|
||||
|
||||
AgentRunResponse runResponse = await agent.RunAsync(message, thread: thread, options: runOptions);
|
||||
|
||||
// Main interaction loop
|
||||
const int MaxIterations = 10;
|
||||
int iteration = 0;
|
||||
// Initialize state machine
|
||||
SearchState currentState = SearchState.Initial;
|
||||
string initialCallId = string.Empty;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Poll until the response is complete.
|
||||
while (runResponse.ContinuationToken is { } token)
|
||||
{
|
||||
// Wait before polling again.
|
||||
await Task.Delay(TimeSpan.FromSeconds(2));
|
||||
|
||||
// Continue with the token.
|
||||
runOptions.ContinuationToken = token;
|
||||
|
||||
runResponse = await agent.RunAsync(thread, runOptions);
|
||||
}
|
||||
|
||||
Console.WriteLine($"Agent response received (ID: {runResponse.ResponseId})");
|
||||
|
||||
if (iteration >= MaxIterations)
|
||||
{
|
||||
Console.WriteLine($"\nReached maximum iterations ({MaxIterations}). Stopping.");
|
||||
break;
|
||||
}
|
||||
|
||||
iteration++;
|
||||
Console.WriteLine($"\n--- Iteration {iteration} ---");
|
||||
|
||||
// Check for computer calls in the response
|
||||
IEnumerable<ComputerCallResponseItem> computerCallResponseItems = runResponse.Messages
|
||||
.SelectMany(x => x.Contents)
|
||||
.Where(c => c.RawRepresentation is ComputerCallResponseItem and not null)
|
||||
.Select(c => (ComputerCallResponseItem)c.RawRepresentation!);
|
||||
|
||||
ComputerCallResponseItem? firstComputerCall = computerCallResponseItems.FirstOrDefault();
|
||||
if (firstComputerCall is null)
|
||||
{
|
||||
Console.WriteLine("No computer call actions found. Ending interaction.");
|
||||
Console.WriteLine($"Final Response: {runResponse}");
|
||||
break;
|
||||
}
|
||||
|
||||
// Process the first computer call response
|
||||
ComputerCallAction action = firstComputerCall.Action;
|
||||
string currentCallId = firstComputerCall.CallId;
|
||||
|
||||
// Set the initial computer call ID for tracking and subsequent responses.
|
||||
if (string.IsNullOrEmpty(initialCallId))
|
||||
{
|
||||
initialCallId = currentCallId;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Processing computer call (ID: {currentCallId})");
|
||||
|
||||
// Simulate executing the action and taking a screenshot
|
||||
(SearchState CurrentState, byte[] ImageBytes) screenInfo = ComputerUseUtil.HandleComputerActionAndTakeScreenshot(action, currentState, screenshots);
|
||||
currentState = screenInfo.CurrentState;
|
||||
|
||||
Console.WriteLine("Sending action result back to agent...");
|
||||
|
||||
AIContent content = new()
|
||||
{
|
||||
RawRepresentation = new ComputerCallOutputResponseItem(
|
||||
initialCallId,
|
||||
output: ComputerCallOutput.CreateScreenshotOutput(new BinaryData(screenInfo.ImageBytes), "image/png"))
|
||||
};
|
||||
|
||||
// Follow-up message with action result and new screenshot
|
||||
message = new(ChatRole.User, [content]);
|
||||
runResponse = await agent.RunAsync(message, thread: thread, options: runOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
# Using Computer Use Tool with AI Agents
|
||||
|
||||
This sample demonstrates how to use the computer use tool with AI agents. The computer use tool allows agents to interact with a computer environment by viewing the screen, controlling the mouse and keyboard, and performing various actions to help complete tasks.
|
||||
|
||||
## What this sample demonstrates
|
||||
|
||||
- Creating agents with computer use capabilities
|
||||
- Using HostedComputerTool (MEAI abstraction)
|
||||
- Using native SDK computer use tools (ResponseTool.CreateComputerTool)
|
||||
- Extracting computer action information from agent responses
|
||||
- Handling computer tool results (text output and screenshots)
|
||||
- Managing agent lifecycle (creation and deletion)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and deployment configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="computer-use-preview" # Optional, defaults to computer-use-preview
|
||||
```
|
||||
|
||||
## Run the sample
|
||||
|
||||
Navigate to the FoundryAgents sample directory and run:
|
||||
|
||||
```powershell
|
||||
cd dotnet/samples/GettingStarted/FoundryAgents
|
||||
dotnet run --project .\FoundryAgents_Step15_ComputerUse
|
||||
```
|
||||
|
||||
## Expected behavior
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create two agents with computer use capabilities:
|
||||
- Option 1: Using HostedComputerTool (MEAI abstraction)
|
||||
- Option 2: Using native SDK computer use tools
|
||||
2. Run the agent with a task: "I need you to help me search for 'OpenAI news'. Please type 'OpenAI news' and submit the search. Once you see search results, the task is complete."
|
||||
3. The agent will use the computer use tool to:
|
||||
- Interpret the screenshots
|
||||
- Issue action requests based on the task
|
||||
- Analyze the search results for "OpenAI news" from the screenshots.
|
||||
4. Extract and display the computer actions performed
|
||||
5. Display the results from the computer tool execution
|
||||
6. Display the final response from the agent
|
||||
7. Clean up resources by deleting both agents
|
||||
@@ -0,0 +1,82 @@
|
||||
# Getting started with Foundry Agents
|
||||
|
||||
The getting started with Foundry Agents samples demonstrate the fundamental concepts and functionalities
|
||||
of Azure Foundry Agents and can be used with Azure Foundry as the AI provider.
|
||||
|
||||
These samples showcase how to work with agents managed through Azure Foundry, including agent creation,
|
||||
versioning, multi-turn conversations, and advanced features like code interpretation and computer use.
|
||||
|
||||
## Getting started with Foundry Agents prerequisites
|
||||
|
||||
Before you begin, ensure you have the following prerequisites:
|
||||
|
||||
- .NET 8.0 SDK or later
|
||||
- Azure Foundry service endpoint and project configured
|
||||
- Azure CLI installed and authenticated (for Azure credential authentication)
|
||||
|
||||
**Note**: These samples use Azure Foundry Agents. For more information, see [Azure AI Foundry documentation](https://learn.microsoft.com/en-us/azure/ai-foundry/).
|
||||
|
||||
**Note**: These samples use Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure Foundry resource. For more information, see the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively).
|
||||
|
||||
## Samples
|
||||
|
||||
|Sample|Description|
|
||||
|---|---|
|
||||
|[Basics](./FoundryAgents_Step01.1_Basics/)|This sample demonstrates how to create and manage AI agents with versioning|
|
||||
|[Running a simple agent](./FoundryAgents_Step01.2_Running/)|This sample demonstrates how to create and run a basic Foundry agent|
|
||||
|[Multi-turn conversation](./FoundryAgents_Step02_MultiturnConversation/)|This sample demonstrates how to implement a multi-turn conversation with a Foundry agent|
|
||||
|[Using function tools](./FoundryAgents_Step03_UsingFunctionTools/)|This sample demonstrates how to use function tools with a Foundry agent|
|
||||
|[Using function tools with approvals](./FoundryAgents_Step04_UsingFunctionToolsWithApprovals/)|This sample demonstrates how to use function tools where approvals require human in the loop approvals before execution|
|
||||
|[Structured output](./FoundryAgents_Step05_StructuredOutput/)|This sample demonstrates how to use structured output with a Foundry agent|
|
||||
|[Persisted conversations](./FoundryAgents_Step06_PersistedConversations/)|This sample demonstrates how to persist conversations and reload them later|
|
||||
|[Observability](./FoundryAgents_Step07_Observability/)|This sample demonstrates how to add telemetry to a Foundry agent|
|
||||
|[Dependency injection](./FoundryAgents_Step08_DependencyInjection/)|This sample demonstrates how to add and resolve a Foundry agent with a dependency injection container|
|
||||
|[Using MCP client as tools](./FoundryAgents_Step09_UsingMcpClientAsTools/)|This sample demonstrates how to use MCP clients as tools with a Foundry agent|
|
||||
|[Using images](./FoundryAgents_Step10_UsingImages/)|This sample demonstrates how to use image multi-modality with a Foundry agent|
|
||||
|[Exposing as a function tool](./FoundryAgents_Step11_AsFunctionTool/)|This sample demonstrates how to expose a Foundry agent as a function tool|
|
||||
|[Using middleware](./FoundryAgents_Step12_Middleware/)|This sample demonstrates how to use middleware with a Foundry agent|
|
||||
|[Using plugins](./FoundryAgents_Step13_Plugins/)|This sample demonstrates how to use plugins with a Foundry agent|
|
||||
|[Code interpreter](./FoundryAgents_Step14_CodeInterpreter/)|This sample demonstrates how to use the code interpreter tool with a Foundry agent|
|
||||
|[Computer use](./FoundryAgents_Step15_ComputerUse/)|This sample demonstrates how to use computer use capabilities with a Foundry agent|
|
||||
|
||||
## Running the samples from the console
|
||||
|
||||
To run the samples, navigate to the desired sample directory, e.g.
|
||||
|
||||
```powershell
|
||||
cd FoundryAgents_Step01.2_Running
|
||||
```
|
||||
|
||||
Set the following environment variables:
|
||||
|
||||
```powershell
|
||||
$env:AZURE_FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.com/api/projects/your-foundry-project" # Replace with your Azure Foundry resource endpoint
|
||||
$env:AZURE_FOUNDRY_PROJECT_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-mini
|
||||
```
|
||||
|
||||
If the variables are not set, you will be prompted for the values when running the samples.
|
||||
|
||||
Execute the following command to build the sample:
|
||||
|
||||
```powershell
|
||||
dotnet build
|
||||
```
|
||||
|
||||
Execute the following command to run the sample:
|
||||
|
||||
```powershell
|
||||
dotnet run --no-build
|
||||
```
|
||||
|
||||
Or just build and run in one step:
|
||||
|
||||
```powershell
|
||||
dotnet run
|
||||
```
|
||||
|
||||
## Running the samples from Visual Studio
|
||||
|
||||
Open the solution in Visual Studio and set the desired sample project as the startup project. Then, run the project using the built-in debugger or by pressing `F5`.
|
||||
|
||||
You will be prompted for any required environment variables if they are not already set.
|
||||
|
||||
@@ -8,6 +8,7 @@ of the agent framework.
|
||||
|Sample|Description|
|
||||
|---|---|
|
||||
|[Agents](./Agents/README.md)|Step by step instructions for getting started with agents|
|
||||
|[Foundry Agents](./FoundryAgents/README.md)|Getting started with Azure Foundry Agents|
|
||||
|[Agent Providers](./AgentProviders/README.md)|Getting started with creating agents using various providers|
|
||||
|[Agents With Retrieval Augmented Generation (RAG)](./AgentWithRAG/README.md)|Adding Retrieval Augmented Generation (RAG) capabilities to your agents.|
|
||||
|[Agents With Memory](./AgentWithMemory/README.md)|Adding Memory capabilities to your agents.|
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ProjectsDebugTargetFrameworks>net9.0</ProjectsDebugTargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(Configuration)' == 'Debug'">$(ProjectsDebugTargetFrameworks)</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<InjectIsExternalInitOnLegacy>true</InjectIsExternalInitOnLegacy>
|
||||
<InjectSharedFoundryAgents>true</InjectSharedFoundryAgents>
|
||||
<InjectSharedWorkflowsExecution>true</InjectSharedWorkflowsExecution>
|
||||
<InjectSharedWorkflowsSettings>true</InjectSharedWorkflowsSettings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative\Microsoft.Agents.AI.Workflows.Declarative.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative.AzureAI\Microsoft.Agents.AI.Workflows.Declarative.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="ConfirmInput.yaml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+3
-6
@@ -1,8 +1,8 @@
|
||||
#
|
||||
# This workflow demonstrates a single agent interaction based on user input.
|
||||
# This workflow demonstrates how to use the Question action
|
||||
# to request user input and confirm it matches the original input.
|
||||
#
|
||||
# Any Foundry Agent may be used to provide the response.
|
||||
# See: ./setup/QuestionAgent.yaml
|
||||
# Note: This workflow doesn't make use of any agents.
|
||||
#
|
||||
kind: Workflow
|
||||
trigger:
|
||||
@@ -59,6 +59,3 @@ trigger:
|
||||
|
||||
Confirmed input:
|
||||
{Local.ConfirmedInput}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Shared.Workflows;
|
||||
|
||||
namespace Demo.Workflows.Declarative.ConfirmInput;
|
||||
|
||||
/// <summary>
|
||||
/// Demonstrate how to use the question action to request user input
|
||||
/// and confirm it matches the original input.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the README.md file in the parent folder (../README.md) for detailed
|
||||
/// information about the configuration required to run this sample.
|
||||
/// </remarks>
|
||||
internal sealed class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
// Initialize configuration
|
||||
IConfiguration configuration = Application.InitializeConfig();
|
||||
Uri foundryEndpoint = new(configuration.GetValue(Application.Settings.FoundryEndpoint));
|
||||
|
||||
// Get input from command line or console
|
||||
string workflowInput = Application.GetInput(args);
|
||||
|
||||
// Create the workflow factory. This class demonstrates how to initialize a
|
||||
// declarative workflow from a YAML file. Once the workflow is created, it
|
||||
// can be executed just like any regular workflow.
|
||||
WorkflowFactory workflowFactory = new("ConfirmInput.yaml", foundryEndpoint);
|
||||
|
||||
// Execute the workflow: The WorkflowRunner demonstrates how to execute
|
||||
// a workflow, handle the workflow events, and providing external input.
|
||||
// This also includes the ability to checkpoint workflow state and how to
|
||||
// resume execution.
|
||||
WorkflowRunner runner = new();
|
||||
await runner.ExecuteAsync(workflowFactory.CreateWorkflow, workflowInput);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ProjectsDebugTargetFrameworks>net9.0</ProjectsDebugTargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(Configuration)' == 'Debug'">$(ProjectsDebugTargetFrameworks)</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<InjectIsExternalInitOnLegacy>true</InjectIsExternalInitOnLegacy>
|
||||
<InjectSharedFoundryAgents>true</InjectSharedFoundryAgents>
|
||||
<InjectSharedWorkflowsExecution>true</InjectSharedWorkflowsExecution>
|
||||
<InjectSharedWorkflowsSettings>true</InjectSharedWorkflowsSettings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative\Microsoft.Agents.AI.Workflows.Declarative.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative.AzureAI\Microsoft.Agents.AI.Workflows.Declarative.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)..\..\..\..\..\..\workflow-samples\CustomerSupport.yaml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,441 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using OpenAI.Responses;
|
||||
using Shared.Foundry;
|
||||
using Shared.Workflows;
|
||||
|
||||
namespace Demo.Workflows.Declarative.CustomerSupport;
|
||||
|
||||
/// <summary>
|
||||
/// This workflow demonstrates using multiple agents to provide automated
|
||||
/// troubleshooting steps to resolve common issues with escalation options.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the README.md file in the parent folder (../README.md) for detailed
|
||||
/// information about the configuration required to run this sample.
|
||||
/// </remarks>
|
||||
internal sealed class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
// Initialize configuration
|
||||
IConfiguration configuration = Application.InitializeConfig();
|
||||
Uri foundryEndpoint = new(configuration.GetValue(Application.Settings.FoundryEndpoint));
|
||||
|
||||
// Create the ticketing plugin (mock functionality)
|
||||
TicketingPlugin plugin = new();
|
||||
|
||||
// Ensure sample agents exist in Foundry.
|
||||
await CreateAgentsAsync(foundryEndpoint, configuration, plugin);
|
||||
|
||||
// Get input from command line or console
|
||||
string workflowInput = Application.GetInput(args);
|
||||
|
||||
// Create the workflow factory. This class demonstrates how to initialize a
|
||||
// declarative workflow from a YAML file. Once the workflow is created, it
|
||||
// can be executed just like any regular workflow.
|
||||
WorkflowFactory workflowFactory =
|
||||
new("CustomerSupport.yaml", foundryEndpoint)
|
||||
{
|
||||
Functions =
|
||||
[
|
||||
AIFunctionFactory.Create(plugin.CreateTicket),
|
||||
AIFunctionFactory.Create(plugin.GetTicket),
|
||||
AIFunctionFactory.Create(plugin.ResolveTicket),
|
||||
AIFunctionFactory.Create(plugin.SendNotification),
|
||||
]
|
||||
};
|
||||
|
||||
// Execute the workflow: The WorkflowRunner demonstrates how to execute
|
||||
// a workflow, handle the workflow events, and providing external input.
|
||||
// This also includes the ability to checkpoint workflow state and how to
|
||||
// resume execution.
|
||||
WorkflowRunner runner = new();
|
||||
await runner.ExecuteAsync(workflowFactory.CreateWorkflow, workflowInput);
|
||||
}
|
||||
|
||||
private static async Task CreateAgentsAsync(Uri foundryEndpoint, IConfiguration configuration, TicketingPlugin plugin)
|
||||
{
|
||||
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "SelfServiceAgent",
|
||||
agentDefinition: DefineSelfServiceAgent(configuration),
|
||||
agentDescription: "Service agent for CustomerSupport workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "TicketingAgent",
|
||||
agentDefinition: DefineTicketingAgent(configuration, plugin),
|
||||
agentDescription: "Ticketing agent for CustomerSupport workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "TicketRoutingAgent",
|
||||
agentDefinition: DefineTicketRoutingAgent(configuration, plugin),
|
||||
agentDescription: "Routing agent for CustomerSupport workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "WindowsSupportAgent",
|
||||
agentDefinition: DefineWindowsSupportAgent(configuration, plugin),
|
||||
agentDescription: "Windows support agent for CustomerSupport workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "TicketResolutionAgent",
|
||||
agentDefinition: DefineResolutionAgent(configuration, plugin),
|
||||
agentDescription: "Resolution agent for CustomerSupport workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "TicketEscalationAgent",
|
||||
agentDefinition: TicketEscalationAgent(configuration, plugin),
|
||||
agentDescription: "Escalate agent for human support");
|
||||
}
|
||||
|
||||
private static PromptAgentDefinition DefineSelfServiceAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
Use your knowledge to work with the user to provide the best possible troubleshooting steps.
|
||||
|
||||
- If the user confirms that the issue is resolved, then the issue is resolved.
|
||||
- If the user reports that the issue persists, then escalate.
|
||||
""",
|
||||
TextOptions =
|
||||
new ResponseTextOptions
|
||||
{
|
||||
TextFormat =
|
||||
ResponseTextFormat.CreateJsonSchemaFormat(
|
||||
"TaskEvaluation",
|
||||
BinaryData.FromString(
|
||||
"""
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"IsResolved": {
|
||||
"type": "boolean",
|
||||
"description": "True if the user issue/ask has been resolved."
|
||||
},
|
||||
"NeedsTicket": {
|
||||
"type": "boolean",
|
||||
"description": "True if the user issue/ask requires that a ticket be filed."
|
||||
},
|
||||
"IssueDescription": {
|
||||
"type": "string",
|
||||
"description": "A concise description of the issue."
|
||||
},
|
||||
"AttemptedResolutionSteps": {
|
||||
"type": "string",
|
||||
"description": "An outline of the steps taken to attempt resolution."
|
||||
}
|
||||
},
|
||||
"required": ["IsResolved", "NeedsTicket", "IssueDescription", "AttemptedResolutionSteps"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
"""),
|
||||
jsonSchemaFormatDescription: null,
|
||||
jsonSchemaIsStrict: true),
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineTicketingAgent(IConfiguration configuration, TicketingPlugin plugin) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
Always create a ticket in Azure DevOps using the available tools.
|
||||
|
||||
Include the following information in the TicketSummary.
|
||||
|
||||
- Issue description: {{IssueDescription}}
|
||||
- Attempted resolution steps: {{AttemptedResolutionSteps}}
|
||||
|
||||
After creating the ticket, provide the user with the ticket ID.
|
||||
""",
|
||||
Tools =
|
||||
{
|
||||
AIFunctionFactory.Create(plugin.CreateTicket).AsOpenAIResponseTool()
|
||||
},
|
||||
StructuredInputs =
|
||||
{
|
||||
["IssueDescription"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "A concise description of the issue.",
|
||||
},
|
||||
["AttemptedResolutionSteps"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "An outline of the steps taken to attempt resolution.",
|
||||
}
|
||||
},
|
||||
TextOptions =
|
||||
new ResponseTextOptions
|
||||
{
|
||||
TextFormat =
|
||||
ResponseTextFormat.CreateJsonSchemaFormat(
|
||||
"TaskEvaluation",
|
||||
BinaryData.FromString(
|
||||
"""
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"TicketId": {
|
||||
"type": "string",
|
||||
"description": "The identifier of the ticket created in response to the user issue."
|
||||
},
|
||||
"TicketSummary": {
|
||||
"type": "string",
|
||||
"description": "The summary of the ticket created in response to the user issue."
|
||||
}
|
||||
},
|
||||
"required": ["TicketId", "TicketSummary"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
"""),
|
||||
jsonSchemaFormatDescription: null,
|
||||
jsonSchemaIsStrict: true),
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineTicketRoutingAgent(IConfiguration configuration, TicketingPlugin plugin) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
Determine how to route the given issue to the appropriate support team.
|
||||
|
||||
Choose from the available teams and their functions:
|
||||
- Windows Activation Support: Windows license activation issues
|
||||
- Windows Support: Windows related issues
|
||||
- Azure Support: Azure related issues
|
||||
- Network Support: Network related issues
|
||||
- Hardware Support: Hardware related issues
|
||||
- Microsoft Office Support: Microsoft Office related issues
|
||||
- General Support: General issues not related to the above categories
|
||||
""",
|
||||
Tools =
|
||||
{
|
||||
AIFunctionFactory.Create(plugin.GetTicket).AsOpenAIResponseTool(),
|
||||
},
|
||||
TextOptions =
|
||||
new ResponseTextOptions
|
||||
{
|
||||
TextFormat =
|
||||
ResponseTextFormat.CreateJsonSchemaFormat(
|
||||
"TaskEvaluation",
|
||||
BinaryData.FromString(
|
||||
"""
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"TeamName": {
|
||||
"type": "string",
|
||||
"description": "The name of the team to route the issue"
|
||||
}
|
||||
},
|
||||
"required": ["TeamName"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
"""),
|
||||
jsonSchemaFormatDescription: null,
|
||||
jsonSchemaIsStrict: true),
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineWindowsSupportAgent(IConfiguration configuration, TicketingPlugin plugin) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
Use your knowledge to work with the user to provide the best possible troubleshooting steps
|
||||
for issues related to Windows operating system.
|
||||
|
||||
- Utilize the "Attempted Resolutions Steps" as a starting point for your troubleshooting.
|
||||
- Never escalate without troubleshooting with the user.
|
||||
- If the user confirms that the issue is resolved, then the issue is resolved.
|
||||
- If the user reports that the issue persists, then escalate.
|
||||
|
||||
Issue: {{IssueDescription}}
|
||||
Attempted Resolution Steps: {{AttemptedResolutionSteps}}
|
||||
""",
|
||||
StructuredInputs =
|
||||
{
|
||||
["IssueDescription"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "A concise description of the issue.",
|
||||
},
|
||||
["AttemptedResolutionSteps"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "An outline of the steps taken to attempt resolution.",
|
||||
}
|
||||
},
|
||||
Tools =
|
||||
{
|
||||
AIFunctionFactory.Create(plugin.GetTicket).AsOpenAIResponseTool(),
|
||||
},
|
||||
TextOptions =
|
||||
new ResponseTextOptions
|
||||
{
|
||||
TextFormat =
|
||||
ResponseTextFormat.CreateJsonSchemaFormat(
|
||||
"TaskEvaluation",
|
||||
BinaryData.FromString(
|
||||
"""
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"IsResolved": {
|
||||
"type": "boolean",
|
||||
"description": "True if the user issue/ask has been resolved."
|
||||
},
|
||||
"NeedsEscalation": {
|
||||
"type": "boolean",
|
||||
"description": "True resolution could not be achieved and the issue/ask requires escalation."
|
||||
},
|
||||
"ResolutionSummary": {
|
||||
"type": "string",
|
||||
"description": "The summary of the steps that led to resolution."
|
||||
}
|
||||
},
|
||||
"required": ["IsResolved", "NeedsEscalation", "ResolutionSummary"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
"""),
|
||||
jsonSchemaFormatDescription: null,
|
||||
jsonSchemaIsStrict: true),
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineResolutionAgent(IConfiguration configuration, TicketingPlugin plugin) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
Resolve the following ticket in Azure DevOps.
|
||||
Always include the resolution details.
|
||||
|
||||
- Ticket ID: #{{TicketId}}
|
||||
- Resolution Summary: {{ResolutionSummary}}
|
||||
""",
|
||||
Tools =
|
||||
{
|
||||
AIFunctionFactory.Create(plugin.ResolveTicket).AsOpenAIResponseTool(),
|
||||
},
|
||||
StructuredInputs =
|
||||
{
|
||||
["TicketId"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "The identifier of the ticket being resolved.",
|
||||
},
|
||||
["ResolutionSummary"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "The steps taken to resolve the issue.",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition TicketEscalationAgent(IConfiguration configuration, TicketingPlugin plugin) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
You escalate the provided issue to human support team by sending an email if the issue is not resolved.
|
||||
|
||||
Here are some additional details that might help:
|
||||
- TicketId : {{TicketId}}
|
||||
- IssueDescription : {{IssueDescription}}
|
||||
- AttemptedResolutionSteps : {{AttemptedResolutionSteps}}
|
||||
|
||||
Before escalating, gather the user's email address for follow-up.
|
||||
If not known, ask the user for their email address so that the support team can reach them when needed.
|
||||
|
||||
When sending the email, include the following details:
|
||||
- To: support@contoso.com
|
||||
- Cc: user's email address
|
||||
- Subject of the email: "Support Ticket - {TicketId} - [Compact Issue Description]"
|
||||
- Body:
|
||||
- Issue description
|
||||
- Attempted resolution steps
|
||||
- User's email address
|
||||
- Any other relevant information from the conversation history
|
||||
|
||||
Assure the user that their issue will be resolved and provide them with a ticket ID for reference.
|
||||
""",
|
||||
Tools =
|
||||
{
|
||||
AIFunctionFactory.Create(plugin.GetTicket).AsOpenAIResponseTool(),
|
||||
AIFunctionFactory.Create(plugin.SendNotification).AsOpenAIResponseTool(),
|
||||
},
|
||||
StructuredInputs =
|
||||
{
|
||||
["TicketId"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "The identifier of the ticket being escalated.",
|
||||
},
|
||||
["IssueDescription"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "A concise description of the issue.",
|
||||
},
|
||||
["ResolutionSummary"] =
|
||||
new StructuredInputDefinition
|
||||
{
|
||||
IsRequired = false,
|
||||
DefaultValue = BinaryData.FromString(@"""unknown"""),
|
||||
Description = "An outline of the steps taken to attempt resolution.",
|
||||
}
|
||||
},
|
||||
TextOptions =
|
||||
new ResponseTextOptions
|
||||
{
|
||||
TextFormat =
|
||||
ResponseTextFormat.CreateJsonSchemaFormat(
|
||||
"TaskEvaluation",
|
||||
BinaryData.FromString(
|
||||
"""
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"IsComplete": {
|
||||
"type": "boolean",
|
||||
"description": "Has the email been sent and no more user input is required."
|
||||
},
|
||||
"UserMessage": {
|
||||
"type": "string",
|
||||
"description": "A natural language message to the user."
|
||||
}
|
||||
},
|
||||
"required": ["IsComplete", "UserMessage"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
"""),
|
||||
jsonSchemaFormatDescription: null,
|
||||
jsonSchemaIsStrict: true),
|
||||
}
|
||||
};
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Demo.Workflows.Declarative.CustomerSupport;
|
||||
|
||||
internal sealed class TicketingPlugin
|
||||
{
|
||||
private readonly Dictionary<string, TicketItem> _ticketStore = [];
|
||||
|
||||
[Description("Retrieve a ticket by identifier from Azure DevOps.")]
|
||||
public TicketItem? GetTicket(string id)
|
||||
{
|
||||
Trace(nameof(GetTicket));
|
||||
|
||||
this._ticketStore.TryGetValue(id, out TicketItem? ticket);
|
||||
|
||||
return ticket;
|
||||
}
|
||||
|
||||
[Description("Create a ticket in Azure DevOps and return its identifier.")]
|
||||
public string CreateTicket(string subject, string description, string notes)
|
||||
{
|
||||
Trace(nameof(CreateTicket));
|
||||
|
||||
TicketItem ticket = new()
|
||||
{
|
||||
Subject = subject,
|
||||
Description = description,
|
||||
Notes = notes,
|
||||
Id = Guid.NewGuid().ToString("N"),
|
||||
};
|
||||
|
||||
this._ticketStore[ticket.Id] = ticket;
|
||||
|
||||
return ticket.Id;
|
||||
}
|
||||
|
||||
[Description("Resolve an existing ticket in Azure DevOps given its identifier.")]
|
||||
public void ResolveTicket(string id, string resolutionSummary)
|
||||
{
|
||||
Trace(nameof(ResolveTicket));
|
||||
|
||||
if (this._ticketStore.TryGetValue(id, out TicketItem? ticket))
|
||||
{
|
||||
ticket.Status = TicketStatus.Resolved;
|
||||
}
|
||||
}
|
||||
|
||||
[Description("Send an email notification to escalate ticket engagement.")]
|
||||
public void SendNotification(string id, string email, string cc, string body)
|
||||
{
|
||||
Trace(nameof(SendNotification));
|
||||
}
|
||||
|
||||
private static void Trace(string functionName)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkMagenta;
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"\nFUNCTION: {functionName}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
|
||||
public enum TicketStatus
|
||||
{
|
||||
Open,
|
||||
InProgress,
|
||||
Resolved,
|
||||
Closed,
|
||||
}
|
||||
|
||||
public sealed class TicketItem
|
||||
{
|
||||
public TicketStatus Status { get; set; } = TicketStatus.Open;
|
||||
public string Subject { get; init; } = string.Empty;
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string Description { get; init; } = string.Empty;
|
||||
public string Notes { get; init; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ProjectsDebugTargetFrameworks>net9.0</ProjectsDebugTargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(Configuration)' == 'Debug'">$(ProjectsDebugTargetFrameworks)</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<InjectIsExternalInitOnLegacy>true</InjectIsExternalInitOnLegacy>
|
||||
<InjectSharedFoundryAgents>true</InjectSharedFoundryAgents>
|
||||
<InjectSharedWorkflowsExecution>true</InjectSharedWorkflowsExecution>
|
||||
<InjectSharedWorkflowsSettings>true</InjectSharedWorkflowsSettings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative\Microsoft.Agents.AI.Workflows.Declarative.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative.AzureAI\Microsoft.Agents.AI.Workflows.Declarative.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)..\..\..\..\..\..\workflow-samples\DeepResearch.yaml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="wttr.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,281 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Azure.AI.Projects;
|
||||
using Azure.AI.Projects.OpenAI;
|
||||
using Azure.Identity;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using OpenAI.Responses;
|
||||
using Shared.Foundry;
|
||||
using Shared.Workflows;
|
||||
|
||||
namespace Demo.Workflows.Declarative.DeepResearch;
|
||||
|
||||
/// <summary>
|
||||
/// Demonstrate a declarative workflow that accomplishes a task
|
||||
/// using the Magentic orchestration pattern developed by AutoGen.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the README.md file in the parent folder (../README.md) for detailed
|
||||
/// information about the configuration required to run this sample.
|
||||
/// </remarks>
|
||||
internal sealed class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
// Initialize configuration
|
||||
IConfiguration configuration = Application.InitializeConfig();
|
||||
Uri foundryEndpoint = new(configuration.GetValue(Application.Settings.FoundryEndpoint));
|
||||
|
||||
// Ensure sample agents exist in Foundry.
|
||||
await CreateAgentsAsync(foundryEndpoint, configuration);
|
||||
|
||||
// Get input from command line or console
|
||||
string workflowInput = Application.GetInput(args);
|
||||
|
||||
// Create the workflow factory. This class demonstrates how to initialize a
|
||||
// declarative workflow from a YAML file. Once the workflow is created, it
|
||||
// can be executed just like any regular workflow.
|
||||
WorkflowFactory workflowFactory = new("DeepResearch.yaml", foundryEndpoint);
|
||||
|
||||
// Execute the workflow: The WorkflowRunner demonstrates how to execute
|
||||
// a workflow, handle the workflow events, and providing external input.
|
||||
// This also includes the ability to checkpoint workflow state and how to
|
||||
// resume execution.
|
||||
WorkflowRunner runner = new();
|
||||
await runner.ExecuteAsync(workflowFactory.CreateWorkflow, workflowInput);
|
||||
}
|
||||
|
||||
private static async Task CreateAgentsAsync(Uri foundryEndpoint, IConfiguration configuration)
|
||||
{
|
||||
AIProjectClient aiProjectClient = new(foundryEndpoint, new AzureCliCredential());
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "ResearchAgent",
|
||||
agentDefinition: DefineResearchAgent(configuration),
|
||||
agentDescription: "Planner agent for DeepResearch workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "PlannerAgent",
|
||||
agentDefinition: DefinePlannerAgent(configuration),
|
||||
agentDescription: "Planner agent for DeepResearch workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "ManagerAgent",
|
||||
agentDefinition: DefineManagerAgent(configuration),
|
||||
agentDescription: "Manager agent for DeepResearch workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "SummaryAgent",
|
||||
agentDefinition: DefineSummaryAgent(configuration),
|
||||
agentDescription: "Summary agent for DeepResearch workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "KnowledgeAgent",
|
||||
agentDefinition: DefineKnowledgeAgent(configuration),
|
||||
agentDescription: "Research agent for DeepResearch workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "CoderAgent",
|
||||
agentDefinition: DefineCoderAgent(configuration),
|
||||
agentDescription: "Coder agent for DeepResearch workflow");
|
||||
|
||||
await aiProjectClient.CreateAgentAsync(
|
||||
agentName: "WeatherAgent",
|
||||
agentDefinition: DefineWeatherAgent(configuration),
|
||||
agentDescription: "Weather agent for DeepResearch workflow");
|
||||
}
|
||||
|
||||
private static PromptAgentDefinition DefineResearchAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelFull))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
In order to help begin addressing the user request, please answer the following pre-survey to the best of your ability.
|
||||
Keep in mind that you are Ken Jennings-level with trivia, and Mensa-level with puzzles, so there should be a deep well to draw from.
|
||||
|
||||
Here is the pre-survey:
|
||||
|
||||
1. Please list any specific facts or figures that are GIVEN in the request itself. It is possible that there are none.
|
||||
2. Please list any facts that may need to be looked up, and WHERE SPECIFICALLY they might be found. In some cases, authoritative sources are mentioned in the request itself.
|
||||
3. Please list any facts that may need to be derived (e.g., via logical deduction, simulation, or computation)
|
||||
4. Please list any facts that are recalled from memory, hunches, well-reasoned guesses, etc.
|
||||
|
||||
When answering this survey, keep in mind that 'facts' will typically be specific names, dates, statistics, etc. Your answer must only use the headings:
|
||||
|
||||
1. GIVEN OR VERIFIED FACTS
|
||||
2. FACTS TO LOOK UP
|
||||
3. FACTS TO DERIVE
|
||||
4. EDUCATED GUESSES
|
||||
|
||||
DO NOT include any other headings or sections in your response. DO NOT list next steps or plans until asked to do so.
|
||||
""",
|
||||
Tools =
|
||||
{
|
||||
//AgentTool.CreateBingGroundingTool( // TODO: Use Bing Grounding when available
|
||||
// new BingGroundingSearchToolParameters(
|
||||
// [new BingGroundingSearchConfiguration(this.GetSetting(Settings.FoundryGroundingTool))]))
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefinePlannerAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions = // TODO: Use Structured Inputs / Prompt Template
|
||||
"""
|
||||
Your only job is to devise an efficient plan that identifies (by name) how a team member may contribute to addressing the user request.
|
||||
|
||||
Only select the following team which is listed as "- [Name]: [Description]"
|
||||
|
||||
- WeatherAgent: Able to retrieve weather information
|
||||
- CoderAgent: Able to write and execute Python code
|
||||
- KnowledgeAgent: Able to perform generic websearches
|
||||
|
||||
The plan must be a bullet point list must be in the form "- [AgentName]: [Specific action or task for that agent to perform]"
|
||||
|
||||
Remember, there is no requirement to involve the entire team -- only select team member's whose particular expertise is required for this task.
|
||||
"""
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineManagerAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions = // TODO: Use Structured Inputs / Prompt Template
|
||||
"""
|
||||
Recall we have assembled the following team:
|
||||
|
||||
- KnowledgeAgent: Able to perform generic websearches
|
||||
- CoderAgent: Able to write and execute Python code
|
||||
- WeatherAgent: Able to retrieve weather information
|
||||
|
||||
To make progress on the request, please answer the following questions, including necessary reasoning:
|
||||
- Is the request fully satisfied? (True if complete, or False if the original request has yet to be SUCCESSFULLY and FULLY addressed)
|
||||
- Are we in a loop where we are repeating the same requests and / or getting the same responses from an agent multiple times? Loops can span multiple turns, and can include repeated actions like scrolling up or down more than a handful of times.
|
||||
- Are we making forward progress? (True if just starting, or recent messages are adding value. False if recent messages show evidence of being stuck in a loop or if there is evidence of significant barriers to success such as the inability to read from a required file)
|
||||
- Who should speak next? (select from: KnowledgeAgent, CoderAgent, WeatherAgent)
|
||||
- What instruction or question would you give this team member? (Phrase as if speaking directly to them, and include any specific information they may need)
|
||||
""",
|
||||
TextOptions =
|
||||
new ResponseTextOptions
|
||||
{
|
||||
TextFormat =
|
||||
ResponseTextFormat.CreateJsonSchemaFormat(
|
||||
"TaskEvaluation",
|
||||
BinaryData.FromString(
|
||||
"""
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"is_request_satisfied": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reason": { "type": "string" },
|
||||
"answer": { "type": "boolean" }
|
||||
},
|
||||
"required": ["reason", "answer"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"is_in_loop": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reason": { "type": "string" },
|
||||
"answer": { "type": "boolean" }
|
||||
},
|
||||
"required": ["reason", "answer"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"is_progress_being_made": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reason": { "type": "string" },
|
||||
"answer": { "type": "boolean" }
|
||||
},
|
||||
"required": ["reason", "answer"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"next_speaker": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reason": { "type": "string" },
|
||||
"answer": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["reason", "answer"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"instruction_or_question": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reason": { "type": "string" },
|
||||
"answer": { "type": "string" }
|
||||
},
|
||||
"required": ["reason", "answer"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["is_request_satisfied", "is_in_loop", "is_progress_being_made", "next_speaker", "instruction_or_question"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
"""),
|
||||
jsonSchemaFormatDescription: null,
|
||||
jsonSchemaIsStrict: true),
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineSummaryAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
We have completed the task.
|
||||
|
||||
Based only on the conversation and without adding any new information,
|
||||
synthesize the result of the conversation as a complete response to the user task.
|
||||
|
||||
The user will only ever see this last response and not the entire conversation,
|
||||
so please ensure it is complete and self-contained.
|
||||
"""
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineKnowledgeAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Tools =
|
||||
{
|
||||
//AgentTool.CreateBingGroundingTool( // TODO: Use Bing Grounding when available
|
||||
// new BingGroundingSearchToolParameters(
|
||||
// [new BingGroundingSearchConfiguration(this.GetSetting(Settings.FoundryGroundingTool))]))
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineCoderAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
You solve problem by writing and executing code.
|
||||
""",
|
||||
Tools =
|
||||
{
|
||||
ResponseTool.CreateCodeInterpreterTool(
|
||||
new(CodeInterpreterToolContainerConfiguration.CreateAutomaticContainerConfiguration()))
|
||||
}
|
||||
};
|
||||
|
||||
private static PromptAgentDefinition DefineWeatherAgent(IConfiguration configuration) =>
|
||||
new(configuration.GetValue(Application.Settings.FoundryModelMini))
|
||||
{
|
||||
Instructions =
|
||||
"""
|
||||
You are a weather expert.
|
||||
""",
|
||||
Tools =
|
||||
{
|
||||
AgentTool.CreateOpenApiTool(
|
||||
new OpenAPIFunctionDefinition(
|
||||
"weather-forecast",
|
||||
BinaryData.FromString(File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "wttr.json"))),
|
||||
new OpenAPIAnonymousAuthenticationDetails()))
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -12,7 +12,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<InjectSharedThrow>true</InjectSharedThrow>
|
||||
<InjectIsExternalInitOnLegacy>true</InjectIsExternalInitOnLegacy>
|
||||
<InjectSharedWorkflowsExecution>true</InjectSharedWorkflowsExecution>
|
||||
<InjectSharedWorkflowsSettings>true</InjectSharedWorkflowsSettings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -27,6 +29,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative\Microsoft.Agents.AI.Workflows.Declarative.csproj" />
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.Workflows.Declarative.AzureAI\Microsoft.Agents.AI.Workflows.Declarative.AzureAI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user