-
Notifications
You must be signed in to change notification settings - Fork 48
Add header propagation functionality #143
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
base: main
Are you sure you want to change the base?
Conversation
@sw-joelmut Oh nice. I have a little POC branch, but I like how this uses existing features. I'll take a look. |
Hi @tracyboehrer, we added the C# Attributes to set which headers require propagation to outgoing requests. The implementation is working when we tested it, but after merging with the latest main changes, things changed and may not work for some scenarios (we suspect Skills). We marked this PR as draft as it is not fully ready to merge with main, and we wanted to know if you like this new approach better, so we can do the final touches and ensure it is working correctly. Let us know if there are some improvements that we could apply, thanks! Note The |
Hi @tracyboehrer, we pushed the latest improvements for setting the header to propagate easier, and updated the PR's description to include attributes. |
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 header propagation functionality by adding middleware to capture incoming request headers and propagate them to outgoing requests.
- Updates test mocks to include header parameters.
- Implements the UseHeaderPropagation extension and associated middleware.
- Adds core header propagation support with new context and attribute-based configuration.
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
src/tests/Microsoft.Agents.Hosting.AspNetCore/CloudAdapterTests.cs | Updated unit tests to adjust for the new header parameter. |
src/libraries/Hosting/AspNetCore/ServiceCollectionExtensions.cs | Added UseHeaderPropagation extension to register the middleware. |
src/libraries/Hosting/AspNetCore/HeaderPropagationMiddleware.cs | New middleware for capturing headers from incoming requests. |
src/libraries/Hosting/AspNetCore/CloudAdapter.cs | Updated to propagate headers via updated activity queue. |
src/libraries/Hosting/AspNetCore/BackgroundQueue/* | Modified QueueBackgroundActivity signature and header copy handling. |
src/libraries/Core/Microsoft.Agents.Core/HeaderPropagation/* | Added core header propagation types and attribute processing. |
src/libraries/Client/* | Updated clients to include header propagation when creating HttpClient. |
{ | ||
ArgumentNullException.ThrowIfNull(claimsIdentity); | ||
ArgumentNullException.ThrowIfNull(activity); | ||
|
||
// Copy to prevent unexpected side effects from later mutations of the original headers. | ||
var copyHeaders = headers != null ? new HeaderDictionary(headers.ToDictionary()) : []; |
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 fallback using '[]' when headers is null may cause a type mismatch. Consider creating an empty HeaderDictionary instead, e.g. 'new HeaderDictionary()'.
var copyHeaders = headers != null ? new HeaderDictionary(headers.ToDictionary()) : []; | |
var copyHeaders = headers != null ? new HeaderDictionary(headers.ToDictionary()) : new HeaderDictionary(); |
Copilot uses AI. Check for mistakes.
|
||
foreach (var header in HeaderPropagationContext.HeadersFromRequest) | ||
{ | ||
httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, [header.Value]); |
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.
Passing '[header.Value]' wraps header.Value in an array, which may not match the expected type. It is likely more appropriate to pass 'header.Value' directly.
httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, [header.Value]); | |
httpClient.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value); |
Copilot uses AI. Check for mistakes.
loadHeaders.Invoke(assembly, [HeaderPropagationContext.HeadersToPropagate]); | ||
} |
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.
When invoking a static method via reflection, the instance parameter should be 'null' rather than 'assembly'. Use 'loadHeaders.Invoke(null, new object[]{ HeaderPropagationContext.HeadersToPropagate })'.
loadHeaders.Invoke(assembly, [HeaderPropagationContext.HeadersToPropagate]); | |
} | |
loadHeaders.Invoke(null, new object[] { HeaderPropagationContext.HeadersToPropagate }); |
Copilot uses AI. Check for mistakes.
@sw-joelmut Getting back to this. I'll let you know. |
# Conflicts: # src/libraries/Client/Microsoft.Agents.Client/HttpAgentClient.cs
Description
This PR adds header propagation functionality, allowing to choose which headers to transition from incoming to outgoing requests.
This implementation uses an Http middleware, a context to share values, and the options to choose which headers to propagate.
Additionally, it will also work with hosted services, as it registers the new request headers into AsyncLocal for the current context by passing the headers via ActivityWithClaims.
How to use it
Most of the propagation configuration is done internally, so, a way to use this feature is adding the
UseHeaderPropagation
method call to the application builder as follows in the Program.cs file.How it knows which headers to propagate
The header propagation functionality exposes a way to set which headers to propagate by using C# Attributes. Whenever a class uses the
[HeaderPropagation]
attribute, it will be automatically loaded into the header propagation context.This functionality provides a collection to Add, Override, Append, and Propagate incoming request headers o outgoing ones.
Here is an example:
Detailed Changes
Note
Working with Skills:
To propagate headers coming from a Root bot, the Skill will also need to register the middleware via UseHeaderPropagation.
Testing
The following image shows a testing header being propagated.
