.NET: [PREVIEW BREAKING] Promote AgentSessionStore into Agents.AI.Abstractions - #7991
Conversation
There was a problem hiding this comment.
Pull request overview
Moves the .NET AgentSessionStore contract into Abstractions, unifying session persistence and user partitioning across hosting surfaces.
Changes:
- Introduces shared nullable lookup and explicit get-or-create semantics.
- Updates Hosting, Foundry, A2A, AGUI, OpenAI, and Azure Blob consumers.
- Adds migration documentation and isolation/compatibility tests.
Reviewed changes
Copilot reviewed 45 out of 45 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
IsolationKeyScopedAgentSessionStoreTests.cs |
Tests user-partition forwarding. |
InMemoryAgentSessionStoreTests.cs |
Tests missing sessions and isolation. |
DelegatingAgentSessionStoreTests.cs |
Updates delegation tests. |
ClaimsIdentityAgentIsolationKeyProviderTests.cs |
Tests blank claims. |
OpenAIResponsesHostingTests.cs |
Uses explicit session creation. |
OpenAIResponsesHostingLiveTests.cs |
Updates live session calls. |
AnthropicResponsesHostingLiveTests.cs |
Updates live session calls. |
AzureBlobHostedAgentBuilderExtensionsTests.cs |
Updates registration assertions. |
AzureBlobAgentSessionStoreTests.cs |
Tests isolation and legacy keys. |
A2AServerServiceCollectionExtensionsTests.cs |
Updates store mocks. |
A2AAgentHandlerTests.cs |
Verifies partition forwarding. |
AgentSessionStoreTests.cs |
Tests the shared contract. |
NoopAgentSessionStore.cs |
Returns null on lookup. |
Microsoft.Agents.AI.Hosting.csproj |
Enables experimental API support. |
Local/InMemoryAgentSessionStore.cs |
Adds user-partitioned storage. |
IsolationKeyScopedAgentSessionStoreOptions.cs |
Updates non-strict semantics. |
IsolationKeyScopedAgentSessionStore.cs |
Forwards isolation as userId. |
HostedAgentBuilderExtensions.cs |
Updates isolation wrapping. |
DelegatingAgentSessionStore.cs |
Delegates the shared API. |
AIHostAgent.cs |
Uses get-or-create semantics. |
Hosting/AgentSessionStore.cs |
Removes duplicate contract. |
Hosting.AzureStorage.csproj |
Enables experimental API support. |
AzureBlobAgentSessionStore.cs |
Adds partitioned Blob keys. |
AzureBlobHostedAgentBuilderExtensions.cs |
Updates isolation documentation. |
ClaimsIdentityAgentIsolationKeyProvider.cs |
Rejects blank claims. |
Hosting.AGUI.AspNetCore.csproj |
Suppresses experimental warning. |
AGUIEndpointRouteBuilderExtensions.cs |
Updates isolation handling. |
Hosting.A2A.csproj |
Suppresses experimental warning. |
A2AServerServiceCollectionExtensions.cs |
Updates A2A partition handling. |
Foundry.Hosting/InMemoryAgentSessionStore.cs |
Adds argument validation. |
FoundryAgentSessionStore.cs |
Validates user partitions. |
FileSystemAgentSessionStore.cs |
Validates user partitions. |
Foundry.Hosting/AgentSessionStore.cs |
Removes duplicate contract. |
PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt |
Records shared API. |
PublicAPI/net9.0/PublicAPI.Unshipped.txt |
Records shared API. |
PublicAPI/net8.0/PublicAPI.Unshipped.txt |
Records shared API. |
PublicAPI/net472/PublicAPI.Unshipped.txt |
Records shared API. |
PublicAPI/net10.0/PublicAPI.Unshipped.txt |
Records shared API. |
Abstractions/AgentSessionStore.cs |
Defines the shared contract. |
local_responses/Server/README.md |
Documents new semantics. |
local_responses/Server/Program.cs |
Migrates the sample. |
003-dotnet-hosting-protocol-helpers.md |
Updates the hosting specification. |
0039-shared-agent-session-store.md |
Adds the architectural decision. |
0032-dotnet-hosting-protocol-helpers.md |
Marks the old decision superseded. |
0031-hosted-per-user-session-storage-isolation.md |
Documents contract promotion. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: Findings reported
Scope: full PR (1 commit(s)): 21d1ee9617d8
Model: gpt-5.6-sol
Overview
The review found 2 verified inline finding(s).
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
2 verified findings remained after source verification (2 medium) across 2 files. Details are attached to the affected lines below.
Affected areas: dotnet/src/Microsoft.Agents.AI.Hosting.AzureStorage/Blob/AzureBlobAgentSessionStore.cs, dotnet/src/Microsoft.Agents.AI.Hosting/DelegatingAgentSessionStore.cs
AgentSessionStore into Agents.AI.Abstractions
AgentSessionStore into Agents.AI.AbstractionsAgentSessionStore into Agents.AI.Abstractions
| AIAgent agent, | ||
| string conversationId, | ||
| AgentSession session, | ||
| string? userId, |
There was a problem hiding this comment.
I'm concerned about having userId here as a single additional dimension by which we would want to slice the storage of sessions. What if someone wanted to have slice by a different dimension instead, or an additional dimension, like tenant.
We have two options as I see it:
- change conversationId to be sessionStorageId and require callers to build the combine e.g. conversation id with user id to get a single key if they wanted to combine those.
- Add a context object where we can add more properties as needed, including potentially an AdditionalProperties dictionary for additional arbitrary dimensions.
I looked at the different implementations we have, and none of them explicitly require userid to be a separate field. They all just end up combining the different parts into some structure.
Option 2 worries me a little bit in that it's unclear to me what properties we'd want to have in there. There are certainly many that may be candidates.
AgentSessionStore into Agents.AI.AbstractionsAgentSessionStore into Agents.AI.Abstractions
| /// default. | ||
| /// </para> | ||
| /// </remarks> | ||
| [Experimental(DiagnosticIds.Experiments.AgentsAIExperiments)] |
There was a problem hiding this comment.
This whole package is still preview, so this is probably not necessary.
| /// instance writes the current key format and only when scoped and unscoped session identifiers cannot | ||
| /// coexist. Sessions loaded through the fallback are written with the current key on their next save. | ||
| /// </remarks> | ||
| public bool EnableLegacyKeyFallback { get; set; } |
There was a problem hiding this comment.
Considering that the package is still preview, do we need this?
Note
This is a Preview version BREAKING change.
Motivation & Context
Microsoft.Agents.AI.HostingandMicrosoft.Agents.AI.Foundry.Hostingexpose incompatibleAgentSessionStoreabstractions. Storage implementations therefore depend on a specific hosting protocol package and cannot be reused consistently across hosting surfaces. A shared contract belongs besideAIAgentandAgentSessionin Abstractions.Description & Review Guide
Microsoft.Agents.AI.AgentSessionStorecontract to Abstractions using the Foundry Hosting behavior. Removes the duplicate Hosting and Foundry Hosting contracts. Updates Hosting, Foundry Hosting, A2A, AGUI, OpenAI, and Azure Storage consumers and implementations. Adds explicit user partition handling, missing session semantics, collision-free version 2 Azure Blob keys, an opt-in legacy key fallback, tests, documentation, and ADR 0039.GetSessionAsyncreturnsnullwhen no value exists,GetOrCreateSessionAsyncperforms explicit creation, and callers must provide the nullable user partition. Each successful lookup must return an independent session instance. Existing Azure Blob sessions requireEnableLegacyKeyFallbackduring a controlled migration. This is a source breaking change for implementations and callers of the previous preview contracts.Related Issue
Fixes #7990
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and the title prefix in sync automatically.