Files
microsoft--agent-framework/dotnet/samples/AGENTS.md
Jose Luis Latorre Millas f4e49958f3 samples: add AgentMemory (Neo4j-agent memory reimplemented in NET ) shopping assistant sample (#7096)
* samples: add Neo4j Shopping Assistant (standalone, published AgentMemory 1.0.1)

The .NET port of the official Neo4j Agent Memory "retail assistant" example
(neo4j-labs/agent-memory examples/microsoft_agent_retail_assistant, referenced
from the Learn integration page), which is currently Python-only.

Wires Neo4jMemoryContextProvider (AIContextProvider), MemoryToolFactory
memory tools, and a ProductCatalog of retail tools over a Neo4j :Product
graph, via the published AgentMemory + AgentMemory.AgentFramework 1.0.1
NuGet packages.

Lives at the repo root rather than under dotnet/samples/: that tree is
.NET 10 + Central Package Management + Microsoft.Agents.AI ~1.13 with
source ProjectReferences, while AgentMemory currently targets net9.0 +
Microsoft.Agents.AI 1.9.0. A repo-native version needs AgentMemory bumped
to track the newer Agents.AI/Extensions.AI line first. Cross-linked from
dotnet/samples/02-agents/AgentWithMemory/README.md as a "See also" entry,
same pattern already used for the cross-folder Custom Memory Implementation
link.

Verified: dotnet build succeeds (0 warnings, 0 errors) against the published
packages, proving the AgentMemory public surface is package-consumable.
Matches sibling AgentWithMemory samples' conventions (BOM + copyright file
header on .cs files, README sections: Features Demonstrated / Prerequisites
/ Environment Variables / Run the Sample / Expected Output).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* samples: move Neo4j shopping assistant into AgentWithMemory as Step06

Relocates the standalone shopping-assistant sample from the repo root into
dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory,
following that folder's naming/README/solution conventions. Renames its identity
from "Neo4j" to "AgentMemory" (the library it actually demonstrates) since this
is a community .NET port, not an officially recognized Neo4j integration - Neo4j
is still referenced where it's a genuine technical detail (the graph backing
store, env vars, Cypher). Adds empty Directory.Build.props/targets markers so it
stays isolated from the repo's net10.0/CPM build, and registers it (skipped, like
the Mem0 sample) in the CI sample-verification list since it needs a live Neo4j
instance.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Update dotnet/samples/02-agents/AgentWithMemory/README.md

Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>

* Update dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory.csproj

Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>

* cleanup :)

* DefaultAzureCredential warning

* fixes - simplification userId

* minor doc fix

* NU1015 fix

* PR review fixes-improvements

* Bump AgentMemory to 1.2.0, let the context provider surface memory tools

WithMemoryOwnerScoping(sp) (1.1.0) already removed the need to manually
wrap agent.RunAsync in ownerContext.BeginOwnerScope(userId). This picks
up 1.2.0's ExposeMemoryToolsFromContextProvider option, so
Neo4jMemoryContextProvider now appends the memory tools to AIContext.Tools
itself on every model call — no more separate MemoryToolFactory wiring,
AIContextProviders = [memoryProvider] is enough.

Addresses westey-m's PR review suggestion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* improvements according to pr review comments

* Fix CI: use plural TargetFrameworks to actually restrict this sample to net10.0

Directory.Build.props sets a repo-wide TargetFrameworks (plural) list
before this project's own properties are evaluated, and the SDK decides
multi-targeting from that plural property at Sdk.props time. The prior
singular TargetFramework=net10.0 override didn't take effect early
enough, so restore still ran against net9.0/net8.0/netstandard2.0/net472
too - frameworks the published AgentMemory 1.2.0 packages don't support
(NU1202), plus surfaced an OpenTelemetry.Api advisory as an error
(NU1902) since TreatWarningsAsErrors is on repo-wide.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Fix CI: pin OpenTelemetry.Api to unblock NU1902 audit failure

The sample opts out of central package management, so it was pulling in
OpenTelemetry.Api 1.12.0 transitively (via Microsoft.Agents.AI), which has
a known moderate-severity vulnerability (GHSA-g94r-2vxg-569j). The repo
treats NuGet audit warnings as errors, so restore failed outright and took
down every dotnet-build matrix leg plus check-format.

Pinned OpenTelemetry.Api to 1.15.3, matching Directory.Packages.props.
With restore succeeding, previously-masked analyzer/format issues surfaced
and are fixed too: RCS1118 (const local for immutable Cypher queries),
CA1859 (List<IRecord> param instead of IReadOnlyList<IRecord>), and IDE1006
naming violations (s_seed field prefix, PascalCase Cypher/Shopper consts).

Verified locally with the same mcr.microsoft.com/dotnet/sdk:10.0 image CI
uses: dotnet build --warnaserror and dotnet format --verify-no-changes both
pass clean, and a full solution build completed ~24 min with zero errors.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
2026-07-16 15:39:23 +00:00

7.1 KiB
Raw Permalink Blame History

Samples Structure & Design Choices — .NET

This file documents the structure and conventions of the .NET samples so that agents (AI or human) can maintain them without rediscovering decisions.

Directory layout

dotnet/samples/
├── 01-get-started/                    # Progressive tutorial (steps 0106)
│   ├── 01_hello_agent/                # Create and run your first agent
│   ├── 02_add_tools/                  # Add function tools
│   ├── 03_multi_turn/                 # Multi-turn conversations with AgentSession
│   ├── 04_memory/                     # Agent memory with AIContextProvider
│   ├── 05_first_workflow/             # Build a workflow with executors and edges
│   └── 06_host_your_agent/            # Host your agent via Azure Functions
├── 02-agents/                         # Deep-dive concept samples
│   ├── Agents/                        # Core agent patterns (tools, structured output,
│   │                                  #   conversations, middleware, plugins, MCP, etc.)
│   ├── AgentProviders/                # Provider-grouped samples
│   │   ├── a2a/                       # A2A provider sample
│   │   ├── anthropic/                 # Anthropic provider samples
│   │   ├── azure/                     # Azure/OpenAI/Foundry model provider samples
│   │   ├── custom/                    # Custom agent implementation sample
│   │   ├── foundry/                   # Microsoft Foundry agent samples
│   │   ├── github-copilot/            # GitHub Copilot provider sample
│   │   ├── google-gemini/             # Google Gemini provider sample
│   │   ├── ollama/                    # Ollama provider sample
│   │   ├── onnx/                      # ONNX Runtime provider sample
│   │   └── openai/                    # OpenAI provider samples
│   ├── AgentOpenTelemetry/            # OpenTelemetry integration
│   ├── AgentSkills/                   # Agent skills patterns
│   ├── AgentWithMemory/               # Memory providers (chat history, Mem0, Valkey, Foundry, AgentMemory)
│   ├── AgentWithRAG/                  # RAG patterns (text, vector store, Foundry)
│   ├── AGUI/                          # AG-UI protocol samples
│   ├── DeclarativeAgents/             # Declarative agent definitions
│   ├── DevUI/                         # DevUI samples
│   └── ModelContextProtocol/          # MCP server/client patterns
├── 03-workflows/                      # Workflow patterns
│   ├── _StartHere/                    # Introductory workflow samples
│   ├── Agents/                        # Agents in workflows
│   ├── Checkpoint/                    # Checkpointing & resume
│   ├── Concurrent/                    # Concurrent execution
│   ├── ConditionalEdges/              # Conditional routing
│   ├── Declarative/                   # YAML-based workflows
│   ├── HumanInTheLoop/                # HITL patterns
│   ├── Loop/                          # Loop patterns
│   ├── Observability/                 # Workflow telemetry
│   ├── SharedStates/                  # State isolation
│   └── Visualization/                 # Workflow visualization
├── 04-hosting/                        # Deployment & hosting
│   ├── A2A/                           # Agent-to-Agent protocol
│   └── DurableAgents/                 # Durable task framework
│       ├── AzureFunctions/            #   Azure Functions hosting
│       └── ConsoleApps/               #   Console app hosting
├── 05-end-to-end/                     # Complete applications
│   ├── A2AClientServer/               # A2A client/server demo
│   ├── AgentWebChat/                  # Aspire-based web chat
│   ├── AgentWithPurview/              # Purview integration
│   ├── AGUIClientServer/              # AG-UI client/server demo
│   ├── AGUIWebChat/                   # AG-UI web chat
│   ├── HostedAgents/                  # Hosted agent scenarios
│   └── M365Agent/                     # Microsoft 365 agent

Design principles

  1. Progressive complexity: Sections 01→05 build from "hello world" to production. Within 01-get-started, projects are numbered 0106 and each step adds exactly one concept.

  2. One concept per project in 01-get-started. Each step is a standalone C# project with a single Program.cs file.

  3. Workflows preserved: 03-workflows/ keeps the upstream folder names intact. Do not rename or restructure workflow samples.

  4. Per-project structure: Each sample is a separate .csproj. Shared build configuration is inherited from Directory.Build.props.

Default provider

All canonical samples (01-get-started) use Microsoft Foundry via AIProjectClient.AsAIAgent() with DefaultAzureCredential:

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

var endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
var model = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini";

// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(model: model, instructions: "...", name: "...");

Environment variables:

  • FOUNDRY_PROJECT_ENDPOINT — Your Foundry project endpoint
  • FOUNDRY_MODEL — Model name (defaults to gpt-5.4-mini)

For authentication, run az login before running samples.

Note: Use FoundryAgent only when demonstrating Foundry-managed (prompt) agents specifically — see 02-agents/AgentsWithFoundry/. For all other samples, use AIProjectClient.AsAIAgent().

Note: For samples demonstrating other providers (Azure OpenAI, OpenAI, Anthropic, etc.), see 02-agents/AgentProviders/.

Snippet tags for docs integration

Samples embed named snippet regions for future :::code integration:

// <snippet_name>
code here
// </snippet_name>

Building and running

All samples use project references to the framework source. To build and run:

cd dotnet/samples/01-get-started/01_hello_agent
dotnet run

Current API notes

  • AIAgent is the primary agent abstraction (created via ChatClient.AsAIAgent(...))
  • AgentSession manages multi-turn conversation state
  • AIContextProvider injects memory and context
  • Prefer AIProjectClient.AsAIAgent(...) for Foundry-backed canonical samples
  • Azure Functions hosting uses ConfigureDurableAgents(options => options.AddAIAgent(agent))
  • Workflows use WorkflowBuilder with Executor<TIn, TOut> and edge connections