* 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>
7.1 KiB
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 01–06)
│ ├── 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
-
Progressive complexity: Sections 01→05 build from "hello world" to production. Within 01-get-started, projects are numbered 01–06 and each step adds exactly one concept.
-
One concept per project in 01-get-started. Each step is a standalone C# project with a single
Program.csfile. -
Workflows preserved: 03-workflows/ keeps the upstream folder names intact. Do not rename or restructure workflow samples.
-
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 endpointFOUNDRY_MODEL— Model name (defaults togpt-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
AIAgentis the primary agent abstraction (created viaChatClient.AsAIAgent(...))AgentSessionmanages multi-turn conversation stateAIContextProviderinjects memory and context- Prefer
AIProjectClient.AsAIAgent(...)for Foundry-backed canonical samples - Azure Functions hosting uses
ConfigureDurableAgents(options => options.AddAIAgent(agent)) - Workflows use
WorkflowBuilderwithExecutor<TIn, TOut>and edge connections