-
Notifications
You must be signed in to change notification settings - Fork 1.1k
.NET: Feature collection adr doc #2503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
.NET: Feature collection adr doc #2503
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces an Architecture Decision Record (ADR) document exploring the design and implications of implementing feature collections in the agent framework. Feature collections would provide a mechanism for passing arbitrary services or data through the agent execution stack in a loosely-typed but type-safe manner.
- Proposes three implementation options: Feature Collections (similar to ASP.NET Core), Additional Properties Dictionary, and IServiceProvider
- Documents extension points where feature collections would be supported (Agent operations and ChatClient operations)
- Explores feature layering concepts and their complexities across application, artifact, and action scopes
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| dotnet/agent-framework-dotnet.slnx | Adds reference to the new ADR document in the solution file |
| docs/decisions/00NN-feature-collections.md | New ADR document proposing and analyzing feature collection implementation options, with detailed comparison of approaches and design considerations |
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
…ollection-adr-doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
…ollection-adr-doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| ## Implementation Options | ||
|
|
||
| Three options were considered for implementing feature collections: | ||
|
|
||
| - **Option 1**: FeatureCollections similar to ASP.NET Core | ||
| - **Option 2**: AdditionalProperties Dictionary | ||
| - **Option 3**: IServiceProvider | ||
|
|
||
| Here are some comparisons about their suitability for our use case: | ||
|
|
||
| | Criteria | Feature Collection | Additional Properties | IServiceProvider | | ||
| |------------------|--------------------|-----------------------|------------------| | ||
| |Ease of use |✅ Good |❌ Bad |✅ Good | | ||
| |User familiarity |❌ Bad |✅ Good |✅ Good | | ||
| |Type safety |✅ Good |❌ Bad |✅ Good | | ||
| |Ability to modify registered options when progressing down the stack|✅ Supported|✅ Supported|❌ Not-Supported (IServiceProvider is read-only)| | ||
| |Already available in MEAI stack|❌ No|✅ Yes|❌ No| | ||
| |Ability to layer features by scope (e.g., per-agent, per-request)|✅ Supported|❌ Not-Supported|❌ Not-Supported| | ||
|
|
||
| ## Feature Collection | ||
|
|
||
| If we choose the feature collection option, we need to decide on the design of the feature collection itself. | ||
|
|
||
| ### Feature Collections extension points | ||
|
|
||
| We need to decide the set of actions that feature collections would be supported for. Here is the suggested list of actions: | ||
|
|
||
| **MAAI.AIAgent:** | ||
|
|
||
| 1. GetNewThread | ||
| 1. E.g. this would allow passing an already existing storage id for the thread to use, or an initialized custom chat message store to use. | ||
| 1. DeserializeThread | ||
| 1. E.g. this would allow passing an already existing storage id for the thread to use, or an initialized custom chat message store to use. | ||
| 1. Run / RunStreaming | ||
| 1. E.g. this would allow passing an override chat message store just for that run, or a desired schema for a structured output middleware component. | ||
|
|
||
| **MEAI.ChatClient:** | ||
|
|
||
| 1. GetResponse / GetStreamingResponse | ||
|
|
||
| ### Feature Layering | ||
|
|
||
| One possible feature when adding support for feature collections is to allow layering of features by scope. | ||
|
|
||
| The following levels of scope could be supported: | ||
|
|
||
| 1. Application - Application wide features that apply to all agents / chat clients | ||
| 2. Artifact (Agent / ChatClient) - Features that apply to all runs of a specific agent or chat client instance | ||
| 3. Action (GetNewThread / Run / GetResponse) - Feature that apply to a single action only | ||
|
|
||
| When retrieving a feature from the collection, the search would start from the most specific scope (Action) and progress to the least specific scope (Application), returning the first matching feature found. | ||
|
|
||
| Introducing layering adds some challenges: | ||
|
|
||
| - There may be multiple feature collections at the same scope level, e.g. an Agent that uses a ChatClient where both have their own feature collections. | ||
| - Do we layer the agent feature collection over the chat client feature collection (Application -> ChatClient -> Agent -> Run), or only use the agent feature collection in the agent (Application -> Agent -> Run), and the chat client feature collection in the chat client (Application -> ChatClient -> Run)? | ||
| - The appropriate base feature collection may change when progressing down the stack, e.g. when an Agent calls a ChatClient, the action feature collection stays the same, but the artifact feature collection changes. | ||
| - Who creates the feature collection hierarchy? | ||
| - If the hierarchy changes as it progresses down the execution stack, then the caller can only pass in the action level feature collection, and the callee needs to combine it with its own artifact level feature collection and the application level feature collection. This will require changes to the feature collection type compared to asp.net, so that it can change its base collections as needed. | ||
|
|
||
| #### Layering Options | ||
|
|
||
| 1. No layering - only a single feature collection is supported per action (the caller can still create a layered collection if desired, but the callee does not do any layering automatically). | ||
| 1. Simple layering - only support layering at the artifact level (Artifact -> Action). | ||
| 1. Only apply applicable artifact level features when calling into that artifact. | ||
| 1. Apply upstream artifact features when calling into downstream artifacts, e.g. Feature hierarchy in ChatClientAgent would be `Agent -> Run` and in ChatClient would be `ChatClient -> Agent -> Run` or `Agent -> ChatClient -> Run` | ||
| 1. Full layering - support layering at all levels (Application -> Artifact -> Action). | ||
| 1. Only apply applicable artifact level features when calling into that artifact. | ||
| 1. Apply upstream artifact features when calling into downstream artifacts, e.g. Feature hierarchy in ChatClientAgent would be `Application -> Agent -> Run` and in ChatClient would be `Application -> ChatClient -> Agent -> Run` or `Application -> Agent -> ChatClient -> Run` | ||
|
|
||
| #### Accessing application level features Options | ||
|
|
||
| 1. The user provides the application level feature collection to each artifact that the user constructs | ||
| 1. Passing the application level feature collection to each artifact is tedious for the user. | ||
| 1. There is a static application level feature collection that can be accessed globally. | ||
| 1. Statics create issues with testing and isolation. | ||
|
|
||
| ### Reconciling with existing AdditionalProperties | ||
|
|
||
| If we decide to add feature collections, separately from the existing AdditionalProperties dictionaries, we need to consider how to explain to users when to use each one. | ||
| One possible approach though is to have the one use the other under the hood. | ||
| AdditionalProperties could be stored as a feature in the feature collection. | ||
|
|
||
| Users would be able to retrieve additional properties from the feature collection, in addition to retrieving it via a dedicated AdditionalProperties property. | ||
| E.g. `features.Get<AdditionalPropertiesDictionary>()` | ||
|
|
||
| One challenge with this approach is that when setting a value in the AdditionalProperties dictionary, the feature collection would need to be created first if it does not already exist. | ||
|
|
||
| ```csharp | ||
| public class AgentRunOptions | ||
| { | ||
| public AdditionalPropertiesDictionary? AdditionalProperties { get; set; } | ||
| public IAgentFeatureCollection? Features { get; set; } | ||
| } | ||
|
|
||
| var options = new AgentRunOptions(); | ||
| // This would need to create the feature collection first, if it does not already exist. | ||
| options.AdditionalProperties ??= new AdditionalPropertiesDictionary(); | ||
| ``` | ||
|
|
||
| Since IAgentFeatureCollection is an interface, AgentRunOptions would need to have a concrete implementation of the interface to create, meaning that the user cannot decide. | ||
| It also means that if the user doesn't realise that AdditionalProperties is implemented using feature collections, they may set a value on AdditionalProperties, and then later overwrite the entire feature collection, losing the AdditionalProperties feature. | ||
|
|
||
| Options to avoid these issues: | ||
|
|
||
| 1. Make `Features` readonly. | ||
| 1. This would prevent the user from overwriting the feature collection after setting AdditionalProperties. | ||
| 1. Since the user cannot set their own implementation of IAgentFeatureCollection, having an interface for it may not be necessary. | ||
|
|
||
| ### Feature Collections vs Mixins | ||
|
|
||
| An alternative to feature collections is to use mixins to add optional capabilities to agents or chat clients, where the 'feature' to pass to the agent would be part of the mixin interface. | ||
| Mixins have the advantage of being strongly typed and discoverable via interface checks. | ||
| However, mixins are less flexible, in that user code and all matching agent implementations need to share the same interface. | ||
| This creates a push towards more centralized mixin contracts which limit flexibility. | ||
|
|
||
| Combining multiple features together is also more difficult with mixins, as a new mixin interface needs to be created for each combination of features. | ||
|
|
||
| ### Feature Collection Implementation | ||
|
|
||
| We have two options for implementing feature collections: | ||
|
|
||
| 1. Create our own [IAgentFeatureCollection interface](https://github.com/microsoft/agent-framework/pull/2354/files#diff-9c42f3e60d70a791af9841d9214e038c6de3eebfc10e3997cb4cdffeb2f1246d) and [implementation](https://github.com/microsoft/agent-framework/pull/2354/files#diff-a435cc738baec500b8799f7f58c1538e3bb06c772a208afc2615ff90ada3f4ca). | ||
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | ||
|
|
||
| #### Roll our own | ||
|
|
||
| Advantages: | ||
|
|
||
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | ||
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection | ||
|
|
||
| Advantages: | ||
|
|
||
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | ||
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | ||
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? | ||
|
|
||
| The current design has some design issues that would be good to avoid. E.g. it does not distinguish between a feature being "not set" and "null". Get returns both as null and there is no tryget method. | ||
| Since the [default implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs) also supports value types, it throws for null values of value types. | ||
| A TryGet method would be more appropriate. |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ADR document is missing key sections that are typically expected in an ADR based on the template: "Decision Drivers" (what factors are driving this decision), "Considered Options" (a summary list), and most importantly "Decision Outcome" (what was actually decided). The document provides extensive "Implementation Options" details but never states which option was chosen or why. This makes the ADR incomplete as a decision record.
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | ||
|
|
||
| #### Roll our own | ||
|
|
||
| Advantages: | ||
|
|
||
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | ||
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection | ||
|
|
||
| Advantages: | ||
|
|
||
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | ||
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | ||
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling error: "asp.net" should be capitalized as "ASP.NET" to match the official product name. This appears in multiple locations throughout the document (lines 267, 332, 339, 345, 349, 350, 355). Please update all instances to use the correct capitalization "ASP.NET".
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse asp.net IFeatureCollection | |
| Advantages: | |
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | |
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? | |
| 2. Reuse the ASP.NET [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in ASP.NET Core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse ASP.NET IFeatureCollection | |
| Advantages: | |
| Reusing the ASP.NET IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from ASP.NET | |
| Core. Users who are using agents in an ASP.NET Core application may be able to pass feature collections from ASP.NET Core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from ASP.NET Core when I'm not building a web application / service? |
| We could add a simple StructuredOutputAgentFeature that can be added to the list of features and also be used to return the generated structured output. | ||
|
|
||
| ```csharp | ||
| internal class StructuredOutputAgentFeature |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent naming: The class is declared as "StructuredOutputAgentFeature" on line 101, but this is marked as "internal". However, in the extension method on line 176, a new instance is created and the feature is used publicly. If this feature class is intended to be used in extension methods accessible to users, it should be "public" rather than "internal".
| internal class StructuredOutputAgentFeature | |
| /// <summary> | |
| /// Represents configuration and results for structured output processing used by agents. | |
| /// </summary> | |
| public class StructuredOutputAgentFeature |
| <File Path="../docs/decisions/0007-agent-filtering-middleware.md" /> | ||
| <File Path="../docs/decisions/0008-python-subpackages.md" /> | ||
| <File Path="../docs/decisions/0009-support-long-running-operations.md" /> | ||
| <File Path="../docs/decisions/00NN-feature-collections.md" /> |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file name uses placeholder numbering "00NN-feature-collections.md". Based on the existing ADR files in the decisions directory, the next sequential number should be 0011, not "00NN". The file should be renamed to "0011-feature-collections.md" and the corresponding reference in the solution file should also be updated.
| <File Path="../docs/decisions/00NN-feature-collections.md" /> | |
| <File Path="../docs/decisions/0011-feature-collections.md" /> |
|
|
||
| We need to decide the set of actions that feature collections would be supported for. Here is the suggested list of actions: | ||
|
|
||
| **MAAI.AIAgent:** |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "MAAI.AIAgent" should be "MEAI.AIAgent" or more likely should reference the Agent Framework package name. Based on the context and usage pattern in other ADR documents where MEAI refers to Microsoft.Extensions.AI, this appears to be a typo. The Agent Framework agents are not part of MEAI but are part of the agent framework itself.
| **MAAI.AIAgent:** | |
| **Agent Framework AIAgent:** |
| Introducing layering adds some challenges: | ||
|
|
||
| - There may be multiple feature collections at the same scope level, e.g. an Agent that uses a ChatClient where both have their own feature collections. | ||
| - Do we layer the agent feature collection over the chat client feature collection (Application -> ChatClient -> Agent -> Run), or only use the agent feature collection in the agent (Application -> Agent -> Run), and the chat client feature collection in the chat client (Application -> ChatClient -> Run)? |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "chat client feature collection in the chat client" is redundant. Consider rewording for clarity, such as "only use the agent's feature collection within the agent" or similar phrasing that avoids the repetition.
| - Do we layer the agent feature collection over the chat client feature collection (Application -> ChatClient -> Agent -> Run), or only use the agent feature collection in the agent (Application -> Agent -> Run), and the chat client feature collection in the chat client (Application -> ChatClient -> Run)? | |
| - Do we layer the agent feature collection over the chat client feature collection (Application -> ChatClient -> Agent -> Run), or keep each artifact's feature collection scoped to itself (Application -> Agent -> Run for the agent, Application -> ChatClient -> Run for the chat client)? |
| |Already available in MEAI stack|❌ No|✅ Yes|❌ No| | ||
| |Ability to layer features by scope (e.g., per-agent, per-request)|✅ Supported|❌ Not-Supported|❌ Not-Supported| | ||
|
|
||
| ## Feature Collection |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent terminology: The document uses both "Feature Collection" (title case) and "feature collection" (lowercase) throughout. For consistency and following typical technical documentation conventions, consider using lowercase "feature collection" when referring to the concept generically, and title case only when referring to the specific type name "FeatureCollection" or interface name.
…proposed decisions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | ||
|
|
||
| #### Roll our own | ||
|
|
||
| Advantages: | ||
|
|
||
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | ||
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection | ||
|
|
||
| Advantages: | ||
|
|
||
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | ||
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization: "asp.net" should be "ASP.NET" to match the official product name and be consistent with usage elsewhere in the document.
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse asp.net IFeatureCollection | |
| Advantages: | |
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | |
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | |
| 2. Reuse the ASP.NET [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in ASP.NET Core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse ASP.NET IFeatureCollection | |
| Advantages: | |
| Reusing the ASP.NET IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from ASP.NET | |
| Core. Users who are using agents in an ASP.NET Core application may be able to pass feature collections from ASP.NET Core to the agent framework directly. |
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | ||
|
|
||
| #### Roll our own | ||
|
|
||
| Advantages: | ||
|
|
||
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | ||
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection | ||
|
|
||
| Advantages: | ||
|
|
||
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | ||
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | ||
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization: "asp.net" should be "ASP.NET" to match the official product name and be consistent with usage elsewhere in the document.
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse asp.net IFeatureCollection | |
| Advantages: | |
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | |
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? | |
| 2. Reuse the ASP.NET [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in ASP.NET Core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse ASP.NET IFeatureCollection | |
| Advantages: | |
| Reusing the ASP.NET IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from ASP.NET | |
| Core. Users who are using agents in an ASP.NET Core application may be able to pass feature collections from ASP.NET Core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from ASP.NET Core when I'm not building a web application / service? |
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | ||
|
|
||
| #### Roll our own | ||
|
|
||
| Advantages: | ||
|
|
||
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | ||
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection | ||
|
|
||
| Advantages: | ||
|
|
||
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | ||
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | ||
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization: "asp.net core" should be "ASP.NET Core" to match the official product name and be consistent with usage elsewhere in the document.
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse asp.net IFeatureCollection | |
| Advantages: | |
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | |
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? | |
| 2. Reuse the ASP.NET [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in ASP.NET Core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse ASP.NET IFeatureCollection | |
| Advantages: | |
| Reusing the ASP.NET IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from ASP.NET | |
| Core. Users who are using agents in an ASP.NET Core application may be able to pass feature collections from ASP.NET Core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from ASP.NET Core when I'm not building a web application / service? |
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection | ||
|
|
||
| Advantages: | ||
|
|
||
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | ||
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | ||
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization: "asp.net core" should be "ASP.NET Core" to match the official product name and be consistent with usage elsewhere in the document.
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse asp.net IFeatureCollection | |
| Advantages: | |
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | |
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? | |
| improve on some of the design decisions made in ASP.NET Core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse ASP.NET Core IFeatureCollection | |
| Advantages: | |
| Reusing the ASP.NET Core IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from ASP.NET | |
| Core. Users who are using agents in an ASP.NET Core application may be able to pass feature collections from ASP.NET Core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from ASP.NET Core when I'm not building a web application / service? |
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection | ||
|
|
||
| Advantages: | ||
|
|
||
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | ||
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | ||
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization: "asp.net core" should be "ASP.NET Core" to match the official product name and be consistent with usage elsewhere in the document.
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse asp.net IFeatureCollection | |
| Advantages: | |
| Reusing the asp.net IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from asp.net | |
| core. Users who are using agents in an asp.net core application may be able to pass feature collections from asp.net core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? | |
| improve on some of the design decisions made in ASP.NET Core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse ASP.NET Core IFeatureCollection | |
| Advantages: | |
| Reusing the ASP.NET Core IFeatureCollection has the advantage of being able to reuse the well-established and tested implementation from ASP.NET Core. | |
| Users who are using agents in an ASP.NET Core application may be able to pass feature collections from ASP.NET Core to the agent framework directly. | |
| Drawbacks: | |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | |
| Users may rightly ask: Why do I need to use a class from ASP.NET Core when I'm not building a web application / service? |
| <File Path="../docs/decisions/0007-agent-filtering-middleware.md" /> | ||
| <File Path="../docs/decisions/0008-python-subpackages.md" /> | ||
| <File Path="../docs/decisions/0009-support-long-running-operations.md" /> | ||
| <File Path="../docs/decisions/00NN-feature-collections.md" /> |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filename uses "00NN" as a placeholder for the ADR number. This should be replaced with the next sequential ADR number in the sequence (appears to be 0010 based on the previous ADR being 0009).
| <File Path="../docs/decisions/00NN-feature-collections.md" /> | |
| <File Path="../docs/decisions/0010-feature-collections.md" /> |
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | ||
|
|
||
| #### Roll our own | ||
|
|
||
| Advantages: | ||
|
|
||
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | ||
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | ||
|
|
||
| Drawbacks: | ||
|
|
||
| It would mean a different implementation to maintain and test. | ||
|
|
||
| #### Reuse asp.net IFeatureCollection |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent capitalization: "asp.net" should be "ASP.NET" to match the official product name and be consistent with usage elsewhere in the document (e.g., line 213 uses "ASP.NET Core").
| 2. Reuse the asp.net [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in asp.net core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse asp.net IFeatureCollection | |
| 2. Reuse the ASP.NET [IFeatureCollection interface](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/IFeatureCollection.cs) and [implementation](https://github.com/dotnet/aspnetcore/blob/main/src/Extensions/Features/src/FeatureCollection.cs). | |
| #### Roll our own | |
| Advantages: | |
| Creating our own IAgentFeatureCollection interface and implementation has the advantage of being more clearly associated with the agent framework and allows us to | |
| improve on some of the design decisions made in ASP.NET Core's IFeatureCollection. | |
| Drawbacks: | |
| It would mean a different implementation to maintain and test. | |
| #### Reuse ASP.NET IFeatureCollection |
| While the package name is `Microsoft.Extensions.Features`, the namespaces of the types are `Microsoft.AspNetCore.Http.Features`, which may create confusion for users of agent framework who are not building web applications or services. | ||
| Users may rightly ask: Why do I need to use a class from asp.net core when I'm not building a web application / service? | ||
|
|
||
| The current design has some design issues that would be good to avoid. E.g. it does not distinguish between a feature being "not set" and "null". Get returns both as null and there is no tryget method. |
Copilot
AI
Jan 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The word "tryget" should be "TryGet" (with capital 'T' and 'G') to match C# method naming conventions, since this is referring to a method name.
| The current design has some design issues that would be good to avoid. E.g. it does not distinguish between a feature being "not set" and "null". Get returns both as null and there is no tryget method. | |
| The current design has some design issues that would be good to avoid. E.g. it does not distinguish between a feature being "not set" and "null". Get returns both as null and there is no TryGet method. |
|
|
||
| // Retrieving a feature | ||
| if (options.AdditionalProperties.TryGetValue(typeof(MyFeature).FullName, out var featureObj) | ||
| && featureObj is MyFeature myFeature) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the values of the additional properties will be represented by JsonElement after deserialization, so we'll need extension methods like TryGetFeature to be able to deserialize the elements to the target type.
| allows storing arbitrary key/value pairs, where the key is a string and the value is an object. | ||
|
|
||
| While FeatureCollection uses Type as a key, AdditionalProperties uses string keys. | ||
| This means that users need to agree on string keys to use for specific features, however it is also possible to use Type.FullName as a key by convention |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add the "feature" prefix to the key to easily distinguish between features and additional props.
| - Feature Collections Container: Use AdditionalProperties | ||
| - Feature Layering: No layering - only a single collection/dictionary is supported per action. Application layers can be added later if needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The base branch was changed.
|
Closing this PR, in favor of #3332, where I'm targeting the main branch. |
Motivation and Context
Introducing features raises a number of questions that are useful to dig into further.
#2325
#3104
Description
Contribution Checklist