Compare commits

...
Author SHA1 Message Date
Eduard van ValkenburgandGitHub 8b73b5b1be Python: bump version and update changelog (#1277)
* bump version and update changelog

* undo lab package version bump

* add changelog to exclude pattern for links

* fix for ignore path

* exclude file
2025-10-07 21:41:59 +00:00
Eduard van ValkenburgandGitHub 76900f0eab Python: [BREAKING] parameter naming and other fixes (#1255)
* parameter naming and other fixes

* fix test

* fix azure openai responses decorator ordering

* fix test

* fix mypy

* fixes in options handling

* fix tests

* final fixes

* exclude macos tests

* fix model param
2025-10-07 21:18:48 +00:00
ChrisandGitHub 1a81ed202e Updated (#1272) 2025-10-07 19:09:41 +00:00
Tao ChenandGitHub df5477921b .NET: Add Orchestration SK->AF migration samples (#1044)
* Add Orchestration SK->AF migration samples

* fix samples

* clean up

* Add handoff

* Comments

* Address comments

* Fix build error

* Comments
2025-10-07 18:54:41 +00:00
CopilotGitHubeavanvalkenburgCopilotcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>Eduard van Valkenburgeavanvalkenburg
93577f76b1 Python: Add CHANGELOG.md to python folder with all merged PRs since first release (#1205)
* Initial plan

* Add CHANGELOG.md to python folder with all merged PRs since 1.0.0b251001

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Update python/CHANGELOG.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/CHANGELOG.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fixed headers in changelog

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <github@vanvalkenburg.eu>
2025-10-07 18:34:10 +00:00
Mark WallaceandGitHub 2b2d3a44a5 Version preview.251007.1 (#1271) 2025-10-07 18:30:12 +00:00
westeyandGitHub 554e1617b3 Rename AsAIAgent to GetAIAgent and update for foundry as well (#1257) 2025-10-07 18:19:18 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b2c5d797f7 Bump Aspire.Hosting.Azure.CognitiveServices from 9.5.0 to 9.5.1 (#1200)
---
updated-dependencies:
- dependency-name: Aspire.Hosting.Azure.CognitiveServices
  dependency-version: 9.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 18:16:12 +00:00
a45e2ab28e Python: Added method to expose agent as MCP server (#1248)
* Added method to expose agent as MCP server

* Update python/packages/core/agent_framework/_agents.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/packages/core/agent_framework/_agents.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Addressed PR feedback

* Updated doc string

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-07 17:21:53 +00:00
SergeyMenshykhandGitHub 1cff86b4ff enable enum serialization as strings and relaxed json escaping (#1267) 2025-10-07 17:07:13 +00:00
8bb1266020 Python: Add PDF file support to OpenAI content parser with filename mapping (#1121)
* Add mapping for application media type in OpenAI responses client

* Enhance multimodal input samples: Add PDF testing functionality and fix image sample

* Standardize filename handling and add multimodal samples

- Standardized filename extraction logic between chat and responses clients
- Both clients now omit filename when not provided (no default fallback)
- Added Azure Responses API multimodal sample with PDF support
- Cleaned up Azure Chat sample to focus on supported features only
- Fixed test comment placement for better code documentation
- Updated README with clear API capability differences

* Enhance multimodal input samples with image and PDF handling

- Refactor image and PDF handling in `azure_chat_multimodal.py` and `openai_chat_multimodal.py` to use new utility functions.
- Add `load_sample_pdf` and `create_sample_image` functions for better test asset management.
- Remove redundant code for creating sample images and PDFs.
- Introduce a sample PDF file in `sample_assets` for testing purposes.

* Fix formatting in OpenAI chat client

---------

Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
2025-10-07 17:04:33 +00:00
Giles OdigweandGitHub 1d27b57672 Python: ollama + azureai openapi samples fix (#1244)
* ollama + azureai openapi samples fix

* small fix
2025-10-07 16:14:34 +00:00
Eric ZhuandGitHub d01d9afb92 Python: Introduce add_agent functionality and added output_response to AgentExecutor; agent streaming behavior to follow workflow invocation (#1184)
* refactor AgentExecutor, add output_response flag for switching on or off workflow output for each agent.

* introduce add_agent

* make default agent's streaming to false

* address comments

* fix test

* add is_streaming to RunnerContext and WorkflowContext

* fix add_agent return

* fix tests

* address comments

* resolve conflict

* update to address comments

* fix
2025-10-07 16:11:40 +00:00
Stephen ToubandGitHub 959e5842c2 Removing duplicating update coalescing logic in AgentRunResponseExtensions (#1169) 2025-10-07 13:42:01 +00:00
d10b44d6bb .NET: Enable access to hosted AIAgents via OpenAI Responses (#947)
* init

* wip

* wip wip wip

* wip wip

* open up API

* enable for multiple agents

* more wip

* make frontend respond.

* wip

* not sure if proper setup

* define type

* cleanup

* frontend streaming wip

* use System.Net.ServerSentEvents

* usings

* reformat via ichatclient

* merge main renaming + refactor

* fix main merge + fix sample (a2a change)

* fix sample

* some rebase (not working yet)

* make it at least build somehow

* make non-stream work without internal types

* Input without custom models

* implement streaming

* test frontend

* enable alerts and fix

* build fixes & rereview

* Update dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI.Responses/Microsoft.Agents.AI.Hosting.OpenAI.Responses.csproj

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dotnet/src/Microsoft.Agents.AI.Hosting.OpenAI.Responses/Utils/ResponseItemJsonConverter.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix agent discovery

* rename

* rename project into Microsoft.Agents.AI.Hosting.OpenAI (no responses in name)

* PR address comments x1

* address PR comments x2

* correctly instantiate OpenAIResponse

* address PR comments x3

* reconfigure JSON serialization & handle AOT warnings

* fix build

* proper ref

* check update differently

* correct check

* exclude dotnet format diagnostics for IL2026 and IL3050

* space  :)

* re-review

* add comments

* remove unnecessary using

* always take last openai response item

* set responseItem Id explicitly

* add agent.name validation for uri

* cleanup

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
2025-10-07 12:39:08 +00:00
SergeyMenshykhandGitHub 3fd5768b34 .NET: Improve structured output for chat client agent (#1172)
* improve structured output for chat client agent

* add comment to the result property

* remove code duplication and add tests

* refactor the CreateAIAgent extension methods to return specific types, so consumers can avoid unnecessary downcasting.

* fix type and remove unused using.

* add ChatClientAgentRunResponse and move AgentRunResponse to the abstractions package to reuse later.

* seal ChatClientAgentRunResponse

* update xml comment

* remove funcitons from sample

* rename agent for streaming
2025-10-07 12:04:26 +00:00
westeyandGitHub 5117d7da5c Add AzureCLI to the dev containers (#1254) 2025-10-07 10:46:54 +00:00
westeyandGitHub 3dc14dac79 .NET: Add a CreateAIAgent extension method to IChatClient (#1223)
* Add a CreateAIAgent extension method to IChatClient

* Fix unit tests

* Add tests with null chat clients to ensure appropriate failure

* Switch to similar constructor

* Add ChatClientBuilder BuildAgent extensions

* Address code review comments.
2025-10-07 09:47:33 +00:00
74905af778 .NET: Fix bug where ChatClientAgent throws when providing a ChatMessageStore with a service that requries service storage (#1229)
* Fix bug where ChatClientAgent throws when providing a ChatMessageStore with a service that requries service storage

* Update dotnet/tests/Microsoft.Agents.AI.UnitTests/ChatClient/ChatClientAgentTests.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-07 08:31:34 +00:00
7506046f43 .NET: Add sample to show ChatReducer usage (#1221)
* Add sample to show ChatReducer usage

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-07 08:17:31 +00:00
49f25358d7 Python: Sample on integration of Azure OpenAI Responses Client with a local MCP server (#1215)
* added a sample on integration of Azure OpenAI Responses Client with hosted Model Context Protocol (MCP)

* added additional comments mentioning that the Microsoft Learn MCP server can be replaced by any other desired MCP server

* corrected the MCP server type to local

* added a newline at the end

* Update python/samples/getting_started/agents/azure_openai/azure_responses_client_with_local_mcp.py

Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>

---------

Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
2025-10-07 07:54:29 +00:00
Eduard van ValkenburgandGitHub b49395fa3d Python: added approval_mode and allowed_tools to local MCP (#1203)
* added approval_mode and allowed_tools to local MCP

* updated docs
2025-10-07 07:44:08 +00:00
7ebe00ec3d [BREAKING] .NET: Workflow Off-Thread Execution Mode (#1233)
* Updates to async run loop.

* fix: Workflow Onwership can be release by nonowner

* fix: Incorrect handling of blockOnPending in StreamingRun

Depending on whether we are running in streaming on non-streaming mode, we may be using the StreamingRun in different ways. Unfortunately, the only place we can really know what is the actual state of execution is in the RunEventStream implementations.

This resulted in blocking where blocking was unneeded and occasionally not-blocking when blocking was needed.

The fix is to move the logic of handling this blocking into RunEventStream implementations.

* fix: Fix cleanup on error and end run

This ensures we clean up the background resources correctly.

* fix: Ensure we let the run loop proceed when shutting down

* fix: Add timeout for Input Waiting

* fix: Make the samples properly clean up `Run`s and `StreamingRun`s

* fix: Simplify Declarative Workflow Run disposal pattern

* Also fixes missing .Disposal() in Integration tests

---------

Co-authored-by: Ben Thomas <ben.thomas@microsoft.com>
2025-10-07 01:07:38 +00:00
0113e0466d .NET Workflows - Fix code generation cases (#1242)
* Updated

* Passing

* Ready

* Update dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/ConversationMessages.yaml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Comment

* Code analysis

* Unit-tests/provider signature

* Comment

* Consistent

* Checkpoint

* Fixed

* Revert

* Test display name

* Enable tests

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-06 23:34:46 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
477c0dbf1a Bump danielpalme/ReportGenerator-GitHub-Action from 5.4.13 to 5.4.16 (#966)
Bumps [danielpalme/ReportGenerator-GitHub-Action](https://github.com/danielpalme/reportgenerator-github-action) from 5.4.13 to 5.4.16.
- [Release notes](https://github.com/danielpalme/reportgenerator-github-action/releases)
- [Commits](https://github.com/danielpalme/reportgenerator-github-action/compare/5.4.13...5.4.16)

---
updated-dependencies:
- dependency-name: danielpalme/ReportGenerator-GitHub-Action
  dependency-version: 5.4.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 23:29:23 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fb95a92fce Bump Aspire.Hosting.AppHost from 9.5.0 to 9.5.1 (#1199)
---
updated-dependencies:
- dependency-name: Aspire.Hosting.AppHost
  dependency-version: 9.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 23:26:35 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
00d5a09e01 Bump Aspire.Microsoft.Azure.Cosmos from 9.5.0 to 9.5.1 (#1201)
---
updated-dependencies:
- dependency-name: Aspire.Microsoft.Azure.Cosmos
  dependency-version: 9.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 23:26:07 +00:00
f81b4a5abe .NET Workflows - Fix converation behaviors for declarative worfklows (#1237)
* Updated

* Passing

* Ready

* Update dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Workflows/ConversationMessages.yaml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Comment

* Code analysis

* Unit-tests/provider signature

* Comment

* Consistent

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-06 22:04:41 +00:00
Michael McKechneyandGitHub f1694b0507 Correcting parameter assignment and using parameter naming vs relying on position (#1239) 2025-10-06 21:46:37 +00:00
66009c617d docs: update dev.md to fix "Get the Code" section (#1217)
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-10-06 19:53:34 +00:00
Giles OdigweandGitHub 4e6ae443cf Python: OpenAI Clients accepting api_key callback (#1139)
* openai clients accepting callable

* fixes

* version checks
2025-10-06 19:51:34 +00:00
Victor DibiaandGitHub ee8d95b3dc test: Make ChatClientAgent no-message test less flaky (#1196)
Capitalize instruction and relax assertion to accept any non-empty response instead of requiring exact text match. Fixes flaky test failures with reasoning models.
2025-10-06 19:09:01 +00:00
Eduard van ValkenburgandGitHub 714e7b50d4 Python: updated docstrings (#1225)
* updated docstrings

* fix tests and mypy

* hosted file search docstring update

* updated versions
2025-10-06 16:04:39 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b2ab9931fd Bump AWSSDK.Extensions.Bedrock.MEAI from 4.0.3.2 to 4.0.3.5 (#1102)
---
updated-dependencies:
- dependency-name: AWSSDK.Extensions.Bedrock.MEAI
  dependency-version: 4.0.3.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 15:16:35 +00:00
b839669eee Add Devcontainers to allow easy use of the AF repo from github codespaces (#1224)
* Add dev containers

* Add workspace folder and cs dev extension

* Try other workspace folder format

* Add default solution.

* Move default solution to settings.json

* Fix repo open

* Remove duplicate python codespace and rename folder

* Add recommended C# extensions and a default build task

* Add vscode icons extension by default

* Add python setup and customizations, plus ai studio for all

* Add bash command

* Try running devsetup from workspace folder

* Remove echo and cd

* Change workspace mount

* Change dotnet workspace name

* Revert workspacemount addition

* Try workspace mount to root

* remove trailing slash

* Try workspacefolder with var

* Revert to original approach

* Modify dev containers to work in main repo.

* Remove trailing comma

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-06 14:20:34 +00:00
CopilotGitHubstephentoubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>Stephen ToubSergeyMenshykh
62854197aa .NET: Fix A2A conversion routines to ignore unknown content types instead of throwing exceptions (#1154)
* Initial plan

* Update A2A conversion routines to ignore unknown content types

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>

* Fix dotnet format

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
2025-10-06 10:29:43 +00:00
Andrew NikolinandGitHub 4c5c6d0f98 Align skill naming (#1207)
Fixing what looks like a simple copy-paste naming issue
2025-10-06 07:43:04 +00:00
CopilotGitHubeavanvalkenburgCopilotcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>eavanvalkenburgEduard van Valkenburg
8bd3e11d3e Python: Standardize docstrings: Use Keyword Args for Settings classes and add environment variable examples (#1202)
* Initial plan

* Update Settings classes to use Keyword Args and add examples

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Add examples and env var documentation to chat clients

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Add env var docs and examples to Responses and AzureAI clients

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Remove Args from class docstrings where they belong in __init__

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Add env var docs and examples to Assistants clients

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* updated to keyword args

* Fix incorrect code block formatting in _workflows/_executor.py

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Fix markdown code blocks in _workflows/_edge.py - use Sphinx format

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Update _assistants_client.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <github@vanvalkenburg.eu>
Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-06 07:37:34 +00:00
0cd794abe7 added missing lib/utils.ts in devui frontend (#1197)
Co-authored-by: Alex Lavaee <alexlavaee@microsoft.com>
2025-10-06 07:34:34 +00:00
Victor DibiaandGitHub 5a7ca13af6 feat: Add name and description support to workflows (#1183)
Add optional name and description fields to workflows in both Python and .NET implementations, matching the existing agent API pattern.

Python changes:
- Add name/description parameters to WorkflowBuilder.__init__
- Add name/description attributes to Workflow class
- Include name/description in to_dict() serialization
- Add WORKFLOW_NAME and WORKFLOW_DESCRIPTION OTEL attributes
- Add tests in test_serialization.py and test_workflow_observability.py

.NET changes:
- Add Name and Description properties to Workflow and Workflow<T>
- Add WithName() and WithDescription() fluent methods to WorkflowBuilder
- Add WorkflowName and WorkflowDescription OTEL tags
- Add test in WorkflowBuilderSmokeTests.cs

This enables applications like DevUI to display human-readable workflow names (e.g., 'Data Processing Pipeline') instead of auto-generated UUIDs (e.g., 'Workflow 50fdd917').

Fixes: #1181
2025-10-04 15:20:17 +00:00
Eduard van ValkenburgandGitHub fd819c6c02 Python: Introducing AI Function approval (#1131)
* support for local function approval

* small fix

* fix mypy

* added bigger test scenario's for function calling and approvals

* updated lock

* updated return message for rejection

* fix test

* updated function result content handling
2025-10-04 15:19:16 +00:00
01f438d710 Python: DevUI improvements. (#1091)
* enable deeplinking in ui, add agent details to entity info, add usage data, add middleware example in samples and foundry agent.

* update ui build

* Update python/packages/devui/frontend/src/components/workflow/workflow-input-form.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/packages/devui/pyproject.toml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/packages/devui/pyproject.toml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* imporove mapping for agent nodes and serialiation for agent run events

* lint fixes

* update pyproj toml and ui updates

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-03 22:22:03 +00:00
ChrisandGitHub 61ac6d43b2 .NET Workflows - Update ObjectModel and PowerFx packages (#1125)
* Update

* Update package version

* Update package version

* This is "IT"!!!
2025-10-03 22:03:11 +00:00
54b35e76ed Python: Updating python DEV_SETUP to add brew-based uv installation. (#1173)
* Updating python DEV_SETUP to add brew-based uv installation.

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-03 20:57:12 +00:00
50c532b4ae docs: Update References to Agent2Agent protocol to use correct terminology (#1162)
Should be `Agent2Agent Protocol` not `Agent-to-Agent` unless talking about general agent to agent communication

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-10-03 19:10:05 +00:00
Jacob AlberandGitHub 32e7ff00b5 .NET: Add support for Subworkflows and many threading fixes (#1066)
* feat: Add support for Workflow-as-Executor

* Fixes routing of 'object' compile-typed variables to properly take in type information
* Fixes a concurrency issue in StepTracer

* fix: Make Subworkflow ExternalRequests work properly

* fix: Threading and Concurrency fixes; prep for OffThread Mode

* refactor: Remove dead code around OffStreamRunEventStream

Currently not used, and will be replaced with a rewrite when brought back, so having it in the change is not valuable.

* ci: Work around issues with dotnet-format not properly analyzing the source

* fix: Fix the logic of AsyncCoordinator and AsyncBarrier

* Prevent individual wait cancellations from canceling the entire barrier
* Propagate information about whether the wait was completed or cancelled, and whether any waiters were present when released

* fix: Remove superfluous acces to .Keys in InProcStepTracer

* refactor: Clean up AsyncCoordinator's use of AsyncBarrier
2025-10-03 17:26:30 +00:00
880a99ca05 .NET Workflows - Enable "human in the loop" case for declarative integration tests (#1171)
* Enabled

* Rollback visitor

* Update dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/WorkflowTest.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-03 17:24:22 +00:00
westeyandGitHub 3ee7461b59 Fix createdAt merging for agent run updates (#1161) 2025-10-03 16:04:06 +00:00
Jacob AlberandGitHub cfcb90bfe0 fix: Make CheckpointInfo constructor public (#1156)
In order to be able to restore checkpoints (and even implement ICheckpointStore)
2025-10-03 15:42:04 +00:00
westeyandGitHub 6a4e759965 Add sample showing how to use any foundry model (#1159) 2025-10-03 15:34:16 +00:00
westeyandGitHub c3b995fb6b Change MD linkchecker to only run when md files are changed in a PR and to run nightly (#1148)
* Ignore null, timeout, status codes

* Only run when a markdown file is changed and run nightly

* Add markdown change

* Add run on link checker change and arbitrary change
2025-10-03 13:11:19 +00:00
SergeyMenshykhandGitHub ca9f6fe21d update a2a sample to work with latest a2a library (#1149) 2025-10-03 12:04:43 +00:00
cf831b0348 Update A2A library to 0.3.1-preview (#1141)
Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
2025-10-03 09:31:31 +00:00
Stephen ToubandGitHub 4daeeb0f07 Add some DebuggerDisplays / DebuggerTypeProxys to abstraction types (#1144) 2025-10-03 08:51:49 +00:00
Evan MattsonandGitHub c543dbaa92 Python: Default DevUI workflows to string input when start node is auto-wrapped agent (#1143)
* DevUI workflows default to string input when start node is AgentExecutor

* Remove unnecessary sample

* Fix lint issue
2025-10-03 08:11:38 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5a208ab1e1 Bump Microsoft.Identity.Client.Extensions.Msal from 4.77.0 to 4.77.1 (#1103)
---
updated-dependencies:
- dependency-name: Microsoft.Identity.Client.Extensions.Msal
  dependency-version: 4.77.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 02:26:37 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3bbb01c095 Bump Anthropic.SDK from 5.5.2 to 5.5.3 (#1101)
---
updated-dependencies:
- dependency-name: Anthropic.SDK
  dependency-version: 5.5.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 01:49:41 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
58e2e58787 Bump Microsoft.NET.Test.Sdk from 17.14.1 to 18.0.0 (#1105)
---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-03 01:49:20 +00:00
390cc541ea .NET Workflows - Clean-up declarative docs and product-context. (#1134)
* Clean-up

* Rollback sample

---------

Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
2025-10-02 20:06:40 +00:00
bbf7e9c4cc Ignore CS8002 warnign when building packages (#1136)
Co-authored-by: Mark Wallace <markwallace@microsoft.com>
2025-10-02 21:04:20 +01:00
caf051637f Version preview.251002.1 (#1112)
Co-authored-by: Mark Wallace <markwallace@microsoft.com>
2025-10-02 21:03:55 +01:00
2f66235a33 .NET: Update dotnet tests workflow to be merge queue friendly (#1133)
* Checks were missing from setup - no change needed to config

* Changing path filtering logic for dotnet tests

* Update .github/workflows/dotnet-build-and-test.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-02 19:06:53 +00:00
2696de7428 docs: add missing pre flag (#1130)
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-10-02 18:50:47 +00:00
d5fe617285 added language and updated docs (#1129)
* added language and update docs

* Fix header formatting in TRANSPARENCY_FAQ.md

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-10-02 17:55:33 +00:00
Roger BarretoandGitHub a659e38f11 Checks were missing from setup - no change needed to config (#1128) 2025-10-02 16:39:20 +00:00
8b80a03fbb Python: updated docstrings of all _files (#1107)
* updated docstrings of all _files

* fix mypy

* fixed codeblocks in workflows and some other files

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-10-02 16:18:58 +00:00
Roger BarretoandGitHub d6c40edbc6 .NET: Enable integration tests on merge (#1123)
* Enable integration tests

* Enable IT in Schedules events

* Adding IT to pull request - Testing

* Remove debug + pull request
2025-10-02 15:49:36 +00:00
074529e5a0 .NET: dotnet sample for OTEL -> Application Insights + Grafana (#1083)
* Add Azure Monitor OpenTelemetry Exporter to AgentOpenTelemetry sample

* Update README to include Application Insights setup and Grafana dashboard links

* Update dotnet/samples/GettingStarted/AgentOpenTelemetry/README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-02 15:21:11 +00:00
Dmytro StrukandGitHub c7f20c8ec5 Python: Added Ollama example using OpenAIChatClient (#1100)
* Added Ollama example using OpenAIChatClient

* Small improvement
2025-10-02 15:14:29 +00:00
79def868b6 .NET: Add Prompt to support and improve AI Agent SK->AF Migration Results (#1081)
* Prompt progress

* Enriched prompt + Added to SLN visibility

* Set starting point for Copilot Migration

* Address prompt detail + prepare copilot migration to work with Agent nugets

* Address more prompt details

* Prompt update

* Improve description for migration

* Improve description for migration

* Improve description for migration

* Improve description for migration

* SLnx Upgrade Assistant use-case

* Extra tweaks to the migration prompt

* Update prompt

* Adding the migration guida as a visible reference to the project

* Improvements

* IMprovement

* Small improvements

* AI Guidance Overhaul.

* Update migration guide with better straightforward examples

* Update breaking glass instructions

* Namespace change + address feedback

* ChatComletionService considerations

* Add middleware guidance + public packages

* Removing + ignoring future generated files

* Potential gh bug?

* Prompt progress

* Enriched prompt + Added to SLN visibility

* Set starting point for Copilot Migration

* Address prompt detail + prepare copilot migration to work with Agent nugets

* Address more prompt details

* Prompt update

* Improve description for migration

* Improve description for migration

* Improve description for migration

* Improve description for migration

* SLnx Upgrade Assistant use-case

* Extra tweaks to the migration prompt

* Update prompt

* Adding the migration guida as a visible reference to the project

* Improvements

* IMprovement

* Small improvements

* AI Guidance Overhaul.

* Update migration guide with better straightforward examples

* Update breaking glass instructions

* Namespace change + address feedback

* ChatComletionService considerations

* Add middleware guidance + public packages

* Removing + ignoring future generated files

* Potential gh bug?

* Version bump

* Address observation

* Address observation

---------

Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
2025-10-02 15:00:19 +00:00
ChrisandGitHub 08ea625de0 .NET: NET Workflows - Skip conversation initialization when identifier is provided (#1087)
* Fix

* Code-gen case

* Tests

* Autosend logic

* Build fix

* Namespace

* Validation enhancement
2025-10-02 14:27:46 +00:00
westeyandGitHub cb62407fb8 .NET: Improve some core types xml docs (#1115)
* Improve some core types xml docs

* Consistent period usage
2025-10-02 14:18:22 +00:00
56beb52124 .NET: Fix lists in XML comments so they render properly in the documentation. (#1113)
* fix lists in XML comments so they render properly in documentation.

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/Extensions/A2ACardResolverExtensions.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

* Update dotnet/src/Microsoft.Agents.AI.A2A/A2AHostAgent.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
2025-10-02 13:58:11 +00:00
b1282254df .NET: Move the AsAIAgent extension methods to the correct class (#1106)
* Move the AsAIAgent extension methods to the correct class

* Fix format issue

* Disable unit test, see issue #1109

---------

Co-authored-by: Mark Wallace <markwallace@microsoft.com>
2025-10-02 12:41:22 +00:00
Shawn HenryandGitHub 1693b76ae3 Update pip install command for agent-framework (#1098) 2025-10-02 06:59:09 +00:00
Stephen ToubandGitHub 3ae9065b6b Tweak AgentAbstractionsJsonUtilities to better match AIJsonUtilities (#1094)
Functional change includes setting the encoder used by the options and employing JsonStringEnumConverter.
2025-10-02 05:19:27 +00:00
CopilotGitHubdmytrostrukcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
07db91174b Python: Fix Azure AI Getting Started samples: Improve documentation and code readability (#1089)
* Initial plan

* Fix Azure AI samples: Add dotenv support, fix async input, improve docs

Co-authored-by: dmytrostruk <13853051+dmytrostruk@users.noreply.github.com>

* Remove dotenv.load_dotenv() and revert async input() changes per review feedback

Co-authored-by: dmytrostruk <13853051+dmytrostruk@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: dmytrostruk <13853051+dmytrostruk@users.noreply.github.com>
2025-10-02 03:22:44 +00:00
CopilotGitHubdmytrostrukcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
cd1bdc1483 Python: Fix multimodal input sample: Document required environment variables and configuration options (#1088)
* Initial plan

* Update multimodal input sample to document required environment variables

Co-authored-by: dmytrostruk <13853051+dmytrostruk@users.noreply.github.com>

* Add examples showing how to pass deployment_name as parameter

Co-authored-by: dmytrostruk <13853051+dmytrostruk@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: dmytrostruk <13853051+dmytrostruk@users.noreply.github.com>
2025-10-02 01:34:31 +00:00
Evan MattsonandGitHub 4f4890cf6a Update getting started samples to reflect AF. Update a unit test. (#1093) 2025-10-02 01:20:12 +00:00
6d0f28eb9b .NET Workflows - Re-enable Declarative Integration Tests (#1080)
* Investigate

* Next

* Update initialization

* Should be ok

* Agent definition dx

* Link agent definitions

* Link agent definitions

* Path resolution #2

* Fix path resolution

* Another pass

* Another

* Better

* One more

* Whoopsie

* Update dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.IntegrationTests/Framework/AgentFactory.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Namespace

* Cleanup

* Temp config for pipeline

* Another temp workaround

* Test config: Bing Grounding Tool

* Update template

* Next pass

* Ok now

* Cleanup

* Test note

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-01 22:21:45 +00:00
Eric ZhuandGitHub 9a59b86fc8 Update README hello world example (#1075) 2025-10-01 21:40:32 +00:00
a414461570 .NET: Re-enable ImplicitUsings in samples and clean up NoWarns (#1060)
* Re-enable ImplicitUsings in samples and clean up NoWarns

* Fix dotnet format

* More dotnet format

* More dotnet format

---------

Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
2025-10-01 19:37:03 +00:00
Stephen ToubandGitHub 0fef277c70 Remove System.Linq.Async dependency from src assemblies (#1069)
We shouldn't be shipping any more dependencies on this package, as it's becoming legacy, replaced by System.Linq.AsyncEnumerable.

We'll eventually want to replace it with System.Linq.AsyncEnumerable in all tests/samples, too, but that's hard to do until SK updates to use S.L.AsyncEnumerable once its 10.0.0 version is released. I did remove the package reference from tests/samples where it's not needed.
2025-10-01 17:17:21 +00:00
ae4cb7d44a README update: badges, docs, and improved hello world (#1072)
* Update README with badges and updated installation instructions

* Update

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update nuget link

* Updated contributor resources

* Updated .NET hello world

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-01 17:15:16 +00:00
ChrisandGitHub 79414f9298 Disable (#1071) 2025-10-01 17:03:55 +00:00
westeyandGitHub 364188c44f .NET: Add link inspector (#1062)
* Add link inspector

* Comment out excludedirs while it's empty

* Fix broken links

* More links fixes

* Push further fixes

* Fix more links
2025-10-01 16:43:17 +00:00
Dmytro StrukandGitHub 193503cab9 Added nuget-props to hosting packages (#1068) 2025-10-01 16:20:41 +00:00
0e813b9c82 fix links in README for Python workflows and observability sections (#1067)
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-10-01 16:19:14 +00:00
ChrisandGitHub f5ca4f42c0 .NET Workflows -Fix Declarative Workflow Tests (#1065)
* Fixed

* Restore generated workflow

* Project

* Fine tune

* Update baseline

* Adjust test-case
2025-10-01 16:15:46 +00:00
dc9d1a6280 Version preview.251001.3 (#1064)
Co-authored-by: Mark Wallace <markwallace@microsoft.com>
2025-10-01 15:00:48 +00:00
631 changed files with 21175 additions and 6427 deletions
+19
View File
@@ -0,0 +1,19 @@
{
"name": "Python 3",
"image": "mcr.microsoft.com/devcontainers/python:3.13-bullseye",
"features": {
"ghcr.io/va-h/devcontainers-features/uv:1": {},
"ghcr.io/devcontainers/features/azure-cli:1.2.8": {}
},
"postCreateCommand": "bash ./devsetup.sh",
"workspaceFolder": "/workspaces/agent-framework/python/",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-windows-ai-studio.windows-ai-studio",
"littlefoxteam.vscode-python-test-adapter"
]
}
}
}
+19
View File
@@ -0,0 +1,19 @@
{
"name": "C# (.NET)",
"image": "mcr.microsoft.com/devcontainers/dotnet:9.0",
"features": {
"ghcr.io/devcontainers/features/dotnet:2.4.0": {},
"ghcr.io/devcontainers/features/powershell:1.5.1": {},
"ghcr.io/devcontainers/features/azure-cli:1.2.8": {}
},
"workspaceFolder": "/workspaces/agent-framework/dotnet/",
"customizations": {
"vscode": {
"extensions": [
"ms-dotnettools.csdevkit",
"vscode-icons-team.vscode-icons",
"ms-windows-ai-studio.windows-ai-studio"
]
}
}
}
+29
View File
@@ -0,0 +1,29 @@
dirs:
- .
excludedFiles:
- ./python/CHANGELOG.md
ignorePatterns:
- pattern: "/github/"
- pattern: "./actions"
- pattern: "./blob"
- pattern: "./issues"
- pattern: "./discussions"
- pattern: "./pulls"
- pattern: "https:\/\/platform.openai.com"
- pattern: "http:\/\/localhost"
- pattern: "http:\/\/127.0.0.1"
- pattern: "0001-spec.md"
- pattern: "0001-madr-architecture-decisions.md"
- pattern: "https://api.powerplatform.com/.default"
- pattern: "https://your-resource.openai.azure.com/"
- pattern: "http://host.docker.internal"
# excludedDirs:
# Folders which include links to localhost, since it's not ignored with regular expressions
baseUrl: https://github.com/microsoft/agent-framework/
aliveStatusCodes:
- 200
- 206
- 429
- 500
- 503
useGitIgnore: true
File diff suppressed because it is too large Load Diff
+35 -9
View File
@@ -8,17 +8,11 @@ name: dotnet-build-and-test
on:
workflow_dispatch:
pull_request:
branches: ["main", "feature*"]
paths:
- dotnet/**
- '.github/workflows/dotnet-build-and-test.yml'
branches: ["main"]
merge_group:
branches: ["main"]
push:
branches: ["main", "feature*"]
paths:
- dotnet/**
- '.github/workflows/dotnet-build-and-test.yml'
branches: ["main"]
schedule:
- cron: "0 0 * * *" # Run at midnight UTC daily
@@ -34,7 +28,33 @@ permissions:
id-token: "write"
jobs:
paths-filter:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
dotnetChanges: ${{ steps.filter.outputs.dotnet}}
steps:
- uses: actions/checkout@v5
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
dotnet:
- 'dotnet/**'
# run only if 'dotnet' files were changed
- name: dotnet tests
if: steps.filter.outputs.dotnet == 'true'
run: echo "Dotnet file"
# run only if not 'dotnet' files were changed
- name: not dotnet tests
if: steps.filter.outputs.dotnet != 'true'
run: echo "NOT dotnet file"
dotnet-build-and-test:
needs: paths-filter
if: needs.paths-filter.outputs.dotnetChanges == 'true'
strategy:
fail-fast: false
matrix:
@@ -54,6 +74,8 @@ jobs:
.
.github
dotnet
workflow-samples
- name: Setup dotnet
uses: actions/setup-dotnet@v5.0.0
with:
@@ -136,10 +158,14 @@ jobs:
# Azure AI Foundry
AzureAI__Endpoint: ${{ secrets.AZUREAI__ENDPOINT }}
AzureAI__DeploymentName: ${{ vars.AZUREAI__DEPLOYMENTNAME }}
AzureAI__BingConnectionId: ${{ vars.AZUREAI__BINGCONECTIONID }}
FOUNDRY_PROJECT_ENDPOINT: ${{ vars.FOUNDRY_PROJECT_ENDPOINT }}
FOUNDRY_MODEL_DEPLOYMENT_NAME: ${{ vars.FOUNDRY_MODEL_DEPLOYMENT_NAME }}
FOUNDRY_CONNECTION_GROUNDING_TOOL: ${{ vars.FOUNDRY_CONNECTION_GROUNDING_TOOL }}
# Generate test reports and check coverage
- name: Generate test reports
uses: danielpalme/ReportGenerator-GitHub-Action@5.4.13
uses: danielpalme/ReportGenerator-GitHub-Action@5.4.16
with:
reports: "./TestResults/Coverage/**/coverage.cobertura.xml"
targetdir: "./TestResults/Reports"
+2 -1
View File
@@ -86,10 +86,11 @@ jobs:
run: docker pull mcr.microsoft.com/dotnet/sdk:${{ matrix.dotnet }}
# This step will run dotnet format on each of the unique csproj files and fail if any changes are made
# exclude-diagnostics should be removed after fixes for IL2026 and IL3050 are out: https://github.com/dotnet/sdk/issues/51136
- name: Run dotnet format
if: steps.find-csproj.outputs.csproj_files != ''
run: |
for csproj in ${{ steps.find-csproj.outputs.csproj_files }}; do
echo "Running dotnet format on $csproj"
docker run --rm -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:${{ matrix.dotnet }} /bin/sh -c "dotnet format $csproj --verify-no-changes --verbosity diagnostic"
docker run --rm -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:${{ matrix.dotnet }} /bin/sh -c "dotnet format $csproj --verify-no-changes --verbosity diagnostic --exclude-diagnostics IL2026 IL3050"
done
+33
View File
@@ -0,0 +1,33 @@
name: Check .md links
on:
workflow_dispatch:
pull_request:
branches: ["main"]
paths:
- '**.md'
- '.github/workflows/markdown-link-check.yml'
- '.github/.linkspector.yml'
schedule:
- cron: "0 0 * * *" # Run at midnight UTC daily
permissions:
contents: read
jobs:
markdown-link-check:
runs-on: ubuntu-22.04
# check out the latest version of the code
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false
# Checks the status of hyperlinks in all files
- name: Run linkspector
uses: umbrelladocs/action-linkspector@v1
with:
reporter: local
filter_mode: nofilter
fail_on_error: true
config_file: ".github/.linkspector.yml"
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
fail-fast: true
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
# TODO(ekzhu): re-enable macos-latest when this is fixed: https://github.com/actions/runner-images/issues/11881
# todo: add macos-latest when problems are resolved
os: [ubuntu-latest, windows-latest]
env:
UV_PYTHON: ${{ matrix.python-version }}
+1
View File
@@ -15,6 +15,7 @@ downloads/
eggs/
.eggs/
lib/
!python/packages/devui/frontend/src/lib/
lib64/
parts/
sdist/
+2 -1
View File
@@ -50,6 +50,7 @@ DO's:
- **DO** give priority to the current style of the project or file you're changing
if it diverges from the general guidelines.
- **DO** use the pre-commit hooks for python to ensure proper formatting.
- **DO** include tests when adding new features. When fixing bugs, start with
adding a test that highlights how the current behavior is broken.
- **DO** keep the discussions focused. When a new or related topic comes up
@@ -115,4 +116,4 @@ builds and run tests (including the ones you are expected to run) for PRs. Build
and test runs must be clean.
If the CI build fails for any reason, the PR issue will be updated with a link
that can be used to determine the cause of the failure.
that can be used to determine the cause of the failure.
+59 -19
View File
@@ -1,7 +1,11 @@
![Microsoft Agent Framework](docs/assets/readme-banner.png)
# Welcome to Microsoft Agent Framework!
[![Microsoft Azure AI Foundry Discord](https://dcbadge.limes.pink/api/server/b5zjErwbQM)](https://discord.gg/b5zjErwbQM)
[![Microsoft Azure AI Foundry Discord](https://dcbadge.limes.pink/api/server/b5zjErwbQM?style=flat)](https://discord.gg/b5zjErwbQM)
[![MS Learn Documentation](https://img.shields.io/badge/MS%20Learn-Documentation-blue)](https://learn.microsoft.com/en-us/agent-framework/)
[![PyPI](https://img.shields.io/pypi/v/agent-framework)](https://pypi.org/project/agent-framework/)
[![NuGet](https://img.shields.io/nuget/v/Microsoft.Agents.AI)](https://www.nuget.org/profiles/MicrosoftAgentFramework/)
Welcome to Microsoft's comprehensive multi-language framework for building, orchestrating, and deploying AI agents with support for both .NET and Python implementations. This framework provides everything from simple chat agents to complex multi-agent workflows with graph-based orchestration.
@@ -19,20 +23,35 @@ Welcome to Microsoft's comprehensive multi-language framework for building, orch
## 📋 Getting Started
**Quick Installation:**
### 📦 Installation
- **Python**: `pip install agent-framework`
- **.NET**: `dotnet add package Microsoft.Agents.AI`
Python
**Getting started documentation:**
```bash
pip install agent-framework --pre
# This will install all sub-packages, see `python/packages` for individual packages.
# It may take a minute on first install on Windows.
```
- **[Quick Start Guide](https://learn.microsoft.com/agent-framework/tutorials/quick-start)** - Simple getting started instructions
.NET
```bash
dotnet add package Microsoft.Agents.AI
```
### 📚 Documentation
- **[Overview](https://learn.microsoft.com/agent-framework/overview/agent-framework-overview)** - High level overview of the framework
- **[Quick Start](https://learn.microsoft.com/agent-framework/tutorials/quick-start)** - Get started with a simple agent
- **[Tutorials](https://learn.microsoft.com/agent-framework/tutorials/overview)** - Step by step tutorials
- **[User Guide](https://learn.microsoft.com/en-us/agent-framework/user-guide/overview)** - In-depth user guide for building agents and workflows
- **[Migration from Semantic Kernel](https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-semantic-kernel)** - Guide to migrate from Semantic Kernel
- **[Migration from AutoGen](https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-autogen)** - Guide to migrate from AutoGen
### ✨ **Highlights**
- **Graph-based Workflows**: Connect agents and deterministic functions using data flows with streaming, checkpointing, human-in-the-loop, and time-travel capabilities
- [Python workflows](./python/samples/getting_started/workflow/) | [.NET workflows](./dotnet/samples/GettingStarted/Workflows/)
- [Python workflows](./python/samples/getting_started/workflows/) | [.NET workflows](./dotnet/samples/GettingStarted/Workflows/)
- **AF Labs**: Experimental packages for cutting-edge features including benchmarking, reinforcement learning, and research initiatives
- [Labs directory](./python/packages/lab/)
- **DevUI**: Interactive developer UI for agent development, testing, and debugging workflows
@@ -52,7 +71,7 @@ Welcome to Microsoft's comprehensive multi-language framework for building, orch
- **Python and C#/.NET Support**: Full framework support for both Python and C#/.NET implementations with consistent APIs
- [Python packages](./python/packages/) | [.NET source](./dotnet/src/)
- **Observability**: Built-in OpenTelemetry integration for distributed tracing, monitoring, and debugging
- [Python observability](./python/samples/getting_started/workflow/observability/) | [.NET telemetry](./dotnet/samples/GettingStarted/AgentOpenTelemetry/)
- [Python observability](./python/samples/getting_started/observability/) | [.NET telemetry](./dotnet/samples/GettingStarted/AgentOpenTelemetry/)
- **Multiple Agent Provider Support**: Support for various LLM providers with more being added continuously
- [Python examples](./python/samples/getting_started/agents/) | [.NET examples](./dotnet/samples/GettingStarted/AgentProviders/)
- **Middleware**: Flexible middleware system for request/response processing, exception handling, and custom pipelines
@@ -69,29 +88,47 @@ Welcome to Microsoft's comprehensive multi-language framework for building, orch
Create a simple Azure Responses Agent that writes a haiku about the Microsoft Agent Framework
```python
# pip install agent-framework --pre
# Use `az login` to authenticate with Azure CLI
import os
import asyncio
from agent_framework.azure import AzureOpenAIResponsesClient
from azure.identity import AzureCliCredential
async def main():
# Initialize a chat agent with basic instructions
agent = AzureOpenAIResponsesClient(credential=AzureCliCredential()).create_agent(
name="HaikuBot",
instructions="You are an upbeat assistant that writes beautifully.",
)
# Initialize a chat agent with Azure OpenAI Responses
# the endpoint, deployment name, and api version can be set via environment variables
# or they can be passed in directly to the AzureOpenAIResponsesClient constructor
agent = AzureOpenAIResponsesClient(
# endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
# deployment_name=os.environ["AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME"],
# api_version=os.environ["AZURE_OPENAI_API_VERSION"],
# api_key=os.environ["AZURE_OPENAI_API_KEY"], # Optional if using AzureCliCredential
credential=AzureCliCredential(), # Optional, if using api_key
).create_agent(
name="HaikuBot",
instructions="You are an upbeat assistant that writes beautifully.",
)
print(await agent.run("Write a haiku about Microsoft Agent Framework."))
print(await agent.run("Write a haiku about Microsoft Agent Framework."))
asyncio.run(main())
if __name__ == "__main__":
asyncio.run(main())
```
### Basic Agent - .NET
```c#
// dotnet add package Microsoft.Agents.AI.OpenAI --prerelease
// dotnet add package Azure.AI.OpenAI
// dotnet add package Azure.Identity
// Use `az login` to authenticate with Azure CLI
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME")!;
@@ -117,10 +154,13 @@ Console.WriteLine(await agent.RunAsync("Write a haiku about Microsoft Agent Fram
- [Agent Provider Samples](./dotnet/samples/GettingStarted/AgentProviders): samples showing different agent providers
- [Workflow Samples](./dotnet/samples/GettingStarted/Workflows): advanced multi-agent patterns and workflow orchestration
## Agent Framework Documentation
## Contributor Resources
- [Documentation](https://learn.microsoft.com/agent-framework/)
- [Agent Framework Repository](https://github.com/microsoft/agent-framework)
- [Contributing Guide](./CONTRIBUTING.md)
- [Python Development Guide](./python/DEV_SETUP.md)
- [Design Documents](./docs/design)
- [Architectural Decision Records](./docs/decisions)
- [MSFT Learn Docs](https://learn.microsoft.com/agent-framework/overview/agent-framework-overview)
## Important Notes
If you use the Microsoft Agent Framework to build applications that operate with third-party servers or agents, you do so at your own risk. We recommend reviewing all data being shared with third-party servers or agents and being cognizant of third-party practices for retention and location of data. It is your responsibility to manage whether your data will flow outside of your organization's Azure compliance and geographic boundaries and any related implications.
+6 -4
View File
@@ -1,4 +1,6 @@
# **What is Microsoft Agent Framework?**
# Responsible AI Transparency FAQs
**What is Microsoft Agent Framework?**
Microsoft Agent Framework is a comprehensive multi-language (C#/.NET and Python) framework for building, orchestrating, and deploying AI agents and multi-agent workflows. The system takes user instructions and conversation inputs and produces intelligent responses through AI agents that can integrate with various LLM providers (OpenAI, Azure OpenAI, Azure AI Foundry). It provides both simple chat agents and complex multi-agent workflows with graph-based orchestration.
@@ -95,7 +97,7 @@ Microsoft Agent Framework relies on existing LLMs. Using the framework retains c
The framework supports multiple external service types:
- **Native Functions**: Custom Python/C# functions that agents can invoke
- **A2A Integration**: Agent-to-agent communication and coordination
- **A2A (Agent2Agent)Integration**: Agent-to-agent communication and coordination
- **Model Context Protocol (MCP)**: External tools and data sources through MCP servers
- **Tools & External Capabilities**: Agent-invokable external services
@@ -108,7 +110,7 @@ Microsoft Agent Framework is an open-source framework that allows integration wi
**Data Access by Service Type**:
- **Native Functions**: Custom functions you develop have access to whatever data you explicitly pass to them as parameters
- **A2A (Agent-to-Agent)**: External agents can access conversation history, messages, and any data you configure to share through the communication interface
- **A2A (Agent2Agent)**: External agents can access conversation history, messages, and any data you configure to share through the communication interface
- **Model Context Protocol (MCP) Servers**: External MCP servers can access data according to the specific MCP server implementation and your configuration
- **External Tools**: Third-party tools and APIs have access to data you explicitly send to them through function calls
@@ -136,4 +138,4 @@ Microsoft Agent Framework is an open-source framework that allows integration wi
- Implement proper error handling for tool failures
- Use strong typing and compatibility validation
- Monitor external service health and implement fallback strategies
- Regular repository updates during preview period for bug fixes
- Regular repository updates during preview period for bug fixes
-30
View File
@@ -1,30 +0,0 @@
# Contributing to DOCS
To allow moving the docs to mslearn later, we are using language pivots as supported with mslearn markdown files.
This means that to make the docs easier to understand for users, we have a [PowerShell script](./generate-language-specific-docs.ps1) that generates language specific versions of the docs in separate folders.
The script strips out any pivots that are for a different language to the target.
Therefore, write your docs in the [docs-templates](./docs-templates/) folder and then
generate the language-specific versions by just running the PowerShell script.
```powershell
.\generate-language-specific-docs.ps1
```
## Using pivots
To have language-specific content, use the `::: zone pivot` syntax in your markdown file.
Note that when using a pivot you always have to have a section for both languages (csharp and python).
```text
::: zone pivot="programming-language-csharp"
C# specific content.
::: zone-end
::: zone pivot="programming-language-python"
Python specific content.
::: zone-end
```
@@ -47,9 +47,9 @@ This section provides an analysis of how other major AI agent frameworks handle
| Haystack | Python | N (Pipeline-based interception) | N/A (Pipeline Components/Routers) | Relies on modular pipelines for implicit interception but lacks explicit middleware/filters; custom components can read/write data flow via routing/transformations, but this is compositional rather than hook-based interception. [Details](#haystack) |
| OpenAI Swarm | Python | N | N/A | No explicit middleware/filters; interception requires custom wrappers or manual handling (e.g., function decorators, client subclassing), lacking native framework support for built-in components to accept such modifications. [Details](#openai-swarm) |
| Atomic Agents | Python | N | N/A (Composable Components) | No explicit middleware/filters; modularity allows composable units but no dedicated interception hooks or callbacks for custom reading/modification mid-execution. [Details](#atomic-agents) |
| Smolagents (Hugging Face)| Python | N | N/A | No explicit support; focuses on simple agent building without interception mechanisms or hooks for reading/modifying execution. [Details](#smolagents) |
| Phidata (Agno) | Python | N | N/A | No explicit middleware/filters; agents use tools/memory but no interception hooks for custom reading/modification of calls. [Details](#phidata) |
| PromptFlow (Microsoft) | Python | N (Tracing only) | Tracing | Supports tracing for LLM interactions, acting as callbacks for debugging/iteration; tracing is read-only for observability/telemetry without options to modify context or intercept calls beyond logging. [Details](#promptflow) |
| Smolagents (Hugging Face)| Python | N | N/A | No explicit support; focuses on simple agent building without interception mechanisms or hooks for reading/modifying execution. [Details](#smolagents-hugging-face) |
| Phidata (Agno) | Python | N | N/A | No explicit middleware/filters; agents use tools/memory but no interception hooks for custom reading/modification of calls. [Details](#phidata-agno) |
| PromptFlow (Microsoft) | Python | N (Tracing only) | Tracing | Supports tracing for LLM interactions, acting as callbacks for debugging/iteration; tracing is read-only for observability/telemetry without options to modify context or intercept calls beyond logging. [Details](#promptflow-microsoft) |
| n8n | JS/TS | Y (read/write) | Callbacks (inherited from LangChain) | AI Agent node uses LangChain under the hood, inheriting callbacks for observability; supports reading/modifying metadata or interrupting flow as in LangChain. [Details](#n8n) |
## Considered Options
+1 -1
View File
@@ -22,7 +22,7 @@
"agent-framework-google == 1.0.0"
]
```
* this means developers can use `pip install agent-framework[google]` to get AF with all Google connectors and dependencies, as well as manually installing the subpackage with `pip install agent-framework-google`.
* this means developers can use `pip install agent-framework[google] --pre` to get AF with all Google connectors and dependencies, as well as manually installing the subpackage with `pip install agent-framework-google --pre`.
### Sample getting started code
```python
+1
View File
@@ -198,6 +198,7 @@ dotnet_diagnostic.CA1508.severity = none # Avoid dead conditional code. Too many
dotnet_diagnostic.CA1510.severity = none # ArgumentNullException.Throw
dotnet_diagnostic.CA1512.severity = none # ArgumentOutOfRangeException.Throw
dotnet_diagnostic.CA1515.severity = none # Making public types from exes internal
dotnet_diagnostic.CA1707.severity = none # Identifiers should not contain underscores
dotnet_diagnostic.CA1846.severity = none # Prefer 'AsSpan' over 'Substring'
dotnet_diagnostic.CA1848.severity = none # For improved performance, use the LoggerMessage delegates
dotnet_diagnostic.CA1849.severity = none # Use async equivalent; analyzer is currently noisy
+5
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"ms-dotnettools.csdevkit"
]
}
+4
View File
@@ -0,0 +1,4 @@
{
"dotnet.defaultSolution": "agent-framework-dotnet.slnx",
"git.openRepositoryInParentFolders": "always"
}
+15
View File
@@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "dotnet",
"task": "build",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"label": "dotnet: build"
}
]
}
+2 -3
View File
@@ -8,8 +8,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<LangVersion>13</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<NoWarn>$(NoWarn);IDE0290;IDE0079;NU5128;CS8002</NoWarn>
<NoWarn>$(NoWarn);NU5128</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<ProjectsCoreTargetFrameworks>net9.0</ProjectsCoreTargetFrameworks>
<ProjectsTargetFrameworks>net9.0;net8.0;netstandard2.0;net472</ProjectsTargetFrameworks>
@@ -33,7 +32,7 @@
<!-- .NET Framework/.NET Standard don't properly support nullable reference types, suppress any warnings for those TFMs -->
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'net472' ">
<NoWarn>$(NoWarn);CS8604;CS8602</NoWarn>
<NoWarn>$(NoWarn);nullable</NoWarn>
</PropertyGroup>
<PropertyGroup>
+16 -11
View File
@@ -7,7 +7,7 @@
</PropertyGroup>
<PropertyGroup>
<!-- Aspire -->
<AspireAppHostSdkVersion>9.5.0</AspireAppHostSdkVersion>
<AspireAppHostSdkVersion>9.5.1</AspireAppHostSdkVersion>
</PropertyGroup>
<ItemGroup>
<!-- Azure.* -->
@@ -19,6 +19,7 @@
<PackageVersion Include="Azure.AI.Agents.Persistent" Version="1.2.0-beta.5" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.3.0-beta.2" />
<PackageVersion Include="Azure.Identity" Version="1.16.0" />
<PackageVersion Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.4.0" />
<PackageVersion Include="CommunityToolkit.Aspire.OllamaSharp" Version="9.8.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="9.0.9" />
<PackageVersion Include="Microsoft.Extensions.AI.AzureAIInference" Version="9.9.1-preview.1.25474.6" />
@@ -50,6 +51,10 @@
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<!-- Microsoft.Extensions.* -->
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="6.0.0" />
<PackageVersion Include="Microsoft.Agents.AI" Version="1.0.0-preview.251001.3" />
<PackageVersion Include="Microsoft.Agents.AI.Abstractions" Version="1.0.0-preview.251001.3" />
<PackageVersion Include="Microsoft.Agents.AI.AzureAI" Version="1.0.0-preview.251001.3" />
<PackageVersion Include="Microsoft.Agents.AI.OpenAI" Version="1.0.0-preview.251001.3" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.9" />
<PackageVersion Include="OpenAI" Version="2.4.0" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="9.9.1" />
@@ -78,25 +83,25 @@
<!-- Agent SDKs -->
<PackageVersion Include="Microsoft.Agents.CopilotStudio.Client" Version="1.2.41" />
<!-- A2A -->
<PackageVersion Include="A2A" Version="0.1.0-preview.2" />
<PackageVersion Include="A2A.AspNetCore" Version="0.1.0-preview.2" />
<PackageVersion Include="A2A" Version="0.3.1-preview" />
<PackageVersion Include="A2A.AspNetCore" Version="0.3.1-preview" />
<!-- MCP -->
<PackageVersion Include="ModelContextProtocol" Version="0.4.0-preview.1" />
<!-- Inference SDKs -->
<PackageVersion Include="Anthropic.SDK" Version="5.5.2" />
<PackageVersion Include="AWSSDK.Extensions.Bedrock.MEAI" Version="4.0.3.2" />
<PackageVersion Include="Anthropic.SDK" Version="5.5.3" />
<PackageVersion Include="AWSSDK.Extensions.Bedrock.MEAI" Version="4.0.3.5" />
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI" Version="0.9.2" />
<PackageVersion Include="OllamaSharp" Version="5.4.7" />
<!-- Identity -->
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.77.0" />
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.77.1" />
<!-- Workflows -->
<PackageVersion Include="Microsoft.Bot.ObjectModel" Version="1.2025.926-1" />
<PackageVersion Include="Microsoft.Bot.ObjectModel.Json" Version="1.2025.926-1" />
<PackageVersion Include="Microsoft.Bot.ObjectModel.PowerFx" Version="1.2025.926-1" />
<PackageVersion Include="Microsoft.PowerFx.Interpreter" Version="1.4.0-build.20250821-1001" />
<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" />
<!-- Test -->
<PackageVersion Include="FluentAssertions" Version="8.7.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<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.65.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Agents.Yaml" Version="1.65.0-beta" />
+28 -51
View File
@@ -1,64 +1,41 @@
# Get Started with Microsoft Agent Framework for C# Developers
## Run the Minimal Console demo
## Samples
The Minimal Console demo is a simple console application which shows how to create and run an agent.
- [Getting Started with Agents](./samples/GettingStarted/Agents): basic agent creation and tool usage
- [Agent Provider Samples](./samples/GettingStarted/AgentProviders): samples showing different agent providers
- [Workflow Samples](./samples/GettingStarted/Workflows): advanced multi-agent patterns and workflow orchestration
Supported Platforms:
- .Net: net9.0, net8.0, netstandard2.0, net472
- OS: Windows, macOS, Linux
## Quickstart
If you want to use the latest published packages following the instructions [here](../docs/FAQS.md).
### Basic Agent - .NET
### 1. Configure required environment variables
```c#
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
This samples uses Azure OpenAI by default so you need to set the following environment variable
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME")!;
``` powershell
$env:AZURE_OPENAI_ENDPOINT = "https://<your deployment>.openai.azure.com/"
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.CreateAIAgent(name: "HaikuBot", instructions: "You are an upbeat assistant that writes beautifully.");
Console.WriteLine(await agent.RunAsync("Write a haiku about Microsoft Agent Framework."));
```
If you want to use OpenAI
## Examples & Samples
1. Edit [Program.cs](./demos/MinimalConsole/Program.cs) and change the following lines:
```csharp
AIAgent agent = new AzureOpenAIClient(
new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!),
new AzureCliCredential())
.GetChatClient("gpt-4o-mini")
.CreateAIAgent(
instructions: "You are a helpful assistant, you can help the user with weather information.",
tools: [AIFunctionFactory.Create(GetWeather)]);
```
To this:
```csharp
AIAgent agent = new OpenAIClient(Environment.GetEnvironmentVariable("OPENAI_API_KEY")!)
.GetChatClient("gpt-4o-mini")
.CreateAIAgent(
instructions: "You are a helpful assistant, you can help the user with weather information.",
tools: [AIFunctionFactory.Create(GetWeather)]);
```
2. Create an environment variable with your OpenAI key
``` powershell
$env:OPENAI_API_KEY = "sk-..."
```
- [Getting Started with Agents](./samples/GettingStarted/Agents): basic agent creation and tool usage
- [Agent Provider Samples](./samples/GettingStarted/AgentProviders): samples showing different agent providers
- [Workflow Samples](./samples/GettingStarted/Workflows): advanced multi-agent patterns and workflow orchestration
### 2. Build the project
```powershell
cd demos\MinimalConsole
dotnet build
```
### 3. Run the demonstration
``` powershell
dotnet run --framework net9.0 --no-build
```
Sample output:
```
The weather in Amsterdam is currently cloudy, with a high temperature of 15°C.
```
## Agent Framework Documentation
- [Documentation](https://learn.microsoft.com/agent-framework/)
- [Agent Framework Repository](https://github.com/microsoft/agent-framework)
- [Design Documents](../docs/design)
- [Architectural Decision Records](../docs/decisions)
- [MSFT Learn Docs](https://learn.microsoft.com/agent-framework/overview/agent-framework-overview)
+22 -4
View File
@@ -24,7 +24,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_AzureFoundry/Agent_With_AzureFoundry.csproj" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_AzureFoundryAgent/Agent_With_AzureFoundryAgent.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" />
<Project Path="samples/GettingStarted/AgentProviders/Agent_With_CustomImplementation/Agent_With_CustomImplementation.csproj" />
@@ -51,10 +52,12 @@
<Project Path="samples/GettingStarted/Agents/Agent_Step13_Memory/Agent_Step13_Memory.csproj" />
<Project Path="samples/GettingStarted/Agents/Agent_Step14_Middleware/Agent_Step14_Middleware.csproj" />
<Project Path="samples/GettingStarted/Agents/Agent_Step15_Plugins/Agent_Step15_Plugins.csproj" />
<Project Path="samples/GettingStarted/Agents/Agent_Step16_ChatReduction/Agent_Step16_ChatReduction.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AgentWithOpenAI/">
<File Path="samples/GettingStarted/AgentWithOpenAI/README.md" />
<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/GettingStarted/ModelContextProtocol/">
<Project Path="samples/GettingStarted/ModelContextProtocol/Agent_MCP_Server/Agent_MCP_Server.csproj" />
@@ -77,9 +80,10 @@
<Project Path="samples/GettingStarted/Workflows/ConditionalEdges/03_MultiSelection/03_MultiSelection.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/Workflows/Declarative/">
<Project Path="samples/GettingStarted/Workflows/Declarative/DeclarativeWorkflow.csproj" />
<Project Path="samples/GettingStarted/Workflows/DeclarativeCode/DeclarativeCode.csproj" />
<Project Path="samples/GettingStarted/Workflows/DeclarativeEject/DeclarativeEject.csproj" />
<File Path="samples/GettingStarted/Workflows/Declarative/README.md" />
<Project Path="samples/GettingStarted/Workflows/Declarative/ExecuteCode/ExecuteCode.csproj" />
<Project Path="samples/GettingStarted/Workflows/Declarative/ExecuteWorkflow/ExecuteWorkflow.csproj" />
<Project Path="samples/GettingStarted/Workflows/Declarative/GenerateCode/GenerateCode.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/Workflows/Declarative/Examples/">
<File Path="../workflow-samples/DeepResearch.yaml" />
@@ -130,6 +134,10 @@
<Project Path="samples/SemanticKernelMigration/AzureAIFoundry/Step03_DependencyInjection/AzureAIFoundry_Step03_DependencyInjection.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureAIFoundry/Step04_CodeInterpreter/AzureAIFoundry_Step04_CodeInterpreter.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/Playground/">
<File Path="samples/SemanticKernelMigration/Playground/README.md" />
<Project Path="samples/SemanticKernelMigration/Playground/SemanticKernelBasic/SemanticKernelBasic.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/OpenAI/">
<Project Path="samples/SemanticKernelMigration/OpenAI/Step01_Basics/OpenAI_Step01_Basics.csproj" />
<Project Path="samples/SemanticKernelMigration/OpenAI/Step02_ToolCall/OpenAI_Step02_ToolCall.csproj" />
@@ -164,6 +172,11 @@
<Project Path="samples/SemanticKernelMigration/AzureOpenAIResponses/Step03_ToolCall/AzureOpenAIResponses_Step03_ToolCall.csproj" />
<Project Path="samples/SemanticKernelMigration/AzureOpenAIResponses/Step04_DependencyInjection/AzureOpenAIResponses_Step04_DependencyInjection.csproj" />
</Folder>
<Folder Name="/Samples/SemanticKernelMigration/AgentOrchestrations/">
<Project Path="samples/SemanticKernelMigration/AgentOrchestrations/Step01_Concurrent/AgentOrchestrations_Step01_Concurrent.csproj" />
<Project Path="samples/SemanticKernelMigration/AgentOrchestrations/Step02_Sequential/AgentOrchestrations_Step02_Sequential.csproj" />
<Project Path="samples/SemanticKernelMigration/AgentOrchestrations/Step03_Handoff/AgentOrchestrations_Step03_Handoff.csproj" />
</Folder>
<Folder Name="/Solution Items/">
<File Path=".editorconfig" />
<File Path=".gitignore" />
@@ -174,6 +187,10 @@
<File Path="nuget.config" />
</Folder>
<Folder Name="/Solution Items/.github/" />
<Folder Name="/Solution Items/.github/upgrades/" />
<Folder Name="/Solution Items/.github/upgrades/prompts/">
<File Path="../.github/upgrades/prompts/SemanticKernelToAgentFramework.md" />
</Folder>
<Folder Name="/Solution Items/.github/workflows/">
<File Path="../.github/workflows/dotnet-build-and-test.yml" />
<File Path="../.github/workflows/dotnet-check-coverage.ps1" />
@@ -279,6 +296,7 @@
<Project Path="src/Microsoft.Agents.AI.CopilotStudio/Microsoft.Agents.AI.CopilotStudio.csproj" />
<Project Path="src/Microsoft.Agents.AI.Hosting.A2A.AspNetCore/Microsoft.Agents.AI.Hosting.A2A.AspNetCore.csproj" />
<Project Path="src/Microsoft.Agents.AI.Hosting.A2A/Microsoft.Agents.AI.Hosting.A2A.csproj" />
<Project Path="src/Microsoft.Agents.AI.Hosting.OpenAI/Microsoft.Agents.AI.Hosting.OpenAI.csproj" />
<Project Path="src/Microsoft.Agents.AI.Hosting/Microsoft.Agents.AI.Hosting.csproj" />
<Project Path="src/Microsoft.Agents.AI.OpenAI/Microsoft.Agents.AI.OpenAI.csproj" />
<Project Path="src/Microsoft.Agents.AI.Workflows.Declarative/Microsoft.Agents.AI.Workflows.Declarative.csproj" />
+1 -6
View File
@@ -3,15 +3,10 @@
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="CopilotStudio" value="https://pkgs.dev.azure.com/Power-Fx/7dd30b4a-31be-4ac9-a649-e6addd4d5b0a/_packaging/CopilotStudio/nuget/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="CopilotStudio">
<package pattern="Microsoft.Bot.*" />
<package pattern="Microsoft.PowerFx.*" />
</packageSource>
</packageSourceMapping>
</configuration>
</configuration>
+2 -2
View File
@@ -2,8 +2,8 @@
<PropertyGroup>
<!-- Central version prefix - applies to all nuget packages. -->
<VersionPrefix>1.0.0</VersionPrefix>
<PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix).251001.2</PackageVersion>
<PackageVersion Condition="'$(VersionSuffix)' == ''">$(VersionPrefix)-preview.251001.2</PackageVersion>
<PackageVersion Condition="'$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix).251007.1</PackageVersion>
<PackageVersion Condition="'$(VersionSuffix)' == ''">$(VersionPrefix)-preview.251007.1</PackageVersion>
<Configurations>Debug;Release;Publish</Configurations>
<IsPackable>true</IsPackable>
+12 -4
View File
@@ -1,8 +1,16 @@
# Suppressing errors for Sample projects under dotnet/samples folder
[*.cs]
dotnet_diagnostic.CA2007.severity = none # Do not directly await a Task
dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member
dotnet_diagnostic.IDE1006.severity = warning # Naming rule violations
dotnet_diagnostic.VSTHRD111.severity = none # Use .ConfigureAwait(bool) is hidden by default, set to none to prevent IDE from changing on autosave
dotnet_diagnostic.CA1716.severity = none # Add summary to documentation comment.
dotnet_diagnostic.CA2000.severity = none # Call System.IDisposable.Dispose on object before all references to it are out of scope
dotnet_diagnostic.CA2007.severity = none # Do not directly await a Task
dotnet_diagnostic.CS1591.severity = none # Missing XML comment for publicly visible type or member
dotnet_diagnostic.IDE1006.severity = warning # Naming rule violations
dotnet_diagnostic.VSTHRD111.severity = none # Use .ConfigureAwait(bool) is hidden by default, set to none to prevent IDE from changing on autosave
dotnet_diagnostic.VSTHRD200.severity = none # Use Async suffix for async methods
dotnet_diagnostic.MEAI001.severity = none # [Experimental] APIs in Microsoft.Extensions.AI
dotnet_diagnostic.OPENAI001.severity = none # [Experimental] APIs in OpenAI
dotnet_diagnostic.SKEXP0110.severity = none # [Experimental] APIs in Microsoft.SemanticKernel
@@ -6,7 +6,6 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
<NoWarn>$(NoWarn);CS1591;VSTHRD111;CA2007;SKEXP0110</NoWarn>
</PropertyGroup>
<ItemGroup>
@@ -6,7 +6,6 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
<NoWarn>$(NoWarn);CS1591;VSTHRD111;CA2007;SKEXP0110</NoWarn>
</PropertyGroup>
<ItemGroup>
@@ -4,7 +4,7 @@
@hostLogistics = http://localhost:5002
### Query agent card for the invoice agent
GET {{hostInvoice}}/.well-known/agent.json
GET {{hostInvoice}}/.well-known/agent-card.json
### Send a message to the invoice agent
POST {{hostInvoice}}
@@ -17,6 +17,7 @@ Content-Type: application/json
"params": {
"id": "12345",
"message": {
"kind": "message",
"role": "user",
"messageId": "msg_1",
"parts": [
@@ -30,7 +31,7 @@ Content-Type: application/json
}
### Query agent card for the policy agent
GET {{hostPolicy}}/.well-known/agent.json
GET {{hostPolicy}}/.well-known/agent-card.json
### Send a message to the policy agent
POST {{hostPolicy}}
@@ -43,6 +44,7 @@ Content-Type: application/json
"params": {
"id": "12345",
"message": {
"kind": "message",
"role": "user",
"messageId": "msg_1",
"parts": [
@@ -56,7 +58,7 @@ Content-Type: application/json
}
### Query agent card for the logistics agent
GET {{hostLogistics}}/.well-known/agent.json
GET {{hostLogistics}}/.well-known/agent-card.json
### Send a message to the logistics agent
POST {{hostLogistics}}
@@ -69,6 +71,7 @@ Content-Type: application/json
"params": {
"id": "12345",
"message": {
"kind": "message",
"role": "user",
"messageId": "msg_1",
"parts": [
@@ -89,7 +89,7 @@ internal static class HostAgentFactory
PushNotifications = false,
};
var invoiceQuery = new AgentSkill()
var policyQuery = new AgentSkill()
{
Id = "id_policy_agent",
Name = "PolicyAgent",
@@ -109,7 +109,7 @@ internal static class HostAgentFactory
DefaultInputModes = ["text"],
DefaultOutputModes = ["text"],
Capabilities = capabilities,
Skills = [invoiceQuery],
Skills = [policyQuery],
};
}
@@ -103,5 +103,6 @@ else
}
app.MapA2A(hostAgent!.TaskManager!, "/");
app.MapWellKnownAgentCard(hostAgent!.TaskManager!, "/");
await app.RunAsync();
+4 -3
View File
@@ -108,7 +108,7 @@ This sample contains a [.http file](https://learn.microsoft.com/aspnet/core/test
1. In Visual Studio open [./A2AServer/A2AServer.http](./A2AServer/A2AServer.http)
1. There are two sent requests for each agent, e.g., for the invoice agent:
1. Query agent card for the invoice agent
`GET {{hostInvoice}}/.well-known/agent.json`
`GET {{hostInvoice}}/.well-known/agent-card.json`
1. Send a message to the invoice agent
```
POST {{hostInvoice}}
@@ -121,6 +121,7 @@ This sample contains a [.http file](https://learn.microsoft.com/aspnet/core/test
"params": {
"id": "12345",
"message": {
"kind": "message",
"role": "user",
"messageId": "msg_1",
"parts": [
@@ -144,7 +145,7 @@ Sample output from the request to send a message to the agent via A2A protocol:
### Testing the Agents using the A2A Inspector
The A2A Inspector is a web-based tool designed to help developers inspect, debug, and validate servers that implement the Google A2A (Agent-to-Agent) protocol. It provides a user-friendly interface to interact with an A2A agent, view communication, and ensure specification compliance.
The A2A Inspector is a web-based tool designed to help developers inspect, debug, and validate servers that implement the Google A2A (Agent2Agent) protocol. It provides a user-friendly interface to interact with an A2A agent, view communication, and ensure specification compliance.
For more information go [here](https://github.com/a2aproject/a2a-inspector).
@@ -223,7 +224,7 @@ Agent: The transaction details for **TICKET-XYZ987** are as follows:
- **Hats:** 200 units at $15.00 each
- **Glasses:** 300 units at $5.00 each
To proceed with the dispute regarding the quantity of t-shirts delivered, please specify the exact quantity issue how many t-shirts were actually received compared to the ordered amount.
To proceed with the dispute regarding the quantity of t-shirts delivered, please specify the exact quantity issue how many t-shirts were actually received compared to the ordered amount.
### Customer Service Policy for Handling Disputes
**Short Shipment Dispute Handling Policy V2.1**
@@ -13,6 +13,7 @@
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting\Microsoft.Agents.AI.Hosting.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI\Microsoft.Agents.AI.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.A2A.AspNetCore\Microsoft.Agents.AI.Hosting.A2A.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.OpenAI\Microsoft.Agents.AI.Hosting.OpenAI.csproj" />
<ProjectReference Include="..\AgentWebChat.ServiceDefaults\AgentWebChat.ServiceDefaults.csproj" />
</ItemGroup>
@@ -1,10 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
using A2A.AspNetCore;
using AgentWebChat.AgentHost;
using AgentWebChat.AgentHost.Utilities;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Agents.AI.Hosting.A2A.AspNetCore;
using Microsoft.Agents.AI.Hosting.OpenAI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;
@@ -84,6 +86,9 @@ app.MapA2A(agentName: "knights-and-knaves", path: "/a2a/knights-and-knaves", age
// Url = "http://localhost:5390/a2a/knights-and-knaves"
});
app.MapOpenAIResponses("pirate");
app.MapOpenAIResponses("knights-and-knaves");
// Map the agents HTTP endpoints
app.MapAgentDiscovery("/agents");
@@ -43,7 +43,7 @@ internal sealed class A2AAgentClient : IAgentClient
{
// Convert all messages to A2A parts and create a single message
var parts = messages.ToParts();
var a2aMessage = new Message
var a2aMessage = new AgentMessage
{
MessageId = Guid.NewGuid().ToString("N"),
ContextId = contextId,
@@ -55,9 +55,9 @@ internal sealed class A2AAgentClient : IAgentClient
var a2aResponse = await a2aClient.SendMessageAsync(messageSendParams, cancellationToken);
// Handle different response types
if (a2aResponse is Message message)
if (a2aResponse is AgentMessage message)
{
var responseMessage = MessageConverter.ToChatMessage(message);
var responseMessage = message.ToChatMessage();
if (responseMessage is not null)
{
results.Add(new AgentRunResponseUpdate(responseMessage.Role, responseMessage.Contents)
@@ -188,17 +188,17 @@ internal sealed class A2AAgentClient : IAgentClient
// Extension method to convert multiple chat messages to A2A messages
internal static class ChatMessageExtensions
{
public static List<Message> ToA2AMessages(this IList<ChatMessage> chatMessages)
public static List<AgentMessage> ToA2AMessages(this IList<ChatMessage> chatMessages)
{
if (chatMessages is null || chatMessages.Count == 0)
{
return [];
}
var result = new List<Message>();
var result = new List<AgentMessage>();
foreach (var chatMessage in chatMessages)
{
result.Add(MessageConverter.ToA2AMessage(chatMessage));
result.Add(chatMessage.ToA2AMessage());
}
return result;
}
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AgentWebChat.Web;
@@ -20,7 +21,10 @@ public class AgentDiscoveryClient(HttpClient httpClient, ILogger<AgentDiscoveryC
public class AgentDiscoveryCard
{
public string? Name { get; set; }
[JsonPropertyName("name")]
public required string Name { get; set; }
[JsonPropertyName("description")]
public string? Description { get; set; }
}
}
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
@@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.A2A\Microsoft.Agents.AI.Hosting.A2A.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting.OpenAI\Microsoft.Agents.AI.Hosting.OpenAI.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Hosting\Microsoft.Agents.AI.Hosting.csproj" />
<ProjectReference Include="..\AgentWebChat.ServiceDefaults\AgentWebChat.ServiceDefaults.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
@@ -4,6 +4,7 @@
@inject IJSRuntime JSRuntime
@inject ILogger<Home> Logger
@inject A2AAgentClient A2AActorClient
@inject OpenAIResponsesAgentClient OpenAIResponsesAgentClient
@rendermode InteractiveServer
@using System.Text
@using System.Text.Json
@@ -51,18 +52,18 @@
<label for="protocol-select" class="protocol-select-label">Choose communication protocol:</label>
<div class="protocol-select-wrapper">
<select id="protocol-select" class="protocol-select" @bind="selectedProtocol" disabled="@(isStreaming)">
<option value="AgenticFramework">Agentic Framework</option>
<option value="OpenAIResponses">OpenAI Responses</option>
<option value="A2A">A2A (Agent-to-Agent)</option>
</select>
<div class="protocol-info">
@switch (selectedProtocol)
{
case Protocol.A2A:
<span class="protocol-description">🔗 A2A protocol supports long-running agentic processes</span>
case Protocol.OpenAIResponses:
<span class="protocol-description">֎ OpenAI Responses</span>
break;
case Protocol.AgenticFramework:
default:
<span class="protocol-description">⚡ Direct agentic framework communication</span>
case Protocol.A2A:
default:
<span class="protocol-description">🔗 A2A protocol supports long-running agentic processes</span>
break;
}
</div>
@@ -881,208 +882,212 @@
@code {
private string currentMessage = "";
private bool isStreaming = false;
private bool isLoadingAgents = true;
private string currentStreamedMessage = "";
private string selectedAgentName = "";
private List<AgentDiscoveryClient.AgentDiscoveryCard> availableAgents = new();
private List<Conversation> conversations = new();
private Conversation? currentConversation;
private string currentMessage = "";
private bool isStreaming = false;
private bool isLoadingAgents = true;
private string currentStreamedMessage = "";
private string selectedAgentName = "";
private List<AgentDiscoveryClient.AgentDiscoveryCard> availableAgents = new();
private List<Conversation> conversations = new();
private Conversation? currentConversation;
// protocol
private Protocol selectedProtocol;
// protocol
private Protocol selectedProtocol;
// a2a agent card
private bool isA2AExpanded = false;
private bool isDiscoveringCard = false;
private string? discoveredAgentCardJson = null;
private string? discoveryError = null;
// a2a agent card
private bool isA2AExpanded = false;
private bool isDiscoveringCard = false;
private string? discoveredAgentCardJson = null;
private string? discoveryError = null;
private enum Protocol
{
AgenticFramework,
A2A // Agent-to-Agent protocol
}
private enum Protocol
{
A2A, // Agent-to-Agent protocol
OpenAIResponses
}
private sealed class Conversation
{
public string SessionId { get; set; } = Guid.NewGuid().ToString("N");
public string AgentName { get; set; } = "";
public List<ChatMessage> Messages { get; set; } = new();
}
private sealed class Conversation
{
public string SessionId { get; set; } = Guid.NewGuid().ToString("N");
public string AgentName { get; set; } = "";
public List<ChatMessage> Messages { get; set; } = new();
}
protected override async Task OnInitializedAsync()
{
Logger.LogDebug("Initializing Agent Chat component");
protected override async Task OnInitializedAsync()
{
Logger.LogDebug("Initializing Agent Chat component");
// Load agents
try
{
availableAgents = await AgentClient.GetAgentsAsync();
Logger.LogInformation("Loaded {AgentCount} agents", availableAgents.Count);
Logger.LogInformation("Loaded Agents info: {AgentData}", JsonSerializer.Serialize(availableAgents, new JsonSerializerOptions() { WriteIndented = true }));
// Load agents
try
{
availableAgents = await AgentClient.GetAgentsAsync();
Logger.LogInformation("Loaded {AgentCount} agents", availableAgents.Count);
Logger.LogInformation("Loaded Agents info: {AgentData}", JsonSerializer.Serialize(availableAgents, new JsonSerializerOptions() { WriteIndented = true }));
// Default to first agent and start a conversation
if (availableAgents.Any())
{
selectedAgentName = availableAgents.First().Name!;
StartNewConversation();
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to load agents");
}
finally
{
isLoadingAgents = false;
}
// Default to first agent and start a conversation
if (availableAgents.Any())
{
selectedAgentName = availableAgents.First().Name!;
StartNewConversation();
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to load agents");
}
finally
{
isLoadingAgents = false;
}
// Conversations start fresh on page load
}
// Conversations start fresh on page load
}
private string GetAgentIcon(string agentName) => agentName?.ToLower() switch
{
"pirate" => "🏴‍☠️",
"knights-and-knaves" => "⚔️",
_ => "🤖"
};
private string GetAgentIcon(string agentName) => agentName?.ToLower() switch
{
"pirate" => "🏴‍☠️",
"knights-and-knaves" => "⚔️",
_ => "🤖"
};
private string GetAgentDisplayName(string agentName) => agentName?.ToLower() switch
{
"pirate" => "Pirate",
"knights-and-knaves" => "Knights & Knaves",
_ => agentName ?? "Agent"
};
private string GetAgentDisplayName(string agentName) => agentName?.ToLower() switch
{
"pirate" => "Pirate",
"knights-and-knaves" => "Knights & Knaves",
_ => agentName ?? "Agent"
};
private void ToggleA2AExpanded() => isA2AExpanded = !isA2AExpanded;
private void ToggleA2AExpanded() => isA2AExpanded = !isA2AExpanded;
private async Task DiscoverAgentCard()
{
if (string.IsNullOrEmpty(selectedAgentName) || isDiscoveringCard)
return;
private async Task DiscoverAgentCard()
{
if (string.IsNullOrEmpty(selectedAgentName) || isDiscoveringCard)
return;
isDiscoveringCard = true;
discoveryError = null;
discoveredAgentCardJson = null;
StateHasChanged();
isDiscoveringCard = true;
discoveryError = null;
discoveredAgentCardJson = null;
StateHasChanged();
try
{
Logger.LogInformation("Discovering agent card for agent: {AgentName}", selectedAgentName);
var agentCard = await A2AActorClient.GetAgentCardAsync(selectedAgentName);
if (agentCard is not null)
{
discoveredAgentCardJson = JsonSerializer.Serialize(agentCard, new JsonSerializerOptions() { WriteIndented = true });
Logger.LogInformation("Successfully discovered agent card for {AgentName}: {CardData}", selectedAgentName, discoveredAgentCardJson);
}
else
{
discoveryError = "No agent card found for this agent.";
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to discover agent card for {AgentName}", selectedAgentName);
discoveryError = $"Failed to discover agent card: {ex.Message}";
}
finally
{
isDiscoveringCard = false;
StateHasChanged();
}
}
try
{
Logger.LogInformation("Discovering agent card for agent: {AgentName}", selectedAgentName);
var agentCard = await A2AActorClient.GetAgentCardAsync(selectedAgentName);
if (agentCard is not null)
{
discoveredAgentCardJson = JsonSerializer.Serialize(agentCard, new JsonSerializerOptions() { WriteIndented = true });
Logger.LogInformation("Successfully discovered agent card for {AgentName}: {CardData}", selectedAgentName, discoveredAgentCardJson);
}
else
{
discoveryError = "No agent card found for this agent.";
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Failed to discover agent card for {AgentName}", selectedAgentName);
discoveryError = $"Failed to discover agent card: {ex.Message}";
}
finally
{
isDiscoveringCard = false;
StateHasChanged();
}
}
private void StartNewConversation()
{
if (string.IsNullOrEmpty(selectedAgentName))
return;
private void StartNewConversation()
{
if (string.IsNullOrEmpty(selectedAgentName))
return;
var newConversation = new Conversation
var newConversation = new Conversation
{
AgentName = selectedAgentName
};
conversations.Add(newConversation);
currentConversation = newConversation;
conversations.Add(newConversation);
currentConversation = newConversation;
Logger.LogInformation("Started new conversation with agent: {AgentName}, session: {SessionId}",
newConversation.AgentName, newConversation.SessionId);
Logger.LogInformation("Started new conversation with agent: {AgentName}, session: {SessionId}",
newConversation.AgentName, newConversation.SessionId);
StateHasChanged();
}
StateHasChanged();
}
private void SelectConversation(string sessionId)
{
currentConversation = conversations.FirstOrDefault(c => c.SessionId == sessionId);
if (currentConversation is not null)
{
selectedAgentName = currentConversation.AgentName;
Logger.LogDebug("Selected conversation with session: {SessionId}", sessionId);
}
StateHasChanged();
}
private void SelectConversation(string sessionId)
{
currentConversation = conversations.FirstOrDefault(c => c.SessionId == sessionId);
if (currentConversation is not null)
{
selectedAgentName = currentConversation.AgentName;
Logger.LogDebug("Selected conversation with session: {SessionId}", sessionId);
}
StateHasChanged();
}
private void CloseConversation(string sessionId)
{
var conversationToRemove = conversations.FirstOrDefault(c => c.SessionId == sessionId);
if (conversationToRemove is not null)
{
conversations.Remove(conversationToRemove);
private void CloseConversation(string sessionId)
{
var conversationToRemove = conversations.FirstOrDefault(c => c.SessionId == sessionId);
if (conversationToRemove is not null)
{
conversations.Remove(conversationToRemove);
if (currentConversation?.SessionId == sessionId)
{
currentConversation = conversations.FirstOrDefault();
if (currentConversation is not null)
{
selectedAgentName = currentConversation.AgentName;
}
}
if (currentConversation?.SessionId == sessionId)
{
currentConversation = conversations.FirstOrDefault();
if (currentConversation is not null)
{
selectedAgentName = currentConversation.AgentName;
}
}
Logger.LogInformation("Closed conversation with session: {SessionId}", sessionId);
}
StateHasChanged();
}
Logger.LogInformation("Closed conversation with session: {SessionId}", sessionId);
}
StateHasChanged();
}
private async Task SendMessage()
{
if (string.IsNullOrWhiteSpace(currentMessage) || isStreaming || currentConversation is null)
return;
private async Task SendMessage()
{
if (string.IsNullOrWhiteSpace(currentMessage) || isStreaming || currentConversation is null)
return;
var userMessage = currentMessage.Trim();
currentMessage = "";
var userMessage = currentMessage.Trim();
currentMessage = "";
Logger.LogInformation("User sending message: '{UserMessage}' to agent {AgentName} in session {SessionId}",
userMessage, currentConversation.AgentName, currentConversation.SessionId);
Logger.LogInformation("User sending message: '{UserMessage}' to agent {AgentName} in session {SessionId}",
userMessage, currentConversation.AgentName, currentConversation.SessionId);
// Add user message to chat
currentConversation.Messages.Add(new ChatMessage(ChatRole.User, userMessage));
StateHasChanged();
await ScrollToBottom();
// Add user message to chat
currentConversation.Messages.Add(new ChatMessage(ChatRole.User, userMessage));
StateHasChanged();
await ScrollToBottom();
// Start streaming response
isStreaming = true;
currentStreamedMessage = "";
StateHasChanged();
// Start streaming response
isStreaming = true;
currentStreamedMessage = "";
StateHasChanged();
StringBuilder responseContent = new();
var hasReceivedContent = false;
StringBuilder responseContent = new();
var hasReceivedContent = false;
using var timeoutCts = new CancellationTokenSource(
using var timeoutCts = new CancellationTokenSource(
#if DEBUG
TimeSpan.FromSeconds(120)
#else
TimeSpan.FromSeconds(20)
TimeSpan.FromSeconds(20)
#endif
);
);
try
{
try
{
// Select the appropriate client based on protocol
// Select the appropriate client based on protocol
IAgentClient agentClient = selectedProtocol switch
{
Protocol.OpenAIResponses => OpenAIResponsesAgentClient,
Protocol.A2A or _ => A2AActorClient
};
var agentClient = A2AActorClient;
var messages = new List<ChatMessage> { new(ChatRole.User, userMessage) };
await foreach (var update in agentClient.RunStreamingAsync(
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ClientModel;
using System.Runtime.CompilerServices;
using A2A;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Responses;
namespace AgentWebChat.Web;
/// <summary>
/// Is a simple frontend client which exercises the ability of exposed agent to communicate via OpenAI Responses protocol.
/// </summary>
internal sealed class OpenAIResponsesAgentClient : IAgentClient
{
private readonly Uri _baseUri;
public OpenAIResponsesAgentClient(string baseUri)
{
this._baseUri = new Uri(baseUri.TrimEnd('/'));
}
public async IAsyncEnumerable<AgentRunResponseUpdate> RunStreamingAsync(
string agentName,
IList<ChatMessage> messages,
string? threadId = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
OpenAIClientOptions options = new()
{
Endpoint = new Uri(this._baseUri, $"/{agentName}/v1/")
};
var openAiClient = new OpenAIResponseClient(model: "myModel!", credential: new ApiKeyCredential("dummy-key"), options: options).AsIChatClient();
var chatOptions = new ChatOptions()
{
ConversationId = threadId
};
await foreach (var update in openAiClient.GetStreamingResponseAsync(messages, chatOptions, cancellationToken: cancellationToken))
{
yield return new AgentRunResponseUpdate(update);
}
}
public Task<AgentCard?> GetAgentCardAsync(string agentName, CancellationToken cancellationToken = default)
=> Task.FromResult<AgentCard?>(null!);
}
@@ -23,6 +23,7 @@ Uri a2aAddress = new("http://localhost:5390/a2a");
builder.Services.AddHttpClient<AgentDiscoveryClient>(client => client.BaseAddress = baseAddress);
builder.Services.AddSingleton(sp => new A2AAgentClient(sp.GetRequiredService<ILogger<A2AAgentClient>>(), a2aAddress));
builder.Services.AddSingleton(sp => new OpenAIResponsesAgentClient("http://localhost:5390"));
var app = builder.Build();
-1
View File
@@ -7,7 +7,6 @@
<IsAotCompatible>false</IsAotCompatible>
<ProjectsTargetFrameworks>net472;net9.0</ProjectsTargetFrameworks>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
<NoWarn>$(NoWarn);CA1707;MEAI001</NoWarn>
</PropertyGroup>
<ItemGroup>
@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
@@ -5,6 +5,7 @@ using System.Diagnostics;
using System.Diagnostics.Metrics;
using Azure.AI.OpenAI;
using Azure.Identity;
using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
@@ -23,6 +24,8 @@ const string ServiceName = "AgentOpenTelemetry";
// Configure OpenTelemetry for Aspire dashboard
var otlpEndpoint = Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT") ?? "http://localhost:4318";
var applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING");
// Create a resource to identify this service
var resource = ResourceBuilder.CreateDefault()
.AddService(ServiceName, serviceVersion: "1.0.0")
@@ -34,13 +37,19 @@ var resource = ResourceBuilder.CreateDefault()
.Build();
// Setup tracing with resource
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(ServiceName, serviceVersion: "1.0.0"))
.AddSource(SourceName) // Our custom activity source
.AddSource("*Microsoft.Agents.AI") // Agent Framework telemetry
.AddHttpClientInstrumentation() // Capture HTTP calls to OpenAI
.AddOtlpExporter(options => options.Endpoint = new Uri(otlpEndpoint))
.Build();
.AddOtlpExporter(options => options.Endpoint = new Uri(otlpEndpoint));
if (!string.IsNullOrWhiteSpace(applicationInsightsConnectionString))
{
tracerProviderBuilder.AddAzureMonitorTraceExporter(options => options.ConnectionString = applicationInsightsConnectionString);
}
using var tracerProvider = tracerProviderBuilder.Build();
// Setup metrics with resource and instrument name filtering
using var meterProvider = Sdk.CreateMeterProviderBuilder()
@@ -60,6 +69,10 @@ serviceCollection.AddLogging(loggingBuilder => loggingBuilder
{
options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(ServiceName, serviceVersion: "1.0.0"));
options.AddOtlpExporter(otlpOptions => otlpOptions.Endpoint = new Uri(otlpEndpoint));
if (!string.IsNullOrWhiteSpace(applicationInsightsConnectionString))
{
options.AddAzureMonitorLogExporter(options => options.ConnectionString = applicationInsightsConnectionString);
}
options.IncludeScopes = true;
options.IncludeFormattedMessage = true;
}));
@@ -85,7 +98,7 @@ Console.WriteLine("""
""");
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT environment variable is not set.");
var deploymentName = System.Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
// Log application startup
appLogger.LogInformation("OpenTelemetry Aspire Demo application started");
@@ -4,10 +4,11 @@ This demo showcases the integration of OpenTelemetry with the Microsoft Agent Fr
## Overview
The demo consists of two main components:
The demo consists of three main components:
1. **Aspire Dashboard** - Provides a web-based interface to visualize OpenTelemetry data
2. **Console Application** - An interactive console application that demonstrates agent interactions with proper OpenTelemetry instrumentation
3. **[Optional] Application Insights** - When the agent is deployed to a production environment, Application Insights can be used to monitor the agent performance.
## Architecture
@@ -25,6 +26,7 @@ graph TD
- Azure OpenAI service endpoint and deployment configured
- Azure CLI installed and authenticated (for Azure credential authentication)
- Docker installed (for running Aspire Dashboard)
- [Optional] Application Insights and Grafana
## Configuration
@@ -37,6 +39,12 @@ $env:AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini" # Optional, defaults to gpt-4o-
**Note**: This demo uses Azure CLI credentials for authentication. Make sure you're logged in with `az login` and have access to the Azure OpenAI resource.
### [Optional] Application Insights Setup
Set the following environment variables:
```powershell
$env:APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=XXXX;IngestionEndpoint=https://XXXX.applicationinsights.azure.com/;LiveEndpoint=https://XXXXX.livediagnostics.monitor.azure.com/;ApplicationId=XXXXX"
```
## Running the Demo
### Quick Start (Using Script)
@@ -108,7 +116,7 @@ You:
- Metrics in the **Metrics** tab showing token usage and duration
- Logs in the **Structured Logs** tab with detailed information
## Viewing Telemetry Data
## Viewing Telemetry Data in Aspire Dashboard
### Traces
1. In the Aspire Dashboard, navigate to the **Traces** tab
@@ -130,6 +138,17 @@ You:
2. Filter by the console application to see detailed logs
3. Logs include information about user inputs, agent responses, and any errors
## [Optional] View Application Insights data in Grafana
Besides the Aspire Dashboard and the Application Insights native UI, you can also use Grafana to visualize the telemetry data in Application Insights. There are two tailored dashboards for you to get started quickly:
### Agent Overview dashboard
Grafana Dashboard Gallery link: <https://aka.ms/amg/dash/af-agent>
![Agent Overview dashboard](https://github.com/Azure/azure-managed-grafana/raw/main/samples/assets/grafana-af-agent.gif)
### Workflow Overview dashboard
Grafana Dashboard Gallery link: <https://aka.ms/amg/dash/af-workflow>
![Workflow Overview dashboard](https://github.com/Azure/azure-managed-grafana/raw/main/samples/assets/grafana-af-workflow.gif)
## Key Features Demonstrated
### OpenTelemetry Integration
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a simple AI agent with an existing A2A agent.
using System;
using A2A;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a simple AI agent with Azure Foundry Agents as the backend.
using System;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to use the OpenAI SDK to create and use a simple AI agent with any model hosted in Azure AI Foundry.
// You could use models from Microsoft, OpenAI, DeepSeek, Hugging Face, Meta, xAI or any other model you have deployed in your Azure AI Foundry resource.
// Note: Ensure that you pick a model that suits your needs. For example, if you want to use function calling, ensure that the model you pick supports function calling.
using System.ClientModel;
using System.ClientModel.Primitives;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI;
var endpoint = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_FOUNDRY_OPENAI_ENDPOINT is not set.");
var apiKey = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_OPENAI_APIKEY");
var model = Environment.GetEnvironmentVariable("AZURE_FOUNDRY_MODEL_DEPLOYMENT") ?? "Phi-4-mini-instruct";
const string JokerName = "Joker";
const string JokerInstructions = "You are good at telling jokes.";
// Since we are using the OpenAI Client SDK, we need to override the default endpoint to point to Azure Foundry.
var clientOptions = new OpenAIClientOptions() { Endpoint = new Uri(endpoint) };
// Create the OpenAI client with either an API key or Azure CLI credential.
OpenAIClient client = string.IsNullOrWhiteSpace(apiKey)
? new OpenAIClient(new BearerTokenPolicy(new AzureCliCredential(), "https://ai.azure.com/.default"), clientOptions)
: new OpenAIClient(new ApiKeyCredential(apiKey), clientOptions);
AIAgent agent = client
.GetChatClient(model)
.CreateAIAgent(JokerInstructions, JokerName);
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -0,0 +1,34 @@
## Overview
This sample shows how to use the OpenAI SDK to create and use a simple AI agent with any model hosted in Azure AI Foundry.
You could use models from Microsoft, OpenAI, DeepSeek, Hugging Face, Meta, xAI or any other model you have deployed in Azure AI Foundry.
**Note**: Ensure that you pick a model that suits your needs. For example, if you want to use function calling, ensure that the model you pick supports function calling.
## Prerequisites
Before you begin, ensure you have the following prerequisites:
- .NET 8.0 SDK or later
- Azure AI Foundry resource
- A model deployment in your Azure AI Foundry resource. This example defaults to using the `Phi-4-mini-instruct` model,
so if you want to use a different model, ensure that you set your `AZURE_FOUNDRY_MODEL_DEPLOYMENT` environment
variable to the name of your deployed model.
- An API key or role based authentication to access the Azure AI Foundry resource
See [here](https://learn.microsoft.com/en-us/azure/ai-foundry/quickstarts/get-started-code?tabs=csharp) for more info on setting up these prerequisites
Set the following environment variables:
```powershell
# Replace with your Azure AI Foundry resource endpoint
# Ensure that you have the "/openai/v1/" path in the URL, since this is required when using the OpenAI SDK to access Azure Foundry models.
$env:AZURE_FOUNDRY_OPENAI_ENDPOINT="https://ai-foundry-<myresourcename>.services.ai.azure.com/openai/v1/"
# Optional, defaults to using Azure CLI for authentication if not provided
$env:AZURE_FOUNDRY_OPENAI_APIKEY="************"
# Optional, defaults to Phi-4-mini-instruct
$env:AZURE_FOUNDRY_MODEL_DEPLOYMENT="Phi-4-mini-instruct"
```
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a simple AI agent with Azure OpenAI Chat Completion as the backend.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,9 +2,6 @@
// This sample shows how to create and use a simple AI agent with Azure OpenAI Responses as the backend.
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -4,13 +4,8 @@
// In this case the agent doesn't use AI at all, and simply parrots back the user input in upper case.
// You can however, build a fully custom agent that uses AI in any way you want.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using SampleApp;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -3,8 +3,8 @@
// This sample shows how to create and use a simple AI agent with ONNX as the backend.
// WARNING: ONNX doesn't support function calling, so any function tools passed to the agent will be ignored.
using System;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.ML.OnnxRuntimeGenAI;
// E.g. C:\repos\Phi-4-mini-instruct-onnx\cpu_and_mobile\cpu-int4-rtn-block-32-acc-level-4
@@ -15,7 +15,7 @@ const string JokerInstructions = "You are good at telling jokes.";
// Get a chat client for ONNX and use it to construct an AIAgent.
using OnnxRuntimeGenAIChatClient chatClient = new(modelPath);
AIAgent agent = new ChatClientAgent(chatClient, JokerInstructions, JokerName);
AIAgent agent = chatClient.CreateAIAgent(JokerInstructions, JokerName);
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,8 +2,8 @@
// This sample shows how to create and use a simple AI agent with Ollama as the backend.
using System;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OllamaSharp;
var endpoint = Environment.GetEnvironmentVariable("OLLAMA_ENDPOINT") ?? throw new InvalidOperationException("OLLAMA_ENDPOINT is not set.");
@@ -13,8 +13,8 @@ const string JokerName = "Joker";
const string JokerInstructions = "You are good at telling jokes.";
// Get a chat client for Ollama and use it to construct an AIAgent.
using OllamaApiClient chatClient = new(new Uri(endpoint), modelName);
AIAgent agent = new ChatClientAgent(chatClient, JokerInstructions, JokerName);
AIAgent agent = new OllamaApiClient(new Uri(endpoint), modelName)
.CreateAIAgent(JokerInstructions, JokerName);
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -5,9 +5,6 @@
// WARNING: The Assistants API is deprecated and will be shut down.
// For more information see the OpenAI documentation: https://platform.openai.com/docs/assistants/migration
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
using System;
using Microsoft.Agents.AI;
using OpenAI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a simple AI agent with OpenAI Chat Completion as the backend.
using System;
using Microsoft.Agents.AI;
using OpenAI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,9 +2,6 @@
// This sample shows how to create and use a simple AI agent with OpenAI Responses as the backend.
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
using System;
using Microsoft.Agents.AI;
using OpenAI;
@@ -4,7 +4,7 @@ These samples show how to create an AIAgent instance using various providers.
This is not an exhaustive list, but shows a variety of the more popular options.
For other samples that demonstrate how to use AIAgent instances,
see the [Getting Started Steps](../GettingStartedSteps/README.md) samples.
see the [Getting Started With Agents](../Agents/README.md) samples.
## Prerequisites
@@ -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_With_AzureFoundry/)|This sample demonstrates how to create an Azure Foundry agent and expose it as an AIAgent|
|[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 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|
|[Creating an AIAgent with a custom implementation](./Agent_With_CustomImplementation/)|This sample demonstrates how to create an AIAgent with a custom implementation|
@@ -5,14 +5,9 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenAI" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
@@ -2,9 +2,7 @@
// This sample shows how to create and use a simple AI agent with OpenAI as the backend.
using System;
using System.ClientModel;
using System.Linq;
using Microsoft.Agents.AI;
using OpenAI;
using OpenAI.Chat;
@@ -3,14 +3,13 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<NoWarn>$(NoWarn);OPENAI001</NoWarn>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference
Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" />
</ItemGroup>
</Project>
@@ -2,7 +2,6 @@
// This sample shows how to create and use an AI agent with reasoning capabilities.
using System;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a simple AI agent with Azure OpenAI as the backend.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a simple AI agent with a multi-turn conversation.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -3,7 +3,6 @@
// This sample demonstrates how to use a ChatClientAgent with function tools.
// It shows both non-streaming and streaming agent interactions using menu-related tools.
using System;
using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
@@ -5,14 +5,13 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
<PackageReference Include="System.Linq.Async" />
</ItemGroup>
<ItemGroup>
@@ -5,9 +5,7 @@
// 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;
using System.ComponentModel;
using System.Linq;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -1,54 +1,53 @@
// Copyright (c) Microsoft. All rights reserved.
// This sample shows how to create and use a simple AI agent with Azure OpenAI as the backend, to produce structured output using JSON schema from a class.
// This sample shows how to configure ChatClientAgent to produce structured output.
using System;
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Serialization;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
using OpenAI.Chat;
using SampleApp;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
// Create the agent options, specifying the response format to use a JSON schema based on the PersonInfo class.
ChatClientAgentOptions agentOptions = new(name: "HelpfulAssistant", instructions: "You are a helpful assistant.")
// Create chat client to be used by chat client agents.
ChatClient chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName);
// Create the ChatClientAgent with the specified name and instructions.
ChatClientAgent agent = chatClient.CreateAIAgent(new ChatClientAgentOptions(name: "HelpfulAssistant", instructions: "You are a helpful assistant."));
// 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 = chatClient.CreateAIAgent(new ChatClientAgentOptions(name: "HelpfulAssistant", instructions: "You are a helpful assistant.")
{
ChatOptions = new()
{
ResponseFormat = ChatResponseFormat.ForJsonSchema<PersonInfo>()
ResponseFormat = Microsoft.Extensions.AI.ChatResponseFormat.ForJsonSchema<PersonInfo>()
}
};
// Create the agent using Azure OpenAI.
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new AzureCliCredential())
.GetChatClient(deploymentName)
.CreateAIAgent(agentOptions);
// Invoke the agent with some unstructured input, to extract the structured information from.
var response = await agent.RunAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");
// Deserialize the response into the PersonInfo class.
var personInfo = response.Deserialize<PersonInfo>(JsonSerializerOptions.Web);
Console.WriteLine("Assistant Output:");
Console.WriteLine($"Name: {personInfo.Name}");
Console.WriteLine($"Age: {personInfo.Age}");
Console.WriteLine($"Occupation: {personInfo.Occupation}");
});
// Invoke the agent with some unstructured input while streaming, to extract the structured information from.
var updates = agent.RunStreamingAsync("Please provide information about John Smith, who is a 35-year-old software engineer.");
var 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 = (await updates.ToAgentRunResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
PersonInfo personInfo = (await updates.ToAgentRunResponseAsync()).Deserialize<PersonInfo>(JsonSerializerOptions.Web);
Console.WriteLine("Assistant Output:");
Console.WriteLine($"Name: {personInfo.Name}");
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,8 +2,6 @@
// This sample shows how to create and use a simple AI agent with a conversation that can be persisted to disk.
using System;
using System.IO;
using System.Text.Json;
using Azure.AI.OpenAI;
using Azure.Identity;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -4,12 +4,7 @@
// This sample shows how to create and use a simple AI agent with a conversation that can be persisted to disk.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a simple AI agent with Azure OpenAI as the backend that logs telemetry using OpenTelemetry.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -4,9 +4,6 @@
// 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 System;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>3afc9b74-af74-4d8e-ae96-fa1c511d11ac</UserSecretsId>
</PropertyGroup>
@@ -2,7 +2,6 @@
// This sample shows how to expose an AI agent as an MCP tool.
using System;
using Azure.AI.Agents.Persistent;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -2,7 +2,6 @@
// This sample shows how to use Image Multi-Modality with an AI agent.
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.AI;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>3afc9b74-af74-4d8e-ae96-fa1c511d11ac</UserSecretsId>
</PropertyGroup>
@@ -2,7 +2,6 @@
// This sample shows how to create and use a Azure OpenAI AI agent as a function tool.
using System;
using System.ComponentModel;
using Azure.AI.OpenAI;
using Azure.Identity;
@@ -5,7 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
@@ -6,12 +6,8 @@
// The component adds a prompt to ask for this information if it is not already known
// and provides it to the model before each invocation if known.
using System;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
@@ -5,8 +5,7 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>disable</ImplicitUsings>
<NoWarn>VSTHRD200;CA1707</NoWarn>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>

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